pg: add GSO support
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.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/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.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   vam->socket_client_main = &socket_client_main;
105   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
106                                       "vpp_api_test",
107                                       0 /* default socket rx, tx buffer */ )))
108     return rv;
109   /* vpp expects the client index in network order */
110   vam->my_client_index = htonl (socket_client_main.client_index);
111   return 0;
112 }
113 #else /* vpp built-in case, we don't do sockets... */
114 int
115 vat_socket_connect (vat_main_t * vam)
116 {
117   return 0;
118 }
119
120 int
121 vl_socket_client_read (int wait)
122 {
123   return -1;
124 };
125
126 int
127 vl_socket_client_write ()
128 {
129   return -1;
130 };
131
132 void *
133 vl_socket_client_msg_alloc (int nbytes)
134 {
135   return 0;
136 }
137 #endif
138
139
140 f64
141 vat_time_now (vat_main_t * vam)
142 {
143 #if VPP_API_TEST_BUILTIN
144   return vlib_time_now (vam->vlib_main);
145 #else
146   return clib_time_now (&vam->clib_time);
147 #endif
148 }
149
150 void
151 errmsg (char *fmt, ...)
152 {
153   vat_main_t *vam = &vat_main;
154   va_list va;
155   u8 *s;
156
157   va_start (va, fmt);
158   s = va_format (0, fmt, &va);
159   va_end (va);
160
161   vec_add1 (s, 0);
162
163 #if VPP_API_TEST_BUILTIN
164   vlib_cli_output (vam->vlib_main, (char *) s);
165 #else
166   {
167     if (vam->ifp != stdin)
168       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
169                vam->input_line_number);
170     else
171       fformat (vam->ofp, "%s\n", (char *) s);
172     fflush (vam->ofp);
173   }
174 #endif
175
176   vec_free (s);
177 }
178
179 #if VPP_API_TEST_BUILTIN == 0
180 static uword
181 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
182 {
183   vat_main_t *vam = va_arg (*args, vat_main_t *);
184   u32 *result = va_arg (*args, u32 *);
185   u8 *if_name;
186   uword *p;
187
188   if (!unformat (input, "%s", &if_name))
189     return 0;
190
191   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
192   if (p == 0)
193     return 0;
194   *result = p[0];
195   return 1;
196 }
197
198 static uword
199 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
200 {
201   return 0;
202 }
203
204 /* Parse an IP4 address %d.%d.%d.%d. */
205 uword
206 unformat_ip4_address (unformat_input_t * input, va_list * args)
207 {
208   u8 *result = va_arg (*args, u8 *);
209   unsigned a[4];
210
211   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
212     return 0;
213
214   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
215     return 0;
216
217   result[0] = a[0];
218   result[1] = a[1];
219   result[2] = a[2];
220   result[3] = a[3];
221
222   return 1;
223 }
224
225 uword
226 unformat_ethernet_address (unformat_input_t * input, va_list * args)
227 {
228   u8 *result = va_arg (*args, u8 *);
229   u32 i, a[6];
230
231   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
232                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
233     return 0;
234
235   /* Check range. */
236   for (i = 0; i < 6; i++)
237     if (a[i] >= (1 << 8))
238       return 0;
239
240   for (i = 0; i < 6; i++)
241     result[i] = a[i];
242
243   return 1;
244 }
245
246 /* Returns ethernet type as an int in host byte order. */
247 uword
248 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
249                                         va_list * args)
250 {
251   u16 *result = va_arg (*args, u16 *);
252   int type;
253
254   /* Numeric type. */
255   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
256     {
257       if (type >= (1 << 16))
258         return 0;
259       *result = type;
260       return 1;
261     }
262   return 0;
263 }
264
265 /* Parse an IP6 address. */
266 uword
267 unformat_ip6_address (unformat_input_t * input, va_list * args)
268 {
269   ip6_address_t *result = va_arg (*args, ip6_address_t *);
270   u16 hex_quads[8];
271   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
272   uword c, n_colon, double_colon_index;
273
274   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
275   double_colon_index = ARRAY_LEN (hex_quads);
276   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
277     {
278       hex_digit = 16;
279       if (c >= '0' && c <= '9')
280         hex_digit = c - '0';
281       else if (c >= 'a' && c <= 'f')
282         hex_digit = c + 10 - 'a';
283       else if (c >= 'A' && c <= 'F')
284         hex_digit = c + 10 - 'A';
285       else if (c == ':' && n_colon < 2)
286         n_colon++;
287       else
288         {
289           unformat_put_input (input);
290           break;
291         }
292
293       /* Too many hex quads. */
294       if (n_hex_quads >= ARRAY_LEN (hex_quads))
295         return 0;
296
297       if (hex_digit < 16)
298         {
299           hex_quad = (hex_quad << 4) | hex_digit;
300
301           /* Hex quad must fit in 16 bits. */
302           if (n_hex_digits >= 4)
303             return 0;
304
305           n_colon = 0;
306           n_hex_digits++;
307         }
308
309       /* Save position of :: */
310       if (n_colon == 2)
311         {
312           /* More than one :: ? */
313           if (double_colon_index < ARRAY_LEN (hex_quads))
314             return 0;
315           double_colon_index = n_hex_quads;
316         }
317
318       if (n_colon > 0 && n_hex_digits > 0)
319         {
320           hex_quads[n_hex_quads++] = hex_quad;
321           hex_quad = 0;
322           n_hex_digits = 0;
323         }
324     }
325
326   if (n_hex_digits > 0)
327     hex_quads[n_hex_quads++] = hex_quad;
328
329   {
330     word i;
331
332     /* Expand :: to appropriate number of zero hex quads. */
333     if (double_colon_index < ARRAY_LEN (hex_quads))
334       {
335         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
336
337         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
338           hex_quads[n_zero + i] = hex_quads[i];
339
340         for (i = 0; i < n_zero; i++)
341           hex_quads[double_colon_index + i] = 0;
342
343         n_hex_quads = ARRAY_LEN (hex_quads);
344       }
345
346     /* Too few hex quads given. */
347     if (n_hex_quads < ARRAY_LEN (hex_quads))
348       return 0;
349
350     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
351       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
352
353     return 1;
354   }
355 }
356
357 uword
358 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
359 {
360   u32 *r = va_arg (*args, u32 *);
361
362   if (0);
363 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
364   foreach_ipsec_policy_action
365 #undef _
366     else
367     return 0;
368   return 1;
369 }
370
371 u8 *
372 format_ipsec_crypto_alg (u8 * s, va_list * args)
373 {
374   u32 i = va_arg (*args, u32);
375   u8 *t = 0;
376
377   switch (i)
378     {
379 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
380       foreach_ipsec_crypto_alg
381 #undef _
382     default:
383       return format (s, "unknown");
384     }
385   return format (s, "%s", t);
386 }
387
388 u8 *
389 format_ipsec_integ_alg (u8 * s, va_list * args)
390 {
391   u32 i = va_arg (*args, u32);
392   u8 *t = 0;
393
394   switch (i)
395     {
396 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
397       foreach_ipsec_integ_alg
398 #undef _
399     default:
400       return format (s, "unknown");
401     }
402   return format (s, "%s", t);
403 }
404
405 #else /* VPP_API_TEST_BUILTIN == 1 */
406 static uword
407 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
408 {
409   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
410   vnet_main_t *vnm = vnet_get_main ();
411   u32 *result = va_arg (*args, u32 *);
412
413   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
414 }
415
416 static uword
417 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
418 {
419   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
420   vnet_main_t *vnm = vnet_get_main ();
421   u32 *result = va_arg (*args, u32 *);
422
423   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
424 }
425
426 #endif /* VPP_API_TEST_BUILTIN */
427
428 uword
429 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
435   foreach_ipsec_crypto_alg
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
444 {
445   u32 *r = va_arg (*args, u32 *);
446
447   if (0);
448 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
449   foreach_ipsec_integ_alg
450 #undef _
451     else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
458 {
459   u8 *r = va_arg (*args, u8 *);
460
461   if (unformat (input, "kbps"))
462     *r = SSE2_QOS_RATE_KBPS;
463   else if (unformat (input, "pps"))
464     *r = SSE2_QOS_RATE_PPS;
465   else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_round_type (unformat_input_t * input, va_list * args)
472 {
473   u8 *r = va_arg (*args, u8 *);
474
475   if (unformat (input, "closest"))
476     *r = SSE2_QOS_ROUND_TO_CLOSEST;
477   else if (unformat (input, "up"))
478     *r = SSE2_QOS_ROUND_TO_UP;
479   else if (unformat (input, "down"))
480     *r = SSE2_QOS_ROUND_TO_DOWN;
481   else
482     return 0;
483   return 1;
484 }
485
486 static uword
487 unformat_policer_type (unformat_input_t * input, va_list * args)
488 {
489   u8 *r = va_arg (*args, u8 *);
490
491   if (unformat (input, "1r2c"))
492     *r = SSE2_QOS_POLICER_TYPE_1R2C;
493   else if (unformat (input, "1r3c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
495   else if (unformat (input, "2r3c-2698"))
496     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
497   else if (unformat (input, "2r3c-4115"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
499   else if (unformat (input, "2r3c-mef5cf1"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
501   else
502     return 0;
503   return 1;
504 }
505
506 static uword
507 unformat_dscp (unformat_input_t * input, va_list * va)
508 {
509   u8 *r = va_arg (*va, u8 *);
510
511   if (0);
512 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
513   foreach_vnet_dscp
514 #undef _
515     else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_action_type (unformat_input_t * input, va_list * va)
522 {
523   sse2_qos_pol_action_params_st *a
524     = va_arg (*va, sse2_qos_pol_action_params_st *);
525
526   if (unformat (input, "drop"))
527     a->action_type = SSE2_QOS_ACTION_DROP;
528   else if (unformat (input, "transmit"))
529     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
530   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
531     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
532   else
533     return 0;
534   return 1;
535 }
536
537 static uword
538 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
539 {
540   u32 *r = va_arg (*va, u32 *);
541   u32 tid;
542
543   if (unformat (input, "ip4"))
544     tid = POLICER_CLASSIFY_TABLE_IP4;
545   else if (unformat (input, "ip6"))
546     tid = POLICER_CLASSIFY_TABLE_IP6;
547   else if (unformat (input, "l2"))
548     tid = POLICER_CLASSIFY_TABLE_L2;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static uword
557 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
558 {
559   u32 *r = va_arg (*va, u32 *);
560   u32 tid;
561
562   if (unformat (input, "ip4"))
563     tid = FLOW_CLASSIFY_TABLE_IP4;
564   else if (unformat (input, "ip6"))
565     tid = FLOW_CLASSIFY_TABLE_IP6;
566   else
567     return 0;
568
569   *r = tid;
570   return 1;
571 }
572
573 #if (VPP_API_TEST_BUILTIN==0)
574
575 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
576 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
577 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
578 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
579
580 uword
581 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
582 {
583   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
584   mfib_itf_attribute_t attr;
585
586   old = *iflags;
587   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
588   {
589     if (unformat (input, mfib_itf_flag_long_names[attr]))
590       *iflags |= (1 << attr);
591   }
592   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
593   {
594     if (unformat (input, mfib_itf_flag_names[attr]))
595       *iflags |= (1 << attr);
596   }
597
598   return (old == *iflags ? 0 : 1);
599 }
600
601 uword
602 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
603 {
604   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
605   mfib_entry_attribute_t attr;
606
607   old = *eflags;
608   FOR_EACH_MFIB_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_flag_long_names[attr]))
611       *eflags |= (1 << attr);
612   }
613   FOR_EACH_MFIB_ATTRIBUTE (attr)
614   {
615     if (unformat (input, mfib_flag_names[attr]))
616       *eflags |= (1 << attr);
617   }
618
619   return (old == *eflags ? 0 : 1);
620 }
621
622 u8 *
623 format_ip4_address (u8 * s, va_list * args)
624 {
625   u8 *a = va_arg (*args, u8 *);
626   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
627 }
628
629 u8 *
630 format_ip6_address (u8 * s, va_list * args)
631 {
632   ip6_address_t *a = va_arg (*args, ip6_address_t *);
633   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
634
635   i_max_n_zero = ARRAY_LEN (a->as_u16);
636   max_n_zeros = 0;
637   i_first_zero = i_max_n_zero;
638   n_zeros = 0;
639   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
640     {
641       u32 is_zero = a->as_u16[i] == 0;
642       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
643         {
644           i_first_zero = i;
645           n_zeros = 0;
646         }
647       n_zeros += is_zero;
648       if ((!is_zero && n_zeros > max_n_zeros)
649           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
650         {
651           i_max_n_zero = i_first_zero;
652           max_n_zeros = n_zeros;
653           i_first_zero = ARRAY_LEN (a->as_u16);
654           n_zeros = 0;
655         }
656     }
657
658   last_double_colon = 0;
659   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
660     {
661       if (i == i_max_n_zero && max_n_zeros > 1)
662         {
663           s = format (s, "::");
664           i += max_n_zeros - 1;
665           last_double_colon = 1;
666         }
667       else
668         {
669           s = format (s, "%s%x",
670                       (last_double_colon || i == 0) ? "" : ":",
671                       clib_net_to_host_u16 (a->as_u16[i]));
672           last_double_colon = 0;
673         }
674     }
675
676   return s;
677 }
678
679 /* Format an IP46 address. */
680 u8 *
681 format_ip46_address (u8 * s, va_list * args)
682 {
683   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
684   ip46_type_t type = va_arg (*args, ip46_type_t);
685   int is_ip4 = 1;
686
687   switch (type)
688     {
689     case IP46_TYPE_ANY:
690       is_ip4 = ip46_address_is_ip4 (ip46);
691       break;
692     case IP46_TYPE_IP4:
693       is_ip4 = 1;
694       break;
695     case IP46_TYPE_IP6:
696       is_ip4 = 0;
697       break;
698     }
699
700   return is_ip4 ?
701     format (s, "%U", format_ip4_address, &ip46->ip4) :
702     format (s, "%U", format_ip6_address, &ip46->ip6);
703 }
704
705 u8 *
706 format_ethernet_address (u8 * s, va_list * args)
707 {
708   u8 *a = va_arg (*args, u8 *);
709
710   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
711                  a[0], a[1], a[2], a[3], a[4], a[5]);
712 }
713 #endif
714
715 static void
716 increment_v4_address (vl_api_ip4_address_t * i)
717 {
718   ip4_address_t *a = (ip4_address_t *) i;
719   u32 v;
720
721   v = ntohl (a->as_u32) + 1;
722   a->as_u32 = ntohl (v);
723 }
724
725 static void
726 increment_v6_address (vl_api_ip6_address_t * i)
727 {
728   ip6_address_t *a = (ip6_address_t *) i;
729   u64 v0, v1;
730
731   v0 = clib_net_to_host_u64 (a->as_u64[0]);
732   v1 = clib_net_to_host_u64 (a->as_u64[1]);
733
734   v1 += 1;
735   if (v1 == 0)
736     v0 += 1;
737   a->as_u64[0] = clib_net_to_host_u64 (v0);
738   a->as_u64[1] = clib_net_to_host_u64 (v1);
739 }
740
741 static void
742 increment_address (vl_api_address_t * a)
743 {
744   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
745     increment_v4_address (&a->un.ip4);
746   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
747     increment_v6_address (&a->un.ip6);
748 }
749
750 static void
751 set_ip4_address (vl_api_address_t * a, u32 v)
752 {
753   if (a->af == ADDRESS_IP4)
754     {
755       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
756       i->as_u32 = v;
757     }
758 }
759
760 static void
761 increment_mac_address (u8 * mac)
762 {
763   u64 tmp = *((u64 *) mac);
764   tmp = clib_net_to_host_u64 (tmp);
765   tmp += 1 << 16;               /* skip unused (least significant) octets */
766   tmp = clib_host_to_net_u64 (tmp);
767
768   clib_memcpy (mac, &tmp, 6);
769 }
770
771 static void
772 vat_json_object_add_address (vat_json_node_t * node,
773                              const char *str, const vl_api_address_t * addr)
774 {
775   if (ADDRESS_IP6 == addr->af)
776     {
777       struct in6_addr ip6;
778
779       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
780       vat_json_object_add_ip6 (node, str, ip6);
781     }
782   else
783     {
784       struct in_addr ip4;
785
786       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
787       vat_json_object_add_ip4 (node, str, ip4);
788     }
789 }
790
791 static void
792 vat_json_object_add_prefix (vat_json_node_t * node,
793                             const vl_api_prefix_t * prefix)
794 {
795   vat_json_object_add_uint (node, "len", prefix->len);
796   vat_json_object_add_address (node, "address", &prefix->address);
797 }
798
799 static void vl_api_create_loopback_reply_t_handler
800   (vl_api_create_loopback_reply_t * mp)
801 {
802   vat_main_t *vam = &vat_main;
803   i32 retval = ntohl (mp->retval);
804
805   vam->retval = retval;
806   vam->regenerate_interface_table = 1;
807   vam->sw_if_index = ntohl (mp->sw_if_index);
808   vam->result_ready = 1;
809 }
810
811 static void vl_api_create_loopback_reply_t_handler_json
812   (vl_api_create_loopback_reply_t * mp)
813 {
814   vat_main_t *vam = &vat_main;
815   vat_json_node_t node;
816
817   vat_json_init_object (&node);
818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
820
821   vat_json_print (vam->ofp, &node);
822   vat_json_free (&node);
823   vam->retval = ntohl (mp->retval);
824   vam->result_ready = 1;
825 }
826
827 static void vl_api_create_loopback_instance_reply_t_handler
828   (vl_api_create_loopback_instance_reply_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   i32 retval = ntohl (mp->retval);
832
833   vam->retval = retval;
834   vam->regenerate_interface_table = 1;
835   vam->sw_if_index = ntohl (mp->sw_if_index);
836   vam->result_ready = 1;
837 }
838
839 static void vl_api_create_loopback_instance_reply_t_handler_json
840   (vl_api_create_loopback_instance_reply_t * mp)
841 {
842   vat_main_t *vam = &vat_main;
843   vat_json_node_t node;
844
845   vat_json_init_object (&node);
846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
848
849   vat_json_print (vam->ofp, &node);
850   vat_json_free (&node);
851   vam->retval = ntohl (mp->retval);
852   vam->result_ready = 1;
853 }
854
855 static void vl_api_af_packet_create_reply_t_handler
856   (vl_api_af_packet_create_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->regenerate_interface_table = 1;
863   vam->sw_if_index = ntohl (mp->sw_if_index);
864   vam->result_ready = 1;
865 }
866
867 static void vl_api_af_packet_create_reply_t_handler_json
868   (vl_api_af_packet_create_reply_t * mp)
869 {
870   vat_main_t *vam = &vat_main;
871   vat_json_node_t node;
872
873   vat_json_init_object (&node);
874   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
875   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
876
877   vat_json_print (vam->ofp, &node);
878   vat_json_free (&node);
879
880   vam->retval = ntohl (mp->retval);
881   vam->result_ready = 1;
882 }
883
884 static void vl_api_create_vlan_subif_reply_t_handler
885   (vl_api_create_vlan_subif_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   i32 retval = ntohl (mp->retval);
889
890   vam->retval = retval;
891   vam->regenerate_interface_table = 1;
892   vam->sw_if_index = ntohl (mp->sw_if_index);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_create_vlan_subif_reply_t_handler_json
897   (vl_api_create_vlan_subif_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_create_subif_reply_t_handler
914   (vl_api_create_subif_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918
919   vam->retval = retval;
920   vam->regenerate_interface_table = 1;
921   vam->sw_if_index = ntohl (mp->sw_if_index);
922   vam->result_ready = 1;
923 }
924
925 static void vl_api_create_subif_reply_t_handler_json
926   (vl_api_create_subif_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_interface_name_renumber_reply_t_handler
943   (vl_api_interface_name_renumber_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947
948   vam->retval = retval;
949   vam->regenerate_interface_table = 1;
950   vam->result_ready = 1;
951 }
952
953 static void vl_api_interface_name_renumber_reply_t_handler_json
954   (vl_api_interface_name_renumber_reply_t * mp)
955 {
956   vat_main_t *vam = &vat_main;
957   vat_json_node_t node;
958
959   vat_json_init_object (&node);
960   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
961
962   vat_json_print (vam->ofp, &node);
963   vat_json_free (&node);
964
965   vam->retval = ntohl (mp->retval);
966   vam->result_ready = 1;
967 }
968
969 /*
970  * Special-case: build the interface table, maintain
971  * the next loopback sw_if_index vbl.
972  */
973 static void vl_api_sw_interface_details_t_handler
974   (vl_api_sw_interface_details_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   u8 *s = format (0, "%s%c", mp->interface_name, 0);
978
979   hash_set_mem (vam->sw_if_index_by_interface_name, s,
980                 ntohl (mp->sw_if_index));
981
982   /* In sub interface case, fill the sub interface table entry */
983   if (mp->sw_if_index != mp->sup_sw_if_index)
984     {
985       sw_interface_subif_t *sub = NULL;
986
987       vec_add2 (vam->sw_if_subif_table, sub, 1);
988
989       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
990       strncpy ((char *) sub->interface_name, (char *) s,
991                vec_len (sub->interface_name));
992       sub->sw_if_index = ntohl (mp->sw_if_index);
993       sub->sub_id = ntohl (mp->sub_id);
994
995       sub->sub_dot1ad = mp->sub_dot1ad;
996       sub->sub_number_of_tags = mp->sub_number_of_tags;
997       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
998       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
999       sub->sub_exact_match = mp->sub_exact_match;
1000       sub->sub_default = mp->sub_default;
1001       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
1002       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
1003
1004       /* vlan tag rewrite */
1005       sub->vtr_op = ntohl (mp->vtr_op);
1006       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1007       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1008       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1009     }
1010 }
1011
1012 static void vl_api_sw_interface_details_t_handler_json
1013   (vl_api_sw_interface_details_t * mp)
1014 {
1015   vat_main_t *vam = &vat_main;
1016   vat_json_node_t *node = NULL;
1017
1018   if (VAT_JSON_ARRAY != vam->json_tree.type)
1019     {
1020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1021       vat_json_init_array (&vam->json_tree);
1022     }
1023   node = vat_json_array_add (&vam->json_tree);
1024
1025   vat_json_init_object (node);
1026   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1027   vat_json_object_add_uint (node, "sup_sw_if_index",
1028                             ntohl (mp->sup_sw_if_index));
1029   vat_json_object_add_uint (node, "l2_address_length",
1030                             ntohl (mp->l2_address_length));
1031   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1032                              sizeof (mp->l2_address));
1033   vat_json_object_add_string_copy (node, "interface_name",
1034                                    mp->interface_name);
1035   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1036   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1037   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1038   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1039   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1040   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1041   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1042   vat_json_object_add_uint (node, "sub_number_of_tags",
1043                             mp->sub_number_of_tags);
1044   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1045                             ntohs (mp->sub_outer_vlan_id));
1046   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1047                             ntohs (mp->sub_inner_vlan_id));
1048   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1049   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1050   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1051                             mp->sub_outer_vlan_id_any);
1052   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1053                             mp->sub_inner_vlan_id_any);
1054   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1055   vat_json_object_add_uint (node, "vtr_push_dot1q",
1056                             ntohl (mp->vtr_push_dot1q));
1057   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1058   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1059   if (mp->sub_dot1ah)
1060     {
1061       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1062                                        format (0, "%U",
1063                                                format_ethernet_address,
1064                                                &mp->b_dmac));
1065       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1066                                        format (0, "%U",
1067                                                format_ethernet_address,
1068                                                &mp->b_smac));
1069       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1070       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1071     }
1072 }
1073
1074 #if VPP_API_TEST_BUILTIN == 0
1075 static void vl_api_sw_interface_event_t_handler
1076   (vl_api_sw_interface_event_t * mp)
1077 {
1078   vat_main_t *vam = &vat_main;
1079   if (vam->interface_event_display)
1080     errmsg ("interface flags: sw_if_index %d %s %s",
1081             ntohl (mp->sw_if_index),
1082             mp->admin_up_down ? "admin-up" : "admin-down",
1083             mp->link_up_down ? "link-up" : "link-down");
1084 }
1085 #endif
1086
1087 __clib_unused static void
1088 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1089 {
1090   /* JSON output not supported */
1091 }
1092
1093 static void
1094 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   i32 retval = ntohl (mp->retval);
1098
1099   vam->retval = retval;
1100   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1101   vam->result_ready = 1;
1102 }
1103
1104 static void
1105 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1106 {
1107   vat_main_t *vam = &vat_main;
1108   vat_json_node_t node;
1109   api_main_t *am = &api_main;
1110   void *oldheap;
1111   u8 *reply;
1112
1113   vat_json_init_object (&node);
1114   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1115   vat_json_object_add_uint (&node, "reply_in_shmem",
1116                             ntohl (mp->reply_in_shmem));
1117   /* Toss the shared-memory original... */
1118   pthread_mutex_lock (&am->vlib_rp->mutex);
1119   oldheap = svm_push_data_heap (am->vlib_rp);
1120
1121   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1122   vec_free (reply);
1123
1124   svm_pop_heap (oldheap);
1125   pthread_mutex_unlock (&am->vlib_rp->mutex);
1126
1127   vat_json_print (vam->ofp, &node);
1128   vat_json_free (&node);
1129
1130   vam->retval = ntohl (mp->retval);
1131   vam->result_ready = 1;
1132 }
1133
1134 static void
1135 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1136 {
1137   vat_main_t *vam = &vat_main;
1138   i32 retval = ntohl (mp->retval);
1139   u32 length = vl_api_string_len (&mp->reply);
1140
1141   vec_reset_length (vam->cmd_reply);
1142
1143   vam->retval = retval;
1144   if (retval == 0)
1145     {
1146       vec_validate (vam->cmd_reply, length);
1147       clib_memcpy ((char *) (vam->cmd_reply),
1148                    vl_api_from_api_string (&mp->reply), length);
1149       vam->cmd_reply[length] = 0;
1150     }
1151   vam->result_ready = 1;
1152 }
1153
1154 static void
1155 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   vat_json_node_t node;
1159
1160   vec_reset_length (vam->cmd_reply);
1161
1162   vat_json_init_object (&node);
1163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1164   vat_json_object_add_string_copy (&node, "reply",
1165                                    vl_api_from_api_string (&mp->reply));
1166
1167   vat_json_print (vam->ofp, &node);
1168   vat_json_free (&node);
1169
1170   vam->retval = ntohl (mp->retval);
1171   vam->result_ready = 1;
1172 }
1173
1174 static void vl_api_classify_add_del_table_reply_t_handler
1175   (vl_api_classify_add_del_table_reply_t * mp)
1176 {
1177   vat_main_t *vam = &vat_main;
1178   i32 retval = ntohl (mp->retval);
1179   if (vam->async_mode)
1180     {
1181       vam->async_errors += (retval < 0);
1182     }
1183   else
1184     {
1185       vam->retval = retval;
1186       if (retval == 0 &&
1187           ((mp->new_table_index != 0xFFFFFFFF) ||
1188            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1189            (mp->match_n_vectors != 0xFFFFFFFF)))
1190         /*
1191          * Note: this is just barely thread-safe, depends on
1192          * the main thread spinning waiting for an answer...
1193          */
1194         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1195                 ntohl (mp->new_table_index),
1196                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1197       vam->result_ready = 1;
1198     }
1199 }
1200
1201 static void vl_api_classify_add_del_table_reply_t_handler_json
1202   (vl_api_classify_add_del_table_reply_t * mp)
1203 {
1204   vat_main_t *vam = &vat_main;
1205   vat_json_node_t node;
1206
1207   vat_json_init_object (&node);
1208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1209   vat_json_object_add_uint (&node, "new_table_index",
1210                             ntohl (mp->new_table_index));
1211   vat_json_object_add_uint (&node, "skip_n_vectors",
1212                             ntohl (mp->skip_n_vectors));
1213   vat_json_object_add_uint (&node, "match_n_vectors",
1214                             ntohl (mp->match_n_vectors));
1215
1216   vat_json_print (vam->ofp, &node);
1217   vat_json_free (&node);
1218
1219   vam->retval = ntohl (mp->retval);
1220   vam->result_ready = 1;
1221 }
1222
1223 static void vl_api_get_node_index_reply_t_handler
1224   (vl_api_get_node_index_reply_t * mp)
1225 {
1226   vat_main_t *vam = &vat_main;
1227   i32 retval = ntohl (mp->retval);
1228   if (vam->async_mode)
1229     {
1230       vam->async_errors += (retval < 0);
1231     }
1232   else
1233     {
1234       vam->retval = retval;
1235       if (retval == 0)
1236         errmsg ("node index %d", ntohl (mp->node_index));
1237       vam->result_ready = 1;
1238     }
1239 }
1240
1241 static void vl_api_get_node_index_reply_t_handler_json
1242   (vl_api_get_node_index_reply_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t node;
1246
1247   vat_json_init_object (&node);
1248   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1249   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1250
1251   vat_json_print (vam->ofp, &node);
1252   vat_json_free (&node);
1253
1254   vam->retval = ntohl (mp->retval);
1255   vam->result_ready = 1;
1256 }
1257
1258 static void vl_api_get_next_index_reply_t_handler
1259   (vl_api_get_next_index_reply_t * mp)
1260 {
1261   vat_main_t *vam = &vat_main;
1262   i32 retval = ntohl (mp->retval);
1263   if (vam->async_mode)
1264     {
1265       vam->async_errors += (retval < 0);
1266     }
1267   else
1268     {
1269       vam->retval = retval;
1270       if (retval == 0)
1271         errmsg ("next node index %d", ntohl (mp->next_index));
1272       vam->result_ready = 1;
1273     }
1274 }
1275
1276 static void vl_api_get_next_index_reply_t_handler_json
1277   (vl_api_get_next_index_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t node;
1281
1282   vat_json_init_object (&node);
1283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1284   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1285
1286   vat_json_print (vam->ofp, &node);
1287   vat_json_free (&node);
1288
1289   vam->retval = ntohl (mp->retval);
1290   vam->result_ready = 1;
1291 }
1292
1293 static void vl_api_add_node_next_reply_t_handler
1294   (vl_api_add_node_next_reply_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   i32 retval = ntohl (mp->retval);
1298   if (vam->async_mode)
1299     {
1300       vam->async_errors += (retval < 0);
1301     }
1302   else
1303     {
1304       vam->retval = retval;
1305       if (retval == 0)
1306         errmsg ("next index %d", ntohl (mp->next_index));
1307       vam->result_ready = 1;
1308     }
1309 }
1310
1311 static void vl_api_add_node_next_reply_t_handler_json
1312   (vl_api_add_node_next_reply_t * mp)
1313 {
1314   vat_main_t *vam = &vat_main;
1315   vat_json_node_t node;
1316
1317   vat_json_init_object (&node);
1318   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1319   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1320
1321   vat_json_print (vam->ofp, &node);
1322   vat_json_free (&node);
1323
1324   vam->retval = ntohl (mp->retval);
1325   vam->result_ready = 1;
1326 }
1327
1328 static void vl_api_show_version_reply_t_handler
1329   (vl_api_show_version_reply_t * mp)
1330 {
1331   vat_main_t *vam = &vat_main;
1332   i32 retval = ntohl (mp->retval);
1333
1334   if (retval >= 0)
1335     {
1336       u8 *s = 0;
1337       char *p = (char *) &mp->program;
1338
1339       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1340       errmsg ("        program: %v\n", s);
1341       vec_free (s);
1342
1343       p +=
1344         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1345       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1346       errmsg ("        version: %v\n", s);
1347       vec_free (s);
1348
1349       p +=
1350         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1351       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1352       errmsg ("     build date: %v\n", s);
1353       vec_free (s);
1354
1355       p +=
1356         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1357       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1358       errmsg ("build directory: %v\n", s);
1359       vec_free (s);
1360     }
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void vl_api_show_version_reply_t_handler_json
1366   (vl_api_show_version_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t node;
1370
1371   vat_json_init_object (&node);
1372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1373   char *p = (char *) &mp->program;
1374   vat_json_object_add_string_copy (&node, "program",
1375                                    vl_api_from_api_string ((vl_api_string_t *)
1376                                                            p));
1377   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1378   vat_json_object_add_string_copy (&node, "version",
1379                                    vl_api_from_api_string ((vl_api_string_t *)
1380                                                            p));
1381   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1382   vat_json_object_add_string_copy (&node, "build_date",
1383                                    vl_api_from_api_string ((vl_api_string_t *)
1384                                                            p));
1385   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1386   vat_json_object_add_string_copy (&node, "build_directory",
1387                                    vl_api_from_api_string ((vl_api_string_t *)
1388                                                            p));
1389
1390   vat_json_print (vam->ofp, &node);
1391   vat_json_free (&node);
1392
1393   vam->retval = ntohl (mp->retval);
1394   vam->result_ready = 1;
1395 }
1396
1397 static void vl_api_show_threads_reply_t_handler
1398   (vl_api_show_threads_reply_t * mp)
1399 {
1400   vat_main_t *vam = &vat_main;
1401   i32 retval = ntohl (mp->retval);
1402   int i, count = 0;
1403
1404   if (retval >= 0)
1405     count = ntohl (mp->count);
1406
1407   for (i = 0; i < count; i++)
1408     print (vam->ofp,
1409            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1410            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1411            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1412            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1413            ntohl (mp->thread_data[i].cpu_socket));
1414
1415   vam->retval = retval;
1416   vam->result_ready = 1;
1417 }
1418
1419 static void vl_api_show_threads_reply_t_handler_json
1420   (vl_api_show_threads_reply_t * mp)
1421 {
1422   vat_main_t *vam = &vat_main;
1423   vat_json_node_t node;
1424   vl_api_thread_data_t *td;
1425   i32 retval = ntohl (mp->retval);
1426   int i, count = 0;
1427
1428   if (retval >= 0)
1429     count = ntohl (mp->count);
1430
1431   vat_json_init_object (&node);
1432   vat_json_object_add_int (&node, "retval", retval);
1433   vat_json_object_add_uint (&node, "count", count);
1434
1435   for (i = 0; i < count; i++)
1436     {
1437       td = &mp->thread_data[i];
1438       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1439       vat_json_object_add_string_copy (&node, "name", td->name);
1440       vat_json_object_add_string_copy (&node, "type", td->type);
1441       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1442       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1443       vat_json_object_add_int (&node, "core", ntohl (td->id));
1444       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1445     }
1446
1447   vat_json_print (vam->ofp, &node);
1448   vat_json_free (&node);
1449
1450   vam->retval = retval;
1451   vam->result_ready = 1;
1452 }
1453
1454 static int
1455 api_show_threads (vat_main_t * vam)
1456 {
1457   vl_api_show_threads_t *mp;
1458   int ret;
1459
1460   print (vam->ofp,
1461          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1462          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1463
1464   M (SHOW_THREADS, mp);
1465
1466   S (mp);
1467   W (ret);
1468   return ret;
1469 }
1470
1471 static void
1472 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1473 {
1474   u32 sw_if_index = ntohl (mp->sw_if_index);
1475   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1476           mp->mac_ip ? "mac/ip binding" : "address resolution",
1477           ntohl (mp->pid), format_ip4_address, mp->ip,
1478           format_vl_api_mac_address, &mp->mac, sw_if_index);
1479 }
1480
1481 static void
1482 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1483 {
1484   /* JSON output not supported */
1485 }
1486
1487 static void
1488 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1489 {
1490   u32 sw_if_index = ntohl (mp->sw_if_index);
1491   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1492           mp->mac_ip ? "mac/ip binding" : "address resolution",
1493           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1494           format_vl_api_mac_address, mp->mac, sw_if_index);
1495 }
1496
1497 static void
1498 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1499 {
1500   /* JSON output not supported */
1501 }
1502
1503 static void
1504 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1505 {
1506   u32 n_macs = ntohl (mp->n_macs);
1507   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1508           ntohl (mp->pid), mp->client_index, n_macs);
1509   int i;
1510   for (i = 0; i < n_macs; i++)
1511     {
1512       vl_api_mac_entry_t *mac = &mp->mac[i];
1513       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1514               i + 1, ntohl (mac->sw_if_index),
1515               format_ethernet_address, mac->mac_addr, mac->action);
1516       if (i == 1000)
1517         break;
1518     }
1519 }
1520
1521 static void
1522 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1523 {
1524   /* JSON output not supported */
1525 }
1526
1527 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1528 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1529
1530 /*
1531  * Special-case: build the bridge domain table, maintain
1532  * the next bd id vbl.
1533  */
1534 static void vl_api_bridge_domain_details_t_handler
1535   (vl_api_bridge_domain_details_t * mp)
1536 {
1537   vat_main_t *vam = &vat_main;
1538   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1539   int i;
1540
1541   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1542          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1543
1544   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1545          ntohl (mp->bd_id), mp->learn, mp->forward,
1546          mp->flood, ntohl (mp->bvi_sw_if_index),
1547          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1548
1549   if (n_sw_ifs)
1550     {
1551       vl_api_bridge_domain_sw_if_t *sw_ifs;
1552       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1553              "Interface Name");
1554
1555       sw_ifs = mp->sw_if_details;
1556       for (i = 0; i < n_sw_ifs; i++)
1557         {
1558           u8 *sw_if_name = 0;
1559           u32 sw_if_index;
1560           hash_pair_t *p;
1561
1562           sw_if_index = ntohl (sw_ifs->sw_if_index);
1563
1564           /* *INDENT-OFF* */
1565           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1566                              ({
1567                                if ((u32) p->value[0] == sw_if_index)
1568                                  {
1569                                    sw_if_name = (u8 *)(p->key);
1570                                    break;
1571                                  }
1572                              }));
1573           /* *INDENT-ON* */
1574           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1575                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1576                  "sw_if_index not found!");
1577
1578           sw_ifs++;
1579         }
1580     }
1581 }
1582
1583 static void vl_api_bridge_domain_details_t_handler_json
1584   (vl_api_bridge_domain_details_t * mp)
1585 {
1586   vat_main_t *vam = &vat_main;
1587   vat_json_node_t *node, *array = NULL;
1588   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1589
1590   if (VAT_JSON_ARRAY != vam->json_tree.type)
1591     {
1592       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1593       vat_json_init_array (&vam->json_tree);
1594     }
1595   node = vat_json_array_add (&vam->json_tree);
1596
1597   vat_json_init_object (node);
1598   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1599   vat_json_object_add_uint (node, "flood", mp->flood);
1600   vat_json_object_add_uint (node, "forward", mp->forward);
1601   vat_json_object_add_uint (node, "learn", mp->learn);
1602   vat_json_object_add_uint (node, "bvi_sw_if_index",
1603                             ntohl (mp->bvi_sw_if_index));
1604   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1605   array = vat_json_object_add (node, "sw_if");
1606   vat_json_init_array (array);
1607
1608
1609
1610   if (n_sw_ifs)
1611     {
1612       vl_api_bridge_domain_sw_if_t *sw_ifs;
1613       int i;
1614
1615       sw_ifs = mp->sw_if_details;
1616       for (i = 0; i < n_sw_ifs; i++)
1617         {
1618           node = vat_json_array_add (array);
1619           vat_json_init_object (node);
1620           vat_json_object_add_uint (node, "sw_if_index",
1621                                     ntohl (sw_ifs->sw_if_index));
1622           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1623           sw_ifs++;
1624         }
1625     }
1626 }
1627
1628 static void vl_api_control_ping_reply_t_handler
1629   (vl_api_control_ping_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   i32 retval = ntohl (mp->retval);
1633   if (vam->async_mode)
1634     {
1635       vam->async_errors += (retval < 0);
1636     }
1637   else
1638     {
1639       vam->retval = retval;
1640       vam->result_ready = 1;
1641     }
1642   if (vam->socket_client_main)
1643     vam->socket_client_main->control_pings_outstanding--;
1644 }
1645
1646 static void vl_api_control_ping_reply_t_handler_json
1647   (vl_api_control_ping_reply_t * mp)
1648 {
1649   vat_main_t *vam = &vat_main;
1650   i32 retval = ntohl (mp->retval);
1651
1652   if (VAT_JSON_NONE != vam->json_tree.type)
1653     {
1654       vat_json_print (vam->ofp, &vam->json_tree);
1655       vat_json_free (&vam->json_tree);
1656       vam->json_tree.type = VAT_JSON_NONE;
1657     }
1658   else
1659     {
1660       /* just print [] */
1661       vat_json_init_array (&vam->json_tree);
1662       vat_json_print (vam->ofp, &vam->json_tree);
1663       vam->json_tree.type = VAT_JSON_NONE;
1664     }
1665
1666   vam->retval = retval;
1667   vam->result_ready = 1;
1668 }
1669
1670 static void
1671   vl_api_bridge_domain_set_mac_age_reply_t_handler
1672   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1673 {
1674   vat_main_t *vam = &vat_main;
1675   i32 retval = ntohl (mp->retval);
1676   if (vam->async_mode)
1677     {
1678       vam->async_errors += (retval < 0);
1679     }
1680   else
1681     {
1682       vam->retval = retval;
1683       vam->result_ready = 1;
1684     }
1685 }
1686
1687 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1688   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   vat_json_node_t node;
1692
1693   vat_json_init_object (&node);
1694   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1695
1696   vat_json_print (vam->ofp, &node);
1697   vat_json_free (&node);
1698
1699   vam->retval = ntohl (mp->retval);
1700   vam->result_ready = 1;
1701 }
1702
1703 static void
1704 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1705 {
1706   vat_main_t *vam = &vat_main;
1707   i32 retval = ntohl (mp->retval);
1708   if (vam->async_mode)
1709     {
1710       vam->async_errors += (retval < 0);
1711     }
1712   else
1713     {
1714       vam->retval = retval;
1715       vam->result_ready = 1;
1716     }
1717 }
1718
1719 static void vl_api_l2_flags_reply_t_handler_json
1720   (vl_api_l2_flags_reply_t * mp)
1721 {
1722   vat_main_t *vam = &vat_main;
1723   vat_json_node_t node;
1724
1725   vat_json_init_object (&node);
1726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1727   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1728                             ntohl (mp->resulting_feature_bitmap));
1729
1730   vat_json_print (vam->ofp, &node);
1731   vat_json_free (&node);
1732
1733   vam->retval = ntohl (mp->retval);
1734   vam->result_ready = 1;
1735 }
1736
1737 static void vl_api_bridge_flags_reply_t_handler
1738   (vl_api_bridge_flags_reply_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   i32 retval = ntohl (mp->retval);
1742   if (vam->async_mode)
1743     {
1744       vam->async_errors += (retval < 0);
1745     }
1746   else
1747     {
1748       vam->retval = retval;
1749       vam->result_ready = 1;
1750     }
1751 }
1752
1753 static void vl_api_bridge_flags_reply_t_handler_json
1754   (vl_api_bridge_flags_reply_t * mp)
1755 {
1756   vat_main_t *vam = &vat_main;
1757   vat_json_node_t node;
1758
1759   vat_json_init_object (&node);
1760   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1761   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1762                             ntohl (mp->resulting_feature_bitmap));
1763
1764   vat_json_print (vam->ofp, &node);
1765   vat_json_free (&node);
1766
1767   vam->retval = ntohl (mp->retval);
1768   vam->result_ready = 1;
1769 }
1770
1771 static void
1772 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   i32 retval = ntohl (mp->retval);
1776   if (vam->async_mode)
1777     {
1778       vam->async_errors += (retval < 0);
1779     }
1780   else
1781     {
1782       vam->retval = retval;
1783       vam->sw_if_index = ntohl (mp->sw_if_index);
1784       vam->result_ready = 1;
1785     }
1786
1787 }
1788
1789 static void vl_api_tap_create_v2_reply_t_handler_json
1790   (vl_api_tap_create_v2_reply_t * mp)
1791 {
1792   vat_main_t *vam = &vat_main;
1793   vat_json_node_t node;
1794
1795   vat_json_init_object (&node);
1796   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1797   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1798
1799   vat_json_print (vam->ofp, &node);
1800   vat_json_free (&node);
1801
1802   vam->retval = ntohl (mp->retval);
1803   vam->result_ready = 1;
1804
1805 }
1806
1807 static void
1808 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1809 {
1810   vat_main_t *vam = &vat_main;
1811   i32 retval = ntohl (mp->retval);
1812   if (vam->async_mode)
1813     {
1814       vam->async_errors += (retval < 0);
1815     }
1816   else
1817     {
1818       vam->retval = retval;
1819       vam->result_ready = 1;
1820     }
1821 }
1822
1823 static void vl_api_tap_delete_v2_reply_t_handler_json
1824   (vl_api_tap_delete_v2_reply_t * mp)
1825 {
1826   vat_main_t *vam = &vat_main;
1827   vat_json_node_t node;
1828
1829   vat_json_init_object (&node);
1830   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1831
1832   vat_json_print (vam->ofp, &node);
1833   vat_json_free (&node);
1834
1835   vam->retval = ntohl (mp->retval);
1836   vam->result_ready = 1;
1837 }
1838
1839 static void
1840 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1841                                           mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844   i32 retval = ntohl (mp->retval);
1845   if (vam->async_mode)
1846     {
1847       vam->async_errors += (retval < 0);
1848     }
1849   else
1850     {
1851       vam->retval = retval;
1852       vam->sw_if_index = ntohl (mp->sw_if_index);
1853       vam->result_ready = 1;
1854     }
1855 }
1856
1857 static void vl_api_virtio_pci_create_reply_t_handler_json
1858   (vl_api_virtio_pci_create_reply_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   vat_json_node_t node;
1862
1863   vat_json_init_object (&node);
1864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1866
1867   vat_json_print (vam->ofp, &node);
1868   vat_json_free (&node);
1869
1870   vam->retval = ntohl (mp->retval);
1871   vam->result_ready = 1;
1872
1873 }
1874
1875 static void
1876 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1877                                           mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   i32 retval = ntohl (mp->retval);
1881   if (vam->async_mode)
1882     {
1883       vam->async_errors += (retval < 0);
1884     }
1885   else
1886     {
1887       vam->retval = retval;
1888       vam->result_ready = 1;
1889     }
1890 }
1891
1892 static void vl_api_virtio_pci_delete_reply_t_handler_json
1893   (vl_api_virtio_pci_delete_reply_t * mp)
1894 {
1895   vat_main_t *vam = &vat_main;
1896   vat_json_node_t node;
1897
1898   vat_json_init_object (&node);
1899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1900
1901   vat_json_print (vam->ofp, &node);
1902   vat_json_free (&node);
1903
1904   vam->retval = ntohl (mp->retval);
1905   vam->result_ready = 1;
1906 }
1907
1908 static void
1909 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1910 {
1911   vat_main_t *vam = &vat_main;
1912   i32 retval = ntohl (mp->retval);
1913
1914   if (vam->async_mode)
1915     {
1916       vam->async_errors += (retval < 0);
1917     }
1918   else
1919     {
1920       vam->retval = retval;
1921       vam->sw_if_index = ntohl (mp->sw_if_index);
1922       vam->result_ready = 1;
1923     }
1924 }
1925
1926 static void vl_api_bond_create_reply_t_handler_json
1927   (vl_api_bond_create_reply_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930   vat_json_node_t node;
1931
1932   vat_json_init_object (&node);
1933   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1934   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1935
1936   vat_json_print (vam->ofp, &node);
1937   vat_json_free (&node);
1938
1939   vam->retval = ntohl (mp->retval);
1940   vam->result_ready = 1;
1941 }
1942
1943 static void
1944 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1945 {
1946   vat_main_t *vam = &vat_main;
1947   i32 retval = ntohl (mp->retval);
1948
1949   if (vam->async_mode)
1950     {
1951       vam->async_errors += (retval < 0);
1952     }
1953   else
1954     {
1955       vam->retval = retval;
1956       vam->result_ready = 1;
1957     }
1958 }
1959
1960 static void vl_api_bond_delete_reply_t_handler_json
1961   (vl_api_bond_delete_reply_t * mp)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   vat_json_node_t node;
1965
1966   vat_json_init_object (&node);
1967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1968
1969   vat_json_print (vam->ofp, &node);
1970   vat_json_free (&node);
1971
1972   vam->retval = ntohl (mp->retval);
1973   vam->result_ready = 1;
1974 }
1975
1976 static void
1977 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   i32 retval = ntohl (mp->retval);
1981
1982   if (vam->async_mode)
1983     {
1984       vam->async_errors += (retval < 0);
1985     }
1986   else
1987     {
1988       vam->retval = retval;
1989       vam->result_ready = 1;
1990     }
1991 }
1992
1993 static void vl_api_bond_enslave_reply_t_handler_json
1994   (vl_api_bond_enslave_reply_t * mp)
1995 {
1996   vat_main_t *vam = &vat_main;
1997   vat_json_node_t node;
1998
1999   vat_json_init_object (&node);
2000   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2001
2002   vat_json_print (vam->ofp, &node);
2003   vat_json_free (&node);
2004
2005   vam->retval = ntohl (mp->retval);
2006   vam->result_ready = 1;
2007 }
2008
2009 static void
2010 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2011                                           mp)
2012 {
2013   vat_main_t *vam = &vat_main;
2014   i32 retval = ntohl (mp->retval);
2015
2016   if (vam->async_mode)
2017     {
2018       vam->async_errors += (retval < 0);
2019     }
2020   else
2021     {
2022       vam->retval = retval;
2023       vam->result_ready = 1;
2024     }
2025 }
2026
2027 static void vl_api_bond_detach_slave_reply_t_handler_json
2028   (vl_api_bond_detach_slave_reply_t * mp)
2029 {
2030   vat_main_t *vam = &vat_main;
2031   vat_json_node_t node;
2032
2033   vat_json_init_object (&node);
2034   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2035
2036   vat_json_print (vam->ofp, &node);
2037   vat_json_free (&node);
2038
2039   vam->retval = ntohl (mp->retval);
2040   vam->result_ready = 1;
2041 }
2042
2043 static void vl_api_sw_interface_bond_details_t_handler
2044   (vl_api_sw_interface_bond_details_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047
2048   print (vam->ofp,
2049          "%-16s %-12d %-12U %-13U %-14u %-14u",
2050          mp->interface_name, ntohl (mp->sw_if_index),
2051          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2052          ntohl (mp->active_slaves), ntohl (mp->slaves));
2053 }
2054
2055 static void vl_api_sw_interface_bond_details_t_handler_json
2056   (vl_api_sw_interface_bond_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vat_json_node_t *node = NULL;
2060
2061   if (VAT_JSON_ARRAY != vam->json_tree.type)
2062     {
2063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064       vat_json_init_array (&vam->json_tree);
2065     }
2066   node = vat_json_array_add (&vam->json_tree);
2067
2068   vat_json_init_object (node);
2069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070   vat_json_object_add_string_copy (node, "interface_name",
2071                                    mp->interface_name);
2072   vat_json_object_add_uint (node, "mode", mp->mode);
2073   vat_json_object_add_uint (node, "load_balance", mp->lb);
2074   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076 }
2077
2078 static int
2079 api_sw_interface_bond_dump (vat_main_t * vam)
2080 {
2081   vl_api_sw_interface_bond_dump_t *mp;
2082   vl_api_control_ping_t *mp_ping;
2083   int ret;
2084
2085   print (vam->ofp,
2086          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087          "interface name", "sw_if_index", "mode", "load balance",
2088          "active slaves", "slaves");
2089
2090   /* Get list of bond interfaces */
2091   M (SW_INTERFACE_BOND_DUMP, mp);
2092   S (mp);
2093
2094   /* Use a control ping for synchronization */
2095   MPING (CONTROL_PING, mp_ping);
2096   S (mp_ping);
2097
2098   W (ret);
2099   return ret;
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106
2107   print (vam->ofp,
2108          "%-25s %-12d %-12d %d", mp->interface_name,
2109          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2110 }
2111
2112 static void vl_api_sw_interface_slave_details_t_handler_json
2113   (vl_api_sw_interface_slave_details_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116   vat_json_node_t *node = NULL;
2117
2118   if (VAT_JSON_ARRAY != vam->json_tree.type)
2119     {
2120       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2121       vat_json_init_array (&vam->json_tree);
2122     }
2123   node = vat_json_array_add (&vam->json_tree);
2124
2125   vat_json_init_object (node);
2126   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2127   vat_json_object_add_string_copy (node, "interface_name",
2128                                    mp->interface_name);
2129   vat_json_object_add_uint (node, "passive", mp->is_passive);
2130   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2131 }
2132
2133 static int
2134 api_sw_interface_slave_dump (vat_main_t * vam)
2135 {
2136   unformat_input_t *i = vam->input;
2137   vl_api_sw_interface_slave_dump_t *mp;
2138   vl_api_control_ping_t *mp_ping;
2139   u32 sw_if_index = ~0;
2140   u8 sw_if_index_set = 0;
2141   int ret;
2142
2143   /* Parse args required to build the message */
2144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2145     {
2146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2147         sw_if_index_set = 1;
2148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2149         sw_if_index_set = 1;
2150       else
2151         break;
2152     }
2153
2154   if (sw_if_index_set == 0)
2155     {
2156       errmsg ("missing vpp interface name. ");
2157       return -99;
2158     }
2159
2160   print (vam->ofp,
2161          "\n%-25s %-12s %-12s %s",
2162          "slave interface name", "sw_if_index", "passive", "long_timeout");
2163
2164   /* Get list of bond interfaces */
2165   M (SW_INTERFACE_SLAVE_DUMP, mp);
2166   mp->sw_if_index = ntohl (sw_if_index);
2167   S (mp);
2168
2169   /* Use a control ping for synchronization */
2170   MPING (CONTROL_PING, mp_ping);
2171   S (mp_ping);
2172
2173   W (ret);
2174   return ret;
2175 }
2176
2177 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2178   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2179 {
2180   vat_main_t *vam = &vat_main;
2181   i32 retval = ntohl (mp->retval);
2182   if (vam->async_mode)
2183     {
2184       vam->async_errors += (retval < 0);
2185     }
2186   else
2187     {
2188       vam->retval = retval;
2189       vam->sw_if_index = ntohl (mp->sw_if_index);
2190       vam->result_ready = 1;
2191     }
2192   vam->regenerate_interface_table = 1;
2193 }
2194
2195 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2196   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vat_json_node_t node;
2200
2201   vat_json_init_object (&node);
2202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2203   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2204                             ntohl (mp->sw_if_index));
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2214   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   i32 retval = ntohl (mp->retval);
2218   if (vam->async_mode)
2219     {
2220       vam->async_errors += (retval < 0);
2221     }
2222   else
2223     {
2224       vam->retval = retval;
2225       vam->sw_if_index = ntohl (mp->sw_if_index);
2226       vam->result_ready = 1;
2227     }
2228 }
2229
2230 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2231   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   vat_json_node_t node;
2235
2236   vat_json_init_object (&node);
2237   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2238   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2239
2240   vat_json_print (vam->ofp, &node);
2241   vat_json_free (&node);
2242
2243   vam->retval = ntohl (mp->retval);
2244   vam->result_ready = 1;
2245 }
2246
2247 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2248   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   i32 retval = ntohl (mp->retval);
2252   if (vam->async_mode)
2253     {
2254       vam->async_errors += (retval < 0);
2255     }
2256   else
2257     {
2258       vam->retval = retval;
2259       vam->result_ready = 1;
2260     }
2261 }
2262
2263 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2264   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2265 {
2266   vat_main_t *vam = &vat_main;
2267   vat_json_node_t node;
2268
2269   vat_json_init_object (&node);
2270   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2271   vat_json_object_add_uint (&node, "fwd_entry_index",
2272                             clib_net_to_host_u32 (mp->fwd_entry_index));
2273
2274   vat_json_print (vam->ofp, &node);
2275   vat_json_free (&node);
2276
2277   vam->retval = ntohl (mp->retval);
2278   vam->result_ready = 1;
2279 }
2280
2281 u8 *
2282 format_lisp_transport_protocol (u8 * s, va_list * args)
2283 {
2284   u32 proto = va_arg (*args, u32);
2285
2286   switch (proto)
2287     {
2288     case 1:
2289       return format (s, "udp");
2290     case 2:
2291       return format (s, "api");
2292     default:
2293       return 0;
2294     }
2295   return 0;
2296 }
2297
2298 static void vl_api_one_get_transport_protocol_reply_t_handler
2299   (vl_api_one_get_transport_protocol_reply_t * mp)
2300 {
2301   vat_main_t *vam = &vat_main;
2302   i32 retval = ntohl (mp->retval);
2303   if (vam->async_mode)
2304     {
2305       vam->async_errors += (retval < 0);
2306     }
2307   else
2308     {
2309       u32 proto = mp->protocol;
2310       print (vam->ofp, "Transport protocol: %U",
2311              format_lisp_transport_protocol, proto);
2312       vam->retval = retval;
2313       vam->result_ready = 1;
2314     }
2315 }
2316
2317 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2318   (vl_api_one_get_transport_protocol_reply_t * mp)
2319 {
2320   vat_main_t *vam = &vat_main;
2321   vat_json_node_t node;
2322   u8 *s;
2323
2324   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2325   vec_add1 (s, 0);
2326
2327   vat_json_init_object (&node);
2328   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2329   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2330
2331   vec_free (s);
2332   vat_json_print (vam->ofp, &node);
2333   vat_json_free (&node);
2334
2335   vam->retval = ntohl (mp->retval);
2336   vam->result_ready = 1;
2337 }
2338
2339 static void vl_api_one_add_del_locator_set_reply_t_handler
2340   (vl_api_one_add_del_locator_set_reply_t * mp)
2341 {
2342   vat_main_t *vam = &vat_main;
2343   i32 retval = ntohl (mp->retval);
2344   if (vam->async_mode)
2345     {
2346       vam->async_errors += (retval < 0);
2347     }
2348   else
2349     {
2350       vam->retval = retval;
2351       vam->result_ready = 1;
2352     }
2353 }
2354
2355 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2356   (vl_api_one_add_del_locator_set_reply_t * mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   vat_json_node_t node;
2360
2361   vat_json_init_object (&node);
2362   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2363   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2364
2365   vat_json_print (vam->ofp, &node);
2366   vat_json_free (&node);
2367
2368   vam->retval = ntohl (mp->retval);
2369   vam->result_ready = 1;
2370 }
2371
2372 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2373   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   i32 retval = ntohl (mp->retval);
2377   if (vam->async_mode)
2378     {
2379       vam->async_errors += (retval < 0);
2380     }
2381   else
2382     {
2383       vam->retval = retval;
2384       vam->sw_if_index = ntohl (mp->sw_if_index);
2385       vam->result_ready = 1;
2386     }
2387   vam->regenerate_interface_table = 1;
2388 }
2389
2390 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2391   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   vat_json_node_t node;
2395
2396   vat_json_init_object (&node);
2397   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2398   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2399
2400   vat_json_print (vam->ofp, &node);
2401   vat_json_free (&node);
2402
2403   vam->retval = ntohl (mp->retval);
2404   vam->result_ready = 1;
2405 }
2406
2407 static void vl_api_vxlan_offload_rx_reply_t_handler
2408   (vl_api_vxlan_offload_rx_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   i32 retval = ntohl (mp->retval);
2412   if (vam->async_mode)
2413     {
2414       vam->async_errors += (retval < 0);
2415     }
2416   else
2417     {
2418       vam->retval = retval;
2419       vam->result_ready = 1;
2420     }
2421 }
2422
2423 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2424   (vl_api_vxlan_offload_rx_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   vat_json_node_t node;
2428
2429   vat_json_init_object (&node);
2430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2431
2432   vat_json_print (vam->ofp, &node);
2433   vat_json_free (&node);
2434
2435   vam->retval = ntohl (mp->retval);
2436   vam->result_ready = 1;
2437 }
2438
2439 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2440   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2441 {
2442   vat_main_t *vam = &vat_main;
2443   i32 retval = ntohl (mp->retval);
2444   if (vam->async_mode)
2445     {
2446       vam->async_errors += (retval < 0);
2447     }
2448   else
2449     {
2450       vam->retval = retval;
2451       vam->sw_if_index = ntohl (mp->sw_if_index);
2452       vam->result_ready = 1;
2453     }
2454 }
2455
2456 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2457   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t node;
2461
2462   vat_json_init_object (&node);
2463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2464   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2465
2466   vat_json_print (vam->ofp, &node);
2467   vat_json_free (&node);
2468
2469   vam->retval = ntohl (mp->retval);
2470   vam->result_ready = 1;
2471 }
2472
2473 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2474   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477   i32 retval = ntohl (mp->retval);
2478   if (vam->async_mode)
2479     {
2480       vam->async_errors += (retval < 0);
2481     }
2482   else
2483     {
2484       vam->retval = retval;
2485       vam->sw_if_index = ntohl (mp->sw_if_index);
2486       vam->result_ready = 1;
2487     }
2488   vam->regenerate_interface_table = 1;
2489 }
2490
2491 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2492   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2493 {
2494   vat_main_t *vam = &vat_main;
2495   vat_json_node_t node;
2496
2497   vat_json_init_object (&node);
2498   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2499   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2500
2501   vat_json_print (vam->ofp, &node);
2502   vat_json_free (&node);
2503
2504   vam->retval = ntohl (mp->retval);
2505   vam->result_ready = 1;
2506 }
2507
2508 static void vl_api_gre_tunnel_add_del_reply_t_handler
2509   (vl_api_gre_tunnel_add_del_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   i32 retval = ntohl (mp->retval);
2513   if (vam->async_mode)
2514     {
2515       vam->async_errors += (retval < 0);
2516     }
2517   else
2518     {
2519       vam->retval = retval;
2520       vam->sw_if_index = ntohl (mp->sw_if_index);
2521       vam->result_ready = 1;
2522     }
2523 }
2524
2525 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2526   (vl_api_gre_tunnel_add_del_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   vat_json_node_t node;
2530
2531   vat_json_init_object (&node);
2532   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2533   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2534
2535   vat_json_print (vam->ofp, &node);
2536   vat_json_free (&node);
2537
2538   vam->retval = ntohl (mp->retval);
2539   vam->result_ready = 1;
2540 }
2541
2542 static void vl_api_create_vhost_user_if_reply_t_handler
2543   (vl_api_create_vhost_user_if_reply_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   i32 retval = ntohl (mp->retval);
2547   if (vam->async_mode)
2548     {
2549       vam->async_errors += (retval < 0);
2550     }
2551   else
2552     {
2553       vam->retval = retval;
2554       vam->sw_if_index = ntohl (mp->sw_if_index);
2555       vam->result_ready = 1;
2556     }
2557   vam->regenerate_interface_table = 1;
2558 }
2559
2560 static void vl_api_create_vhost_user_if_reply_t_handler_json
2561   (vl_api_create_vhost_user_if_reply_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564   vat_json_node_t node;
2565
2566   vat_json_init_object (&node);
2567   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2568   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2569
2570   vat_json_print (vam->ofp, &node);
2571   vat_json_free (&node);
2572
2573   vam->retval = ntohl (mp->retval);
2574   vam->result_ready = 1;
2575 }
2576
2577 static void vl_api_dns_resolve_name_reply_t_handler
2578   (vl_api_dns_resolve_name_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   i32 retval = ntohl (mp->retval);
2582   if (vam->async_mode)
2583     {
2584       vam->async_errors += (retval < 0);
2585     }
2586   else
2587     {
2588       vam->retval = retval;
2589       vam->result_ready = 1;
2590
2591       if (retval == 0)
2592         {
2593           if (mp->ip4_set)
2594             clib_warning ("ip4 address %U", format_ip4_address,
2595                           (ip4_address_t *) mp->ip4_address);
2596           if (mp->ip6_set)
2597             clib_warning ("ip6 address %U", format_ip6_address,
2598                           (ip6_address_t *) mp->ip6_address);
2599         }
2600       else
2601         clib_warning ("retval %d", retval);
2602     }
2603 }
2604
2605 static void vl_api_dns_resolve_name_reply_t_handler_json
2606   (vl_api_dns_resolve_name_reply_t * mp)
2607 {
2608   clib_warning ("not implemented");
2609 }
2610
2611 static void vl_api_dns_resolve_ip_reply_t_handler
2612   (vl_api_dns_resolve_ip_reply_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   i32 retval = ntohl (mp->retval);
2616   if (vam->async_mode)
2617     {
2618       vam->async_errors += (retval < 0);
2619     }
2620   else
2621     {
2622       vam->retval = retval;
2623       vam->result_ready = 1;
2624
2625       if (retval == 0)
2626         {
2627           clib_warning ("canonical name %s", mp->name);
2628         }
2629       else
2630         clib_warning ("retval %d", retval);
2631     }
2632 }
2633
2634 static void vl_api_dns_resolve_ip_reply_t_handler_json
2635   (vl_api_dns_resolve_ip_reply_t * mp)
2636 {
2637   clib_warning ("not implemented");
2638 }
2639
2640
2641 static void vl_api_ip_address_details_t_handler
2642   (vl_api_ip_address_details_t * mp)
2643 {
2644   vat_main_t *vam = &vat_main;
2645   static ip_address_details_t empty_ip_address_details = { {0} };
2646   ip_address_details_t *address = NULL;
2647   ip_details_t *current_ip_details = NULL;
2648   ip_details_t *details = NULL;
2649
2650   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2651
2652   if (!details || vam->current_sw_if_index >= vec_len (details)
2653       || !details[vam->current_sw_if_index].present)
2654     {
2655       errmsg ("ip address details arrived but not stored");
2656       errmsg ("ip_dump should be called first");
2657       return;
2658     }
2659
2660   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2661
2662 #define addresses (current_ip_details->addr)
2663
2664   vec_validate_init_empty (addresses, vec_len (addresses),
2665                            empty_ip_address_details);
2666
2667   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2668
2669   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2670   address->prefix_length = mp->prefix.len;
2671 #undef addresses
2672 }
2673
2674 static void vl_api_ip_address_details_t_handler_json
2675   (vl_api_ip_address_details_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   vat_json_node_t *node = NULL;
2679
2680   if (VAT_JSON_ARRAY != vam->json_tree.type)
2681     {
2682       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2683       vat_json_init_array (&vam->json_tree);
2684     }
2685   node = vat_json_array_add (&vam->json_tree);
2686
2687   vat_json_init_object (node);
2688   vat_json_object_add_prefix (node, &mp->prefix);
2689 }
2690
2691 static void
2692 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   static ip_details_t empty_ip_details = { 0 };
2696   ip_details_t *ip = NULL;
2697   u32 sw_if_index = ~0;
2698
2699   sw_if_index = ntohl (mp->sw_if_index);
2700
2701   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2702                            sw_if_index, empty_ip_details);
2703
2704   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2705                          sw_if_index);
2706
2707   ip->present = 1;
2708 }
2709
2710 static void
2711 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2712 {
2713   vat_main_t *vam = &vat_main;
2714
2715   if (VAT_JSON_ARRAY != vam->json_tree.type)
2716     {
2717       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2718       vat_json_init_array (&vam->json_tree);
2719     }
2720   vat_json_array_add_uint (&vam->json_tree,
2721                            clib_net_to_host_u32 (mp->sw_if_index));
2722 }
2723
2724 static void
2725 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2726 {
2727   u8 *s, i;
2728
2729   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2730               "host_mac %U router_addr %U",
2731               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2732               mp->lease.hostname,
2733               format_ip4_address, mp->lease.host_address,
2734               format_ethernet_address, mp->lease.host_mac,
2735               format_ip4_address, mp->lease.router_address);
2736
2737   for (i = 0; i < mp->lease.count; i++)
2738     s =
2739       format (s, " domain_server_addr %U", format_ip4_address,
2740               mp->lease.domain_server[i].address);
2741
2742   errmsg ((char *) s);
2743   vec_free (s);
2744 }
2745
2746 static void vl_api_dhcp_compl_event_t_handler_json
2747   (vl_api_dhcp_compl_event_t * mp)
2748 {
2749   /* JSON output not supported */
2750 }
2751
2752 static void vl_api_get_first_msg_id_reply_t_handler
2753   (vl_api_get_first_msg_id_reply_t * mp)
2754 {
2755   vat_main_t *vam = &vat_main;
2756   i32 retval = ntohl (mp->retval);
2757
2758   if (vam->async_mode)
2759     {
2760       vam->async_errors += (retval < 0);
2761     }
2762   else
2763     {
2764       vam->retval = retval;
2765       vam->result_ready = 1;
2766     }
2767   if (retval >= 0)
2768     {
2769       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2770     }
2771 }
2772
2773 static void vl_api_get_first_msg_id_reply_t_handler_json
2774   (vl_api_get_first_msg_id_reply_t * mp)
2775 {
2776   vat_main_t *vam = &vat_main;
2777   vat_json_node_t node;
2778
2779   vat_json_init_object (&node);
2780   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2781   vat_json_object_add_uint (&node, "first_msg_id",
2782                             (uint) ntohs (mp->first_msg_id));
2783
2784   vat_json_print (vam->ofp, &node);
2785   vat_json_free (&node);
2786
2787   vam->retval = ntohl (mp->retval);
2788   vam->result_ready = 1;
2789 }
2790
2791 static void vl_api_get_node_graph_reply_t_handler
2792   (vl_api_get_node_graph_reply_t * mp)
2793 {
2794   vat_main_t *vam = &vat_main;
2795   api_main_t *am = &api_main;
2796   i32 retval = ntohl (mp->retval);
2797   u8 *pvt_copy, *reply;
2798   void *oldheap;
2799   vlib_node_t *node;
2800   int i;
2801
2802   if (vam->async_mode)
2803     {
2804       vam->async_errors += (retval < 0);
2805     }
2806   else
2807     {
2808       vam->retval = retval;
2809       vam->result_ready = 1;
2810     }
2811
2812   /* "Should never happen..." */
2813   if (retval != 0)
2814     return;
2815
2816   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2817   pvt_copy = vec_dup (reply);
2818
2819   /* Toss the shared-memory original... */
2820   pthread_mutex_lock (&am->vlib_rp->mutex);
2821   oldheap = svm_push_data_heap (am->vlib_rp);
2822
2823   vec_free (reply);
2824
2825   svm_pop_heap (oldheap);
2826   pthread_mutex_unlock (&am->vlib_rp->mutex);
2827
2828   if (vam->graph_nodes)
2829     {
2830       hash_free (vam->graph_node_index_by_name);
2831
2832       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2833         {
2834           node = vam->graph_nodes[0][i];
2835           vec_free (node->name);
2836           vec_free (node->next_nodes);
2837           vec_free (node);
2838         }
2839       vec_free (vam->graph_nodes[0]);
2840       vec_free (vam->graph_nodes);
2841     }
2842
2843   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2844   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2845   vec_free (pvt_copy);
2846
2847   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2848     {
2849       node = vam->graph_nodes[0][i];
2850       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2851     }
2852 }
2853
2854 static void vl_api_get_node_graph_reply_t_handler_json
2855   (vl_api_get_node_graph_reply_t * mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   api_main_t *am = &api_main;
2859   void *oldheap;
2860   vat_json_node_t node;
2861   u8 *reply;
2862
2863   /* $$$$ make this real? */
2864   vat_json_init_object (&node);
2865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2866   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2867
2868   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2869
2870   /* Toss the shared-memory original... */
2871   pthread_mutex_lock (&am->vlib_rp->mutex);
2872   oldheap = svm_push_data_heap (am->vlib_rp);
2873
2874   vec_free (reply);
2875
2876   svm_pop_heap (oldheap);
2877   pthread_mutex_unlock (&am->vlib_rp->mutex);
2878
2879   vat_json_print (vam->ofp, &node);
2880   vat_json_free (&node);
2881
2882   vam->retval = ntohl (mp->retval);
2883   vam->result_ready = 1;
2884 }
2885
2886 static void
2887 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   u8 *s = 0;
2891
2892   if (mp->local)
2893     {
2894       s = format (s, "%=16d%=16d%=16d",
2895                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2896     }
2897   else
2898     {
2899       s = format (s, "%=16U%=16d%=16d",
2900                   mp->is_ipv6 ? format_ip6_address :
2901                   format_ip4_address,
2902                   mp->ip_address, mp->priority, mp->weight);
2903     }
2904
2905   print (vam->ofp, "%v", s);
2906   vec_free (s);
2907 }
2908
2909 static void
2910 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2911 {
2912   vat_main_t *vam = &vat_main;
2913   vat_json_node_t *node = NULL;
2914   struct in6_addr ip6;
2915   struct in_addr ip4;
2916
2917   if (VAT_JSON_ARRAY != vam->json_tree.type)
2918     {
2919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2920       vat_json_init_array (&vam->json_tree);
2921     }
2922   node = vat_json_array_add (&vam->json_tree);
2923   vat_json_init_object (node);
2924
2925   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2926   vat_json_object_add_uint (node, "priority", mp->priority);
2927   vat_json_object_add_uint (node, "weight", mp->weight);
2928
2929   if (mp->local)
2930     vat_json_object_add_uint (node, "sw_if_index",
2931                               clib_net_to_host_u32 (mp->sw_if_index));
2932   else
2933     {
2934       if (mp->is_ipv6)
2935         {
2936           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2937           vat_json_object_add_ip6 (node, "address", ip6);
2938         }
2939       else
2940         {
2941           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2942           vat_json_object_add_ip4 (node, "address", ip4);
2943         }
2944     }
2945 }
2946
2947 static void
2948 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2949                                           mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   u8 *ls_name = 0;
2953
2954   ls_name = format (0, "%s", mp->ls_name);
2955
2956   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2957          ls_name);
2958   vec_free (ls_name);
2959 }
2960
2961 static void
2962   vl_api_one_locator_set_details_t_handler_json
2963   (vl_api_one_locator_set_details_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   vat_json_node_t *node = 0;
2967   u8 *ls_name = 0;
2968
2969   ls_name = format (0, "%s", mp->ls_name);
2970   vec_add1 (ls_name, 0);
2971
2972   if (VAT_JSON_ARRAY != vam->json_tree.type)
2973     {
2974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2975       vat_json_init_array (&vam->json_tree);
2976     }
2977   node = vat_json_array_add (&vam->json_tree);
2978
2979   vat_json_init_object (node);
2980   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2981   vat_json_object_add_uint (node, "ls_index",
2982                             clib_net_to_host_u32 (mp->ls_index));
2983   vec_free (ls_name);
2984 }
2985
2986 typedef struct
2987 {
2988   u32 spi;
2989   u8 si;
2990 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2991
2992 uword
2993 unformat_nsh_address (unformat_input_t * input, va_list * args)
2994 {
2995   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2996   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2997 }
2998
2999 u8 *
3000 format_nsh_address_vat (u8 * s, va_list * args)
3001 {
3002   nsh_t *a = va_arg (*args, nsh_t *);
3003   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3004 }
3005
3006 static u8 *
3007 format_lisp_flat_eid (u8 * s, va_list * args)
3008 {
3009   u32 type = va_arg (*args, u32);
3010   u8 *eid = va_arg (*args, u8 *);
3011   u32 eid_len = va_arg (*args, u32);
3012
3013   switch (type)
3014     {
3015     case 0:
3016       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3017     case 1:
3018       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3019     case 2:
3020       return format (s, "%U", format_ethernet_address, eid);
3021     case 3:
3022       return format (s, "%U", format_nsh_address_vat, eid);
3023     }
3024   return 0;
3025 }
3026
3027 static u8 *
3028 format_lisp_eid_vat (u8 * s, va_list * args)
3029 {
3030   u32 type = va_arg (*args, u32);
3031   u8 *eid = va_arg (*args, u8 *);
3032   u32 eid_len = va_arg (*args, u32);
3033   u8 *seid = va_arg (*args, u8 *);
3034   u32 seid_len = va_arg (*args, u32);
3035   u32 is_src_dst = va_arg (*args, u32);
3036
3037   if (is_src_dst)
3038     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3039
3040   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3041
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   u8 *s = 0, *eid = 0;
3050
3051   if (~0 == mp->locator_set_index)
3052     s = format (0, "action: %d", mp->action);
3053   else
3054     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3055
3056   eid = format (0, "%U", format_lisp_eid_vat,
3057                 mp->eid_type,
3058                 mp->eid,
3059                 mp->eid_prefix_len,
3060                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3061   vec_add1 (eid, 0);
3062
3063   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3064          clib_net_to_host_u32 (mp->vni),
3065          eid,
3066          mp->is_local ? "local" : "remote",
3067          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3068          clib_net_to_host_u16 (mp->key_id), mp->key);
3069
3070   vec_free (s);
3071   vec_free (eid);
3072 }
3073
3074 static void
3075 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3076                                              * mp)
3077 {
3078   vat_main_t *vam = &vat_main;
3079   vat_json_node_t *node = 0;
3080   u8 *eid = 0;
3081
3082   if (VAT_JSON_ARRAY != vam->json_tree.type)
3083     {
3084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3085       vat_json_init_array (&vam->json_tree);
3086     }
3087   node = vat_json_array_add (&vam->json_tree);
3088
3089   vat_json_init_object (node);
3090   if (~0 == mp->locator_set_index)
3091     vat_json_object_add_uint (node, "action", mp->action);
3092   else
3093     vat_json_object_add_uint (node, "locator_set_index",
3094                               clib_net_to_host_u32 (mp->locator_set_index));
3095
3096   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3097   if (mp->eid_type == 3)
3098     {
3099       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3100       vat_json_init_object (nsh_json);
3101       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3102       vat_json_object_add_uint (nsh_json, "spi",
3103                                 clib_net_to_host_u32 (nsh->spi));
3104       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3105     }
3106   else
3107     {
3108       eid = format (0, "%U", format_lisp_eid_vat,
3109                     mp->eid_type,
3110                     mp->eid,
3111                     mp->eid_prefix_len,
3112                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3113       vec_add1 (eid, 0);
3114       vat_json_object_add_string_copy (node, "eid", eid);
3115       vec_free (eid);
3116     }
3117   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3118   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3119   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3120
3121   if (mp->key_id)
3122     {
3123       vat_json_object_add_uint (node, "key_id",
3124                                 clib_net_to_host_u16 (mp->key_id));
3125       vat_json_object_add_string_copy (node, "key", mp->key);
3126     }
3127 }
3128
3129 static void
3130 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3131 {
3132   vat_main_t *vam = &vat_main;
3133   u8 *seid = 0, *deid = 0;
3134   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3135
3136   deid = format (0, "%U", format_lisp_eid_vat,
3137                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3138
3139   seid = format (0, "%U", format_lisp_eid_vat,
3140                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3141
3142   vec_add1 (deid, 0);
3143   vec_add1 (seid, 0);
3144
3145   if (mp->is_ip4)
3146     format_ip_address_fcn = format_ip4_address;
3147   else
3148     format_ip_address_fcn = format_ip6_address;
3149
3150
3151   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3152          clib_net_to_host_u32 (mp->vni),
3153          seid, deid,
3154          format_ip_address_fcn, mp->lloc,
3155          format_ip_address_fcn, mp->rloc,
3156          clib_net_to_host_u32 (mp->pkt_count),
3157          clib_net_to_host_u32 (mp->bytes));
3158
3159   vec_free (deid);
3160   vec_free (seid);
3161 }
3162
3163 static void
3164 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3165 {
3166   struct in6_addr ip6;
3167   struct in_addr ip4;
3168   vat_main_t *vam = &vat_main;
3169   vat_json_node_t *node = 0;
3170   u8 *deid = 0, *seid = 0;
3171
3172   if (VAT_JSON_ARRAY != vam->json_tree.type)
3173     {
3174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3175       vat_json_init_array (&vam->json_tree);
3176     }
3177   node = vat_json_array_add (&vam->json_tree);
3178
3179   vat_json_init_object (node);
3180   deid = format (0, "%U", format_lisp_eid_vat,
3181                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3182
3183   seid = format (0, "%U", format_lisp_eid_vat,
3184                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3185
3186   vec_add1 (deid, 0);
3187   vec_add1 (seid, 0);
3188
3189   vat_json_object_add_string_copy (node, "seid", seid);
3190   vat_json_object_add_string_copy (node, "deid", deid);
3191   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3192
3193   if (mp->is_ip4)
3194     {
3195       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3196       vat_json_object_add_ip4 (node, "lloc", ip4);
3197       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3198       vat_json_object_add_ip4 (node, "rloc", ip4);
3199     }
3200   else
3201     {
3202       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3203       vat_json_object_add_ip6 (node, "lloc", ip6);
3204       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3205       vat_json_object_add_ip6 (node, "rloc", ip6);
3206     }
3207   vat_json_object_add_uint (node, "pkt_count",
3208                             clib_net_to_host_u32 (mp->pkt_count));
3209   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3210
3211   vec_free (deid);
3212   vec_free (seid);
3213 }
3214
3215 static void
3216   vl_api_one_eid_table_map_details_t_handler
3217   (vl_api_one_eid_table_map_details_t * mp)
3218 {
3219   vat_main_t *vam = &vat_main;
3220
3221   u8 *line = format (0, "%=10d%=10d",
3222                      clib_net_to_host_u32 (mp->vni),
3223                      clib_net_to_host_u32 (mp->dp_table));
3224   print (vam->ofp, "%v", line);
3225   vec_free (line);
3226 }
3227
3228 static void
3229   vl_api_one_eid_table_map_details_t_handler_json
3230   (vl_api_one_eid_table_map_details_t * mp)
3231 {
3232   vat_main_t *vam = &vat_main;
3233   vat_json_node_t *node = NULL;
3234
3235   if (VAT_JSON_ARRAY != vam->json_tree.type)
3236     {
3237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3238       vat_json_init_array (&vam->json_tree);
3239     }
3240   node = vat_json_array_add (&vam->json_tree);
3241   vat_json_init_object (node);
3242   vat_json_object_add_uint (node, "dp_table",
3243                             clib_net_to_host_u32 (mp->dp_table));
3244   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3245 }
3246
3247 static void
3248   vl_api_one_eid_table_vni_details_t_handler
3249   (vl_api_one_eid_table_vni_details_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252
3253   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3254   print (vam->ofp, "%v", line);
3255   vec_free (line);
3256 }
3257
3258 static void
3259   vl_api_one_eid_table_vni_details_t_handler_json
3260   (vl_api_one_eid_table_vni_details_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   vat_json_node_t *node = NULL;
3264
3265   if (VAT_JSON_ARRAY != vam->json_tree.type)
3266     {
3267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3268       vat_json_init_array (&vam->json_tree);
3269     }
3270   node = vat_json_array_add (&vam->json_tree);
3271   vat_json_init_object (node);
3272   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3273 }
3274
3275 static void
3276   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3277   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3278 {
3279   vat_main_t *vam = &vat_main;
3280   int retval = clib_net_to_host_u32 (mp->retval);
3281
3282   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3283   print (vam->ofp, "fallback threshold value: %d", mp->value);
3284
3285   vam->retval = retval;
3286   vam->result_ready = 1;
3287 }
3288
3289 static void
3290   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3291   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3292 {
3293   vat_main_t *vam = &vat_main;
3294   vat_json_node_t _node, *node = &_node;
3295   int retval = clib_net_to_host_u32 (mp->retval);
3296
3297   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3298   vat_json_init_object (node);
3299   vat_json_object_add_uint (node, "value", mp->value);
3300
3301   vat_json_print (vam->ofp, node);
3302   vat_json_free (node);
3303
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306 }
3307
3308 static void
3309   vl_api_show_one_map_register_state_reply_t_handler
3310   (vl_api_show_one_map_register_state_reply_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   int retval = clib_net_to_host_u32 (mp->retval);
3314
3315   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3316
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319 }
3320
3321 static void
3322   vl_api_show_one_map_register_state_reply_t_handler_json
3323   (vl_api_show_one_map_register_state_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   vat_json_node_t _node, *node = &_node;
3327   int retval = clib_net_to_host_u32 (mp->retval);
3328
3329   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3330
3331   vat_json_init_object (node);
3332   vat_json_object_add_string_copy (node, "state", s);
3333
3334   vat_json_print (vam->ofp, node);
3335   vat_json_free (node);
3336
3337   vam->retval = retval;
3338   vam->result_ready = 1;
3339   vec_free (s);
3340 }
3341
3342 static void
3343   vl_api_show_one_rloc_probe_state_reply_t_handler
3344   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3345 {
3346   vat_main_t *vam = &vat_main;
3347   int retval = clib_net_to_host_u32 (mp->retval);
3348
3349   if (retval)
3350     goto end;
3351
3352   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3353 end:
3354   vam->retval = retval;
3355   vam->result_ready = 1;
3356 }
3357
3358 static void
3359   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3360   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3361 {
3362   vat_main_t *vam = &vat_main;
3363   vat_json_node_t _node, *node = &_node;
3364   int retval = clib_net_to_host_u32 (mp->retval);
3365
3366   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3367   vat_json_init_object (node);
3368   vat_json_object_add_string_copy (node, "state", s);
3369
3370   vat_json_print (vam->ofp, node);
3371   vat_json_free (node);
3372
3373   vam->retval = retval;
3374   vam->result_ready = 1;
3375   vec_free (s);
3376 }
3377
3378 static void
3379   vl_api_show_one_stats_enable_disable_reply_t_handler
3380   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3381 {
3382   vat_main_t *vam = &vat_main;
3383   int retval = clib_net_to_host_u32 (mp->retval);
3384
3385   if (retval)
3386     goto end;
3387
3388   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3389 end:
3390   vam->retval = retval;
3391   vam->result_ready = 1;
3392 }
3393
3394 static void
3395   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3396   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399   vat_json_node_t _node, *node = &_node;
3400   int retval = clib_net_to_host_u32 (mp->retval);
3401
3402   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3403   vat_json_init_object (node);
3404   vat_json_object_add_string_copy (node, "state", s);
3405
3406   vat_json_print (vam->ofp, node);
3407   vat_json_free (node);
3408
3409   vam->retval = retval;
3410   vam->result_ready = 1;
3411   vec_free (s);
3412 }
3413
3414 static void
3415 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3416 {
3417   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3418   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3419   e->vni = clib_net_to_host_u32 (e->vni);
3420 }
3421
3422 static void
3423   gpe_fwd_entries_get_reply_t_net_to_host
3424   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3425 {
3426   u32 i;
3427
3428   mp->count = clib_net_to_host_u32 (mp->count);
3429   for (i = 0; i < mp->count; i++)
3430     {
3431       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3432     }
3433 }
3434
3435 static u8 *
3436 format_gpe_encap_mode (u8 * s, va_list * args)
3437 {
3438   u32 mode = va_arg (*args, u32);
3439
3440   switch (mode)
3441     {
3442     case 0:
3443       return format (s, "lisp");
3444     case 1:
3445       return format (s, "vxlan");
3446     }
3447   return 0;
3448 }
3449
3450 static void
3451   vl_api_gpe_get_encap_mode_reply_t_handler
3452   (vl_api_gpe_get_encap_mode_reply_t * mp)
3453 {
3454   vat_main_t *vam = &vat_main;
3455
3456   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3457   vam->retval = ntohl (mp->retval);
3458   vam->result_ready = 1;
3459 }
3460
3461 static void
3462   vl_api_gpe_get_encap_mode_reply_t_handler_json
3463   (vl_api_gpe_get_encap_mode_reply_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   vat_json_node_t node;
3467
3468   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3469   vec_add1 (encap_mode, 0);
3470
3471   vat_json_init_object (&node);
3472   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3473
3474   vec_free (encap_mode);
3475   vat_json_print (vam->ofp, &node);
3476   vat_json_free (&node);
3477
3478   vam->retval = ntohl (mp->retval);
3479   vam->result_ready = 1;
3480 }
3481
3482 static void
3483   vl_api_gpe_fwd_entry_path_details_t_handler
3484   (vl_api_gpe_fwd_entry_path_details_t * mp)
3485 {
3486   vat_main_t *vam = &vat_main;
3487   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3488
3489   if (mp->lcl_loc.is_ip4)
3490     format_ip_address_fcn = format_ip4_address;
3491   else
3492     format_ip_address_fcn = format_ip6_address;
3493
3494   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3495          format_ip_address_fcn, &mp->lcl_loc,
3496          format_ip_address_fcn, &mp->rmt_loc);
3497 }
3498
3499 static void
3500 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3501 {
3502   struct in6_addr ip6;
3503   struct in_addr ip4;
3504
3505   if (loc->is_ip4)
3506     {
3507       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3508       vat_json_object_add_ip4 (n, "address", ip4);
3509     }
3510   else
3511     {
3512       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3513       vat_json_object_add_ip6 (n, "address", ip6);
3514     }
3515   vat_json_object_add_uint (n, "weight", loc->weight);
3516 }
3517
3518 static void
3519   vl_api_gpe_fwd_entry_path_details_t_handler_json
3520   (vl_api_gpe_fwd_entry_path_details_t * mp)
3521 {
3522   vat_main_t *vam = &vat_main;
3523   vat_json_node_t *node = NULL;
3524   vat_json_node_t *loc_node;
3525
3526   if (VAT_JSON_ARRAY != vam->json_tree.type)
3527     {
3528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3529       vat_json_init_array (&vam->json_tree);
3530     }
3531   node = vat_json_array_add (&vam->json_tree);
3532   vat_json_init_object (node);
3533
3534   loc_node = vat_json_object_add (node, "local_locator");
3535   vat_json_init_object (loc_node);
3536   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3537
3538   loc_node = vat_json_object_add (node, "remote_locator");
3539   vat_json_init_object (loc_node);
3540   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3541 }
3542
3543 static void
3544   vl_api_gpe_fwd_entries_get_reply_t_handler
3545   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   u32 i;
3549   int retval = clib_net_to_host_u32 (mp->retval);
3550   vl_api_gpe_fwd_entry_t *e;
3551
3552   if (retval)
3553     goto end;
3554
3555   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3556
3557   for (i = 0; i < mp->count; i++)
3558     {
3559       e = &mp->entries[i];
3560       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3561              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3562              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3563     }
3564
3565 end:
3566   vam->retval = retval;
3567   vam->result_ready = 1;
3568 }
3569
3570 static void
3571   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3572   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3573 {
3574   u8 *s = 0;
3575   vat_main_t *vam = &vat_main;
3576   vat_json_node_t *e = 0, root;
3577   u32 i;
3578   int retval = clib_net_to_host_u32 (mp->retval);
3579   vl_api_gpe_fwd_entry_t *fwd;
3580
3581   if (retval)
3582     goto end;
3583
3584   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3585   vat_json_init_array (&root);
3586
3587   for (i = 0; i < mp->count; i++)
3588     {
3589       e = vat_json_array_add (&root);
3590       fwd = &mp->entries[i];
3591
3592       vat_json_init_object (e);
3593       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3594       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3595       vat_json_object_add_int (e, "vni", fwd->vni);
3596       vat_json_object_add_int (e, "action", fwd->action);
3597
3598       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3599                   fwd->leid_prefix_len);
3600       vec_add1 (s, 0);
3601       vat_json_object_add_string_copy (e, "leid", s);
3602       vec_free (s);
3603
3604       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3605                   fwd->reid_prefix_len);
3606       vec_add1 (s, 0);
3607       vat_json_object_add_string_copy (e, "reid", s);
3608       vec_free (s);
3609     }
3610
3611   vat_json_print (vam->ofp, &root);
3612   vat_json_free (&root);
3613
3614 end:
3615   vam->retval = retval;
3616   vam->result_ready = 1;
3617 }
3618
3619 static void
3620   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3621   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   u32 i, n;
3625   int retval = clib_net_to_host_u32 (mp->retval);
3626   vl_api_gpe_native_fwd_rpath_t *r;
3627
3628   if (retval)
3629     goto end;
3630
3631   n = clib_net_to_host_u32 (mp->count);
3632
3633   for (i = 0; i < n; i++)
3634     {
3635       r = &mp->entries[i];
3636       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3637              clib_net_to_host_u32 (r->fib_index),
3638              clib_net_to_host_u32 (r->nh_sw_if_index),
3639              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3640     }
3641
3642 end:
3643   vam->retval = retval;
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3649   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   vat_json_node_t root, *e;
3653   u32 i, n;
3654   int retval = clib_net_to_host_u32 (mp->retval);
3655   vl_api_gpe_native_fwd_rpath_t *r;
3656   u8 *s;
3657
3658   if (retval)
3659     goto end;
3660
3661   n = clib_net_to_host_u32 (mp->count);
3662   vat_json_init_array (&root);
3663
3664   for (i = 0; i < n; i++)
3665     {
3666       e = vat_json_array_add (&root);
3667       vat_json_init_object (e);
3668       r = &mp->entries[i];
3669       s =
3670         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3671                 r->nh_addr);
3672       vec_add1 (s, 0);
3673       vat_json_object_add_string_copy (e, "ip4", s);
3674       vec_free (s);
3675
3676       vat_json_object_add_uint (e, "fib_index",
3677                                 clib_net_to_host_u32 (r->fib_index));
3678       vat_json_object_add_uint (e, "nh_sw_if_index",
3679                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3680     }
3681
3682   vat_json_print (vam->ofp, &root);
3683   vat_json_free (&root);
3684
3685 end:
3686   vam->retval = retval;
3687   vam->result_ready = 1;
3688 }
3689
3690 static void
3691   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3692   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695   u32 i, n;
3696   int retval = clib_net_to_host_u32 (mp->retval);
3697
3698   if (retval)
3699     goto end;
3700
3701   n = clib_net_to_host_u32 (mp->count);
3702
3703   for (i = 0; i < n; i++)
3704     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3705
3706 end:
3707   vam->retval = retval;
3708   vam->result_ready = 1;
3709 }
3710
3711 static void
3712   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3713   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3714 {
3715   vat_main_t *vam = &vat_main;
3716   vat_json_node_t root;
3717   u32 i, n;
3718   int retval = clib_net_to_host_u32 (mp->retval);
3719
3720   if (retval)
3721     goto end;
3722
3723   n = clib_net_to_host_u32 (mp->count);
3724   vat_json_init_array (&root);
3725
3726   for (i = 0; i < n; i++)
3727     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3728
3729   vat_json_print (vam->ofp, &root);
3730   vat_json_free (&root);
3731
3732 end:
3733   vam->retval = retval;
3734   vam->result_ready = 1;
3735 }
3736
3737 static void
3738   vl_api_one_ndp_entries_get_reply_t_handler
3739   (vl_api_one_ndp_entries_get_reply_t * mp)
3740 {
3741   vat_main_t *vam = &vat_main;
3742   u32 i, n;
3743   int retval = clib_net_to_host_u32 (mp->retval);
3744
3745   if (retval)
3746     goto end;
3747
3748   n = clib_net_to_host_u32 (mp->count);
3749
3750   for (i = 0; i < n; i++)
3751     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3752            format_ethernet_address, mp->entries[i].mac);
3753
3754 end:
3755   vam->retval = retval;
3756   vam->result_ready = 1;
3757 }
3758
3759 static void
3760   vl_api_one_ndp_entries_get_reply_t_handler_json
3761   (vl_api_one_ndp_entries_get_reply_t * mp)
3762 {
3763   u8 *s = 0;
3764   vat_main_t *vam = &vat_main;
3765   vat_json_node_t *e = 0, root;
3766   u32 i, n;
3767   int retval = clib_net_to_host_u32 (mp->retval);
3768   vl_api_one_ndp_entry_t *arp_entry;
3769
3770   if (retval)
3771     goto end;
3772
3773   n = clib_net_to_host_u32 (mp->count);
3774   vat_json_init_array (&root);
3775
3776   for (i = 0; i < n; i++)
3777     {
3778       e = vat_json_array_add (&root);
3779       arp_entry = &mp->entries[i];
3780
3781       vat_json_init_object (e);
3782       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3783       vec_add1 (s, 0);
3784
3785       vat_json_object_add_string_copy (e, "mac", s);
3786       vec_free (s);
3787
3788       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3789       vec_add1 (s, 0);
3790       vat_json_object_add_string_copy (e, "ip6", s);
3791       vec_free (s);
3792     }
3793
3794   vat_json_print (vam->ofp, &root);
3795   vat_json_free (&root);
3796
3797 end:
3798   vam->retval = retval;
3799   vam->result_ready = 1;
3800 }
3801
3802 static void
3803   vl_api_one_l2_arp_entries_get_reply_t_handler
3804   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3805 {
3806   vat_main_t *vam = &vat_main;
3807   u32 i, n;
3808   int retval = clib_net_to_host_u32 (mp->retval);
3809
3810   if (retval)
3811     goto end;
3812
3813   n = clib_net_to_host_u32 (mp->count);
3814
3815   for (i = 0; i < n; i++)
3816     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3817            format_ethernet_address, mp->entries[i].mac);
3818
3819 end:
3820   vam->retval = retval;
3821   vam->result_ready = 1;
3822 }
3823
3824 static void
3825   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3826   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3827 {
3828   u8 *s = 0;
3829   vat_main_t *vam = &vat_main;
3830   vat_json_node_t *e = 0, root;
3831   u32 i, n;
3832   int retval = clib_net_to_host_u32 (mp->retval);
3833   vl_api_one_l2_arp_entry_t *arp_entry;
3834
3835   if (retval)
3836     goto end;
3837
3838   n = clib_net_to_host_u32 (mp->count);
3839   vat_json_init_array (&root);
3840
3841   for (i = 0; i < n; i++)
3842     {
3843       e = vat_json_array_add (&root);
3844       arp_entry = &mp->entries[i];
3845
3846       vat_json_init_object (e);
3847       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3848       vec_add1 (s, 0);
3849
3850       vat_json_object_add_string_copy (e, "mac", s);
3851       vec_free (s);
3852
3853       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3854       vec_add1 (s, 0);
3855       vat_json_object_add_string_copy (e, "ip4", s);
3856       vec_free (s);
3857     }
3858
3859   vat_json_print (vam->ofp, &root);
3860   vat_json_free (&root);
3861
3862 end:
3863   vam->retval = retval;
3864   vam->result_ready = 1;
3865 }
3866
3867 static void
3868 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_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_ndp_bd_get_reply_t_handler_json
3891   (vl_api_one_ndp_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_l2_arp_bd_get_reply_t_handler
3920   (vl_api_one_l2_arp_bd_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
3926   if (retval)
3927     goto end;
3928
3929   n = clib_net_to_host_u32 (mp->count);
3930
3931   for (i = 0; i < n; i++)
3932     {
3933       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3934     }
3935
3936 end:
3937   vam->retval = retval;
3938   vam->result_ready = 1;
3939 }
3940
3941 static void
3942   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3943   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3944 {
3945   vat_main_t *vam = &vat_main;
3946   vat_json_node_t root;
3947   u32 i, n;
3948   int retval = clib_net_to_host_u32 (mp->retval);
3949
3950   if (retval)
3951     goto end;
3952
3953   n = clib_net_to_host_u32 (mp->count);
3954   vat_json_init_array (&root);
3955
3956   for (i = 0; i < n; i++)
3957     {
3958       vat_json_array_add_uint (&root,
3959                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3960     }
3961
3962   vat_json_print (vam->ofp, &root);
3963   vat_json_free (&root);
3964
3965 end:
3966   vam->retval = retval;
3967   vam->result_ready = 1;
3968 }
3969
3970 static void
3971   vl_api_one_adjacencies_get_reply_t_handler
3972   (vl_api_one_adjacencies_get_reply_t * mp)
3973 {
3974   vat_main_t *vam = &vat_main;
3975   u32 i, n;
3976   int retval = clib_net_to_host_u32 (mp->retval);
3977   vl_api_one_adjacency_t *a;
3978
3979   if (retval)
3980     goto end;
3981
3982   n = clib_net_to_host_u32 (mp->count);
3983
3984   for (i = 0; i < n; i++)
3985     {
3986       a = &mp->adjacencies[i];
3987       print (vam->ofp, "%U %40U",
3988              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3989              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3990     }
3991
3992 end:
3993   vam->retval = retval;
3994   vam->result_ready = 1;
3995 }
3996
3997 static void
3998   vl_api_one_adjacencies_get_reply_t_handler_json
3999   (vl_api_one_adjacencies_get_reply_t * mp)
4000 {
4001   u8 *s = 0;
4002   vat_main_t *vam = &vat_main;
4003   vat_json_node_t *e = 0, root;
4004   u32 i, n;
4005   int retval = clib_net_to_host_u32 (mp->retval);
4006   vl_api_one_adjacency_t *a;
4007
4008   if (retval)
4009     goto end;
4010
4011   n = clib_net_to_host_u32 (mp->count);
4012   vat_json_init_array (&root);
4013
4014   for (i = 0; i < n; i++)
4015     {
4016       e = vat_json_array_add (&root);
4017       a = &mp->adjacencies[i];
4018
4019       vat_json_init_object (e);
4020       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4021                   a->leid_prefix_len);
4022       vec_add1 (s, 0);
4023       vat_json_object_add_string_copy (e, "leid", s);
4024       vec_free (s);
4025
4026       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4027                   a->reid_prefix_len);
4028       vec_add1 (s, 0);
4029       vat_json_object_add_string_copy (e, "reid", s);
4030       vec_free (s);
4031     }
4032
4033   vat_json_print (vam->ofp, &root);
4034   vat_json_free (&root);
4035
4036 end:
4037   vam->retval = retval;
4038   vam->result_ready = 1;
4039 }
4040
4041 static void
4042 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4043 {
4044   vat_main_t *vam = &vat_main;
4045
4046   print (vam->ofp, "%=20U",
4047          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4048          mp->ip_address);
4049 }
4050
4051 static void
4052   vl_api_one_map_server_details_t_handler_json
4053   (vl_api_one_map_server_details_t * mp)
4054 {
4055   vat_main_t *vam = &vat_main;
4056   vat_json_node_t *node = NULL;
4057   struct in6_addr ip6;
4058   struct in_addr ip4;
4059
4060   if (VAT_JSON_ARRAY != vam->json_tree.type)
4061     {
4062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4063       vat_json_init_array (&vam->json_tree);
4064     }
4065   node = vat_json_array_add (&vam->json_tree);
4066
4067   vat_json_init_object (node);
4068   if (mp->is_ipv6)
4069     {
4070       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4071       vat_json_object_add_ip6 (node, "map-server", ip6);
4072     }
4073   else
4074     {
4075       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4076       vat_json_object_add_ip4 (node, "map-server", ip4);
4077     }
4078 }
4079
4080 static void
4081 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4082                                            * mp)
4083 {
4084   vat_main_t *vam = &vat_main;
4085
4086   print (vam->ofp, "%=20U",
4087          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4088          mp->ip_address);
4089 }
4090
4091 static void
4092   vl_api_one_map_resolver_details_t_handler_json
4093   (vl_api_one_map_resolver_details_t * mp)
4094 {
4095   vat_main_t *vam = &vat_main;
4096   vat_json_node_t *node = NULL;
4097   struct in6_addr ip6;
4098   struct in_addr ip4;
4099
4100   if (VAT_JSON_ARRAY != vam->json_tree.type)
4101     {
4102       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4103       vat_json_init_array (&vam->json_tree);
4104     }
4105   node = vat_json_array_add (&vam->json_tree);
4106
4107   vat_json_init_object (node);
4108   if (mp->is_ipv6)
4109     {
4110       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4111       vat_json_object_add_ip6 (node, "map resolver", ip6);
4112     }
4113   else
4114     {
4115       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4116       vat_json_object_add_ip4 (node, "map resolver", ip4);
4117     }
4118 }
4119
4120 static void
4121 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4122 {
4123   vat_main_t *vam = &vat_main;
4124   i32 retval = ntohl (mp->retval);
4125
4126   if (0 <= retval)
4127     {
4128       print (vam->ofp, "feature: %s\ngpe: %s",
4129              mp->feature_status ? "enabled" : "disabled",
4130              mp->gpe_status ? "enabled" : "disabled");
4131     }
4132
4133   vam->retval = retval;
4134   vam->result_ready = 1;
4135 }
4136
4137 static void
4138   vl_api_show_one_status_reply_t_handler_json
4139   (vl_api_show_one_status_reply_t * mp)
4140 {
4141   vat_main_t *vam = &vat_main;
4142   vat_json_node_t node;
4143   u8 *gpe_status = NULL;
4144   u8 *feature_status = NULL;
4145
4146   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4147   feature_status = format (0, "%s",
4148                            mp->feature_status ? "enabled" : "disabled");
4149   vec_add1 (gpe_status, 0);
4150   vec_add1 (feature_status, 0);
4151
4152   vat_json_init_object (&node);
4153   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4154   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4155
4156   vec_free (gpe_status);
4157   vec_free (feature_status);
4158
4159   vat_json_print (vam->ofp, &node);
4160   vat_json_free (&node);
4161
4162   vam->retval = ntohl (mp->retval);
4163   vam->result_ready = 1;
4164 }
4165
4166 static void
4167   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4168   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4169 {
4170   vat_main_t *vam = &vat_main;
4171   i32 retval = ntohl (mp->retval);
4172
4173   if (retval >= 0)
4174     {
4175       print (vam->ofp, "%=20s", mp->locator_set_name);
4176     }
4177
4178   vam->retval = retval;
4179   vam->result_ready = 1;
4180 }
4181
4182 static void
4183   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4184   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4185 {
4186   vat_main_t *vam = &vat_main;
4187   vat_json_node_t *node = NULL;
4188
4189   if (VAT_JSON_ARRAY != vam->json_tree.type)
4190     {
4191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4192       vat_json_init_array (&vam->json_tree);
4193     }
4194   node = vat_json_array_add (&vam->json_tree);
4195
4196   vat_json_init_object (node);
4197   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4198
4199   vat_json_print (vam->ofp, node);
4200   vat_json_free (node);
4201
4202   vam->retval = ntohl (mp->retval);
4203   vam->result_ready = 1;
4204 }
4205
4206 static u8 *
4207 format_lisp_map_request_mode (u8 * s, va_list * args)
4208 {
4209   u32 mode = va_arg (*args, u32);
4210
4211   switch (mode)
4212     {
4213     case 0:
4214       return format (0, "dst-only");
4215     case 1:
4216       return format (0, "src-dst");
4217     }
4218   return 0;
4219 }
4220
4221 static void
4222   vl_api_show_one_map_request_mode_reply_t_handler
4223   (vl_api_show_one_map_request_mode_reply_t * mp)
4224 {
4225   vat_main_t *vam = &vat_main;
4226   i32 retval = ntohl (mp->retval);
4227
4228   if (0 <= retval)
4229     {
4230       u32 mode = mp->mode;
4231       print (vam->ofp, "map_request_mode: %U",
4232              format_lisp_map_request_mode, mode);
4233     }
4234
4235   vam->retval = retval;
4236   vam->result_ready = 1;
4237 }
4238
4239 static void
4240   vl_api_show_one_map_request_mode_reply_t_handler_json
4241   (vl_api_show_one_map_request_mode_reply_t * mp)
4242 {
4243   vat_main_t *vam = &vat_main;
4244   vat_json_node_t node;
4245   u8 *s = 0;
4246   u32 mode;
4247
4248   mode = mp->mode;
4249   s = format (0, "%U", format_lisp_map_request_mode, mode);
4250   vec_add1 (s, 0);
4251
4252   vat_json_init_object (&node);
4253   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4254   vat_json_print (vam->ofp, &node);
4255   vat_json_free (&node);
4256
4257   vec_free (s);
4258   vam->retval = ntohl (mp->retval);
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_one_show_xtr_mode_reply_t_handler
4264   (vl_api_one_show_xtr_mode_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   i32 retval = ntohl (mp->retval);
4268
4269   if (0 <= retval)
4270     {
4271       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4272     }
4273
4274   vam->retval = retval;
4275   vam->result_ready = 1;
4276 }
4277
4278 static void
4279   vl_api_one_show_xtr_mode_reply_t_handler_json
4280   (vl_api_one_show_xtr_mode_reply_t * mp)
4281 {
4282   vat_main_t *vam = &vat_main;
4283   vat_json_node_t node;
4284   u8 *status = 0;
4285
4286   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4287   vec_add1 (status, 0);
4288
4289   vat_json_init_object (&node);
4290   vat_json_object_add_string_copy (&node, "status", status);
4291
4292   vec_free (status);
4293
4294   vat_json_print (vam->ofp, &node);
4295   vat_json_free (&node);
4296
4297   vam->retval = ntohl (mp->retval);
4298   vam->result_ready = 1;
4299 }
4300
4301 static void
4302   vl_api_one_show_pitr_mode_reply_t_handler
4303   (vl_api_one_show_pitr_mode_reply_t * mp)
4304 {
4305   vat_main_t *vam = &vat_main;
4306   i32 retval = ntohl (mp->retval);
4307
4308   if (0 <= retval)
4309     {
4310       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4311     }
4312
4313   vam->retval = retval;
4314   vam->result_ready = 1;
4315 }
4316
4317 static void
4318   vl_api_one_show_pitr_mode_reply_t_handler_json
4319   (vl_api_one_show_pitr_mode_reply_t * mp)
4320 {
4321   vat_main_t *vam = &vat_main;
4322   vat_json_node_t node;
4323   u8 *status = 0;
4324
4325   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4326   vec_add1 (status, 0);
4327
4328   vat_json_init_object (&node);
4329   vat_json_object_add_string_copy (&node, "status", status);
4330
4331   vec_free (status);
4332
4333   vat_json_print (vam->ofp, &node);
4334   vat_json_free (&node);
4335
4336   vam->retval = ntohl (mp->retval);
4337   vam->result_ready = 1;
4338 }
4339
4340 static void
4341   vl_api_one_show_petr_mode_reply_t_handler
4342   (vl_api_one_show_petr_mode_reply_t * mp)
4343 {
4344   vat_main_t *vam = &vat_main;
4345   i32 retval = ntohl (mp->retval);
4346
4347   if (0 <= retval)
4348     {
4349       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4350     }
4351
4352   vam->retval = retval;
4353   vam->result_ready = 1;
4354 }
4355
4356 static void
4357   vl_api_one_show_petr_mode_reply_t_handler_json
4358   (vl_api_one_show_petr_mode_reply_t * mp)
4359 {
4360   vat_main_t *vam = &vat_main;
4361   vat_json_node_t node;
4362   u8 *status = 0;
4363
4364   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4365   vec_add1 (status, 0);
4366
4367   vat_json_init_object (&node);
4368   vat_json_object_add_string_copy (&node, "status", status);
4369
4370   vec_free (status);
4371
4372   vat_json_print (vam->ofp, &node);
4373   vat_json_free (&node);
4374
4375   vam->retval = ntohl (mp->retval);
4376   vam->result_ready = 1;
4377 }
4378
4379 static void
4380   vl_api_show_one_use_petr_reply_t_handler
4381   (vl_api_show_one_use_petr_reply_t * mp)
4382 {
4383   vat_main_t *vam = &vat_main;
4384   i32 retval = ntohl (mp->retval);
4385
4386   if (0 <= retval)
4387     {
4388       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4389       if (mp->status)
4390         {
4391           print (vam->ofp, "Proxy-ETR address; %U",
4392                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4393                  mp->address);
4394         }
4395     }
4396
4397   vam->retval = retval;
4398   vam->result_ready = 1;
4399 }
4400
4401 static void
4402   vl_api_show_one_use_petr_reply_t_handler_json
4403   (vl_api_show_one_use_petr_reply_t * mp)
4404 {
4405   vat_main_t *vam = &vat_main;
4406   vat_json_node_t node;
4407   u8 *status = 0;
4408   struct in_addr ip4;
4409   struct in6_addr ip6;
4410
4411   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4412   vec_add1 (status, 0);
4413
4414   vat_json_init_object (&node);
4415   vat_json_object_add_string_copy (&node, "status", status);
4416   if (mp->status)
4417     {
4418       if (mp->is_ip4)
4419         {
4420           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4421           vat_json_object_add_ip6 (&node, "address", ip6);
4422         }
4423       else
4424         {
4425           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4426           vat_json_object_add_ip4 (&node, "address", ip4);
4427         }
4428     }
4429
4430   vec_free (status);
4431
4432   vat_json_print (vam->ofp, &node);
4433   vat_json_free (&node);
4434
4435   vam->retval = ntohl (mp->retval);
4436   vam->result_ready = 1;
4437 }
4438
4439 static void
4440   vl_api_show_one_nsh_mapping_reply_t_handler
4441   (vl_api_show_one_nsh_mapping_reply_t * mp)
4442 {
4443   vat_main_t *vam = &vat_main;
4444   i32 retval = ntohl (mp->retval);
4445
4446   if (0 <= retval)
4447     {
4448       print (vam->ofp, "%-20s%-16s",
4449              mp->is_set ? "set" : "not-set",
4450              mp->is_set ? (char *) mp->locator_set_name : "");
4451     }
4452
4453   vam->retval = retval;
4454   vam->result_ready = 1;
4455 }
4456
4457 static void
4458   vl_api_show_one_nsh_mapping_reply_t_handler_json
4459   (vl_api_show_one_nsh_mapping_reply_t * mp)
4460 {
4461   vat_main_t *vam = &vat_main;
4462   vat_json_node_t node;
4463   u8 *status = 0;
4464
4465   status = format (0, "%s", mp->is_set ? "yes" : "no");
4466   vec_add1 (status, 0);
4467
4468   vat_json_init_object (&node);
4469   vat_json_object_add_string_copy (&node, "is_set", status);
4470   if (mp->is_set)
4471     {
4472       vat_json_object_add_string_copy (&node, "locator_set",
4473                                        mp->locator_set_name);
4474     }
4475
4476   vec_free (status);
4477
4478   vat_json_print (vam->ofp, &node);
4479   vat_json_free (&node);
4480
4481   vam->retval = ntohl (mp->retval);
4482   vam->result_ready = 1;
4483 }
4484
4485 static void
4486   vl_api_show_one_map_register_ttl_reply_t_handler
4487   (vl_api_show_one_map_register_ttl_reply_t * mp)
4488 {
4489   vat_main_t *vam = &vat_main;
4490   i32 retval = ntohl (mp->retval);
4491
4492   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4493
4494   if (0 <= retval)
4495     {
4496       print (vam->ofp, "ttl: %u", mp->ttl);
4497     }
4498
4499   vam->retval = retval;
4500   vam->result_ready = 1;
4501 }
4502
4503 static void
4504   vl_api_show_one_map_register_ttl_reply_t_handler_json
4505   (vl_api_show_one_map_register_ttl_reply_t * mp)
4506 {
4507   vat_main_t *vam = &vat_main;
4508   vat_json_node_t node;
4509
4510   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4511   vat_json_init_object (&node);
4512   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4513
4514   vat_json_print (vam->ofp, &node);
4515   vat_json_free (&node);
4516
4517   vam->retval = ntohl (mp->retval);
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4523 {
4524   vat_main_t *vam = &vat_main;
4525   i32 retval = ntohl (mp->retval);
4526
4527   if (0 <= retval)
4528     {
4529       print (vam->ofp, "%-20s%-16s",
4530              mp->status ? "enabled" : "disabled",
4531              mp->status ? (char *) mp->locator_set_name : "");
4532     }
4533
4534   vam->retval = retval;
4535   vam->result_ready = 1;
4536 }
4537
4538 static void
4539 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4540 {
4541   vat_main_t *vam = &vat_main;
4542   vat_json_node_t node;
4543   u8 *status = 0;
4544
4545   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4546   vec_add1 (status, 0);
4547
4548   vat_json_init_object (&node);
4549   vat_json_object_add_string_copy (&node, "status", status);
4550   if (mp->status)
4551     {
4552       vat_json_object_add_string_copy (&node, "locator_set",
4553                                        mp->locator_set_name);
4554     }
4555
4556   vec_free (status);
4557
4558   vat_json_print (vam->ofp, &node);
4559   vat_json_free (&node);
4560
4561   vam->retval = ntohl (mp->retval);
4562   vam->result_ready = 1;
4563 }
4564
4565 static u8 *
4566 format_policer_type (u8 * s, va_list * va)
4567 {
4568   u32 i = va_arg (*va, u32);
4569
4570   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4571     s = format (s, "1r2c");
4572   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4573     s = format (s, "1r3c");
4574   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4575     s = format (s, "2r3c-2698");
4576   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4577     s = format (s, "2r3c-4115");
4578   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4579     s = format (s, "2r3c-mef5cf1");
4580   else
4581     s = format (s, "ILLEGAL");
4582   return s;
4583 }
4584
4585 static u8 *
4586 format_policer_rate_type (u8 * s, va_list * va)
4587 {
4588   u32 i = va_arg (*va, u32);
4589
4590   if (i == SSE2_QOS_RATE_KBPS)
4591     s = format (s, "kbps");
4592   else if (i == SSE2_QOS_RATE_PPS)
4593     s = format (s, "pps");
4594   else
4595     s = format (s, "ILLEGAL");
4596   return s;
4597 }
4598
4599 static u8 *
4600 format_policer_round_type (u8 * s, va_list * va)
4601 {
4602   u32 i = va_arg (*va, u32);
4603
4604   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4605     s = format (s, "closest");
4606   else if (i == SSE2_QOS_ROUND_TO_UP)
4607     s = format (s, "up");
4608   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4609     s = format (s, "down");
4610   else
4611     s = format (s, "ILLEGAL");
4612   return s;
4613 }
4614
4615 static u8 *
4616 format_policer_action_type (u8 * s, va_list * va)
4617 {
4618   u32 i = va_arg (*va, u32);
4619
4620   if (i == SSE2_QOS_ACTION_DROP)
4621     s = format (s, "drop");
4622   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4623     s = format (s, "transmit");
4624   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4625     s = format (s, "mark-and-transmit");
4626   else
4627     s = format (s, "ILLEGAL");
4628   return s;
4629 }
4630
4631 static u8 *
4632 format_dscp (u8 * s, va_list * va)
4633 {
4634   u32 i = va_arg (*va, u32);
4635   char *t = 0;
4636
4637   switch (i)
4638     {
4639 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4640       foreach_vnet_dscp
4641 #undef _
4642     default:
4643       return format (s, "ILLEGAL");
4644     }
4645   s = format (s, "%s", t);
4646   return s;
4647 }
4648
4649 static void
4650 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4651 {
4652   vat_main_t *vam = &vat_main;
4653   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4654
4655   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4656     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4657   else
4658     conform_dscp_str = format (0, "");
4659
4660   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4661     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4662   else
4663     exceed_dscp_str = format (0, "");
4664
4665   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4666     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4667   else
4668     violate_dscp_str = format (0, "");
4669
4670   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4671          "rate type %U, round type %U, %s rate, %s color-aware, "
4672          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4673          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4674          "conform action %U%s, exceed action %U%s, violate action %U%s",
4675          mp->name,
4676          format_policer_type, mp->type,
4677          ntohl (mp->cir),
4678          ntohl (mp->eir),
4679          clib_net_to_host_u64 (mp->cb),
4680          clib_net_to_host_u64 (mp->eb),
4681          format_policer_rate_type, mp->rate_type,
4682          format_policer_round_type, mp->round_type,
4683          mp->single_rate ? "single" : "dual",
4684          mp->color_aware ? "is" : "not",
4685          ntohl (mp->cir_tokens_per_period),
4686          ntohl (mp->pir_tokens_per_period),
4687          ntohl (mp->scale),
4688          ntohl (mp->current_limit),
4689          ntohl (mp->current_bucket),
4690          ntohl (mp->extended_limit),
4691          ntohl (mp->extended_bucket),
4692          clib_net_to_host_u64 (mp->last_update_time),
4693          format_policer_action_type, mp->conform_action_type,
4694          conform_dscp_str,
4695          format_policer_action_type, mp->exceed_action_type,
4696          exceed_dscp_str,
4697          format_policer_action_type, mp->violate_action_type,
4698          violate_dscp_str);
4699
4700   vec_free (conform_dscp_str);
4701   vec_free (exceed_dscp_str);
4702   vec_free (violate_dscp_str);
4703 }
4704
4705 static void vl_api_policer_details_t_handler_json
4706   (vl_api_policer_details_t * mp)
4707 {
4708   vat_main_t *vam = &vat_main;
4709   vat_json_node_t *node;
4710   u8 *rate_type_str, *round_type_str, *type_str;
4711   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4712
4713   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4714   round_type_str =
4715     format (0, "%U", format_policer_round_type, mp->round_type);
4716   type_str = format (0, "%U", format_policer_type, mp->type);
4717   conform_action_str = format (0, "%U", format_policer_action_type,
4718                                mp->conform_action_type);
4719   exceed_action_str = format (0, "%U", format_policer_action_type,
4720                               mp->exceed_action_type);
4721   violate_action_str = format (0, "%U", format_policer_action_type,
4722                                mp->violate_action_type);
4723
4724   if (VAT_JSON_ARRAY != vam->json_tree.type)
4725     {
4726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4727       vat_json_init_array (&vam->json_tree);
4728     }
4729   node = vat_json_array_add (&vam->json_tree);
4730
4731   vat_json_init_object (node);
4732   vat_json_object_add_string_copy (node, "name", mp->name);
4733   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4734   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4735   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4736   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4737   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4738   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4739   vat_json_object_add_string_copy (node, "type", type_str);
4740   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4741   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4742   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4743   vat_json_object_add_uint (node, "cir_tokens_per_period",
4744                             ntohl (mp->cir_tokens_per_period));
4745   vat_json_object_add_uint (node, "eir_tokens_per_period",
4746                             ntohl (mp->pir_tokens_per_period));
4747   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4748   vat_json_object_add_uint (node, "current_bucket",
4749                             ntohl (mp->current_bucket));
4750   vat_json_object_add_uint (node, "extended_limit",
4751                             ntohl (mp->extended_limit));
4752   vat_json_object_add_uint (node, "extended_bucket",
4753                             ntohl (mp->extended_bucket));
4754   vat_json_object_add_uint (node, "last_update_time",
4755                             ntohl (mp->last_update_time));
4756   vat_json_object_add_string_copy (node, "conform_action",
4757                                    conform_action_str);
4758   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4759     {
4760       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4761       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4762       vec_free (dscp_str);
4763     }
4764   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4765   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4766     {
4767       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4768       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4769       vec_free (dscp_str);
4770     }
4771   vat_json_object_add_string_copy (node, "violate_action",
4772                                    violate_action_str);
4773   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4774     {
4775       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4776       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4777       vec_free (dscp_str);
4778     }
4779
4780   vec_free (rate_type_str);
4781   vec_free (round_type_str);
4782   vec_free (type_str);
4783   vec_free (conform_action_str);
4784   vec_free (exceed_action_str);
4785   vec_free (violate_action_str);
4786 }
4787
4788 static void
4789 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4790                                            mp)
4791 {
4792   vat_main_t *vam = &vat_main;
4793   int i, count = ntohl (mp->count);
4794
4795   if (count > 0)
4796     print (vam->ofp, "classify table ids (%d) : ", count);
4797   for (i = 0; i < count; i++)
4798     {
4799       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4800       print (vam->ofp, (i < count - 1) ? "," : "");
4801     }
4802   vam->retval = ntohl (mp->retval);
4803   vam->result_ready = 1;
4804 }
4805
4806 static void
4807   vl_api_classify_table_ids_reply_t_handler_json
4808   (vl_api_classify_table_ids_reply_t * mp)
4809 {
4810   vat_main_t *vam = &vat_main;
4811   int i, count = ntohl (mp->count);
4812
4813   if (count > 0)
4814     {
4815       vat_json_node_t node;
4816
4817       vat_json_init_object (&node);
4818       for (i = 0; i < count; i++)
4819         {
4820           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4821         }
4822       vat_json_print (vam->ofp, &node);
4823       vat_json_free (&node);
4824     }
4825   vam->retval = ntohl (mp->retval);
4826   vam->result_ready = 1;
4827 }
4828
4829 static void
4830   vl_api_classify_table_by_interface_reply_t_handler
4831   (vl_api_classify_table_by_interface_reply_t * mp)
4832 {
4833   vat_main_t *vam = &vat_main;
4834   u32 table_id;
4835
4836   table_id = ntohl (mp->l2_table_id);
4837   if (table_id != ~0)
4838     print (vam->ofp, "l2 table id : %d", table_id);
4839   else
4840     print (vam->ofp, "l2 table id : No input ACL tables configured");
4841   table_id = ntohl (mp->ip4_table_id);
4842   if (table_id != ~0)
4843     print (vam->ofp, "ip4 table id : %d", table_id);
4844   else
4845     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4846   table_id = ntohl (mp->ip6_table_id);
4847   if (table_id != ~0)
4848     print (vam->ofp, "ip6 table id : %d", table_id);
4849   else
4850     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4851   vam->retval = ntohl (mp->retval);
4852   vam->result_ready = 1;
4853 }
4854
4855 static void
4856   vl_api_classify_table_by_interface_reply_t_handler_json
4857   (vl_api_classify_table_by_interface_reply_t * mp)
4858 {
4859   vat_main_t *vam = &vat_main;
4860   vat_json_node_t node;
4861
4862   vat_json_init_object (&node);
4863
4864   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4865   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4866   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4867
4868   vat_json_print (vam->ofp, &node);
4869   vat_json_free (&node);
4870
4871   vam->retval = ntohl (mp->retval);
4872   vam->result_ready = 1;
4873 }
4874
4875 static void vl_api_policer_add_del_reply_t_handler
4876   (vl_api_policer_add_del_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   i32 retval = ntohl (mp->retval);
4880   if (vam->async_mode)
4881     {
4882       vam->async_errors += (retval < 0);
4883     }
4884   else
4885     {
4886       vam->retval = retval;
4887       vam->result_ready = 1;
4888       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4889         /*
4890          * Note: this is just barely thread-safe, depends on
4891          * the main thread spinning waiting for an answer...
4892          */
4893         errmsg ("policer index %d", ntohl (mp->policer_index));
4894     }
4895 }
4896
4897 static void vl_api_policer_add_del_reply_t_handler_json
4898   (vl_api_policer_add_del_reply_t * mp)
4899 {
4900   vat_main_t *vam = &vat_main;
4901   vat_json_node_t node;
4902
4903   vat_json_init_object (&node);
4904   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4905   vat_json_object_add_uint (&node, "policer_index",
4906                             ntohl (mp->policer_index));
4907
4908   vat_json_print (vam->ofp, &node);
4909   vat_json_free (&node);
4910
4911   vam->retval = ntohl (mp->retval);
4912   vam->result_ready = 1;
4913 }
4914
4915 /* Format hex dump. */
4916 u8 *
4917 format_hex_bytes (u8 * s, va_list * va)
4918 {
4919   u8 *bytes = va_arg (*va, u8 *);
4920   int n_bytes = va_arg (*va, int);
4921   uword i;
4922
4923   /* Print short or long form depending on byte count. */
4924   uword short_form = n_bytes <= 32;
4925   u32 indent = format_get_indent (s);
4926
4927   if (n_bytes == 0)
4928     return s;
4929
4930   for (i = 0; i < n_bytes; i++)
4931     {
4932       if (!short_form && (i % 32) == 0)
4933         s = format (s, "%08x: ", i);
4934       s = format (s, "%02x", bytes[i]);
4935       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4936         s = format (s, "\n%U", format_white_space, indent);
4937     }
4938
4939   return s;
4940 }
4941
4942 static void
4943 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4944                                             * mp)
4945 {
4946   vat_main_t *vam = &vat_main;
4947   i32 retval = ntohl (mp->retval);
4948   if (retval == 0)
4949     {
4950       print (vam->ofp, "classify table info :");
4951       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4952              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4953              ntohl (mp->miss_next_index));
4954       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4955              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4956              ntohl (mp->match_n_vectors));
4957       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4958              ntohl (mp->mask_length));
4959     }
4960   vam->retval = retval;
4961   vam->result_ready = 1;
4962 }
4963
4964 static void
4965   vl_api_classify_table_info_reply_t_handler_json
4966   (vl_api_classify_table_info_reply_t * mp)
4967 {
4968   vat_main_t *vam = &vat_main;
4969   vat_json_node_t node;
4970
4971   i32 retval = ntohl (mp->retval);
4972   if (retval == 0)
4973     {
4974       vat_json_init_object (&node);
4975
4976       vat_json_object_add_int (&node, "sessions",
4977                                ntohl (mp->active_sessions));
4978       vat_json_object_add_int (&node, "nexttbl",
4979                                ntohl (mp->next_table_index));
4980       vat_json_object_add_int (&node, "nextnode",
4981                                ntohl (mp->miss_next_index));
4982       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4983       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4984       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4985       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4986                       ntohl (mp->mask_length), 0);
4987       vat_json_object_add_string_copy (&node, "mask", s);
4988
4989       vat_json_print (vam->ofp, &node);
4990       vat_json_free (&node);
4991     }
4992   vam->retval = ntohl (mp->retval);
4993   vam->result_ready = 1;
4994 }
4995
4996 static void
4997 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4998                                            mp)
4999 {
5000   vat_main_t *vam = &vat_main;
5001
5002   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5003          ntohl (mp->hit_next_index), ntohl (mp->advance),
5004          ntohl (mp->opaque_index));
5005   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5006          ntohl (mp->match_length));
5007 }
5008
5009 static void
5010   vl_api_classify_session_details_t_handler_json
5011   (vl_api_classify_session_details_t * mp)
5012 {
5013   vat_main_t *vam = &vat_main;
5014   vat_json_node_t *node = NULL;
5015
5016   if (VAT_JSON_ARRAY != vam->json_tree.type)
5017     {
5018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5019       vat_json_init_array (&vam->json_tree);
5020     }
5021   node = vat_json_array_add (&vam->json_tree);
5022
5023   vat_json_init_object (node);
5024   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5025   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5026   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5027   u8 *s =
5028     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5029             0);
5030   vat_json_object_add_string_copy (node, "match", s);
5031 }
5032
5033 static void vl_api_pg_create_interface_reply_t_handler
5034   (vl_api_pg_create_interface_reply_t * mp)
5035 {
5036   vat_main_t *vam = &vat_main;
5037
5038   vam->retval = ntohl (mp->retval);
5039   vam->result_ready = 1;
5040 }
5041
5042 static void vl_api_pg_create_interface_reply_t_handler_json
5043   (vl_api_pg_create_interface_reply_t * mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046   vat_json_node_t node;
5047
5048   i32 retval = ntohl (mp->retval);
5049   if (retval == 0)
5050     {
5051       vat_json_init_object (&node);
5052
5053       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5054
5055       vat_json_print (vam->ofp, &node);
5056       vat_json_free (&node);
5057     }
5058   vam->retval = ntohl (mp->retval);
5059   vam->result_ready = 1;
5060 }
5061
5062 static void vl_api_policer_classify_details_t_handler
5063   (vl_api_policer_classify_details_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066
5067   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5068          ntohl (mp->table_index));
5069 }
5070
5071 static void vl_api_policer_classify_details_t_handler_json
5072   (vl_api_policer_classify_details_t * mp)
5073 {
5074   vat_main_t *vam = &vat_main;
5075   vat_json_node_t *node;
5076
5077   if (VAT_JSON_ARRAY != vam->json_tree.type)
5078     {
5079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5080       vat_json_init_array (&vam->json_tree);
5081     }
5082   node = vat_json_array_add (&vam->json_tree);
5083
5084   vat_json_init_object (node);
5085   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5086   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5087 }
5088
5089 static void vl_api_flow_classify_details_t_handler
5090   (vl_api_flow_classify_details_t * mp)
5091 {
5092   vat_main_t *vam = &vat_main;
5093
5094   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5095          ntohl (mp->table_index));
5096 }
5097
5098 static void vl_api_flow_classify_details_t_handler_json
5099   (vl_api_flow_classify_details_t * mp)
5100 {
5101   vat_main_t *vam = &vat_main;
5102   vat_json_node_t *node;
5103
5104   if (VAT_JSON_ARRAY != vam->json_tree.type)
5105     {
5106       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5107       vat_json_init_array (&vam->json_tree);
5108     }
5109   node = vat_json_array_add (&vam->json_tree);
5110
5111   vat_json_init_object (node);
5112   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5113   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5114 }
5115
5116 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5117 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5118 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5119 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5120 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5121 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5122 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5123 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5124 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5125 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5126
5127 /*
5128  * Generate boilerplate reply handlers, which
5129  * dig the return value out of the xxx_reply_t API message,
5130  * stick it into vam->retval, and set vam->result_ready
5131  *
5132  * Could also do this by pointing N message decode slots at
5133  * a single function, but that could break in subtle ways.
5134  */
5135
5136 #define foreach_standard_reply_retval_handler           \
5137 _(sw_interface_set_flags_reply)                         \
5138 _(sw_interface_add_del_address_reply)                   \
5139 _(sw_interface_set_rx_mode_reply)                       \
5140 _(sw_interface_set_rx_placement_reply)                  \
5141 _(sw_interface_set_table_reply)                         \
5142 _(sw_interface_set_mpls_enable_reply)                   \
5143 _(sw_interface_set_vpath_reply)                         \
5144 _(sw_interface_set_vxlan_bypass_reply)                  \
5145 _(sw_interface_set_geneve_bypass_reply)                 \
5146 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5147 _(sw_interface_set_l2_bridge_reply)                     \
5148 _(bridge_domain_add_del_reply)                          \
5149 _(sw_interface_set_l2_xconnect_reply)                   \
5150 _(l2fib_add_del_reply)                                  \
5151 _(l2fib_flush_int_reply)                                \
5152 _(l2fib_flush_bd_reply)                                 \
5153 _(ip_route_add_del_reply)                               \
5154 _(ip_table_add_del_reply)                               \
5155 _(ip_mroute_add_del_reply)                              \
5156 _(mpls_route_add_del_reply)                             \
5157 _(mpls_table_add_del_reply)                             \
5158 _(mpls_ip_bind_unbind_reply)                            \
5159 _(bier_route_add_del_reply)                             \
5160 _(bier_table_add_del_reply)                             \
5161 _(proxy_arp_add_del_reply)                              \
5162 _(proxy_arp_intfc_enable_disable_reply)                 \
5163 _(sw_interface_set_unnumbered_reply)                    \
5164 _(ip_neighbor_add_del_reply)                            \
5165 _(reset_fib_reply)                                      \
5166 _(dhcp_proxy_config_reply)                              \
5167 _(dhcp_proxy_set_vss_reply)                             \
5168 _(dhcp_client_config_reply)                             \
5169 _(set_ip_flow_hash_reply)                               \
5170 _(sw_interface_ip6_enable_disable_reply)                \
5171 _(ip6nd_proxy_add_del_reply)                            \
5172 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5173 _(sw_interface_ip6nd_ra_config_reply)                   \
5174 _(set_arp_neighbor_limit_reply)                         \
5175 _(l2_patch_add_del_reply)                               \
5176 _(sr_mpls_policy_add_reply)                             \
5177 _(sr_mpls_policy_mod_reply)                             \
5178 _(sr_mpls_policy_del_reply)                             \
5179 _(sr_policy_add_reply)                                  \
5180 _(sr_policy_mod_reply)                                  \
5181 _(sr_policy_del_reply)                                  \
5182 _(sr_localsid_add_del_reply)                            \
5183 _(sr_steering_add_del_reply)                            \
5184 _(classify_add_del_session_reply)                       \
5185 _(classify_set_interface_ip_table_reply)                \
5186 _(classify_set_interface_l2_tables_reply)               \
5187 _(l2tpv3_set_tunnel_cookies_reply)                      \
5188 _(l2tpv3_interface_enable_disable_reply)                \
5189 _(l2tpv3_set_lookup_key_reply)                          \
5190 _(l2_fib_clear_table_reply)                             \
5191 _(l2_interface_efp_filter_reply)                        \
5192 _(l2_interface_vlan_tag_rewrite_reply)                  \
5193 _(modify_vhost_user_if_reply)                           \
5194 _(delete_vhost_user_if_reply)                           \
5195 _(ip_probe_neighbor_reply)                              \
5196 _(ip_scan_neighbor_enable_disable_reply)                \
5197 _(want_ip4_arp_events_reply)                            \
5198 _(want_ip6_nd_events_reply)                             \
5199 _(want_l2_macs_events_reply)                            \
5200 _(input_acl_set_interface_reply)                        \
5201 _(ipsec_spd_add_del_reply)                              \
5202 _(ipsec_interface_add_del_spd_reply)                    \
5203 _(ipsec_spd_entry_add_del_reply)                        \
5204 _(ipsec_sad_entry_add_del_reply)                        \
5205 _(ipsec_tunnel_if_add_del_reply)                        \
5206 _(ipsec_tunnel_if_set_sa_reply)                         \
5207 _(delete_loopback_reply)                                \
5208 _(bd_ip_mac_add_del_reply)                              \
5209 _(bd_ip_mac_flush_reply)                                \
5210 _(want_interface_events_reply)                          \
5211 _(cop_interface_enable_disable_reply)                   \
5212 _(cop_whitelist_enable_disable_reply)                   \
5213 _(sw_interface_clear_stats_reply)                       \
5214 _(ioam_enable_reply)                                    \
5215 _(ioam_disable_reply)                                   \
5216 _(one_add_del_locator_reply)                            \
5217 _(one_add_del_local_eid_reply)                          \
5218 _(one_add_del_remote_mapping_reply)                     \
5219 _(one_add_del_adjacency_reply)                          \
5220 _(one_add_del_map_resolver_reply)                       \
5221 _(one_add_del_map_server_reply)                         \
5222 _(one_enable_disable_reply)                             \
5223 _(one_rloc_probe_enable_disable_reply)                  \
5224 _(one_map_register_enable_disable_reply)                \
5225 _(one_map_register_set_ttl_reply)                       \
5226 _(one_set_transport_protocol_reply)                     \
5227 _(one_map_register_fallback_threshold_reply)            \
5228 _(one_pitr_set_locator_set_reply)                       \
5229 _(one_map_request_mode_reply)                           \
5230 _(one_add_del_map_request_itr_rlocs_reply)              \
5231 _(one_eid_table_add_del_map_reply)                      \
5232 _(one_use_petr_reply)                                   \
5233 _(one_stats_enable_disable_reply)                       \
5234 _(one_add_del_l2_arp_entry_reply)                       \
5235 _(one_add_del_ndp_entry_reply)                          \
5236 _(one_stats_flush_reply)                                \
5237 _(one_enable_disable_xtr_mode_reply)                    \
5238 _(one_enable_disable_pitr_mode_reply)                   \
5239 _(one_enable_disable_petr_mode_reply)                   \
5240 _(gpe_enable_disable_reply)                             \
5241 _(gpe_set_encap_mode_reply)                             \
5242 _(gpe_add_del_iface_reply)                              \
5243 _(gpe_add_del_native_fwd_rpath_reply)                   \
5244 _(af_packet_delete_reply)                               \
5245 _(policer_classify_set_interface_reply)                 \
5246 _(netmap_create_reply)                                  \
5247 _(netmap_delete_reply)                                  \
5248 _(set_ipfix_exporter_reply)                             \
5249 _(set_ipfix_classify_stream_reply)                      \
5250 _(ipfix_classify_table_add_del_reply)                   \
5251 _(flow_classify_set_interface_reply)                    \
5252 _(sw_interface_span_enable_disable_reply)               \
5253 _(pg_capture_reply)                                     \
5254 _(pg_enable_disable_reply)                              \
5255 _(ip_source_and_port_range_check_add_del_reply)         \
5256 _(ip_source_and_port_range_check_interface_add_del_reply)\
5257 _(delete_subif_reply)                                   \
5258 _(l2_interface_pbb_tag_rewrite_reply)                   \
5259 _(set_punt_reply)                                       \
5260 _(feature_enable_disable_reply)                         \
5261 _(sw_interface_tag_add_del_reply)                       \
5262 _(hw_interface_set_mtu_reply)                           \
5263 _(p2p_ethernet_add_reply)                               \
5264 _(p2p_ethernet_del_reply)                               \
5265 _(lldp_config_reply)                                    \
5266 _(sw_interface_set_lldp_reply)                          \
5267 _(tcp_configure_src_addresses_reply)                    \
5268 _(dns_enable_disable_reply)                             \
5269 _(dns_name_server_add_del_reply)                        \
5270 _(session_rule_add_del_reply)                           \
5271 _(ip_container_proxy_add_del_reply)                     \
5272 _(output_acl_set_interface_reply)                       \
5273 _(qos_record_enable_disable_reply)
5274
5275 #define _(n)                                    \
5276     static void vl_api_##n##_t_handler          \
5277     (vl_api_##n##_t * mp)                       \
5278     {                                           \
5279         vat_main_t * vam = &vat_main;           \
5280         i32 retval = ntohl(mp->retval);         \
5281         if (vam->async_mode) {                  \
5282             vam->async_errors += (retval < 0);  \
5283         } else {                                \
5284             vam->retval = retval;               \
5285             vam->result_ready = 1;              \
5286         }                                       \
5287     }
5288 foreach_standard_reply_retval_handler;
5289 #undef _
5290
5291 #define _(n)                                    \
5292     static void vl_api_##n##_t_handler_json     \
5293     (vl_api_##n##_t * mp)                       \
5294     {                                           \
5295         vat_main_t * vam = &vat_main;           \
5296         vat_json_node_t node;                   \
5297         vat_json_init_object(&node);            \
5298         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5299         vat_json_print(vam->ofp, &node);        \
5300         vam->retval = ntohl(mp->retval);        \
5301         vam->result_ready = 1;                  \
5302     }
5303 foreach_standard_reply_retval_handler;
5304 #undef _
5305
5306 /*
5307  * Table of message reply handlers, must include boilerplate handlers
5308  * we just generated
5309  */
5310
5311 #define foreach_vpe_api_reply_msg                                       \
5312 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5313 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5314 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5315 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5316 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5317 _(CLI_REPLY, cli_reply)                                                 \
5318 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5319 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5320   sw_interface_add_del_address_reply)                                   \
5321 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5322 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5323 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5324 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5325 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5326 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5327 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5328 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5329 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5330 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5331   sw_interface_set_l2_xconnect_reply)                                   \
5332 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5333   sw_interface_set_l2_bridge_reply)                                     \
5334 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5335 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5336 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5337 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5338 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5339 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5340 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5341 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5342 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5343 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5344 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5345 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5346 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5347 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5348 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5349 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5350 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5351 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5352 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5353 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5354 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5355 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5356 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5357 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5358 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5359 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5360 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5361 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5362 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5363 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5364   proxy_arp_intfc_enable_disable_reply)                                 \
5365 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5366 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5367   sw_interface_set_unnumbered_reply)                                    \
5368 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5369 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5370 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5371 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5372 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5373 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5374 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5375 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5376 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5377 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5378   sw_interface_ip6_enable_disable_reply)                                \
5379 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5380 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5381 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5382   sw_interface_ip6nd_ra_prefix_reply)                                   \
5383 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5384   sw_interface_ip6nd_ra_config_reply)                                   \
5385 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5386 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5387 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5388 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5389 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5390 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5391 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5392 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5393 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5394 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5395 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5396 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5397 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5398 classify_set_interface_ip_table_reply)                                  \
5399 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5400   classify_set_interface_l2_tables_reply)                               \
5401 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5402 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5403 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5404 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5405 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5406   l2tpv3_interface_enable_disable_reply)                                \
5407 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5408 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5409 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5410 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5411 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5412 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5413 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5414 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5415 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5416 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5417 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5418 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5419 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5420 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5421 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5422 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5423 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5424 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5425 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5426 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5427 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5428 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5429 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5430 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5431 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5432 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5433 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5434 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5435 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5436 _(L2_MACS_EVENT, l2_macs_event)                                         \
5437 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5438 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5439 _(IP_DETAILS, ip_details)                                               \
5440 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5441 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5442 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5443 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5444 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5445 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5446 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5447 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5448 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5449 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5450 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5451 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5452 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5453 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5454 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5455 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5456 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5457 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5458 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5459 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5460 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5461 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5462 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5463 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5464 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5465 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5466 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5467 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5468 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5469   one_map_register_enable_disable_reply)                                \
5470 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5471 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5472 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5473 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5474   one_map_register_fallback_threshold_reply)                            \
5475 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5476   one_rloc_probe_enable_disable_reply)                                  \
5477 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5478 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5479 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5480 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5481 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5482 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5483 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5484 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5485 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5486 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5487 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5488 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5489 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5490 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5491 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5492 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5493   show_one_stats_enable_disable_reply)                                  \
5494 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5495 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5496 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5497 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5498 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5499 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5500 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5501 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5502   one_enable_disable_pitr_mode_reply)                                   \
5503 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5504   one_enable_disable_petr_mode_reply)                                   \
5505 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5506 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5507 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5508 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5509 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5510 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5511 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5512 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5513 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5514 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5515 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5516 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5517   gpe_add_del_native_fwd_rpath_reply)                                   \
5518 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5519   gpe_fwd_entry_path_details)                                           \
5520 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5521 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5522   one_add_del_map_request_itr_rlocs_reply)                              \
5523 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5524   one_get_map_request_itr_rlocs_reply)                                  \
5525 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5526 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5527 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5528 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5529 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5530 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5531   show_one_map_register_state_reply)                                    \
5532 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5533 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5534   show_one_map_register_fallback_threshold_reply)                       \
5535 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5536 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5537 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5538 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5539 _(POLICER_DETAILS, policer_details)                                     \
5540 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5541 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5542 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5543 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5544 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5545 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5546 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5547 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5548 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5549 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5550 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5551 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5552 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5553 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5554 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5555 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5556 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5557 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5558 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5559 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5560 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5561 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5562 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5563 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5564 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5565 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5566  ip_source_and_port_range_check_add_del_reply)                          \
5567 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5568  ip_source_and_port_range_check_interface_add_del_reply)                \
5569 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5570 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5571 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5572 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5573 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5574 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5575 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5576 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5577 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5578 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5579 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5580 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5581 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5582 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5583 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5584 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5585 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5586 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5587 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5588 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5589 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5590 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5591 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5592 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5593 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5594 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5595
5596 #define foreach_standalone_reply_msg                                    \
5597 _(SW_INTERFACE_EVENT, sw_interface_event)
5598
5599 typedef struct
5600 {
5601   u8 *name;
5602   u32 value;
5603 } name_sort_t;
5604
5605 #define STR_VTR_OP_CASE(op)     \
5606     case L2_VTR_ ## op:         \
5607         return "" # op;
5608
5609 static const char *
5610 str_vtr_op (u32 vtr_op)
5611 {
5612   switch (vtr_op)
5613     {
5614       STR_VTR_OP_CASE (DISABLED);
5615       STR_VTR_OP_CASE (PUSH_1);
5616       STR_VTR_OP_CASE (PUSH_2);
5617       STR_VTR_OP_CASE (POP_1);
5618       STR_VTR_OP_CASE (POP_2);
5619       STR_VTR_OP_CASE (TRANSLATE_1_1);
5620       STR_VTR_OP_CASE (TRANSLATE_1_2);
5621       STR_VTR_OP_CASE (TRANSLATE_2_1);
5622       STR_VTR_OP_CASE (TRANSLATE_2_2);
5623     }
5624
5625   return "UNKNOWN";
5626 }
5627
5628 static int
5629 dump_sub_interface_table (vat_main_t * vam)
5630 {
5631   const sw_interface_subif_t *sub = NULL;
5632
5633   if (vam->json_output)
5634     {
5635       clib_warning
5636         ("JSON output supported only for VPE API calls and dump_stats_table");
5637       return -99;
5638     }
5639
5640   print (vam->ofp,
5641          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5642          "Interface", "sw_if_index",
5643          "sub id", "dot1ad", "tags", "outer id",
5644          "inner id", "exact", "default", "outer any", "inner any");
5645
5646   vec_foreach (sub, vam->sw_if_subif_table)
5647   {
5648     print (vam->ofp,
5649            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5650            sub->interface_name,
5651            sub->sw_if_index,
5652            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5653            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5654            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5655            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5656     if (sub->vtr_op != L2_VTR_DISABLED)
5657       {
5658         print (vam->ofp,
5659                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5660                "tag1: %d tag2: %d ]",
5661                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5662                sub->vtr_tag1, sub->vtr_tag2);
5663       }
5664   }
5665
5666   return 0;
5667 }
5668
5669 static int
5670 name_sort_cmp (void *a1, void *a2)
5671 {
5672   name_sort_t *n1 = a1;
5673   name_sort_t *n2 = a2;
5674
5675   return strcmp ((char *) n1->name, (char *) n2->name);
5676 }
5677
5678 static int
5679 dump_interface_table (vat_main_t * vam)
5680 {
5681   hash_pair_t *p;
5682   name_sort_t *nses = 0, *ns;
5683
5684   if (vam->json_output)
5685     {
5686       clib_warning
5687         ("JSON output supported only for VPE API calls and dump_stats_table");
5688       return -99;
5689     }
5690
5691   /* *INDENT-OFF* */
5692   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5693   ({
5694     vec_add2 (nses, ns, 1);
5695     ns->name = (u8 *)(p->key);
5696     ns->value = (u32) p->value[0];
5697   }));
5698   /* *INDENT-ON* */
5699
5700   vec_sort_with_function (nses, name_sort_cmp);
5701
5702   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5703   vec_foreach (ns, nses)
5704   {
5705     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5706   }
5707   vec_free (nses);
5708   return 0;
5709 }
5710
5711 static int
5712 dump_ip_table (vat_main_t * vam, int is_ipv6)
5713 {
5714   const ip_details_t *det = NULL;
5715   const ip_address_details_t *address = NULL;
5716   u32 i = ~0;
5717
5718   print (vam->ofp, "%-12s", "sw_if_index");
5719
5720   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5721   {
5722     i++;
5723     if (!det->present)
5724       {
5725         continue;
5726       }
5727     print (vam->ofp, "%-12d", i);
5728     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5729     if (!det->addr)
5730       {
5731         continue;
5732       }
5733     vec_foreach (address, det->addr)
5734     {
5735       print (vam->ofp,
5736              "            %-30U%-13d",
5737              is_ipv6 ? format_ip6_address : format_ip4_address,
5738              address->ip, address->prefix_length);
5739     }
5740   }
5741
5742   return 0;
5743 }
5744
5745 static int
5746 dump_ipv4_table (vat_main_t * vam)
5747 {
5748   if (vam->json_output)
5749     {
5750       clib_warning
5751         ("JSON output supported only for VPE API calls and dump_stats_table");
5752       return -99;
5753     }
5754
5755   return dump_ip_table (vam, 0);
5756 }
5757
5758 static int
5759 dump_ipv6_table (vat_main_t * vam)
5760 {
5761   if (vam->json_output)
5762     {
5763       clib_warning
5764         ("JSON output supported only for VPE API calls and dump_stats_table");
5765       return -99;
5766     }
5767
5768   return dump_ip_table (vam, 1);
5769 }
5770
5771 /*
5772  * Pass CLI buffers directly in the CLI_INBAND API message,
5773  * instead of an additional shared memory area.
5774  */
5775 static int
5776 exec_inband (vat_main_t * vam)
5777 {
5778   vl_api_cli_inband_t *mp;
5779   unformat_input_t *i = vam->input;
5780   int ret;
5781
5782   if (vec_len (i->buffer) == 0)
5783     return -1;
5784
5785   if (vam->exec_mode == 0 && unformat (i, "mode"))
5786     {
5787       vam->exec_mode = 1;
5788       return 0;
5789     }
5790   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5791     {
5792       vam->exec_mode = 0;
5793       return 0;
5794     }
5795
5796   /*
5797    * In order for the CLI command to work, it
5798    * must be a vector ending in \n, not a C-string ending
5799    * in \n\0.
5800    */
5801   u32 len = vec_len (vam->input->buffer);
5802   M2 (CLI_INBAND, mp, len);
5803   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5804
5805   S (mp);
5806   W (ret);
5807   /* json responses may or may not include a useful reply... */
5808   if (vec_len (vam->cmd_reply))
5809     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5810   return ret;
5811 }
5812
5813 int
5814 exec (vat_main_t * vam)
5815 {
5816   return exec_inband (vam);
5817 }
5818
5819 static int
5820 api_create_loopback (vat_main_t * vam)
5821 {
5822   unformat_input_t *i = vam->input;
5823   vl_api_create_loopback_t *mp;
5824   vl_api_create_loopback_instance_t *mp_lbi;
5825   u8 mac_address[6];
5826   u8 mac_set = 0;
5827   u8 is_specified = 0;
5828   u32 user_instance = 0;
5829   int ret;
5830
5831   clib_memset (mac_address, 0, sizeof (mac_address));
5832
5833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5834     {
5835       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5836         mac_set = 1;
5837       if (unformat (i, "instance %d", &user_instance))
5838         is_specified = 1;
5839       else
5840         break;
5841     }
5842
5843   if (is_specified)
5844     {
5845       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5846       mp_lbi->is_specified = is_specified;
5847       if (is_specified)
5848         mp_lbi->user_instance = htonl (user_instance);
5849       if (mac_set)
5850         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5851       S (mp_lbi);
5852     }
5853   else
5854     {
5855       /* Construct the API message */
5856       M (CREATE_LOOPBACK, mp);
5857       if (mac_set)
5858         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5859       S (mp);
5860     }
5861
5862   W (ret);
5863   return ret;
5864 }
5865
5866 static int
5867 api_delete_loopback (vat_main_t * vam)
5868 {
5869   unformat_input_t *i = vam->input;
5870   vl_api_delete_loopback_t *mp;
5871   u32 sw_if_index = ~0;
5872   int ret;
5873
5874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5875     {
5876       if (unformat (i, "sw_if_index %d", &sw_if_index))
5877         ;
5878       else
5879         break;
5880     }
5881
5882   if (sw_if_index == ~0)
5883     {
5884       errmsg ("missing sw_if_index");
5885       return -99;
5886     }
5887
5888   /* Construct the API message */
5889   M (DELETE_LOOPBACK, mp);
5890   mp->sw_if_index = ntohl (sw_if_index);
5891
5892   S (mp);
5893   W (ret);
5894   return ret;
5895 }
5896
5897 static int
5898 api_want_interface_events (vat_main_t * vam)
5899 {
5900   unformat_input_t *i = vam->input;
5901   vl_api_want_interface_events_t *mp;
5902   int enable = -1;
5903   int ret;
5904
5905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5906     {
5907       if (unformat (i, "enable"))
5908         enable = 1;
5909       else if (unformat (i, "disable"))
5910         enable = 0;
5911       else
5912         break;
5913     }
5914
5915   if (enable == -1)
5916     {
5917       errmsg ("missing enable|disable");
5918       return -99;
5919     }
5920
5921   M (WANT_INTERFACE_EVENTS, mp);
5922   mp->enable_disable = enable;
5923
5924   vam->interface_event_display = enable;
5925
5926   S (mp);
5927   W (ret);
5928   return ret;
5929 }
5930
5931
5932 /* Note: non-static, called once to set up the initial intfc table */
5933 int
5934 api_sw_interface_dump (vat_main_t * vam)
5935 {
5936   vl_api_sw_interface_dump_t *mp;
5937   vl_api_control_ping_t *mp_ping;
5938   hash_pair_t *p;
5939   name_sort_t *nses = 0, *ns;
5940   sw_interface_subif_t *sub = NULL;
5941   int ret;
5942
5943   /* Toss the old name table */
5944   /* *INDENT-OFF* */
5945   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5946   ({
5947     vec_add2 (nses, ns, 1);
5948     ns->name = (u8 *)(p->key);
5949     ns->value = (u32) p->value[0];
5950   }));
5951   /* *INDENT-ON* */
5952
5953   hash_free (vam->sw_if_index_by_interface_name);
5954
5955   vec_foreach (ns, nses) vec_free (ns->name);
5956
5957   vec_free (nses);
5958
5959   vec_foreach (sub, vam->sw_if_subif_table)
5960   {
5961     vec_free (sub->interface_name);
5962   }
5963   vec_free (vam->sw_if_subif_table);
5964
5965   /* recreate the interface name hash table */
5966   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5967
5968   /*
5969    * Ask for all interface names. Otherwise, the epic catalog of
5970    * name filters becomes ridiculously long, and vat ends up needing
5971    * to be taught about new interface types.
5972    */
5973   M (SW_INTERFACE_DUMP, mp);
5974   S (mp);
5975
5976   /* Use a control ping for synchronization */
5977   MPING (CONTROL_PING, mp_ping);
5978   S (mp_ping);
5979
5980   W (ret);
5981   return ret;
5982 }
5983
5984 static int
5985 api_sw_interface_set_flags (vat_main_t * vam)
5986 {
5987   unformat_input_t *i = vam->input;
5988   vl_api_sw_interface_set_flags_t *mp;
5989   u32 sw_if_index;
5990   u8 sw_if_index_set = 0;
5991   u8 admin_up = 0;
5992   int ret;
5993
5994   /* Parse args required to build the message */
5995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5996     {
5997       if (unformat (i, "admin-up"))
5998         admin_up = 1;
5999       else if (unformat (i, "admin-down"))
6000         admin_up = 0;
6001       else
6002         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6003         sw_if_index_set = 1;
6004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6005         sw_if_index_set = 1;
6006       else
6007         break;
6008     }
6009
6010   if (sw_if_index_set == 0)
6011     {
6012       errmsg ("missing interface name or sw_if_index");
6013       return -99;
6014     }
6015
6016   /* Construct the API message */
6017   M (SW_INTERFACE_SET_FLAGS, mp);
6018   mp->sw_if_index = ntohl (sw_if_index);
6019   mp->admin_up_down = admin_up;
6020
6021   /* send it... */
6022   S (mp);
6023
6024   /* Wait for a reply, return the good/bad news... */
6025   W (ret);
6026   return ret;
6027 }
6028
6029 static int
6030 api_sw_interface_set_rx_mode (vat_main_t * vam)
6031 {
6032   unformat_input_t *i = vam->input;
6033   vl_api_sw_interface_set_rx_mode_t *mp;
6034   u32 sw_if_index;
6035   u8 sw_if_index_set = 0;
6036   int ret;
6037   u8 queue_id_valid = 0;
6038   u32 queue_id;
6039   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6040
6041   /* Parse args required to build the message */
6042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6043     {
6044       if (unformat (i, "queue %d", &queue_id))
6045         queue_id_valid = 1;
6046       else if (unformat (i, "polling"))
6047         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6048       else if (unformat (i, "interrupt"))
6049         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6050       else if (unformat (i, "adaptive"))
6051         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6052       else
6053         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6054         sw_if_index_set = 1;
6055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6056         sw_if_index_set = 1;
6057       else
6058         break;
6059     }
6060
6061   if (sw_if_index_set == 0)
6062     {
6063       errmsg ("missing interface name or sw_if_index");
6064       return -99;
6065     }
6066   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6067     {
6068       errmsg ("missing rx-mode");
6069       return -99;
6070     }
6071
6072   /* Construct the API message */
6073   M (SW_INTERFACE_SET_RX_MODE, mp);
6074   mp->sw_if_index = ntohl (sw_if_index);
6075   mp->mode = mode;
6076   mp->queue_id_valid = queue_id_valid;
6077   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6078
6079   /* send it... */
6080   S (mp);
6081
6082   /* Wait for a reply, return the good/bad news... */
6083   W (ret);
6084   return ret;
6085 }
6086
6087 static int
6088 api_sw_interface_set_rx_placement (vat_main_t * vam)
6089 {
6090   unformat_input_t *i = vam->input;
6091   vl_api_sw_interface_set_rx_placement_t *mp;
6092   u32 sw_if_index;
6093   u8 sw_if_index_set = 0;
6094   int ret;
6095   u8 is_main = 0;
6096   u32 queue_id, thread_index;
6097
6098   /* Parse args required to build the message */
6099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6100     {
6101       if (unformat (i, "queue %d", &queue_id))
6102         ;
6103       else if (unformat (i, "main"))
6104         is_main = 1;
6105       else if (unformat (i, "worker %d", &thread_index))
6106         ;
6107       else
6108         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6109         sw_if_index_set = 1;
6110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6111         sw_if_index_set = 1;
6112       else
6113         break;
6114     }
6115
6116   if (sw_if_index_set == 0)
6117     {
6118       errmsg ("missing interface name or sw_if_index");
6119       return -99;
6120     }
6121
6122   if (is_main)
6123     thread_index = 0;
6124   /* Construct the API message */
6125   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6126   mp->sw_if_index = ntohl (sw_if_index);
6127   mp->worker_id = ntohl (thread_index);
6128   mp->queue_id = ntohl (queue_id);
6129   mp->is_main = is_main;
6130
6131   /* send it... */
6132   S (mp);
6133   /* Wait for a reply, return the good/bad news... */
6134   W (ret);
6135   return ret;
6136 }
6137
6138 static void vl_api_sw_interface_rx_placement_details_t_handler
6139   (vl_api_sw_interface_rx_placement_details_t * mp)
6140 {
6141   vat_main_t *vam = &vat_main;
6142   u32 worker_id = ntohl (mp->worker_id);
6143
6144   print (vam->ofp,
6145          "\n%-11d %-11s %-6d %-5d %-9s",
6146          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6147          worker_id, ntohl (mp->queue_id),
6148          (mp->mode ==
6149           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6150 }
6151
6152 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6153   (vl_api_sw_interface_rx_placement_details_t * mp)
6154 {
6155   vat_main_t *vam = &vat_main;
6156   vat_json_node_t *node = NULL;
6157
6158   if (VAT_JSON_ARRAY != vam->json_tree.type)
6159     {
6160       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6161       vat_json_init_array (&vam->json_tree);
6162     }
6163   node = vat_json_array_add (&vam->json_tree);
6164
6165   vat_json_init_object (node);
6166   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6167   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6168   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6169   vat_json_object_add_uint (node, "mode", mp->mode);
6170 }
6171
6172 static int
6173 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6174 {
6175   unformat_input_t *i = vam->input;
6176   vl_api_sw_interface_rx_placement_dump_t *mp;
6177   vl_api_control_ping_t *mp_ping;
6178   int ret;
6179   u32 sw_if_index;
6180   u8 sw_if_index_set = 0;
6181
6182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6183     {
6184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6185         sw_if_index_set++;
6186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6187         sw_if_index_set++;
6188       else
6189         break;
6190     }
6191
6192   print (vam->ofp,
6193          "\n%-11s %-11s %-6s %-5s %-4s",
6194          "sw_if_index", "main/worker", "thread", "queue", "mode");
6195
6196   /* Dump Interface rx placement */
6197   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6198
6199   if (sw_if_index_set)
6200     mp->sw_if_index = htonl (sw_if_index);
6201   else
6202     mp->sw_if_index = ~0;
6203
6204   S (mp);
6205
6206   /* Use a control ping for synchronization */
6207   MPING (CONTROL_PING, mp_ping);
6208   S (mp_ping);
6209
6210   W (ret);
6211   return ret;
6212 }
6213
6214 static int
6215 api_sw_interface_clear_stats (vat_main_t * vam)
6216 {
6217   unformat_input_t *i = vam->input;
6218   vl_api_sw_interface_clear_stats_t *mp;
6219   u32 sw_if_index;
6220   u8 sw_if_index_set = 0;
6221   int ret;
6222
6223   /* Parse args required to build the message */
6224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6225     {
6226       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6227         sw_if_index_set = 1;
6228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6229         sw_if_index_set = 1;
6230       else
6231         break;
6232     }
6233
6234   /* Construct the API message */
6235   M (SW_INTERFACE_CLEAR_STATS, mp);
6236
6237   if (sw_if_index_set == 1)
6238     mp->sw_if_index = ntohl (sw_if_index);
6239   else
6240     mp->sw_if_index = ~0;
6241
6242   /* send it... */
6243   S (mp);
6244
6245   /* Wait for a reply, return the good/bad news... */
6246   W (ret);
6247   return ret;
6248 }
6249
6250 static int
6251 api_sw_interface_add_del_address (vat_main_t * vam)
6252 {
6253   unformat_input_t *i = vam->input;
6254   vl_api_sw_interface_add_del_address_t *mp;
6255   u32 sw_if_index;
6256   u8 sw_if_index_set = 0;
6257   u8 is_add = 1, del_all = 0;
6258   u32 address_length = 0;
6259   u8 v4_address_set = 0;
6260   u8 v6_address_set = 0;
6261   ip4_address_t v4address;
6262   ip6_address_t v6address;
6263   int ret;
6264
6265   /* Parse args required to build the message */
6266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6267     {
6268       if (unformat (i, "del-all"))
6269         del_all = 1;
6270       else if (unformat (i, "del"))
6271         is_add = 0;
6272       else
6273         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6274         sw_if_index_set = 1;
6275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6276         sw_if_index_set = 1;
6277       else if (unformat (i, "%U/%d",
6278                          unformat_ip4_address, &v4address, &address_length))
6279         v4_address_set = 1;
6280       else if (unformat (i, "%U/%d",
6281                          unformat_ip6_address, &v6address, &address_length))
6282         v6_address_set = 1;
6283       else
6284         break;
6285     }
6286
6287   if (sw_if_index_set == 0)
6288     {
6289       errmsg ("missing interface name or sw_if_index");
6290       return -99;
6291     }
6292   if (v4_address_set && v6_address_set)
6293     {
6294       errmsg ("both v4 and v6 addresses set");
6295       return -99;
6296     }
6297   if (!v4_address_set && !v6_address_set && !del_all)
6298     {
6299       errmsg ("no addresses set");
6300       return -99;
6301     }
6302
6303   /* Construct the API message */
6304   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6305
6306   mp->sw_if_index = ntohl (sw_if_index);
6307   mp->is_add = is_add;
6308   mp->del_all = del_all;
6309   if (v6_address_set)
6310     {
6311       mp->is_ipv6 = 1;
6312       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6313     }
6314   else
6315     {
6316       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6317     }
6318   mp->address_length = address_length;
6319
6320   /* send it... */
6321   S (mp);
6322
6323   /* Wait for a reply, return good/bad news  */
6324   W (ret);
6325   return ret;
6326 }
6327
6328 static int
6329 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6330 {
6331   unformat_input_t *i = vam->input;
6332   vl_api_sw_interface_set_mpls_enable_t *mp;
6333   u32 sw_if_index;
6334   u8 sw_if_index_set = 0;
6335   u8 enable = 1;
6336   int ret;
6337
6338   /* Parse args required to build the message */
6339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6340     {
6341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6342         sw_if_index_set = 1;
6343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6344         sw_if_index_set = 1;
6345       else if (unformat (i, "disable"))
6346         enable = 0;
6347       else if (unformat (i, "dis"))
6348         enable = 0;
6349       else
6350         break;
6351     }
6352
6353   if (sw_if_index_set == 0)
6354     {
6355       errmsg ("missing interface name or sw_if_index");
6356       return -99;
6357     }
6358
6359   /* Construct the API message */
6360   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6361
6362   mp->sw_if_index = ntohl (sw_if_index);
6363   mp->enable = enable;
6364
6365   /* send it... */
6366   S (mp);
6367
6368   /* Wait for a reply... */
6369   W (ret);
6370   return ret;
6371 }
6372
6373 static int
6374 api_sw_interface_set_table (vat_main_t * vam)
6375 {
6376   unformat_input_t *i = vam->input;
6377   vl_api_sw_interface_set_table_t *mp;
6378   u32 sw_if_index, vrf_id = 0;
6379   u8 sw_if_index_set = 0;
6380   u8 is_ipv6 = 0;
6381   int ret;
6382
6383   /* Parse args required to build the message */
6384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6385     {
6386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6387         sw_if_index_set = 1;
6388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6389         sw_if_index_set = 1;
6390       else if (unformat (i, "vrf %d", &vrf_id))
6391         ;
6392       else if (unformat (i, "ipv6"))
6393         is_ipv6 = 1;
6394       else
6395         break;
6396     }
6397
6398   if (sw_if_index_set == 0)
6399     {
6400       errmsg ("missing interface name or sw_if_index");
6401       return -99;
6402     }
6403
6404   /* Construct the API message */
6405   M (SW_INTERFACE_SET_TABLE, mp);
6406
6407   mp->sw_if_index = ntohl (sw_if_index);
6408   mp->is_ipv6 = is_ipv6;
6409   mp->vrf_id = ntohl (vrf_id);
6410
6411   /* send it... */
6412   S (mp);
6413
6414   /* Wait for a reply... */
6415   W (ret);
6416   return ret;
6417 }
6418
6419 static void vl_api_sw_interface_get_table_reply_t_handler
6420   (vl_api_sw_interface_get_table_reply_t * mp)
6421 {
6422   vat_main_t *vam = &vat_main;
6423
6424   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6425
6426   vam->retval = ntohl (mp->retval);
6427   vam->result_ready = 1;
6428
6429 }
6430
6431 static void vl_api_sw_interface_get_table_reply_t_handler_json
6432   (vl_api_sw_interface_get_table_reply_t * mp)
6433 {
6434   vat_main_t *vam = &vat_main;
6435   vat_json_node_t node;
6436
6437   vat_json_init_object (&node);
6438   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6439   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6440
6441   vat_json_print (vam->ofp, &node);
6442   vat_json_free (&node);
6443
6444   vam->retval = ntohl (mp->retval);
6445   vam->result_ready = 1;
6446 }
6447
6448 static int
6449 api_sw_interface_get_table (vat_main_t * vam)
6450 {
6451   unformat_input_t *i = vam->input;
6452   vl_api_sw_interface_get_table_t *mp;
6453   u32 sw_if_index;
6454   u8 sw_if_index_set = 0;
6455   u8 is_ipv6 = 0;
6456   int ret;
6457
6458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6459     {
6460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6461         sw_if_index_set = 1;
6462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6463         sw_if_index_set = 1;
6464       else if (unformat (i, "ipv6"))
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   M (SW_INTERFACE_GET_TABLE, mp);
6477   mp->sw_if_index = htonl (sw_if_index);
6478   mp->is_ipv6 = is_ipv6;
6479
6480   S (mp);
6481   W (ret);
6482   return ret;
6483 }
6484
6485 static int
6486 api_sw_interface_set_vpath (vat_main_t * vam)
6487 {
6488   unformat_input_t *i = vam->input;
6489   vl_api_sw_interface_set_vpath_t *mp;
6490   u32 sw_if_index = 0;
6491   u8 sw_if_index_set = 0;
6492   u8 is_enable = 0;
6493   int ret;
6494
6495   /* Parse args required to build the message */
6496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6497     {
6498       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6499         sw_if_index_set = 1;
6500       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6501         sw_if_index_set = 1;
6502       else if (unformat (i, "enable"))
6503         is_enable = 1;
6504       else if (unformat (i, "disable"))
6505         is_enable = 0;
6506       else
6507         break;
6508     }
6509
6510   if (sw_if_index_set == 0)
6511     {
6512       errmsg ("missing interface name or sw_if_index");
6513       return -99;
6514     }
6515
6516   /* Construct the API message */
6517   M (SW_INTERFACE_SET_VPATH, mp);
6518
6519   mp->sw_if_index = ntohl (sw_if_index);
6520   mp->enable = is_enable;
6521
6522   /* send it... */
6523   S (mp);
6524
6525   /* Wait for a reply... */
6526   W (ret);
6527   return ret;
6528 }
6529
6530 static int
6531 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6532 {
6533   unformat_input_t *i = vam->input;
6534   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6535   u32 sw_if_index = 0;
6536   u8 sw_if_index_set = 0;
6537   u8 is_enable = 1;
6538   u8 is_ipv6 = 0;
6539   int ret;
6540
6541   /* Parse args required to build the message */
6542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6543     {
6544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6545         sw_if_index_set = 1;
6546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6547         sw_if_index_set = 1;
6548       else if (unformat (i, "enable"))
6549         is_enable = 1;
6550       else if (unformat (i, "disable"))
6551         is_enable = 0;
6552       else if (unformat (i, "ip4"))
6553         is_ipv6 = 0;
6554       else if (unformat (i, "ip6"))
6555         is_ipv6 = 1;
6556       else
6557         break;
6558     }
6559
6560   if (sw_if_index_set == 0)
6561     {
6562       errmsg ("missing interface name or sw_if_index");
6563       return -99;
6564     }
6565
6566   /* Construct the API message */
6567   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6568
6569   mp->sw_if_index = ntohl (sw_if_index);
6570   mp->enable = is_enable;
6571   mp->is_ipv6 = is_ipv6;
6572
6573   /* send it... */
6574   S (mp);
6575
6576   /* Wait for a reply... */
6577   W (ret);
6578   return ret;
6579 }
6580
6581 static int
6582 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6583 {
6584   unformat_input_t *i = vam->input;
6585   vl_api_sw_interface_set_geneve_bypass_t *mp;
6586   u32 sw_if_index = 0;
6587   u8 sw_if_index_set = 0;
6588   u8 is_enable = 1;
6589   u8 is_ipv6 = 0;
6590   int ret;
6591
6592   /* Parse args required to build the message */
6593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6594     {
6595       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6598         sw_if_index_set = 1;
6599       else if (unformat (i, "enable"))
6600         is_enable = 1;
6601       else if (unformat (i, "disable"))
6602         is_enable = 0;
6603       else if (unformat (i, "ip4"))
6604         is_ipv6 = 0;
6605       else if (unformat (i, "ip6"))
6606         is_ipv6 = 1;
6607       else
6608         break;
6609     }
6610
6611   if (sw_if_index_set == 0)
6612     {
6613       errmsg ("missing interface name or sw_if_index");
6614       return -99;
6615     }
6616
6617   /* Construct the API message */
6618   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6619
6620   mp->sw_if_index = ntohl (sw_if_index);
6621   mp->enable = is_enable;
6622   mp->is_ipv6 = is_ipv6;
6623
6624   /* send it... */
6625   S (mp);
6626
6627   /* Wait for a reply... */
6628   W (ret);
6629   return ret;
6630 }
6631
6632 static int
6633 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6634 {
6635   unformat_input_t *i = vam->input;
6636   vl_api_sw_interface_set_l2_xconnect_t *mp;
6637   u32 rx_sw_if_index;
6638   u8 rx_sw_if_index_set = 0;
6639   u32 tx_sw_if_index;
6640   u8 tx_sw_if_index_set = 0;
6641   u8 enable = 1;
6642   int ret;
6643
6644   /* Parse args required to build the message */
6645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6646     {
6647       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6648         rx_sw_if_index_set = 1;
6649       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6650         tx_sw_if_index_set = 1;
6651       else if (unformat (i, "rx"))
6652         {
6653           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6654             {
6655               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6656                             &rx_sw_if_index))
6657                 rx_sw_if_index_set = 1;
6658             }
6659           else
6660             break;
6661         }
6662       else if (unformat (i, "tx"))
6663         {
6664           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665             {
6666               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6667                             &tx_sw_if_index))
6668                 tx_sw_if_index_set = 1;
6669             }
6670           else
6671             break;
6672         }
6673       else if (unformat (i, "enable"))
6674         enable = 1;
6675       else if (unformat (i, "disable"))
6676         enable = 0;
6677       else
6678         break;
6679     }
6680
6681   if (rx_sw_if_index_set == 0)
6682     {
6683       errmsg ("missing rx interface name or rx_sw_if_index");
6684       return -99;
6685     }
6686
6687   if (enable && (tx_sw_if_index_set == 0))
6688     {
6689       errmsg ("missing tx interface name or tx_sw_if_index");
6690       return -99;
6691     }
6692
6693   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6694
6695   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6696   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6697   mp->enable = enable;
6698
6699   S (mp);
6700   W (ret);
6701   return ret;
6702 }
6703
6704 static int
6705 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6706 {
6707   unformat_input_t *i = vam->input;
6708   vl_api_sw_interface_set_l2_bridge_t *mp;
6709   vl_api_l2_port_type_t port_type;
6710   u32 rx_sw_if_index;
6711   u8 rx_sw_if_index_set = 0;
6712   u32 bd_id;
6713   u8 bd_id_set = 0;
6714   u32 shg = 0;
6715   u8 enable = 1;
6716   int ret;
6717
6718   port_type = L2_API_PORT_TYPE_NORMAL;
6719
6720   /* Parse args required to build the message */
6721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6722     {
6723       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6724         rx_sw_if_index_set = 1;
6725       else if (unformat (i, "bd_id %d", &bd_id))
6726         bd_id_set = 1;
6727       else
6728         if (unformat
6729             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6730         rx_sw_if_index_set = 1;
6731       else if (unformat (i, "shg %d", &shg))
6732         ;
6733       else if (unformat (i, "bvi"))
6734         port_type = L2_API_PORT_TYPE_BVI;
6735       else if (unformat (i, "uu-fwd"))
6736         port_type = L2_API_PORT_TYPE_UU_FWD;
6737       else if (unformat (i, "enable"))
6738         enable = 1;
6739       else if (unformat (i, "disable"))
6740         enable = 0;
6741       else
6742         break;
6743     }
6744
6745   if (rx_sw_if_index_set == 0)
6746     {
6747       errmsg ("missing rx interface name or sw_if_index");
6748       return -99;
6749     }
6750
6751   if (enable && (bd_id_set == 0))
6752     {
6753       errmsg ("missing bridge domain");
6754       return -99;
6755     }
6756
6757   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6758
6759   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6760   mp->bd_id = ntohl (bd_id);
6761   mp->shg = (u8) shg;
6762   mp->port_type = ntohl (port_type);
6763   mp->enable = enable;
6764
6765   S (mp);
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_bridge_domain_dump (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_bridge_domain_dump_t *mp;
6775   vl_api_control_ping_t *mp_ping;
6776   u32 bd_id = ~0;
6777   int ret;
6778
6779   /* Parse args required to build the message */
6780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6781     {
6782       if (unformat (i, "bd_id %d", &bd_id))
6783         ;
6784       else
6785         break;
6786     }
6787
6788   M (BRIDGE_DOMAIN_DUMP, mp);
6789   mp->bd_id = ntohl (bd_id);
6790   S (mp);
6791
6792   /* Use a control ping for synchronization */
6793   MPING (CONTROL_PING, mp_ping);
6794   S (mp_ping);
6795
6796   W (ret);
6797   return ret;
6798 }
6799
6800 static int
6801 api_bridge_domain_add_del (vat_main_t * vam)
6802 {
6803   unformat_input_t *i = vam->input;
6804   vl_api_bridge_domain_add_del_t *mp;
6805   u32 bd_id = ~0;
6806   u8 is_add = 1;
6807   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6808   u8 *bd_tag = NULL;
6809   u32 mac_age = 0;
6810   int ret;
6811
6812   /* Parse args required to build the message */
6813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6814     {
6815       if (unformat (i, "bd_id %d", &bd_id))
6816         ;
6817       else if (unformat (i, "flood %d", &flood))
6818         ;
6819       else if (unformat (i, "uu-flood %d", &uu_flood))
6820         ;
6821       else if (unformat (i, "forward %d", &forward))
6822         ;
6823       else if (unformat (i, "learn %d", &learn))
6824         ;
6825       else if (unformat (i, "arp-term %d", &arp_term))
6826         ;
6827       else if (unformat (i, "mac-age %d", &mac_age))
6828         ;
6829       else if (unformat (i, "bd-tag %s", &bd_tag))
6830         ;
6831       else if (unformat (i, "del"))
6832         {
6833           is_add = 0;
6834           flood = uu_flood = forward = learn = 0;
6835         }
6836       else
6837         break;
6838     }
6839
6840   if (bd_id == ~0)
6841     {
6842       errmsg ("missing bridge domain");
6843       ret = -99;
6844       goto done;
6845     }
6846
6847   if (mac_age > 255)
6848     {
6849       errmsg ("mac age must be less than 256 ");
6850       ret = -99;
6851       goto done;
6852     }
6853
6854   if ((bd_tag) && (vec_len (bd_tag) > 63))
6855     {
6856       errmsg ("bd-tag cannot be longer than 63");
6857       ret = -99;
6858       goto done;
6859     }
6860
6861   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6862
6863   mp->bd_id = ntohl (bd_id);
6864   mp->flood = flood;
6865   mp->uu_flood = uu_flood;
6866   mp->forward = forward;
6867   mp->learn = learn;
6868   mp->arp_term = arp_term;
6869   mp->is_add = is_add;
6870   mp->mac_age = (u8) mac_age;
6871   if (bd_tag)
6872     {
6873       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6874       mp->bd_tag[vec_len (bd_tag)] = 0;
6875     }
6876   S (mp);
6877   W (ret);
6878
6879 done:
6880   vec_free (bd_tag);
6881   return ret;
6882 }
6883
6884 static int
6885 api_l2fib_flush_bd (vat_main_t * vam)
6886 {
6887   unformat_input_t *i = vam->input;
6888   vl_api_l2fib_flush_bd_t *mp;
6889   u32 bd_id = ~0;
6890   int ret;
6891
6892   /* Parse args required to build the message */
6893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6894     {
6895       if (unformat (i, "bd_id %d", &bd_id));
6896       else
6897         break;
6898     }
6899
6900   if (bd_id == ~0)
6901     {
6902       errmsg ("missing bridge domain");
6903       return -99;
6904     }
6905
6906   M (L2FIB_FLUSH_BD, mp);
6907
6908   mp->bd_id = htonl (bd_id);
6909
6910   S (mp);
6911   W (ret);
6912   return ret;
6913 }
6914
6915 static int
6916 api_l2fib_flush_int (vat_main_t * vam)
6917 {
6918   unformat_input_t *i = vam->input;
6919   vl_api_l2fib_flush_int_t *mp;
6920   u32 sw_if_index = ~0;
6921   int ret;
6922
6923   /* Parse args required to build the message */
6924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6925     {
6926       if (unformat (i, "sw_if_index %d", &sw_if_index));
6927       else
6928         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6929       else
6930         break;
6931     }
6932
6933   if (sw_if_index == ~0)
6934     {
6935       errmsg ("missing interface name or sw_if_index");
6936       return -99;
6937     }
6938
6939   M (L2FIB_FLUSH_INT, mp);
6940
6941   mp->sw_if_index = ntohl (sw_if_index);
6942
6943   S (mp);
6944   W (ret);
6945   return ret;
6946 }
6947
6948 static int
6949 api_l2fib_add_del (vat_main_t * vam)
6950 {
6951   unformat_input_t *i = vam->input;
6952   vl_api_l2fib_add_del_t *mp;
6953   f64 timeout;
6954   u8 mac[6] = { 0 };
6955   u8 mac_set = 0;
6956   u32 bd_id;
6957   u8 bd_id_set = 0;
6958   u32 sw_if_index = 0;
6959   u8 sw_if_index_set = 0;
6960   u8 is_add = 1;
6961   u8 static_mac = 0;
6962   u8 filter_mac = 0;
6963   u8 bvi_mac = 0;
6964   int count = 1;
6965   f64 before = 0;
6966   int j;
6967
6968   /* Parse args required to build the message */
6969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6970     {
6971       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6972         mac_set = 1;
6973       else if (unformat (i, "bd_id %d", &bd_id))
6974         bd_id_set = 1;
6975       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6976         sw_if_index_set = 1;
6977       else if (unformat (i, "sw_if"))
6978         {
6979           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6980             {
6981               if (unformat
6982                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6983                 sw_if_index_set = 1;
6984             }
6985           else
6986             break;
6987         }
6988       else if (unformat (i, "static"))
6989         static_mac = 1;
6990       else if (unformat (i, "filter"))
6991         {
6992           filter_mac = 1;
6993           static_mac = 1;
6994         }
6995       else if (unformat (i, "bvi"))
6996         {
6997           bvi_mac = 1;
6998           static_mac = 1;
6999         }
7000       else if (unformat (i, "del"))
7001         is_add = 0;
7002       else if (unformat (i, "count %d", &count))
7003         ;
7004       else
7005         break;
7006     }
7007
7008   if (mac_set == 0)
7009     {
7010       errmsg ("missing mac address");
7011       return -99;
7012     }
7013
7014   if (bd_id_set == 0)
7015     {
7016       errmsg ("missing bridge domain");
7017       return -99;
7018     }
7019
7020   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7021     {
7022       errmsg ("missing interface name or sw_if_index");
7023       return -99;
7024     }
7025
7026   if (count > 1)
7027     {
7028       /* Turn on async mode */
7029       vam->async_mode = 1;
7030       vam->async_errors = 0;
7031       before = vat_time_now (vam);
7032     }
7033
7034   for (j = 0; j < count; j++)
7035     {
7036       M (L2FIB_ADD_DEL, mp);
7037
7038       clib_memcpy (mp->mac, mac, 6);
7039       mp->bd_id = ntohl (bd_id);
7040       mp->is_add = is_add;
7041       mp->sw_if_index = ntohl (sw_if_index);
7042
7043       if (is_add)
7044         {
7045           mp->static_mac = static_mac;
7046           mp->filter_mac = filter_mac;
7047           mp->bvi_mac = bvi_mac;
7048         }
7049       increment_mac_address (mac);
7050       /* send it... */
7051       S (mp);
7052     }
7053
7054   if (count > 1)
7055     {
7056       vl_api_control_ping_t *mp_ping;
7057       f64 after;
7058
7059       /* Shut off async mode */
7060       vam->async_mode = 0;
7061
7062       MPING (CONTROL_PING, mp_ping);
7063       S (mp_ping);
7064
7065       timeout = vat_time_now (vam) + 1.0;
7066       while (vat_time_now (vam) < timeout)
7067         if (vam->result_ready == 1)
7068           goto out;
7069       vam->retval = -99;
7070
7071     out:
7072       if (vam->retval == -99)
7073         errmsg ("timeout");
7074
7075       if (vam->async_errors > 0)
7076         {
7077           errmsg ("%d asynchronous errors", vam->async_errors);
7078           vam->retval = -98;
7079         }
7080       vam->async_errors = 0;
7081       after = vat_time_now (vam);
7082
7083       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7084              count, after - before, count / (after - before));
7085     }
7086   else
7087     {
7088       int ret;
7089
7090       /* Wait for a reply... */
7091       W (ret);
7092       return ret;
7093     }
7094   /* Return the good/bad news */
7095   return (vam->retval);
7096 }
7097
7098 static int
7099 api_bridge_domain_set_mac_age (vat_main_t * vam)
7100 {
7101   unformat_input_t *i = vam->input;
7102   vl_api_bridge_domain_set_mac_age_t *mp;
7103   u32 bd_id = ~0;
7104   u32 mac_age = 0;
7105   int ret;
7106
7107   /* Parse args required to build the message */
7108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7109     {
7110       if (unformat (i, "bd_id %d", &bd_id));
7111       else if (unformat (i, "mac-age %d", &mac_age));
7112       else
7113         break;
7114     }
7115
7116   if (bd_id == ~0)
7117     {
7118       errmsg ("missing bridge domain");
7119       return -99;
7120     }
7121
7122   if (mac_age > 255)
7123     {
7124       errmsg ("mac age must be less than 256 ");
7125       return -99;
7126     }
7127
7128   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7129
7130   mp->bd_id = htonl (bd_id);
7131   mp->mac_age = (u8) mac_age;
7132
7133   S (mp);
7134   W (ret);
7135   return ret;
7136 }
7137
7138 static int
7139 api_l2_flags (vat_main_t * vam)
7140 {
7141   unformat_input_t *i = vam->input;
7142   vl_api_l2_flags_t *mp;
7143   u32 sw_if_index;
7144   u32 flags = 0;
7145   u8 sw_if_index_set = 0;
7146   u8 is_set = 0;
7147   int ret;
7148
7149   /* Parse args required to build the message */
7150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7151     {
7152       if (unformat (i, "sw_if_index %d", &sw_if_index))
7153         sw_if_index_set = 1;
7154       else if (unformat (i, "sw_if"))
7155         {
7156           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7157             {
7158               if (unformat
7159                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7160                 sw_if_index_set = 1;
7161             }
7162           else
7163             break;
7164         }
7165       else if (unformat (i, "learn"))
7166         flags |= L2_LEARN;
7167       else if (unformat (i, "forward"))
7168         flags |= L2_FWD;
7169       else if (unformat (i, "flood"))
7170         flags |= L2_FLOOD;
7171       else if (unformat (i, "uu-flood"))
7172         flags |= L2_UU_FLOOD;
7173       else if (unformat (i, "arp-term"))
7174         flags |= L2_ARP_TERM;
7175       else if (unformat (i, "off"))
7176         is_set = 0;
7177       else if (unformat (i, "disable"))
7178         is_set = 0;
7179       else
7180         break;
7181     }
7182
7183   if (sw_if_index_set == 0)
7184     {
7185       errmsg ("missing interface name or sw_if_index");
7186       return -99;
7187     }
7188
7189   M (L2_FLAGS, mp);
7190
7191   mp->sw_if_index = ntohl (sw_if_index);
7192   mp->feature_bitmap = ntohl (flags);
7193   mp->is_set = is_set;
7194
7195   S (mp);
7196   W (ret);
7197   return ret;
7198 }
7199
7200 static int
7201 api_bridge_flags (vat_main_t * vam)
7202 {
7203   unformat_input_t *i = vam->input;
7204   vl_api_bridge_flags_t *mp;
7205   u32 bd_id;
7206   u8 bd_id_set = 0;
7207   u8 is_set = 1;
7208   bd_flags_t flags = 0;
7209   int ret;
7210
7211   /* Parse args required to build the message */
7212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7213     {
7214       if (unformat (i, "bd_id %d", &bd_id))
7215         bd_id_set = 1;
7216       else if (unformat (i, "learn"))
7217         flags |= BRIDGE_API_FLAG_LEARN;
7218       else if (unformat (i, "forward"))
7219         flags |= BRIDGE_API_FLAG_FWD;
7220       else if (unformat (i, "flood"))
7221         flags |= BRIDGE_API_FLAG_FLOOD;
7222       else if (unformat (i, "uu-flood"))
7223         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7224       else if (unformat (i, "arp-term"))
7225         flags |= BRIDGE_API_FLAG_ARP_TERM;
7226       else if (unformat (i, "off"))
7227         is_set = 0;
7228       else if (unformat (i, "disable"))
7229         is_set = 0;
7230       else
7231         break;
7232     }
7233
7234   if (bd_id_set == 0)
7235     {
7236       errmsg ("missing bridge domain");
7237       return -99;
7238     }
7239
7240   M (BRIDGE_FLAGS, mp);
7241
7242   mp->bd_id = ntohl (bd_id);
7243   mp->flags = ntohl (flags);
7244   mp->is_set = is_set;
7245
7246   S (mp);
7247   W (ret);
7248   return ret;
7249 }
7250
7251 static int
7252 api_bd_ip_mac_add_del (vat_main_t * vam)
7253 {
7254   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7255   vl_api_mac_address_t mac = { 0 };
7256   unformat_input_t *i = vam->input;
7257   vl_api_bd_ip_mac_add_del_t *mp;
7258   u32 bd_id;
7259   u8 is_add = 1;
7260   u8 bd_id_set = 0;
7261   u8 ip_set = 0;
7262   u8 mac_set = 0;
7263   int ret;
7264
7265
7266   /* Parse args required to build the message */
7267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7268     {
7269       if (unformat (i, "bd_id %d", &bd_id))
7270         {
7271           bd_id_set++;
7272         }
7273       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7274         {
7275           ip_set++;
7276         }
7277       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7278         {
7279           mac_set++;
7280         }
7281       else if (unformat (i, "del"))
7282         is_add = 0;
7283       else
7284         break;
7285     }
7286
7287   if (bd_id_set == 0)
7288     {
7289       errmsg ("missing bridge domain");
7290       return -99;
7291     }
7292   else if (ip_set == 0)
7293     {
7294       errmsg ("missing IP address");
7295       return -99;
7296     }
7297   else if (mac_set == 0)
7298     {
7299       errmsg ("missing MAC address");
7300       return -99;
7301     }
7302
7303   M (BD_IP_MAC_ADD_DEL, mp);
7304
7305   mp->entry.bd_id = ntohl (bd_id);
7306   mp->is_add = is_add;
7307
7308   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7309   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7310
7311   S (mp);
7312   W (ret);
7313   return ret;
7314 }
7315
7316 static int
7317 api_bd_ip_mac_flush (vat_main_t * vam)
7318 {
7319   unformat_input_t *i = vam->input;
7320   vl_api_bd_ip_mac_flush_t *mp;
7321   u32 bd_id;
7322   u8 bd_id_set = 0;
7323   int ret;
7324
7325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326     {
7327       if (unformat (i, "bd_id %d", &bd_id))
7328         {
7329           bd_id_set++;
7330         }
7331       else
7332         break;
7333     }
7334
7335   if (bd_id_set == 0)
7336     {
7337       errmsg ("missing bridge domain");
7338       return -99;
7339     }
7340
7341   M (BD_IP_MAC_FLUSH, mp);
7342
7343   mp->bd_id = ntohl (bd_id);
7344
7345   S (mp);
7346   W (ret);
7347   return ret;
7348 }
7349
7350 static void vl_api_bd_ip_mac_details_t_handler
7351   (vl_api_bd_ip_mac_details_t * mp)
7352 {
7353   vat_main_t *vam = &vat_main;
7354
7355   print (vam->ofp,
7356          "\n%-5d %U %U",
7357          ntohl (mp->entry.bd_id),
7358          format_vl_api_mac_address, mp->entry.mac,
7359          format_vl_api_address, &mp->entry.ip);
7360 }
7361
7362 static void vl_api_bd_ip_mac_details_t_handler_json
7363   (vl_api_bd_ip_mac_details_t * mp)
7364 {
7365   vat_main_t *vam = &vat_main;
7366   vat_json_node_t *node = NULL;
7367
7368   if (VAT_JSON_ARRAY != vam->json_tree.type)
7369     {
7370       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7371       vat_json_init_array (&vam->json_tree);
7372     }
7373   node = vat_json_array_add (&vam->json_tree);
7374
7375   vat_json_init_object (node);
7376   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7377   vat_json_object_add_string_copy (node, "mac_address",
7378                                    format (0, "%U", format_vl_api_mac_address,
7379                                            &mp->entry.mac));
7380   u8 *ip = 0;
7381
7382   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7383   vat_json_object_add_string_copy (node, "ip_address", ip);
7384   vec_free (ip);
7385 }
7386
7387 static int
7388 api_bd_ip_mac_dump (vat_main_t * vam)
7389 {
7390   unformat_input_t *i = vam->input;
7391   vl_api_bd_ip_mac_dump_t *mp;
7392   vl_api_control_ping_t *mp_ping;
7393   int ret;
7394   u32 bd_id;
7395   u8 bd_id_set = 0;
7396
7397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7398     {
7399       if (unformat (i, "bd_id %d", &bd_id))
7400         {
7401           bd_id_set++;
7402         }
7403       else
7404         break;
7405     }
7406
7407   print (vam->ofp,
7408          "\n%-5s %-7s %-20s %-30s",
7409          "bd_id", "is_ipv6", "mac_address", "ip_address");
7410
7411   /* Dump Bridge Domain Ip to Mac entries */
7412   M (BD_IP_MAC_DUMP, mp);
7413
7414   if (bd_id_set)
7415     mp->bd_id = htonl (bd_id);
7416   else
7417     mp->bd_id = ~0;
7418
7419   S (mp);
7420
7421   /* Use a control ping for synchronization */
7422   MPING (CONTROL_PING, mp_ping);
7423   S (mp_ping);
7424
7425   W (ret);
7426   return ret;
7427 }
7428
7429 static int
7430 api_tap_create_v2 (vat_main_t * vam)
7431 {
7432   unformat_input_t *i = vam->input;
7433   vl_api_tap_create_v2_t *mp;
7434 #define TAP_FLAG_GSO (1 << 0)
7435   u8 mac_address[6];
7436   u8 random_mac = 1;
7437   u32 id = ~0;
7438   u8 *host_if_name = 0;
7439   u8 *host_ns = 0;
7440   u8 host_mac_addr[6];
7441   u8 host_mac_addr_set = 0;
7442   u8 *host_bridge = 0;
7443   ip4_address_t host_ip4_addr;
7444   ip4_address_t host_ip4_gw;
7445   u8 host_ip4_gw_set = 0;
7446   u32 host_ip4_prefix_len = 0;
7447   ip6_address_t host_ip6_addr;
7448   ip6_address_t host_ip6_gw;
7449   u8 host_ip6_gw_set = 0;
7450   u32 host_ip6_prefix_len = 0;
7451   u8 host_mtu_set = 0;
7452   u32 host_mtu_size = 0;
7453   u32 tap_flags = 0;
7454   int ret;
7455   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7456
7457   clib_memset (mac_address, 0, sizeof (mac_address));
7458
7459   /* Parse args required to build the message */
7460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7461     {
7462       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7463         {
7464           random_mac = 0;
7465         }
7466       else if (unformat (i, "id %u", &id))
7467         ;
7468       else if (unformat (i, "host-if-name %s", &host_if_name))
7469         ;
7470       else if (unformat (i, "host-ns %s", &host_ns))
7471         ;
7472       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7473                          host_mac_addr))
7474         host_mac_addr_set = 1;
7475       else if (unformat (i, "host-bridge %s", &host_bridge))
7476         ;
7477       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7478                          &host_ip4_addr, &host_ip4_prefix_len))
7479         ;
7480       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7481                          &host_ip6_addr, &host_ip6_prefix_len))
7482         ;
7483       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7484                          &host_ip4_gw))
7485         host_ip4_gw_set = 1;
7486       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7487                          &host_ip6_gw))
7488         host_ip6_gw_set = 1;
7489       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7490         ;
7491       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7492         ;
7493       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7494         host_mtu_set = 1;
7495       else if (unformat (i, "no-gso"))
7496         tap_flags &= ~TAP_FLAG_GSO;
7497       else if (unformat (i, "gso"))
7498         tap_flags |= TAP_FLAG_GSO;
7499       else
7500         break;
7501     }
7502
7503   if (vec_len (host_if_name) > 63)
7504     {
7505       errmsg ("tap name too long. ");
7506       return -99;
7507     }
7508   if (vec_len (host_ns) > 63)
7509     {
7510       errmsg ("host name space too long. ");
7511       return -99;
7512     }
7513   if (vec_len (host_bridge) > 63)
7514     {
7515       errmsg ("host bridge name too long. ");
7516       return -99;
7517     }
7518   if (host_ip4_prefix_len > 32)
7519     {
7520       errmsg ("host ip4 prefix length not valid. ");
7521       return -99;
7522     }
7523   if (host_ip6_prefix_len > 128)
7524     {
7525       errmsg ("host ip6 prefix length not valid. ");
7526       return -99;
7527     }
7528   if (!is_pow2 (rx_ring_sz))
7529     {
7530       errmsg ("rx ring size must be power of 2. ");
7531       return -99;
7532     }
7533   if (rx_ring_sz > 32768)
7534     {
7535       errmsg ("rx ring size must be 32768 or lower. ");
7536       return -99;
7537     }
7538   if (!is_pow2 (tx_ring_sz))
7539     {
7540       errmsg ("tx ring size must be power of 2. ");
7541       return -99;
7542     }
7543   if (tx_ring_sz > 32768)
7544     {
7545       errmsg ("tx ring size must be 32768 or lower. ");
7546       return -99;
7547     }
7548   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7549     {
7550       errmsg ("host MTU size must be in between 64 and 65355. ");
7551       return -99;
7552     }
7553
7554   /* Construct the API message */
7555   M (TAP_CREATE_V2, mp);
7556
7557   mp->use_random_mac = random_mac;
7558
7559   mp->id = ntohl (id);
7560   mp->host_namespace_set = host_ns != 0;
7561   mp->host_bridge_set = host_bridge != 0;
7562   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7563   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7564   mp->rx_ring_sz = ntohs (rx_ring_sz);
7565   mp->tx_ring_sz = ntohs (tx_ring_sz);
7566   mp->host_mtu_set = host_mtu_set;
7567   mp->host_mtu_size = ntohl (host_mtu_size);
7568   mp->tap_flags = ntohl (tap_flags);
7569
7570   if (random_mac == 0)
7571     clib_memcpy (mp->mac_address, mac_address, 6);
7572   if (host_mac_addr_set)
7573     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7574   if (host_if_name)
7575     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7576   if (host_ns)
7577     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7578   if (host_bridge)
7579     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7580   if (host_ip4_prefix_len)
7581     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7582   if (host_ip6_prefix_len)
7583     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7584   if (host_ip4_gw_set)
7585     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7586   if (host_ip6_gw_set)
7587     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7588
7589   vec_free (host_ns);
7590   vec_free (host_if_name);
7591   vec_free (host_bridge);
7592
7593   /* send it... */
7594   S (mp);
7595
7596   /* Wait for a reply... */
7597   W (ret);
7598   return ret;
7599 }
7600
7601 static int
7602 api_tap_delete_v2 (vat_main_t * vam)
7603 {
7604   unformat_input_t *i = vam->input;
7605   vl_api_tap_delete_v2_t *mp;
7606   u32 sw_if_index = ~0;
7607   u8 sw_if_index_set = 0;
7608   int ret;
7609
7610   /* Parse args required to build the message */
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7614         sw_if_index_set = 1;
7615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7616         sw_if_index_set = 1;
7617       else
7618         break;
7619     }
7620
7621   if (sw_if_index_set == 0)
7622     {
7623       errmsg ("missing vpp interface name. ");
7624       return -99;
7625     }
7626
7627   /* Construct the API message */
7628   M (TAP_DELETE_V2, mp);
7629
7630   mp->sw_if_index = ntohl (sw_if_index);
7631
7632   /* send it... */
7633   S (mp);
7634
7635   /* Wait for a reply... */
7636   W (ret);
7637   return ret;
7638 }
7639
7640 uword
7641 unformat_pci_addr (unformat_input_t * input, va_list * args)
7642 {
7643   struct pci_addr_t
7644   {
7645     u16 domain;
7646     u8 bus;
7647     u8 slot:5;
7648     u8 function:3;
7649   } *addr;
7650   addr = va_arg (*args, struct pci_addr_t *);
7651   u32 x[4];
7652
7653   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7654     return 0;
7655
7656   addr->domain = x[0];
7657   addr->bus = x[1];
7658   addr->slot = x[2];
7659   addr->function = x[3];
7660
7661   return 1;
7662 }
7663
7664 static int
7665 api_virtio_pci_create (vat_main_t * vam)
7666 {
7667   unformat_input_t *i = vam->input;
7668   vl_api_virtio_pci_create_t *mp;
7669   u8 mac_address[6];
7670   u8 random_mac = 1;
7671   u8 gso_enabled = 0;
7672   u32 pci_addr = 0;
7673   u64 features = (u64) ~ (0ULL);
7674   int ret;
7675
7676   clib_memset (mac_address, 0, sizeof (mac_address));
7677
7678   /* Parse args required to build the message */
7679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7680     {
7681       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7682         {
7683           random_mac = 0;
7684         }
7685       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7686         ;
7687       else if (unformat (i, "features 0x%llx", &features))
7688         ;
7689       else if (unformat (i, "gso-enabled"))
7690         gso_enabled = 1;
7691       else
7692         break;
7693     }
7694
7695   if (pci_addr == 0)
7696     {
7697       errmsg ("pci address must be non zero. ");
7698       return -99;
7699     }
7700
7701   /* Construct the API message */
7702   M (VIRTIO_PCI_CREATE, mp);
7703
7704   mp->use_random_mac = random_mac;
7705
7706   mp->pci_addr = htonl (pci_addr);
7707   mp->features = clib_host_to_net_u64 (features);
7708   mp->gso_enabled = gso_enabled;
7709
7710   if (random_mac == 0)
7711     clib_memcpy (mp->mac_address, mac_address, 6);
7712
7713   /* send it... */
7714   S (mp);
7715
7716   /* Wait for a reply... */
7717   W (ret);
7718   return ret;
7719 }
7720
7721 static int
7722 api_virtio_pci_delete (vat_main_t * vam)
7723 {
7724   unformat_input_t *i = vam->input;
7725   vl_api_virtio_pci_delete_t *mp;
7726   u32 sw_if_index = ~0;
7727   u8 sw_if_index_set = 0;
7728   int ret;
7729
7730   /* Parse args required to build the message */
7731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7732     {
7733       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7734         sw_if_index_set = 1;
7735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7736         sw_if_index_set = 1;
7737       else
7738         break;
7739     }
7740
7741   if (sw_if_index_set == 0)
7742     {
7743       errmsg ("missing vpp interface name. ");
7744       return -99;
7745     }
7746
7747   /* Construct the API message */
7748   M (VIRTIO_PCI_DELETE, mp);
7749
7750   mp->sw_if_index = htonl (sw_if_index);
7751
7752   /* send it... */
7753   S (mp);
7754
7755   /* Wait for a reply... */
7756   W (ret);
7757   return ret;
7758 }
7759
7760 static int
7761 api_bond_create (vat_main_t * vam)
7762 {
7763   unformat_input_t *i = vam->input;
7764   vl_api_bond_create_t *mp;
7765   u8 mac_address[6];
7766   u8 custom_mac = 0;
7767   int ret;
7768   u8 mode;
7769   u8 lb;
7770   u8 mode_is_set = 0;
7771   u32 id = ~0;
7772   u8 numa_only = 0;
7773
7774   clib_memset (mac_address, 0, sizeof (mac_address));
7775   lb = BOND_LB_L2;
7776
7777   /* Parse args required to build the message */
7778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779     {
7780       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7781         mode_is_set = 1;
7782       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7783                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7784         ;
7785       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7786                          mac_address))
7787         custom_mac = 1;
7788       else if (unformat (i, "numa-only"))
7789         numa_only = 1;
7790       else if (unformat (i, "id %u", &id))
7791         ;
7792       else
7793         break;
7794     }
7795
7796   if (mode_is_set == 0)
7797     {
7798       errmsg ("Missing bond mode. ");
7799       return -99;
7800     }
7801
7802   /* Construct the API message */
7803   M (BOND_CREATE, mp);
7804
7805   mp->use_custom_mac = custom_mac;
7806
7807   mp->mode = mode;
7808   mp->lb = lb;
7809   mp->id = htonl (id);
7810   mp->numa_only = numa_only;
7811
7812   if (custom_mac)
7813     clib_memcpy (mp->mac_address, mac_address, 6);
7814
7815   /* send it... */
7816   S (mp);
7817
7818   /* Wait for a reply... */
7819   W (ret);
7820   return ret;
7821 }
7822
7823 static int
7824 api_bond_delete (vat_main_t * vam)
7825 {
7826   unformat_input_t *i = vam->input;
7827   vl_api_bond_delete_t *mp;
7828   u32 sw_if_index = ~0;
7829   u8 sw_if_index_set = 0;
7830   int ret;
7831
7832   /* Parse args required to build the message */
7833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7834     {
7835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7836         sw_if_index_set = 1;
7837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7838         sw_if_index_set = 1;
7839       else
7840         break;
7841     }
7842
7843   if (sw_if_index_set == 0)
7844     {
7845       errmsg ("missing vpp interface name. ");
7846       return -99;
7847     }
7848
7849   /* Construct the API message */
7850   M (BOND_DELETE, mp);
7851
7852   mp->sw_if_index = ntohl (sw_if_index);
7853
7854   /* send it... */
7855   S (mp);
7856
7857   /* Wait for a reply... */
7858   W (ret);
7859   return ret;
7860 }
7861
7862 static int
7863 api_bond_enslave (vat_main_t * vam)
7864 {
7865   unformat_input_t *i = vam->input;
7866   vl_api_bond_enslave_t *mp;
7867   u32 bond_sw_if_index;
7868   int ret;
7869   u8 is_passive;
7870   u8 is_long_timeout;
7871   u32 bond_sw_if_index_is_set = 0;
7872   u32 sw_if_index;
7873   u8 sw_if_index_is_set = 0;
7874
7875   /* Parse args required to build the message */
7876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7877     {
7878       if (unformat (i, "sw_if_index %d", &sw_if_index))
7879         sw_if_index_is_set = 1;
7880       else if (unformat (i, "bond %u", &bond_sw_if_index))
7881         bond_sw_if_index_is_set = 1;
7882       else if (unformat (i, "passive %d", &is_passive))
7883         ;
7884       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7885         ;
7886       else
7887         break;
7888     }
7889
7890   if (bond_sw_if_index_is_set == 0)
7891     {
7892       errmsg ("Missing bond sw_if_index. ");
7893       return -99;
7894     }
7895   if (sw_if_index_is_set == 0)
7896     {
7897       errmsg ("Missing slave sw_if_index. ");
7898       return -99;
7899     }
7900
7901   /* Construct the API message */
7902   M (BOND_ENSLAVE, mp);
7903
7904   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7905   mp->sw_if_index = ntohl (sw_if_index);
7906   mp->is_long_timeout = is_long_timeout;
7907   mp->is_passive = is_passive;
7908
7909   /* send it... */
7910   S (mp);
7911
7912   /* Wait for a reply... */
7913   W (ret);
7914   return ret;
7915 }
7916
7917 static int
7918 api_bond_detach_slave (vat_main_t * vam)
7919 {
7920   unformat_input_t *i = vam->input;
7921   vl_api_bond_detach_slave_t *mp;
7922   u32 sw_if_index = ~0;
7923   u8 sw_if_index_set = 0;
7924   int ret;
7925
7926   /* Parse args required to build the message */
7927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7928     {
7929       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7930         sw_if_index_set = 1;
7931       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7932         sw_if_index_set = 1;
7933       else
7934         break;
7935     }
7936
7937   if (sw_if_index_set == 0)
7938     {
7939       errmsg ("missing vpp interface name. ");
7940       return -99;
7941     }
7942
7943   /* Construct the API message */
7944   M (BOND_DETACH_SLAVE, mp);
7945
7946   mp->sw_if_index = ntohl (sw_if_index);
7947
7948   /* send it... */
7949   S (mp);
7950
7951   /* Wait for a reply... */
7952   W (ret);
7953   return ret;
7954 }
7955
7956 static int
7957 api_ip_table_add_del (vat_main_t * vam)
7958 {
7959   unformat_input_t *i = vam->input;
7960   vl_api_ip_table_add_del_t *mp;
7961   u32 table_id = ~0;
7962   u8 is_ipv6 = 0;
7963   u8 is_add = 1;
7964   int ret = 0;
7965
7966   /* Parse args required to build the message */
7967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7968     {
7969       if (unformat (i, "ipv6"))
7970         is_ipv6 = 1;
7971       else if (unformat (i, "del"))
7972         is_add = 0;
7973       else if (unformat (i, "add"))
7974         is_add = 1;
7975       else if (unformat (i, "table %d", &table_id))
7976         ;
7977       else
7978         {
7979           clib_warning ("parse error '%U'", format_unformat_error, i);
7980           return -99;
7981         }
7982     }
7983
7984   if (~0 == table_id)
7985     {
7986       errmsg ("missing table-ID");
7987       return -99;
7988     }
7989
7990   /* Construct the API message */
7991   M (IP_TABLE_ADD_DEL, mp);
7992
7993   mp->table.table_id = ntohl (table_id);
7994   mp->table.is_ip6 = is_ipv6;
7995   mp->is_add = is_add;
7996
7997   /* send it... */
7998   S (mp);
7999
8000   /* Wait for a reply... */
8001   W (ret);
8002
8003   return ret;
8004 }
8005
8006 uword
8007 unformat_fib_path (unformat_input_t * input, va_list * args)
8008 {
8009   vat_main_t *vam = va_arg (*args, vat_main_t *);
8010   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8011   u32 weight, preference;
8012   mpls_label_t out_label;
8013
8014   clib_memset (path, 0, sizeof (*path));
8015   path->weight = 1;
8016   path->sw_if_index = ~0;
8017   path->rpf_id = ~0;
8018   path->n_labels = 0;
8019
8020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8021     {
8022       if (unformat (input, "%U %U",
8023                     unformat_vl_api_ip4_address,
8024                     &path->nh.address.ip4,
8025                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8026         {
8027           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8028         }
8029       else if (unformat (input, "%U %U",
8030                          unformat_vl_api_ip6_address,
8031                          &path->nh.address.ip6,
8032                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8033         {
8034           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8035         }
8036       else if (unformat (input, "weight %u", &weight))
8037         {
8038           path->weight = weight;
8039         }
8040       else if (unformat (input, "preference %u", &preference))
8041         {
8042           path->preference = preference;
8043         }
8044       else if (unformat (input, "%U next-hop-table %d",
8045                          unformat_vl_api_ip4_address,
8046                          &path->nh.address.ip4, &path->table_id))
8047         {
8048           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8049         }
8050       else if (unformat (input, "%U next-hop-table %d",
8051                          unformat_vl_api_ip6_address,
8052                          &path->nh.address.ip6, &path->table_id))
8053         {
8054           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8055         }
8056       else if (unformat (input, "%U",
8057                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8058         {
8059           /*
8060            * the recursive next-hops are by default in the default table
8061            */
8062           path->table_id = 0;
8063           path->sw_if_index = ~0;
8064           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8065         }
8066       else if (unformat (input, "%U",
8067                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8068         {
8069           /*
8070            * the recursive next-hops are by default in the default table
8071            */
8072           path->table_id = 0;
8073           path->sw_if_index = ~0;
8074           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8075         }
8076       else if (unformat (input, "resolve-via-host"))
8077         {
8078           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8079         }
8080       else if (unformat (input, "resolve-via-attached"))
8081         {
8082           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8083         }
8084       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8085         {
8086           path->type = FIB_API_PATH_TYPE_LOCAL;
8087           path->sw_if_index = ~0;
8088           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8089         }
8090       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8091         {
8092           path->type = FIB_API_PATH_TYPE_LOCAL;
8093           path->sw_if_index = ~0;
8094           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8095         }
8096       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8097         ;
8098       else if (unformat (input, "via-label %d", &path->nh.via_label))
8099         {
8100           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8101           path->sw_if_index = ~0;
8102         }
8103       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8104         {
8105           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8106           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8107         }
8108       else if (unformat (input, "local"))
8109         {
8110           path->type = FIB_API_PATH_TYPE_LOCAL;
8111         }
8112       else if (unformat (input, "out-labels"))
8113         {
8114           while (unformat (input, "%d", &out_label))
8115             {
8116               path->label_stack[path->n_labels].label = out_label;
8117               path->label_stack[path->n_labels].is_uniform = 0;
8118               path->label_stack[path->n_labels].ttl = 64;
8119               path->n_labels++;
8120             }
8121         }
8122       else if (unformat (input, "via"))
8123         {
8124           /* new path, back up and return */
8125           unformat_put_input (input);
8126           unformat_put_input (input);
8127           unformat_put_input (input);
8128           unformat_put_input (input);
8129           break;
8130         }
8131       else
8132         {
8133           return (0);
8134         }
8135     }
8136
8137   path->proto = ntohl (path->proto);
8138   path->type = ntohl (path->type);
8139   path->flags = ntohl (path->flags);
8140   path->table_id = ntohl (path->table_id);
8141   path->sw_if_index = ntohl (path->sw_if_index);
8142
8143   return (1);
8144 }
8145
8146 static int
8147 api_ip_route_add_del (vat_main_t * vam)
8148 {
8149   unformat_input_t *i = vam->input;
8150   vl_api_ip_route_add_del_t *mp;
8151   u32 vrf_id = 0;
8152   u8 is_add = 1;
8153   u8 is_multipath = 0;
8154   u8 prefix_set = 0;
8155   u8 path_count = 0;
8156   vl_api_prefix_t pfx = { };
8157   vl_api_fib_path_t paths[8];
8158   int count = 1;
8159   int j;
8160   f64 before = 0;
8161   u32 random_add_del = 0;
8162   u32 *random_vector = 0;
8163   u32 random_seed = 0xdeaddabe;
8164
8165   /* Parse args required to build the message */
8166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8167     {
8168       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8169         prefix_set = 1;
8170       else if (unformat (i, "del"))
8171         is_add = 0;
8172       else if (unformat (i, "add"))
8173         is_add = 1;
8174       else if (unformat (i, "vrf %d", &vrf_id))
8175         ;
8176       else if (unformat (i, "count %d", &count))
8177         ;
8178       else if (unformat (i, "random"))
8179         random_add_del = 1;
8180       else if (unformat (i, "multipath"))
8181         is_multipath = 1;
8182       else if (unformat (i, "seed %d", &random_seed))
8183         ;
8184       else
8185         if (unformat
8186             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8187         {
8188           path_count++;
8189           if (8 == path_count)
8190             {
8191               errmsg ("max 8 paths");
8192               return -99;
8193             }
8194         }
8195       else
8196         {
8197           clib_warning ("parse error '%U'", format_unformat_error, i);
8198           return -99;
8199         }
8200     }
8201
8202   if (!path_count)
8203     {
8204       errmsg ("specify a path; via ...");
8205       return -99;
8206     }
8207   if (prefix_set == 0)
8208     {
8209       errmsg ("missing prefix");
8210       return -99;
8211     }
8212
8213   /* Generate a pile of unique, random routes */
8214   if (random_add_del)
8215     {
8216       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8217       u32 this_random_address;
8218       uword *random_hash;
8219
8220       random_hash = hash_create (count, sizeof (uword));
8221
8222       hash_set (random_hash, i->as_u32, 1);
8223       for (j = 0; j <= count; j++)
8224         {
8225           do
8226             {
8227               this_random_address = random_u32 (&random_seed);
8228               this_random_address =
8229                 clib_host_to_net_u32 (this_random_address);
8230             }
8231           while (hash_get (random_hash, this_random_address));
8232           vec_add1 (random_vector, this_random_address);
8233           hash_set (random_hash, this_random_address, 1);
8234         }
8235       hash_free (random_hash);
8236       set_ip4_address (&pfx.address, random_vector[0]);
8237     }
8238
8239   if (count > 1)
8240     {
8241       /* Turn on async mode */
8242       vam->async_mode = 1;
8243       vam->async_errors = 0;
8244       before = vat_time_now (vam);
8245     }
8246
8247   for (j = 0; j < count; j++)
8248     {
8249       /* Construct the API message */
8250       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8251
8252       mp->is_add = is_add;
8253       mp->is_multipath = is_multipath;
8254
8255       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8256       mp->route.table_id = ntohl (vrf_id);
8257       mp->route.n_paths = path_count;
8258
8259       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8260
8261       if (random_add_del)
8262         set_ip4_address (&pfx.address, random_vector[j + 1]);
8263       else
8264         increment_address (&pfx.address);
8265       /* send it... */
8266       S (mp);
8267       /* If we receive SIGTERM, stop now... */
8268       if (vam->do_exit)
8269         break;
8270     }
8271
8272   /* When testing multiple add/del ops, use a control-ping to sync */
8273   if (count > 1)
8274     {
8275       vl_api_control_ping_t *mp_ping;
8276       f64 after;
8277       f64 timeout;
8278
8279       /* Shut off async mode */
8280       vam->async_mode = 0;
8281
8282       MPING (CONTROL_PING, mp_ping);
8283       S (mp_ping);
8284
8285       timeout = vat_time_now (vam) + 1.0;
8286       while (vat_time_now (vam) < timeout)
8287         if (vam->result_ready == 1)
8288           goto out;
8289       vam->retval = -99;
8290
8291     out:
8292       if (vam->retval == -99)
8293         errmsg ("timeout");
8294
8295       if (vam->async_errors > 0)
8296         {
8297           errmsg ("%d asynchronous errors", vam->async_errors);
8298           vam->retval = -98;
8299         }
8300       vam->async_errors = 0;
8301       after = vat_time_now (vam);
8302
8303       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8304       if (j > 0)
8305         count = j;
8306
8307       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8308              count, after - before, count / (after - before));
8309     }
8310   else
8311     {
8312       int ret;
8313
8314       /* Wait for a reply... */
8315       W (ret);
8316       return ret;
8317     }
8318
8319   /* Return the good/bad news */
8320   return (vam->retval);
8321 }
8322
8323 static int
8324 api_ip_mroute_add_del (vat_main_t * vam)
8325 {
8326   unformat_input_t *i = vam->input;
8327   u8 path_set = 0, prefix_set = 0, is_add = 1;
8328   vl_api_ip_mroute_add_del_t *mp;
8329   mfib_entry_flags_t eflags = 0;
8330   vl_api_mfib_path_t path;
8331   vl_api_mprefix_t pfx = { };
8332   u32 vrf_id = 0;
8333   int ret;
8334
8335   /* Parse args required to build the message */
8336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8337     {
8338       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8339         {
8340           prefix_set = 1;
8341           pfx.grp_address_length = htons (pfx.grp_address_length);
8342         }
8343       else if (unformat (i, "del"))
8344         is_add = 0;
8345       else if (unformat (i, "add"))
8346         is_add = 1;
8347       else if (unformat (i, "vrf %d", &vrf_id))
8348         ;
8349       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8350         path.itf_flags = htonl (path.itf_flags);
8351       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8352         ;
8353       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8354         path_set = 1;
8355       else
8356         {
8357           clib_warning ("parse error '%U'", format_unformat_error, i);
8358           return -99;
8359         }
8360     }
8361
8362   if (prefix_set == 0)
8363     {
8364       errmsg ("missing addresses\n");
8365       return -99;
8366     }
8367   if (path_set == 0)
8368     {
8369       errmsg ("missing path\n");
8370       return -99;
8371     }
8372
8373   /* Construct the API message */
8374   M (IP_MROUTE_ADD_DEL, mp);
8375
8376   mp->is_add = is_add;
8377   mp->is_multipath = 1;
8378
8379   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8380   mp->route.table_id = htonl (vrf_id);
8381   mp->route.n_paths = 1;
8382   mp->route.entry_flags = htonl (eflags);
8383
8384   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8385
8386   /* send it... */
8387   S (mp);
8388   /* Wait for a reply... */
8389   W (ret);
8390   return ret;
8391 }
8392
8393 static int
8394 api_mpls_table_add_del (vat_main_t * vam)
8395 {
8396   unformat_input_t *i = vam->input;
8397   vl_api_mpls_table_add_del_t *mp;
8398   u32 table_id = ~0;
8399   u8 is_add = 1;
8400   int ret = 0;
8401
8402   /* Parse args required to build the message */
8403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8404     {
8405       if (unformat (i, "table %d", &table_id))
8406         ;
8407       else if (unformat (i, "del"))
8408         is_add = 0;
8409       else if (unformat (i, "add"))
8410         is_add = 1;
8411       else
8412         {
8413           clib_warning ("parse error '%U'", format_unformat_error, i);
8414           return -99;
8415         }
8416     }
8417
8418   if (~0 == table_id)
8419     {
8420       errmsg ("missing table-ID");
8421       return -99;
8422     }
8423
8424   /* Construct the API message */
8425   M (MPLS_TABLE_ADD_DEL, mp);
8426
8427   mp->mt_table.mt_table_id = ntohl (table_id);
8428   mp->mt_is_add = is_add;
8429
8430   /* send it... */
8431   S (mp);
8432
8433   /* Wait for a reply... */
8434   W (ret);
8435
8436   return ret;
8437 }
8438
8439 static int
8440 api_mpls_route_add_del (vat_main_t * vam)
8441 {
8442   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8443   mpls_label_t local_label = MPLS_LABEL_INVALID;
8444   unformat_input_t *i = vam->input;
8445   vl_api_mpls_route_add_del_t *mp;
8446   vl_api_fib_path_t paths[8];
8447   int count = 1, j;
8448   f64 before = 0;
8449
8450   /* Parse args required to build the message */
8451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (i, "%d", &local_label))
8454         ;
8455       else if (unformat (i, "eos"))
8456         is_eos = 1;
8457       else if (unformat (i, "non-eos"))
8458         is_eos = 0;
8459       else if (unformat (i, "del"))
8460         is_add = 0;
8461       else if (unformat (i, "add"))
8462         is_add = 1;
8463       else if (unformat (i, "multipath"))
8464         is_multipath = 1;
8465       else if (unformat (i, "count %d", &count))
8466         ;
8467       else
8468         if (unformat
8469             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8470         {
8471           path_count++;
8472           if (8 == path_count)
8473             {
8474               errmsg ("max 8 paths");
8475               return -99;
8476             }
8477         }
8478       else
8479         {
8480           clib_warning ("parse error '%U'", format_unformat_error, i);
8481           return -99;
8482         }
8483     }
8484
8485   if (!path_count)
8486     {
8487       errmsg ("specify a path; via ...");
8488       return -99;
8489     }
8490
8491   if (MPLS_LABEL_INVALID == local_label)
8492     {
8493       errmsg ("missing label");
8494       return -99;
8495     }
8496
8497   if (count > 1)
8498     {
8499       /* Turn on async mode */
8500       vam->async_mode = 1;
8501       vam->async_errors = 0;
8502       before = vat_time_now (vam);
8503     }
8504
8505   for (j = 0; j < count; j++)
8506     {
8507       /* Construct the API message */
8508       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8509
8510       mp->mr_is_add = is_add;
8511       mp->mr_is_multipath = is_multipath;
8512
8513       mp->mr_route.mr_label = local_label;
8514       mp->mr_route.mr_eos = is_eos;
8515       mp->mr_route.mr_table_id = 0;
8516       mp->mr_route.mr_n_paths = path_count;
8517
8518       clib_memcpy (&mp->mr_route.mr_paths, paths,
8519                    sizeof (paths[0]) * path_count);
8520
8521       local_label++;
8522
8523       /* send it... */
8524       S (mp);
8525       /* If we receive SIGTERM, stop now... */
8526       if (vam->do_exit)
8527         break;
8528     }
8529
8530   /* When testing multiple add/del ops, use a control-ping to sync */
8531   if (count > 1)
8532     {
8533       vl_api_control_ping_t *mp_ping;
8534       f64 after;
8535       f64 timeout;
8536
8537       /* Shut off async mode */
8538       vam->async_mode = 0;
8539
8540       MPING (CONTROL_PING, mp_ping);
8541       S (mp_ping);
8542
8543       timeout = vat_time_now (vam) + 1.0;
8544       while (vat_time_now (vam) < timeout)
8545         if (vam->result_ready == 1)
8546           goto out;
8547       vam->retval = -99;
8548
8549     out:
8550       if (vam->retval == -99)
8551         errmsg ("timeout");
8552
8553       if (vam->async_errors > 0)
8554         {
8555           errmsg ("%d asynchronous errors", vam->async_errors);
8556           vam->retval = -98;
8557         }
8558       vam->async_errors = 0;
8559       after = vat_time_now (vam);
8560
8561       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8562       if (j > 0)
8563         count = j;
8564
8565       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8566              count, after - before, count / (after - before));
8567     }
8568   else
8569     {
8570       int ret;
8571
8572       /* Wait for a reply... */
8573       W (ret);
8574       return ret;
8575     }
8576
8577   /* Return the good/bad news */
8578   return (vam->retval);
8579   return (0);
8580 }
8581
8582 static int
8583 api_mpls_ip_bind_unbind (vat_main_t * vam)
8584 {
8585   unformat_input_t *i = vam->input;
8586   vl_api_mpls_ip_bind_unbind_t *mp;
8587   u32 ip_table_id = 0;
8588   u8 is_bind = 1;
8589   vl_api_prefix_t pfx;
8590   u8 prefix_set = 0;
8591   mpls_label_t local_label = MPLS_LABEL_INVALID;
8592   int ret;
8593
8594   /* Parse args required to build the message */
8595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8596     {
8597       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8598         prefix_set = 1;
8599       else if (unformat (i, "%d", &local_label))
8600         ;
8601       else if (unformat (i, "table-id %d", &ip_table_id))
8602         ;
8603       else if (unformat (i, "unbind"))
8604         is_bind = 0;
8605       else if (unformat (i, "bind"))
8606         is_bind = 1;
8607       else
8608         {
8609           clib_warning ("parse error '%U'", format_unformat_error, i);
8610           return -99;
8611         }
8612     }
8613
8614   if (!prefix_set)
8615     {
8616       errmsg ("IP prefix not set");
8617       return -99;
8618     }
8619
8620   if (MPLS_LABEL_INVALID == local_label)
8621     {
8622       errmsg ("missing label");
8623       return -99;
8624     }
8625
8626   /* Construct the API message */
8627   M (MPLS_IP_BIND_UNBIND, mp);
8628
8629   mp->mb_is_bind = is_bind;
8630   mp->mb_ip_table_id = ntohl (ip_table_id);
8631   mp->mb_mpls_table_id = 0;
8632   mp->mb_label = ntohl (local_label);
8633   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8634
8635   /* send it... */
8636   S (mp);
8637
8638   /* Wait for a reply... */
8639   W (ret);
8640   return ret;
8641   return (0);
8642 }
8643
8644 static int
8645 api_sr_mpls_policy_add (vat_main_t * vam)
8646 {
8647   unformat_input_t *i = vam->input;
8648   vl_api_sr_mpls_policy_add_t *mp;
8649   u32 bsid = 0;
8650   u32 weight = 1;
8651   u8 type = 0;
8652   u8 n_segments = 0;
8653   u32 sid;
8654   u32 *segments = NULL;
8655   int ret;
8656
8657   /* Parse args required to build the message */
8658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (i, "bsid %d", &bsid))
8661         ;
8662       else if (unformat (i, "weight %d", &weight))
8663         ;
8664       else if (unformat (i, "spray"))
8665         type = 1;
8666       else if (unformat (i, "next %d", &sid))
8667         {
8668           n_segments += 1;
8669           vec_add1 (segments, htonl (sid));
8670         }
8671       else
8672         {
8673           clib_warning ("parse error '%U'", format_unformat_error, i);
8674           return -99;
8675         }
8676     }
8677
8678   if (bsid == 0)
8679     {
8680       errmsg ("bsid not set");
8681       return -99;
8682     }
8683
8684   if (n_segments == 0)
8685     {
8686       errmsg ("no sid in segment stack");
8687       return -99;
8688     }
8689
8690   /* Construct the API message */
8691   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8692
8693   mp->bsid = htonl (bsid);
8694   mp->weight = htonl (weight);
8695   mp->type = type;
8696   mp->n_segments = n_segments;
8697   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8698   vec_free (segments);
8699
8700   /* send it... */
8701   S (mp);
8702
8703   /* Wait for a reply... */
8704   W (ret);
8705   return ret;
8706 }
8707
8708 static int
8709 api_sr_mpls_policy_del (vat_main_t * vam)
8710 {
8711   unformat_input_t *i = vam->input;
8712   vl_api_sr_mpls_policy_del_t *mp;
8713   u32 bsid = 0;
8714   int ret;
8715
8716   /* Parse args required to build the message */
8717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8718     {
8719       if (unformat (i, "bsid %d", &bsid))
8720         ;
8721       else
8722         {
8723           clib_warning ("parse error '%U'", format_unformat_error, i);
8724           return -99;
8725         }
8726     }
8727
8728   if (bsid == 0)
8729     {
8730       errmsg ("bsid not set");
8731       return -99;
8732     }
8733
8734   /* Construct the API message */
8735   M (SR_MPLS_POLICY_DEL, mp);
8736
8737   mp->bsid = htonl (bsid);
8738
8739   /* send it... */
8740   S (mp);
8741
8742   /* Wait for a reply... */
8743   W (ret);
8744   return ret;
8745 }
8746
8747 static int
8748 api_bier_table_add_del (vat_main_t * vam)
8749 {
8750   unformat_input_t *i = vam->input;
8751   vl_api_bier_table_add_del_t *mp;
8752   u8 is_add = 1;
8753   u32 set = 0, sub_domain = 0, hdr_len = 3;
8754   mpls_label_t local_label = MPLS_LABEL_INVALID;
8755   int ret;
8756
8757   /* Parse args required to build the message */
8758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8759     {
8760       if (unformat (i, "sub-domain %d", &sub_domain))
8761         ;
8762       else if (unformat (i, "set %d", &set))
8763         ;
8764       else if (unformat (i, "label %d", &local_label))
8765         ;
8766       else if (unformat (i, "hdr-len %d", &hdr_len))
8767         ;
8768       else if (unformat (i, "add"))
8769         is_add = 1;
8770       else if (unformat (i, "del"))
8771         is_add = 0;
8772       else
8773         {
8774           clib_warning ("parse error '%U'", format_unformat_error, i);
8775           return -99;
8776         }
8777     }
8778
8779   if (MPLS_LABEL_INVALID == local_label)
8780     {
8781       errmsg ("missing label\n");
8782       return -99;
8783     }
8784
8785   /* Construct the API message */
8786   M (BIER_TABLE_ADD_DEL, mp);
8787
8788   mp->bt_is_add = is_add;
8789   mp->bt_label = ntohl (local_label);
8790   mp->bt_tbl_id.bt_set = set;
8791   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8792   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8793
8794   /* send it... */
8795   S (mp);
8796
8797   /* Wait for a reply... */
8798   W (ret);
8799
8800   return (ret);
8801 }
8802
8803 static int
8804 api_bier_route_add_del (vat_main_t * vam)
8805 {
8806   unformat_input_t *i = vam->input;
8807   vl_api_bier_route_add_del_t *mp;
8808   u8 is_add = 1;
8809   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8810   ip4_address_t v4_next_hop_address;
8811   ip6_address_t v6_next_hop_address;
8812   u8 next_hop_set = 0;
8813   u8 next_hop_proto_is_ip4 = 1;
8814   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8815   int ret;
8816
8817   /* Parse args required to build the message */
8818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8819     {
8820       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8821         {
8822           next_hop_proto_is_ip4 = 1;
8823           next_hop_set = 1;
8824         }
8825       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8826         {
8827           next_hop_proto_is_ip4 = 0;
8828           next_hop_set = 1;
8829         }
8830       if (unformat (i, "sub-domain %d", &sub_domain))
8831         ;
8832       else if (unformat (i, "set %d", &set))
8833         ;
8834       else if (unformat (i, "hdr-len %d", &hdr_len))
8835         ;
8836       else if (unformat (i, "bp %d", &bp))
8837         ;
8838       else if (unformat (i, "add"))
8839         is_add = 1;
8840       else if (unformat (i, "del"))
8841         is_add = 0;
8842       else if (unformat (i, "out-label %d", &next_hop_out_label))
8843         ;
8844       else
8845         {
8846           clib_warning ("parse error '%U'", format_unformat_error, i);
8847           return -99;
8848         }
8849     }
8850
8851   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8852     {
8853       errmsg ("next hop / label set\n");
8854       return -99;
8855     }
8856   if (0 == bp)
8857     {
8858       errmsg ("bit=position not set\n");
8859       return -99;
8860     }
8861
8862   /* Construct the API message */
8863   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8864
8865   mp->br_is_add = is_add;
8866   mp->br_route.br_tbl_id.bt_set = set;
8867   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8868   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8869   mp->br_route.br_bp = ntohs (bp);
8870   mp->br_route.br_n_paths = 1;
8871   mp->br_route.br_paths[0].n_labels = 1;
8872   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8873   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8874                                     FIB_API_PATH_NH_PROTO_IP4 :
8875                                     FIB_API_PATH_NH_PROTO_IP6);
8876
8877   if (next_hop_proto_is_ip4)
8878     {
8879       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8880                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8881     }
8882   else
8883     {
8884       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8885                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8886     }
8887
8888   /* send it... */
8889   S (mp);
8890
8891   /* Wait for a reply... */
8892   W (ret);
8893
8894   return (ret);
8895 }
8896
8897 static int
8898 api_proxy_arp_add_del (vat_main_t * vam)
8899 {
8900   unformat_input_t *i = vam->input;
8901   vl_api_proxy_arp_add_del_t *mp;
8902   u32 vrf_id = 0;
8903   u8 is_add = 1;
8904   vl_api_ip4_address_t lo, hi;
8905   u8 range_set = 0;
8906   int ret;
8907
8908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8909     {
8910       if (unformat (i, "vrf %d", &vrf_id))
8911         ;
8912       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8913                          unformat_vl_api_ip4_address, &hi))
8914         range_set = 1;
8915       else if (unformat (i, "del"))
8916         is_add = 0;
8917       else
8918         {
8919           clib_warning ("parse error '%U'", format_unformat_error, i);
8920           return -99;
8921         }
8922     }
8923
8924   if (range_set == 0)
8925     {
8926       errmsg ("address range not set");
8927       return -99;
8928     }
8929
8930   M (PROXY_ARP_ADD_DEL, mp);
8931
8932   mp->proxy.table_id = ntohl (vrf_id);
8933   mp->is_add = is_add;
8934   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8935   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8936
8937   S (mp);
8938   W (ret);
8939   return ret;
8940 }
8941
8942 static int
8943 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8944 {
8945   unformat_input_t *i = vam->input;
8946   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8947   u32 sw_if_index;
8948   u8 enable = 1;
8949   u8 sw_if_index_set = 0;
8950   int ret;
8951
8952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8953     {
8954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8955         sw_if_index_set = 1;
8956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8957         sw_if_index_set = 1;
8958       else if (unformat (i, "enable"))
8959         enable = 1;
8960       else if (unformat (i, "disable"))
8961         enable = 0;
8962       else
8963         {
8964           clib_warning ("parse error '%U'", format_unformat_error, i);
8965           return -99;
8966         }
8967     }
8968
8969   if (sw_if_index_set == 0)
8970     {
8971       errmsg ("missing interface name or sw_if_index");
8972       return -99;
8973     }
8974
8975   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8976
8977   mp->sw_if_index = ntohl (sw_if_index);
8978   mp->enable_disable = enable;
8979
8980   S (mp);
8981   W (ret);
8982   return ret;
8983 }
8984
8985 static int
8986 api_mpls_tunnel_add_del (vat_main_t * vam)
8987 {
8988   unformat_input_t *i = vam->input;
8989   vl_api_mpls_tunnel_add_del_t *mp;
8990
8991   vl_api_fib_path_t paths[8];
8992   u32 sw_if_index = ~0;
8993   u8 path_count = 0;
8994   u8 l2_only = 0;
8995   u8 is_add = 1;
8996   int ret;
8997
8998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8999     {
9000       if (unformat (i, "add"))
9001         is_add = 1;
9002       else
9003         if (unformat
9004             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9005         is_add = 0;
9006       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9007         is_add = 0;
9008       else if (unformat (i, "l2-only"))
9009         l2_only = 1;
9010       else
9011         if (unformat
9012             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9013         {
9014           path_count++;
9015           if (8 == path_count)
9016             {
9017               errmsg ("max 8 paths");
9018               return -99;
9019             }
9020         }
9021       else
9022         {
9023           clib_warning ("parse error '%U'", format_unformat_error, i);
9024           return -99;
9025         }
9026     }
9027
9028   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9029
9030   mp->mt_is_add = is_add;
9031   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9032   mp->mt_tunnel.mt_l2_only = l2_only;
9033   mp->mt_tunnel.mt_is_multicast = 0;
9034   mp->mt_tunnel.mt_n_paths = path_count;
9035
9036   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9037                sizeof (paths[0]) * path_count);
9038
9039   S (mp);
9040   W (ret);
9041   return ret;
9042 }
9043
9044 static int
9045 api_sw_interface_set_unnumbered (vat_main_t * vam)
9046 {
9047   unformat_input_t *i = vam->input;
9048   vl_api_sw_interface_set_unnumbered_t *mp;
9049   u32 sw_if_index;
9050   u32 unnum_sw_index = ~0;
9051   u8 is_add = 1;
9052   u8 sw_if_index_set = 0;
9053   int ret;
9054
9055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9056     {
9057       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9058         sw_if_index_set = 1;
9059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9060         sw_if_index_set = 1;
9061       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9062         ;
9063       else if (unformat (i, "del"))
9064         is_add = 0;
9065       else
9066         {
9067           clib_warning ("parse error '%U'", format_unformat_error, i);
9068           return -99;
9069         }
9070     }
9071
9072   if (sw_if_index_set == 0)
9073     {
9074       errmsg ("missing interface name or sw_if_index");
9075       return -99;
9076     }
9077
9078   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9079
9080   mp->sw_if_index = ntohl (sw_if_index);
9081   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9082   mp->is_add = is_add;
9083
9084   S (mp);
9085   W (ret);
9086   return ret;
9087 }
9088
9089 static int
9090 api_ip_neighbor_add_del (vat_main_t * vam)
9091 {
9092   vl_api_mac_address_t mac_address;
9093   unformat_input_t *i = vam->input;
9094   vl_api_ip_neighbor_add_del_t *mp;
9095   vl_api_address_t ip_address;
9096   u32 sw_if_index;
9097   u8 sw_if_index_set = 0;
9098   u8 is_add = 1;
9099   u8 mac_set = 0;
9100   u8 address_set = 0;
9101   int ret;
9102   ip_neighbor_flags_t flags;
9103
9104   flags = IP_NEIGHBOR_FLAG_NONE;
9105   clib_memset (&ip_address, 0, sizeof (ip_address));
9106   clib_memset (&mac_address, 0, sizeof (mac_address));
9107
9108   /* Parse args required to build the message */
9109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9110     {
9111       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9112         {
9113           mac_set = 1;
9114         }
9115       else if (unformat (i, "del"))
9116         is_add = 0;
9117       else
9118         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9119         sw_if_index_set = 1;
9120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9121         sw_if_index_set = 1;
9122       else if (unformat (i, "static"))
9123         flags |= IP_NEIGHBOR_FLAG_STATIC;
9124       else if (unformat (i, "no-fib-entry"))
9125         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9126       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9127         address_set = 1;
9128       else
9129         {
9130           clib_warning ("parse error '%U'", format_unformat_error, i);
9131           return -99;
9132         }
9133     }
9134
9135   if (sw_if_index_set == 0)
9136     {
9137       errmsg ("missing interface name or sw_if_index");
9138       return -99;
9139     }
9140   if (!address_set)
9141     {
9142       errmsg ("no address set");
9143       return -99;
9144     }
9145
9146   /* Construct the API message */
9147   M (IP_NEIGHBOR_ADD_DEL, mp);
9148
9149   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9150   mp->is_add = is_add;
9151   mp->neighbor.flags = htonl (flags);
9152   if (mac_set)
9153     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9154                  sizeof (mac_address));
9155   if (address_set)
9156     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9157
9158   /* send it... */
9159   S (mp);
9160
9161   /* Wait for a reply, return good/bad news  */
9162   W (ret);
9163   return ret;
9164 }
9165
9166 static int
9167 api_create_vlan_subif (vat_main_t * vam)
9168 {
9169   unformat_input_t *i = vam->input;
9170   vl_api_create_vlan_subif_t *mp;
9171   u32 sw_if_index;
9172   u8 sw_if_index_set = 0;
9173   u32 vlan_id;
9174   u8 vlan_id_set = 0;
9175   int ret;
9176
9177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9178     {
9179       if (unformat (i, "sw_if_index %d", &sw_if_index))
9180         sw_if_index_set = 1;
9181       else
9182         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9183         sw_if_index_set = 1;
9184       else if (unformat (i, "vlan %d", &vlan_id))
9185         vlan_id_set = 1;
9186       else
9187         {
9188           clib_warning ("parse error '%U'", format_unformat_error, i);
9189           return -99;
9190         }
9191     }
9192
9193   if (sw_if_index_set == 0)
9194     {
9195       errmsg ("missing interface name or sw_if_index");
9196       return -99;
9197     }
9198
9199   if (vlan_id_set == 0)
9200     {
9201       errmsg ("missing vlan_id");
9202       return -99;
9203     }
9204   M (CREATE_VLAN_SUBIF, mp);
9205
9206   mp->sw_if_index = ntohl (sw_if_index);
9207   mp->vlan_id = ntohl (vlan_id);
9208
9209   S (mp);
9210   W (ret);
9211   return ret;
9212 }
9213
9214 #define foreach_create_subif_bit                \
9215 _(no_tags)                                      \
9216 _(one_tag)                                      \
9217 _(two_tags)                                     \
9218 _(dot1ad)                                       \
9219 _(exact_match)                                  \
9220 _(default_sub)                                  \
9221 _(outer_vlan_id_any)                            \
9222 _(inner_vlan_id_any)
9223
9224 static int
9225 api_create_subif (vat_main_t * vam)
9226 {
9227   unformat_input_t *i = vam->input;
9228   vl_api_create_subif_t *mp;
9229   u32 sw_if_index;
9230   u8 sw_if_index_set = 0;
9231   u32 sub_id;
9232   u8 sub_id_set = 0;
9233   u32 no_tags = 0;
9234   u32 one_tag = 0;
9235   u32 two_tags = 0;
9236   u32 dot1ad = 0;
9237   u32 exact_match = 0;
9238   u32 default_sub = 0;
9239   u32 outer_vlan_id_any = 0;
9240   u32 inner_vlan_id_any = 0;
9241   u32 tmp;
9242   u16 outer_vlan_id = 0;
9243   u16 inner_vlan_id = 0;
9244   int ret;
9245
9246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9247     {
9248       if (unformat (i, "sw_if_index %d", &sw_if_index))
9249         sw_if_index_set = 1;
9250       else
9251         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9252         sw_if_index_set = 1;
9253       else if (unformat (i, "sub_id %d", &sub_id))
9254         sub_id_set = 1;
9255       else if (unformat (i, "outer_vlan_id %d", &tmp))
9256         outer_vlan_id = tmp;
9257       else if (unformat (i, "inner_vlan_id %d", &tmp))
9258         inner_vlan_id = tmp;
9259
9260 #define _(a) else if (unformat (i, #a)) a = 1 ;
9261       foreach_create_subif_bit
9262 #undef _
9263         else
9264         {
9265           clib_warning ("parse error '%U'", format_unformat_error, i);
9266           return -99;
9267         }
9268     }
9269
9270   if (sw_if_index_set == 0)
9271     {
9272       errmsg ("missing interface name or sw_if_index");
9273       return -99;
9274     }
9275
9276   if (sub_id_set == 0)
9277     {
9278       errmsg ("missing sub_id");
9279       return -99;
9280     }
9281   M (CREATE_SUBIF, mp);
9282
9283   mp->sw_if_index = ntohl (sw_if_index);
9284   mp->sub_id = ntohl (sub_id);
9285
9286 #define _(a) mp->a = a;
9287   foreach_create_subif_bit;
9288 #undef _
9289
9290   mp->outer_vlan_id = ntohs (outer_vlan_id);
9291   mp->inner_vlan_id = ntohs (inner_vlan_id);
9292
9293   S (mp);
9294   W (ret);
9295   return ret;
9296 }
9297
9298 static int
9299 api_reset_fib (vat_main_t * vam)
9300 {
9301   unformat_input_t *i = vam->input;
9302   vl_api_reset_fib_t *mp;
9303   u32 vrf_id = 0;
9304   u8 is_ipv6 = 0;
9305   u8 vrf_id_set = 0;
9306
9307   int ret;
9308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9309     {
9310       if (unformat (i, "vrf %d", &vrf_id))
9311         vrf_id_set = 1;
9312       else if (unformat (i, "ipv6"))
9313         is_ipv6 = 1;
9314       else
9315         {
9316           clib_warning ("parse error '%U'", format_unformat_error, i);
9317           return -99;
9318         }
9319     }
9320
9321   if (vrf_id_set == 0)
9322     {
9323       errmsg ("missing vrf id");
9324       return -99;
9325     }
9326
9327   M (RESET_FIB, mp);
9328
9329   mp->vrf_id = ntohl (vrf_id);
9330   mp->is_ipv6 = is_ipv6;
9331
9332   S (mp);
9333   W (ret);
9334   return ret;
9335 }
9336
9337 static int
9338 api_dhcp_proxy_config (vat_main_t * vam)
9339 {
9340   unformat_input_t *i = vam->input;
9341   vl_api_dhcp_proxy_config_t *mp;
9342   u32 rx_vrf_id = 0;
9343   u32 server_vrf_id = 0;
9344   u8 is_add = 1;
9345   u8 v4_address_set = 0;
9346   u8 v6_address_set = 0;
9347   ip4_address_t v4address;
9348   ip6_address_t v6address;
9349   u8 v4_src_address_set = 0;
9350   u8 v6_src_address_set = 0;
9351   ip4_address_t v4srcaddress;
9352   ip6_address_t v6srcaddress;
9353   int ret;
9354
9355   /* Parse args required to build the message */
9356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9357     {
9358       if (unformat (i, "del"))
9359         is_add = 0;
9360       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9361         ;
9362       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9363         ;
9364       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9365         v4_address_set = 1;
9366       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9367         v6_address_set = 1;
9368       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9369         v4_src_address_set = 1;
9370       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9371         v6_src_address_set = 1;
9372       else
9373         break;
9374     }
9375
9376   if (v4_address_set && v6_address_set)
9377     {
9378       errmsg ("both v4 and v6 server addresses set");
9379       return -99;
9380     }
9381   if (!v4_address_set && !v6_address_set)
9382     {
9383       errmsg ("no server addresses set");
9384       return -99;
9385     }
9386
9387   if (v4_src_address_set && v6_src_address_set)
9388     {
9389       errmsg ("both v4 and v6  src addresses set");
9390       return -99;
9391     }
9392   if (!v4_src_address_set && !v6_src_address_set)
9393     {
9394       errmsg ("no src addresses set");
9395       return -99;
9396     }
9397
9398   if (!(v4_src_address_set && v4_address_set) &&
9399       !(v6_src_address_set && v6_address_set))
9400     {
9401       errmsg ("no matching server and src addresses set");
9402       return -99;
9403     }
9404
9405   /* Construct the API message */
9406   M (DHCP_PROXY_CONFIG, mp);
9407
9408   mp->is_add = is_add;
9409   mp->rx_vrf_id = ntohl (rx_vrf_id);
9410   mp->server_vrf_id = ntohl (server_vrf_id);
9411   if (v6_address_set)
9412     {
9413       mp->is_ipv6 = 1;
9414       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9415       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9416     }
9417   else
9418     {
9419       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9420       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9421     }
9422
9423   /* send it... */
9424   S (mp);
9425
9426   /* Wait for a reply, return good/bad news  */
9427   W (ret);
9428   return ret;
9429 }
9430
9431 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9432 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9433
9434 static void
9435 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9436 {
9437   vat_main_t *vam = &vat_main;
9438   u32 i, count = mp->count;
9439   vl_api_dhcp_server_t *s;
9440
9441   if (mp->is_ipv6)
9442     print (vam->ofp,
9443            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9444            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9445            ntohl (mp->rx_vrf_id),
9446            format_ip6_address, mp->dhcp_src_address,
9447            mp->vss_type, mp->vss_vpn_ascii_id,
9448            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9449   else
9450     print (vam->ofp,
9451            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9452            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9453            ntohl (mp->rx_vrf_id),
9454            format_ip4_address, mp->dhcp_src_address,
9455            mp->vss_type, mp->vss_vpn_ascii_id,
9456            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9457
9458   for (i = 0; i < count; i++)
9459     {
9460       s = &mp->servers[i];
9461
9462       if (mp->is_ipv6)
9463         print (vam->ofp,
9464                " Server Table-ID %d, Server Address %U",
9465                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9466       else
9467         print (vam->ofp,
9468                " Server Table-ID %d, Server Address %U",
9469                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9470     }
9471 }
9472
9473 static void vl_api_dhcp_proxy_details_t_handler_json
9474   (vl_api_dhcp_proxy_details_t * mp)
9475 {
9476   vat_main_t *vam = &vat_main;
9477   vat_json_node_t *node = NULL;
9478   u32 i, count = mp->count;
9479   struct in_addr ip4;
9480   struct in6_addr ip6;
9481   vl_api_dhcp_server_t *s;
9482
9483   if (VAT_JSON_ARRAY != vam->json_tree.type)
9484     {
9485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9486       vat_json_init_array (&vam->json_tree);
9487     }
9488   node = vat_json_array_add (&vam->json_tree);
9489
9490   vat_json_init_object (node);
9491   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9492   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9493                              sizeof (mp->vss_type));
9494   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9495                                    mp->vss_vpn_ascii_id);
9496   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9497   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9498
9499   if (mp->is_ipv6)
9500     {
9501       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9502       vat_json_object_add_ip6 (node, "src_address", ip6);
9503     }
9504   else
9505     {
9506       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9507       vat_json_object_add_ip4 (node, "src_address", ip4);
9508     }
9509
9510   for (i = 0; i < count; i++)
9511     {
9512       s = &mp->servers[i];
9513
9514       vat_json_object_add_uint (node, "server-table-id",
9515                                 ntohl (s->server_vrf_id));
9516
9517       if (mp->is_ipv6)
9518         {
9519           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9520           vat_json_object_add_ip4 (node, "src_address", ip4);
9521         }
9522       else
9523         {
9524           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9525           vat_json_object_add_ip6 (node, "server_address", ip6);
9526         }
9527     }
9528 }
9529
9530 static int
9531 api_dhcp_proxy_dump (vat_main_t * vam)
9532 {
9533   unformat_input_t *i = vam->input;
9534   vl_api_control_ping_t *mp_ping;
9535   vl_api_dhcp_proxy_dump_t *mp;
9536   u8 is_ipv6 = 0;
9537   int ret;
9538
9539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9540     {
9541       if (unformat (i, "ipv6"))
9542         is_ipv6 = 1;
9543       else
9544         {
9545           clib_warning ("parse error '%U'", format_unformat_error, i);
9546           return -99;
9547         }
9548     }
9549
9550   M (DHCP_PROXY_DUMP, mp);
9551
9552   mp->is_ip6 = is_ipv6;
9553   S (mp);
9554
9555   /* Use a control ping for synchronization */
9556   MPING (CONTROL_PING, mp_ping);
9557   S (mp_ping);
9558
9559   W (ret);
9560   return ret;
9561 }
9562
9563 static int
9564 api_dhcp_proxy_set_vss (vat_main_t * vam)
9565 {
9566   unformat_input_t *i = vam->input;
9567   vl_api_dhcp_proxy_set_vss_t *mp;
9568   u8 is_ipv6 = 0;
9569   u8 is_add = 1;
9570   u32 tbl_id = ~0;
9571   u8 vss_type = VSS_TYPE_DEFAULT;
9572   u8 *vpn_ascii_id = 0;
9573   u32 oui = 0;
9574   u32 fib_id = 0;
9575   int ret;
9576
9577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9578     {
9579       if (unformat (i, "tbl_id %d", &tbl_id))
9580         ;
9581       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9582         vss_type = VSS_TYPE_ASCII;
9583       else if (unformat (i, "fib_id %d", &fib_id))
9584         vss_type = VSS_TYPE_VPN_ID;
9585       else if (unformat (i, "oui %d", &oui))
9586         vss_type = VSS_TYPE_VPN_ID;
9587       else if (unformat (i, "ipv6"))
9588         is_ipv6 = 1;
9589       else if (unformat (i, "del"))
9590         is_add = 0;
9591       else
9592         break;
9593     }
9594
9595   if (tbl_id == ~0)
9596     {
9597       errmsg ("missing tbl_id ");
9598       vec_free (vpn_ascii_id);
9599       return -99;
9600     }
9601
9602   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9603     {
9604       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9605       vec_free (vpn_ascii_id);
9606       return -99;
9607     }
9608
9609   M (DHCP_PROXY_SET_VSS, mp);
9610   mp->tbl_id = ntohl (tbl_id);
9611   mp->vss_type = vss_type;
9612   if (vpn_ascii_id)
9613     {
9614       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9615       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9616     }
9617   mp->vpn_index = ntohl (fib_id);
9618   mp->oui = ntohl (oui);
9619   mp->is_ipv6 = is_ipv6;
9620   mp->is_add = is_add;
9621
9622   S (mp);
9623   W (ret);
9624
9625   vec_free (vpn_ascii_id);
9626   return ret;
9627 }
9628
9629 static int
9630 api_dhcp_client_config (vat_main_t * vam)
9631 {
9632   unformat_input_t *i = vam->input;
9633   vl_api_dhcp_client_config_t *mp;
9634   u32 sw_if_index;
9635   u8 sw_if_index_set = 0;
9636   u8 is_add = 1;
9637   u8 *hostname = 0;
9638   u8 disable_event = 0;
9639   int ret;
9640
9641   /* Parse args required to build the message */
9642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9643     {
9644       if (unformat (i, "del"))
9645         is_add = 0;
9646       else
9647         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9648         sw_if_index_set = 1;
9649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9650         sw_if_index_set = 1;
9651       else if (unformat (i, "hostname %s", &hostname))
9652         ;
9653       else if (unformat (i, "disable_event"))
9654         disable_event = 1;
9655       else
9656         break;
9657     }
9658
9659   if (sw_if_index_set == 0)
9660     {
9661       errmsg ("missing interface name or sw_if_index");
9662       return -99;
9663     }
9664
9665   if (vec_len (hostname) > 63)
9666     {
9667       errmsg ("hostname too long");
9668     }
9669   vec_add1 (hostname, 0);
9670
9671   /* Construct the API message */
9672   M (DHCP_CLIENT_CONFIG, mp);
9673
9674   mp->is_add = is_add;
9675   mp->client.sw_if_index = htonl (sw_if_index);
9676   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9677   vec_free (hostname);
9678   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9679   mp->client.pid = htonl (getpid ());
9680
9681   /* send it... */
9682   S (mp);
9683
9684   /* Wait for a reply, return good/bad news  */
9685   W (ret);
9686   return ret;
9687 }
9688
9689 static int
9690 api_set_ip_flow_hash (vat_main_t * vam)
9691 {
9692   unformat_input_t *i = vam->input;
9693   vl_api_set_ip_flow_hash_t *mp;
9694   u32 vrf_id = 0;
9695   u8 is_ipv6 = 0;
9696   u8 vrf_id_set = 0;
9697   u8 src = 0;
9698   u8 dst = 0;
9699   u8 sport = 0;
9700   u8 dport = 0;
9701   u8 proto = 0;
9702   u8 reverse = 0;
9703   int ret;
9704
9705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9706     {
9707       if (unformat (i, "vrf %d", &vrf_id))
9708         vrf_id_set = 1;
9709       else if (unformat (i, "ipv6"))
9710         is_ipv6 = 1;
9711       else if (unformat (i, "src"))
9712         src = 1;
9713       else if (unformat (i, "dst"))
9714         dst = 1;
9715       else if (unformat (i, "sport"))
9716         sport = 1;
9717       else if (unformat (i, "dport"))
9718         dport = 1;
9719       else if (unformat (i, "proto"))
9720         proto = 1;
9721       else if (unformat (i, "reverse"))
9722         reverse = 1;
9723
9724       else
9725         {
9726           clib_warning ("parse error '%U'", format_unformat_error, i);
9727           return -99;
9728         }
9729     }
9730
9731   if (vrf_id_set == 0)
9732     {
9733       errmsg ("missing vrf id");
9734       return -99;
9735     }
9736
9737   M (SET_IP_FLOW_HASH, mp);
9738   mp->src = src;
9739   mp->dst = dst;
9740   mp->sport = sport;
9741   mp->dport = dport;
9742   mp->proto = proto;
9743   mp->reverse = reverse;
9744   mp->vrf_id = ntohl (vrf_id);
9745   mp->is_ipv6 = is_ipv6;
9746
9747   S (mp);
9748   W (ret);
9749   return ret;
9750 }
9751
9752 static int
9753 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9754 {
9755   unformat_input_t *i = vam->input;
9756   vl_api_sw_interface_ip6_enable_disable_t *mp;
9757   u32 sw_if_index;
9758   u8 sw_if_index_set = 0;
9759   u8 enable = 0;
9760   int ret;
9761
9762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9763     {
9764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9765         sw_if_index_set = 1;
9766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9767         sw_if_index_set = 1;
9768       else if (unformat (i, "enable"))
9769         enable = 1;
9770       else if (unformat (i, "disable"))
9771         enable = 0;
9772       else
9773         {
9774           clib_warning ("parse error '%U'", format_unformat_error, i);
9775           return -99;
9776         }
9777     }
9778
9779   if (sw_if_index_set == 0)
9780     {
9781       errmsg ("missing interface name or sw_if_index");
9782       return -99;
9783     }
9784
9785   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9786
9787   mp->sw_if_index = ntohl (sw_if_index);
9788   mp->enable = enable;
9789
9790   S (mp);
9791   W (ret);
9792   return ret;
9793 }
9794
9795 static int
9796 api_ip6nd_proxy_add_del (vat_main_t * vam)
9797 {
9798   unformat_input_t *i = vam->input;
9799   vl_api_ip6nd_proxy_add_del_t *mp;
9800   u32 sw_if_index = ~0;
9801   u8 v6_address_set = 0;
9802   vl_api_ip6_address_t v6address;
9803   u8 is_del = 0;
9804   int ret;
9805
9806   /* Parse args required to build the message */
9807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9808     {
9809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9810         ;
9811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9812         ;
9813       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9814         v6_address_set = 1;
9815       if (unformat (i, "del"))
9816         is_del = 1;
9817       else
9818         {
9819           clib_warning ("parse error '%U'", format_unformat_error, i);
9820           return -99;
9821         }
9822     }
9823
9824   if (sw_if_index == ~0)
9825     {
9826       errmsg ("missing interface name or sw_if_index");
9827       return -99;
9828     }
9829   if (!v6_address_set)
9830     {
9831       errmsg ("no address set");
9832       return -99;
9833     }
9834
9835   /* Construct the API message */
9836   M (IP6ND_PROXY_ADD_DEL, mp);
9837
9838   mp->is_del = is_del;
9839   mp->sw_if_index = ntohl (sw_if_index);
9840   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9841
9842   /* send it... */
9843   S (mp);
9844
9845   /* Wait for a reply, return good/bad news  */
9846   W (ret);
9847   return ret;
9848 }
9849
9850 static int
9851 api_ip6nd_proxy_dump (vat_main_t * vam)
9852 {
9853   vl_api_ip6nd_proxy_dump_t *mp;
9854   vl_api_control_ping_t *mp_ping;
9855   int ret;
9856
9857   M (IP6ND_PROXY_DUMP, mp);
9858
9859   S (mp);
9860
9861   /* Use a control ping for synchronization */
9862   MPING (CONTROL_PING, mp_ping);
9863   S (mp_ping);
9864
9865   W (ret);
9866   return ret;
9867 }
9868
9869 static void vl_api_ip6nd_proxy_details_t_handler
9870   (vl_api_ip6nd_proxy_details_t * mp)
9871 {
9872   vat_main_t *vam = &vat_main;
9873
9874   print (vam->ofp, "host %U sw_if_index %d",
9875          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9876 }
9877
9878 static void vl_api_ip6nd_proxy_details_t_handler_json
9879   (vl_api_ip6nd_proxy_details_t * mp)
9880 {
9881   vat_main_t *vam = &vat_main;
9882   struct in6_addr ip6;
9883   vat_json_node_t *node = NULL;
9884
9885   if (VAT_JSON_ARRAY != vam->json_tree.type)
9886     {
9887       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9888       vat_json_init_array (&vam->json_tree);
9889     }
9890   node = vat_json_array_add (&vam->json_tree);
9891
9892   vat_json_init_object (node);
9893   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9894
9895   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9896   vat_json_object_add_ip6 (node, "host", ip6);
9897 }
9898
9899 static int
9900 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9901 {
9902   unformat_input_t *i = vam->input;
9903   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9904   u32 sw_if_index;
9905   u8 sw_if_index_set = 0;
9906   u8 v6_address_set = 0;
9907   vl_api_prefix_t pfx;
9908   u8 use_default = 0;
9909   u8 no_advertise = 0;
9910   u8 off_link = 0;
9911   u8 no_autoconfig = 0;
9912   u8 no_onlink = 0;
9913   u8 is_no = 0;
9914   u32 val_lifetime = 0;
9915   u32 pref_lifetime = 0;
9916   int ret;
9917
9918   /* Parse args required to build the message */
9919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9920     {
9921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9922         sw_if_index_set = 1;
9923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9924         sw_if_index_set = 1;
9925       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9926         v6_address_set = 1;
9927       else if (unformat (i, "val_life %d", &val_lifetime))
9928         ;
9929       else if (unformat (i, "pref_life %d", &pref_lifetime))
9930         ;
9931       else if (unformat (i, "def"))
9932         use_default = 1;
9933       else if (unformat (i, "noadv"))
9934         no_advertise = 1;
9935       else if (unformat (i, "offl"))
9936         off_link = 1;
9937       else if (unformat (i, "noauto"))
9938         no_autoconfig = 1;
9939       else if (unformat (i, "nolink"))
9940         no_onlink = 1;
9941       else if (unformat (i, "isno"))
9942         is_no = 1;
9943       else
9944         {
9945           clib_warning ("parse error '%U'", format_unformat_error, i);
9946           return -99;
9947         }
9948     }
9949
9950   if (sw_if_index_set == 0)
9951     {
9952       errmsg ("missing interface name or sw_if_index");
9953       return -99;
9954     }
9955   if (!v6_address_set)
9956     {
9957       errmsg ("no address set");
9958       return -99;
9959     }
9960
9961   /* Construct the API message */
9962   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9963
9964   mp->sw_if_index = ntohl (sw_if_index);
9965   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9966   mp->use_default = use_default;
9967   mp->no_advertise = no_advertise;
9968   mp->off_link = off_link;
9969   mp->no_autoconfig = no_autoconfig;
9970   mp->no_onlink = no_onlink;
9971   mp->is_no = is_no;
9972   mp->val_lifetime = ntohl (val_lifetime);
9973   mp->pref_lifetime = ntohl (pref_lifetime);
9974
9975   /* send it... */
9976   S (mp);
9977
9978   /* Wait for a reply, return good/bad news  */
9979   W (ret);
9980   return ret;
9981 }
9982
9983 static int
9984 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9985 {
9986   unformat_input_t *i = vam->input;
9987   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9988   u32 sw_if_index;
9989   u8 sw_if_index_set = 0;
9990   u8 suppress = 0;
9991   u8 managed = 0;
9992   u8 other = 0;
9993   u8 ll_option = 0;
9994   u8 send_unicast = 0;
9995   u8 cease = 0;
9996   u8 is_no = 0;
9997   u8 default_router = 0;
9998   u32 max_interval = 0;
9999   u32 min_interval = 0;
10000   u32 lifetime = 0;
10001   u32 initial_count = 0;
10002   u32 initial_interval = 0;
10003   int ret;
10004
10005
10006   /* Parse args required to build the message */
10007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10008     {
10009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10010         sw_if_index_set = 1;
10011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10012         sw_if_index_set = 1;
10013       else if (unformat (i, "maxint %d", &max_interval))
10014         ;
10015       else if (unformat (i, "minint %d", &min_interval))
10016         ;
10017       else if (unformat (i, "life %d", &lifetime))
10018         ;
10019       else if (unformat (i, "count %d", &initial_count))
10020         ;
10021       else if (unformat (i, "interval %d", &initial_interval))
10022         ;
10023       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10024         suppress = 1;
10025       else if (unformat (i, "managed"))
10026         managed = 1;
10027       else if (unformat (i, "other"))
10028         other = 1;
10029       else if (unformat (i, "ll"))
10030         ll_option = 1;
10031       else if (unformat (i, "send"))
10032         send_unicast = 1;
10033       else if (unformat (i, "cease"))
10034         cease = 1;
10035       else if (unformat (i, "isno"))
10036         is_no = 1;
10037       else if (unformat (i, "def"))
10038         default_router = 1;
10039       else
10040         {
10041           clib_warning ("parse error '%U'", format_unformat_error, i);
10042           return -99;
10043         }
10044     }
10045
10046   if (sw_if_index_set == 0)
10047     {
10048       errmsg ("missing interface name or sw_if_index");
10049       return -99;
10050     }
10051
10052   /* Construct the API message */
10053   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10054
10055   mp->sw_if_index = ntohl (sw_if_index);
10056   mp->max_interval = ntohl (max_interval);
10057   mp->min_interval = ntohl (min_interval);
10058   mp->lifetime = ntohl (lifetime);
10059   mp->initial_count = ntohl (initial_count);
10060   mp->initial_interval = ntohl (initial_interval);
10061   mp->suppress = suppress;
10062   mp->managed = managed;
10063   mp->other = other;
10064   mp->ll_option = ll_option;
10065   mp->send_unicast = send_unicast;
10066   mp->cease = cease;
10067   mp->is_no = is_no;
10068   mp->default_router = default_router;
10069
10070   /* send it... */
10071   S (mp);
10072
10073   /* Wait for a reply, return good/bad news  */
10074   W (ret);
10075   return ret;
10076 }
10077
10078 static int
10079 api_set_arp_neighbor_limit (vat_main_t * vam)
10080 {
10081   unformat_input_t *i = vam->input;
10082   vl_api_set_arp_neighbor_limit_t *mp;
10083   u32 arp_nbr_limit;
10084   u8 limit_set = 0;
10085   u8 is_ipv6 = 0;
10086   int ret;
10087
10088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10089     {
10090       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10091         limit_set = 1;
10092       else if (unformat (i, "ipv6"))
10093         is_ipv6 = 1;
10094       else
10095         {
10096           clib_warning ("parse error '%U'", format_unformat_error, i);
10097           return -99;
10098         }
10099     }
10100
10101   if (limit_set == 0)
10102     {
10103       errmsg ("missing limit value");
10104       return -99;
10105     }
10106
10107   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10108
10109   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10110   mp->is_ipv6 = is_ipv6;
10111
10112   S (mp);
10113   W (ret);
10114   return ret;
10115 }
10116
10117 static int
10118 api_l2_patch_add_del (vat_main_t * vam)
10119 {
10120   unformat_input_t *i = vam->input;
10121   vl_api_l2_patch_add_del_t *mp;
10122   u32 rx_sw_if_index;
10123   u8 rx_sw_if_index_set = 0;
10124   u32 tx_sw_if_index;
10125   u8 tx_sw_if_index_set = 0;
10126   u8 is_add = 1;
10127   int ret;
10128
10129   /* Parse args required to build the message */
10130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10131     {
10132       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10133         rx_sw_if_index_set = 1;
10134       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10135         tx_sw_if_index_set = 1;
10136       else if (unformat (i, "rx"))
10137         {
10138           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10139             {
10140               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10141                             &rx_sw_if_index))
10142                 rx_sw_if_index_set = 1;
10143             }
10144           else
10145             break;
10146         }
10147       else if (unformat (i, "tx"))
10148         {
10149           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10150             {
10151               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10152                             &tx_sw_if_index))
10153                 tx_sw_if_index_set = 1;
10154             }
10155           else
10156             break;
10157         }
10158       else if (unformat (i, "del"))
10159         is_add = 0;
10160       else
10161         break;
10162     }
10163
10164   if (rx_sw_if_index_set == 0)
10165     {
10166       errmsg ("missing rx interface name or rx_sw_if_index");
10167       return -99;
10168     }
10169
10170   if (tx_sw_if_index_set == 0)
10171     {
10172       errmsg ("missing tx interface name or tx_sw_if_index");
10173       return -99;
10174     }
10175
10176   M (L2_PATCH_ADD_DEL, mp);
10177
10178   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10179   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10180   mp->is_add = is_add;
10181
10182   S (mp);
10183   W (ret);
10184   return ret;
10185 }
10186
10187 u8 is_del;
10188 u8 localsid_addr[16];
10189 u8 end_psp;
10190 u8 behavior;
10191 u32 sw_if_index;
10192 u32 vlan_index;
10193 u32 fib_table;
10194 u8 nh_addr[16];
10195
10196 static int
10197 api_sr_localsid_add_del (vat_main_t * vam)
10198 {
10199   unformat_input_t *i = vam->input;
10200   vl_api_sr_localsid_add_del_t *mp;
10201
10202   u8 is_del;
10203   ip6_address_t localsid;
10204   u8 end_psp = 0;
10205   u8 behavior = ~0;
10206   u32 sw_if_index;
10207   u32 fib_table = ~(u32) 0;
10208   ip6_address_t nh_addr6;
10209   ip4_address_t nh_addr4;
10210   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10211   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10212
10213   bool nexthop_set = 0;
10214
10215   int ret;
10216
10217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10218     {
10219       if (unformat (i, "del"))
10220         is_del = 1;
10221       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10222       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10223         nexthop_set = 1;
10224       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10225         nexthop_set = 1;
10226       else if (unformat (i, "behavior %u", &behavior));
10227       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10228       else if (unformat (i, "fib-table %u", &fib_table));
10229       else if (unformat (i, "end.psp %u", &behavior));
10230       else
10231         break;
10232     }
10233
10234   M (SR_LOCALSID_ADD_DEL, mp);
10235
10236   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10237   if (nexthop_set)
10238     {
10239       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10240       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10241     }
10242   mp->behavior = behavior;
10243   mp->sw_if_index = ntohl (sw_if_index);
10244   mp->fib_table = ntohl (fib_table);
10245   mp->end_psp = end_psp;
10246   mp->is_del = is_del;
10247
10248   S (mp);
10249   W (ret);
10250   return ret;
10251 }
10252
10253 static int
10254 api_ioam_enable (vat_main_t * vam)
10255 {
10256   unformat_input_t *input = vam->input;
10257   vl_api_ioam_enable_t *mp;
10258   u32 id = 0;
10259   int has_trace_option = 0;
10260   int has_pot_option = 0;
10261   int has_seqno_option = 0;
10262   int has_analyse_option = 0;
10263   int ret;
10264
10265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10266     {
10267       if (unformat (input, "trace"))
10268         has_trace_option = 1;
10269       else if (unformat (input, "pot"))
10270         has_pot_option = 1;
10271       else if (unformat (input, "seqno"))
10272         has_seqno_option = 1;
10273       else if (unformat (input, "analyse"))
10274         has_analyse_option = 1;
10275       else
10276         break;
10277     }
10278   M (IOAM_ENABLE, mp);
10279   mp->id = htons (id);
10280   mp->seqno = has_seqno_option;
10281   mp->analyse = has_analyse_option;
10282   mp->pot_enable = has_pot_option;
10283   mp->trace_enable = has_trace_option;
10284
10285   S (mp);
10286   W (ret);
10287   return ret;
10288 }
10289
10290
10291 static int
10292 api_ioam_disable (vat_main_t * vam)
10293 {
10294   vl_api_ioam_disable_t *mp;
10295   int ret;
10296
10297   M (IOAM_DISABLE, mp);
10298   S (mp);
10299   W (ret);
10300   return ret;
10301 }
10302
10303 #define foreach_tcp_proto_field                 \
10304 _(src_port)                                     \
10305 _(dst_port)
10306
10307 #define foreach_udp_proto_field                 \
10308 _(src_port)                                     \
10309 _(dst_port)
10310
10311 #define foreach_ip4_proto_field                 \
10312 _(src_address)                                  \
10313 _(dst_address)                                  \
10314 _(tos)                                          \
10315 _(length)                                       \
10316 _(fragment_id)                                  \
10317 _(ttl)                                          \
10318 _(protocol)                                     \
10319 _(checksum)
10320
10321 typedef struct
10322 {
10323   u16 src_port, dst_port;
10324 } tcpudp_header_t;
10325
10326 #if VPP_API_TEST_BUILTIN == 0
10327 uword
10328 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10329 {
10330   u8 **maskp = va_arg (*args, u8 **);
10331   u8 *mask = 0;
10332   u8 found_something = 0;
10333   tcp_header_t *tcp;
10334
10335 #define _(a) u8 a=0;
10336   foreach_tcp_proto_field;
10337 #undef _
10338
10339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10340     {
10341       if (0);
10342 #define _(a) else if (unformat (input, #a)) a=1;
10343       foreach_tcp_proto_field
10344 #undef _
10345         else
10346         break;
10347     }
10348
10349 #define _(a) found_something += a;
10350   foreach_tcp_proto_field;
10351 #undef _
10352
10353   if (found_something == 0)
10354     return 0;
10355
10356   vec_validate (mask, sizeof (*tcp) - 1);
10357
10358   tcp = (tcp_header_t *) mask;
10359
10360 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10361   foreach_tcp_proto_field;
10362 #undef _
10363
10364   *maskp = mask;
10365   return 1;
10366 }
10367
10368 uword
10369 unformat_udp_mask (unformat_input_t * input, va_list * args)
10370 {
10371   u8 **maskp = va_arg (*args, u8 **);
10372   u8 *mask = 0;
10373   u8 found_something = 0;
10374   udp_header_t *udp;
10375
10376 #define _(a) u8 a=0;
10377   foreach_udp_proto_field;
10378 #undef _
10379
10380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10381     {
10382       if (0);
10383 #define _(a) else if (unformat (input, #a)) a=1;
10384       foreach_udp_proto_field
10385 #undef _
10386         else
10387         break;
10388     }
10389
10390 #define _(a) found_something += a;
10391   foreach_udp_proto_field;
10392 #undef _
10393
10394   if (found_something == 0)
10395     return 0;
10396
10397   vec_validate (mask, sizeof (*udp) - 1);
10398
10399   udp = (udp_header_t *) mask;
10400
10401 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10402   foreach_udp_proto_field;
10403 #undef _
10404
10405   *maskp = mask;
10406   return 1;
10407 }
10408
10409 uword
10410 unformat_l4_mask (unformat_input_t * input, va_list * args)
10411 {
10412   u8 **maskp = va_arg (*args, u8 **);
10413   u16 src_port = 0, dst_port = 0;
10414   tcpudp_header_t *tcpudp;
10415
10416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10417     {
10418       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10419         return 1;
10420       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10421         return 1;
10422       else if (unformat (input, "src_port"))
10423         src_port = 0xFFFF;
10424       else if (unformat (input, "dst_port"))
10425         dst_port = 0xFFFF;
10426       else
10427         return 0;
10428     }
10429
10430   if (!src_port && !dst_port)
10431     return 0;
10432
10433   u8 *mask = 0;
10434   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10435
10436   tcpudp = (tcpudp_header_t *) mask;
10437   tcpudp->src_port = src_port;
10438   tcpudp->dst_port = dst_port;
10439
10440   *maskp = mask;
10441
10442   return 1;
10443 }
10444
10445 uword
10446 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10447 {
10448   u8 **maskp = va_arg (*args, u8 **);
10449   u8 *mask = 0;
10450   u8 found_something = 0;
10451   ip4_header_t *ip;
10452
10453 #define _(a) u8 a=0;
10454   foreach_ip4_proto_field;
10455 #undef _
10456   u8 version = 0;
10457   u8 hdr_length = 0;
10458
10459
10460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10461     {
10462       if (unformat (input, "version"))
10463         version = 1;
10464       else if (unformat (input, "hdr_length"))
10465         hdr_length = 1;
10466       else if (unformat (input, "src"))
10467         src_address = 1;
10468       else if (unformat (input, "dst"))
10469         dst_address = 1;
10470       else if (unformat (input, "proto"))
10471         protocol = 1;
10472
10473 #define _(a) else if (unformat (input, #a)) a=1;
10474       foreach_ip4_proto_field
10475 #undef _
10476         else
10477         break;
10478     }
10479
10480 #define _(a) found_something += a;
10481   foreach_ip4_proto_field;
10482 #undef _
10483
10484   if (found_something == 0)
10485     return 0;
10486
10487   vec_validate (mask, sizeof (*ip) - 1);
10488
10489   ip = (ip4_header_t *) mask;
10490
10491 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10492   foreach_ip4_proto_field;
10493 #undef _
10494
10495   ip->ip_version_and_header_length = 0;
10496
10497   if (version)
10498     ip->ip_version_and_header_length |= 0xF0;
10499
10500   if (hdr_length)
10501     ip->ip_version_and_header_length |= 0x0F;
10502
10503   *maskp = mask;
10504   return 1;
10505 }
10506
10507 #define foreach_ip6_proto_field                 \
10508 _(src_address)                                  \
10509 _(dst_address)                                  \
10510 _(payload_length)                               \
10511 _(hop_limit)                                    \
10512 _(protocol)
10513
10514 uword
10515 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10516 {
10517   u8 **maskp = va_arg (*args, u8 **);
10518   u8 *mask = 0;
10519   u8 found_something = 0;
10520   ip6_header_t *ip;
10521   u32 ip_version_traffic_class_and_flow_label;
10522
10523 #define _(a) u8 a=0;
10524   foreach_ip6_proto_field;
10525 #undef _
10526   u8 version = 0;
10527   u8 traffic_class = 0;
10528   u8 flow_label = 0;
10529
10530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10531     {
10532       if (unformat (input, "version"))
10533         version = 1;
10534       else if (unformat (input, "traffic-class"))
10535         traffic_class = 1;
10536       else if (unformat (input, "flow-label"))
10537         flow_label = 1;
10538       else if (unformat (input, "src"))
10539         src_address = 1;
10540       else if (unformat (input, "dst"))
10541         dst_address = 1;
10542       else if (unformat (input, "proto"))
10543         protocol = 1;
10544
10545 #define _(a) else if (unformat (input, #a)) a=1;
10546       foreach_ip6_proto_field
10547 #undef _
10548         else
10549         break;
10550     }
10551
10552 #define _(a) found_something += a;
10553   foreach_ip6_proto_field;
10554 #undef _
10555
10556   if (found_something == 0)
10557     return 0;
10558
10559   vec_validate (mask, sizeof (*ip) - 1);
10560
10561   ip = (ip6_header_t *) mask;
10562
10563 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10564   foreach_ip6_proto_field;
10565 #undef _
10566
10567   ip_version_traffic_class_and_flow_label = 0;
10568
10569   if (version)
10570     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10571
10572   if (traffic_class)
10573     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10574
10575   if (flow_label)
10576     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10577
10578   ip->ip_version_traffic_class_and_flow_label =
10579     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10580
10581   *maskp = mask;
10582   return 1;
10583 }
10584
10585 uword
10586 unformat_l3_mask (unformat_input_t * input, va_list * args)
10587 {
10588   u8 **maskp = va_arg (*args, u8 **);
10589
10590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10591     {
10592       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10593         return 1;
10594       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10595         return 1;
10596       else
10597         break;
10598     }
10599   return 0;
10600 }
10601
10602 uword
10603 unformat_l2_mask (unformat_input_t * input, va_list * args)
10604 {
10605   u8 **maskp = va_arg (*args, u8 **);
10606   u8 *mask = 0;
10607   u8 src = 0;
10608   u8 dst = 0;
10609   u8 proto = 0;
10610   u8 tag1 = 0;
10611   u8 tag2 = 0;
10612   u8 ignore_tag1 = 0;
10613   u8 ignore_tag2 = 0;
10614   u8 cos1 = 0;
10615   u8 cos2 = 0;
10616   u8 dot1q = 0;
10617   u8 dot1ad = 0;
10618   int len = 14;
10619
10620   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10621     {
10622       if (unformat (input, "src"))
10623         src = 1;
10624       else if (unformat (input, "dst"))
10625         dst = 1;
10626       else if (unformat (input, "proto"))
10627         proto = 1;
10628       else if (unformat (input, "tag1"))
10629         tag1 = 1;
10630       else if (unformat (input, "tag2"))
10631         tag2 = 1;
10632       else if (unformat (input, "ignore-tag1"))
10633         ignore_tag1 = 1;
10634       else if (unformat (input, "ignore-tag2"))
10635         ignore_tag2 = 1;
10636       else if (unformat (input, "cos1"))
10637         cos1 = 1;
10638       else if (unformat (input, "cos2"))
10639         cos2 = 1;
10640       else if (unformat (input, "dot1q"))
10641         dot1q = 1;
10642       else if (unformat (input, "dot1ad"))
10643         dot1ad = 1;
10644       else
10645         break;
10646     }
10647   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10648        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10649     return 0;
10650
10651   if (tag1 || ignore_tag1 || cos1 || dot1q)
10652     len = 18;
10653   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10654     len = 22;
10655
10656   vec_validate (mask, len - 1);
10657
10658   if (dst)
10659     clib_memset (mask, 0xff, 6);
10660
10661   if (src)
10662     clib_memset (mask + 6, 0xff, 6);
10663
10664   if (tag2 || dot1ad)
10665     {
10666       /* inner vlan tag */
10667       if (tag2)
10668         {
10669           mask[19] = 0xff;
10670           mask[18] = 0x0f;
10671         }
10672       if (cos2)
10673         mask[18] |= 0xe0;
10674       if (proto)
10675         mask[21] = mask[20] = 0xff;
10676       if (tag1)
10677         {
10678           mask[15] = 0xff;
10679           mask[14] = 0x0f;
10680         }
10681       if (cos1)
10682         mask[14] |= 0xe0;
10683       *maskp = mask;
10684       return 1;
10685     }
10686   if (tag1 | dot1q)
10687     {
10688       if (tag1)
10689         {
10690           mask[15] = 0xff;
10691           mask[14] = 0x0f;
10692         }
10693       if (cos1)
10694         mask[14] |= 0xe0;
10695       if (proto)
10696         mask[16] = mask[17] = 0xff;
10697
10698       *maskp = mask;
10699       return 1;
10700     }
10701   if (cos2)
10702     mask[18] |= 0xe0;
10703   if (cos1)
10704     mask[14] |= 0xe0;
10705   if (proto)
10706     mask[12] = mask[13] = 0xff;
10707
10708   *maskp = mask;
10709   return 1;
10710 }
10711
10712 uword
10713 unformat_classify_mask (unformat_input_t * input, va_list * args)
10714 {
10715   u8 **maskp = va_arg (*args, u8 **);
10716   u32 *skipp = va_arg (*args, u32 *);
10717   u32 *matchp = va_arg (*args, u32 *);
10718   u32 match;
10719   u8 *mask = 0;
10720   u8 *l2 = 0;
10721   u8 *l3 = 0;
10722   u8 *l4 = 0;
10723   int i;
10724
10725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10726     {
10727       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10728         ;
10729       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10730         ;
10731       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10732         ;
10733       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10734         ;
10735       else
10736         break;
10737     }
10738
10739   if (l4 && !l3)
10740     {
10741       vec_free (mask);
10742       vec_free (l2);
10743       vec_free (l4);
10744       return 0;
10745     }
10746
10747   if (mask || l2 || l3 || l4)
10748     {
10749       if (l2 || l3 || l4)
10750         {
10751           /* "With a free Ethernet header in every package" */
10752           if (l2 == 0)
10753             vec_validate (l2, 13);
10754           mask = l2;
10755           if (vec_len (l3))
10756             {
10757               vec_append (mask, l3);
10758               vec_free (l3);
10759             }
10760           if (vec_len (l4))
10761             {
10762               vec_append (mask, l4);
10763               vec_free (l4);
10764             }
10765         }
10766
10767       /* Scan forward looking for the first significant mask octet */
10768       for (i = 0; i < vec_len (mask); i++)
10769         if (mask[i])
10770           break;
10771
10772       /* compute (skip, match) params */
10773       *skipp = i / sizeof (u32x4);
10774       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10775
10776       /* Pad mask to an even multiple of the vector size */
10777       while (vec_len (mask) % sizeof (u32x4))
10778         vec_add1 (mask, 0);
10779
10780       match = vec_len (mask) / sizeof (u32x4);
10781
10782       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10783         {
10784           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10785           if (*tmp || *(tmp + 1))
10786             break;
10787           match--;
10788         }
10789       if (match == 0)
10790         clib_warning ("BUG: match 0");
10791
10792       _vec_len (mask) = match * sizeof (u32x4);
10793
10794       *matchp = match;
10795       *maskp = mask;
10796
10797       return 1;
10798     }
10799
10800   return 0;
10801 }
10802 #endif /* VPP_API_TEST_BUILTIN */
10803
10804 #define foreach_l2_next                         \
10805 _(drop, DROP)                                   \
10806 _(ethernet, ETHERNET_INPUT)                     \
10807 _(ip4, IP4_INPUT)                               \
10808 _(ip6, IP6_INPUT)
10809
10810 uword
10811 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10812 {
10813   u32 *miss_next_indexp = va_arg (*args, u32 *);
10814   u32 next_index = 0;
10815   u32 tmp;
10816
10817 #define _(n,N) \
10818   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10819   foreach_l2_next;
10820 #undef _
10821
10822   if (unformat (input, "%d", &tmp))
10823     {
10824       next_index = tmp;
10825       goto out;
10826     }
10827
10828   return 0;
10829
10830 out:
10831   *miss_next_indexp = next_index;
10832   return 1;
10833 }
10834
10835 #define foreach_ip_next                         \
10836 _(drop, DROP)                                   \
10837 _(local, LOCAL)                                 \
10838 _(rewrite, REWRITE)
10839
10840 uword
10841 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10842 {
10843   u32 *miss_next_indexp = va_arg (*args, u32 *);
10844   u32 next_index = 0;
10845   u32 tmp;
10846
10847 #define _(n,N) \
10848   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10849   foreach_ip_next;
10850 #undef _
10851
10852   if (unformat (input, "%d", &tmp))
10853     {
10854       next_index = tmp;
10855       goto out;
10856     }
10857
10858   return 0;
10859
10860 out:
10861   *miss_next_indexp = next_index;
10862   return 1;
10863 }
10864
10865 #define foreach_acl_next                        \
10866 _(deny, DENY)
10867
10868 uword
10869 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10870 {
10871   u32 *miss_next_indexp = va_arg (*args, u32 *);
10872   u32 next_index = 0;
10873   u32 tmp;
10874
10875 #define _(n,N) \
10876   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10877   foreach_acl_next;
10878 #undef _
10879
10880   if (unformat (input, "permit"))
10881     {
10882       next_index = ~0;
10883       goto out;
10884     }
10885   else if (unformat (input, "%d", &tmp))
10886     {
10887       next_index = tmp;
10888       goto out;
10889     }
10890
10891   return 0;
10892
10893 out:
10894   *miss_next_indexp = next_index;
10895   return 1;
10896 }
10897
10898 uword
10899 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10900 {
10901   u32 *r = va_arg (*args, u32 *);
10902
10903   if (unformat (input, "conform-color"))
10904     *r = POLICE_CONFORM;
10905   else if (unformat (input, "exceed-color"))
10906     *r = POLICE_EXCEED;
10907   else
10908     return 0;
10909
10910   return 1;
10911 }
10912
10913 static int
10914 api_classify_add_del_table (vat_main_t * vam)
10915 {
10916   unformat_input_t *i = vam->input;
10917   vl_api_classify_add_del_table_t *mp;
10918
10919   u32 nbuckets = 2;
10920   u32 skip = ~0;
10921   u32 match = ~0;
10922   int is_add = 1;
10923   int del_chain = 0;
10924   u32 table_index = ~0;
10925   u32 next_table_index = ~0;
10926   u32 miss_next_index = ~0;
10927   u32 memory_size = 32 << 20;
10928   u8 *mask = 0;
10929   u32 current_data_flag = 0;
10930   int current_data_offset = 0;
10931   int ret;
10932
10933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10934     {
10935       if (unformat (i, "del"))
10936         is_add = 0;
10937       else if (unformat (i, "del-chain"))
10938         {
10939           is_add = 0;
10940           del_chain = 1;
10941         }
10942       else if (unformat (i, "buckets %d", &nbuckets))
10943         ;
10944       else if (unformat (i, "memory_size %d", &memory_size))
10945         ;
10946       else if (unformat (i, "skip %d", &skip))
10947         ;
10948       else if (unformat (i, "match %d", &match))
10949         ;
10950       else if (unformat (i, "table %d", &table_index))
10951         ;
10952       else if (unformat (i, "mask %U", unformat_classify_mask,
10953                          &mask, &skip, &match))
10954         ;
10955       else if (unformat (i, "next-table %d", &next_table_index))
10956         ;
10957       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10958                          &miss_next_index))
10959         ;
10960       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10961                          &miss_next_index))
10962         ;
10963       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10964                          &miss_next_index))
10965         ;
10966       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10967         ;
10968       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10969         ;
10970       else
10971         break;
10972     }
10973
10974   if (is_add && mask == 0)
10975     {
10976       errmsg ("Mask required");
10977       return -99;
10978     }
10979
10980   if (is_add && skip == ~0)
10981     {
10982       errmsg ("skip count required");
10983       return -99;
10984     }
10985
10986   if (is_add && match == ~0)
10987     {
10988       errmsg ("match count required");
10989       return -99;
10990     }
10991
10992   if (!is_add && table_index == ~0)
10993     {
10994       errmsg ("table index required for delete");
10995       return -99;
10996     }
10997
10998   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10999
11000   mp->is_add = is_add;
11001   mp->del_chain = del_chain;
11002   mp->table_index = ntohl (table_index);
11003   mp->nbuckets = ntohl (nbuckets);
11004   mp->memory_size = ntohl (memory_size);
11005   mp->skip_n_vectors = ntohl (skip);
11006   mp->match_n_vectors = ntohl (match);
11007   mp->next_table_index = ntohl (next_table_index);
11008   mp->miss_next_index = ntohl (miss_next_index);
11009   mp->current_data_flag = ntohl (current_data_flag);
11010   mp->current_data_offset = ntohl (current_data_offset);
11011   mp->mask_len = ntohl (vec_len (mask));
11012   clib_memcpy (mp->mask, mask, vec_len (mask));
11013
11014   vec_free (mask);
11015
11016   S (mp);
11017   W (ret);
11018   return ret;
11019 }
11020
11021 #if VPP_API_TEST_BUILTIN == 0
11022 uword
11023 unformat_l4_match (unformat_input_t * input, va_list * args)
11024 {
11025   u8 **matchp = va_arg (*args, u8 **);
11026
11027   u8 *proto_header = 0;
11028   int src_port = 0;
11029   int dst_port = 0;
11030
11031   tcpudp_header_t h;
11032
11033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11034     {
11035       if (unformat (input, "src_port %d", &src_port))
11036         ;
11037       else if (unformat (input, "dst_port %d", &dst_port))
11038         ;
11039       else
11040         return 0;
11041     }
11042
11043   h.src_port = clib_host_to_net_u16 (src_port);
11044   h.dst_port = clib_host_to_net_u16 (dst_port);
11045   vec_validate (proto_header, sizeof (h) - 1);
11046   memcpy (proto_header, &h, sizeof (h));
11047
11048   *matchp = proto_header;
11049
11050   return 1;
11051 }
11052
11053 uword
11054 unformat_ip4_match (unformat_input_t * input, va_list * args)
11055 {
11056   u8 **matchp = va_arg (*args, u8 **);
11057   u8 *match = 0;
11058   ip4_header_t *ip;
11059   int version = 0;
11060   u32 version_val;
11061   int hdr_length = 0;
11062   u32 hdr_length_val;
11063   int src = 0, dst = 0;
11064   ip4_address_t src_val, dst_val;
11065   int proto = 0;
11066   u32 proto_val;
11067   int tos = 0;
11068   u32 tos_val;
11069   int length = 0;
11070   u32 length_val;
11071   int fragment_id = 0;
11072   u32 fragment_id_val;
11073   int ttl = 0;
11074   int ttl_val;
11075   int checksum = 0;
11076   u32 checksum_val;
11077
11078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11079     {
11080       if (unformat (input, "version %d", &version_val))
11081         version = 1;
11082       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11083         hdr_length = 1;
11084       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11085         src = 1;
11086       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11087         dst = 1;
11088       else if (unformat (input, "proto %d", &proto_val))
11089         proto = 1;
11090       else if (unformat (input, "tos %d", &tos_val))
11091         tos = 1;
11092       else if (unformat (input, "length %d", &length_val))
11093         length = 1;
11094       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11095         fragment_id = 1;
11096       else if (unformat (input, "ttl %d", &ttl_val))
11097         ttl = 1;
11098       else if (unformat (input, "checksum %d", &checksum_val))
11099         checksum = 1;
11100       else
11101         break;
11102     }
11103
11104   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11105       + ttl + checksum == 0)
11106     return 0;
11107
11108   /*
11109    * Aligned because we use the real comparison functions
11110    */
11111   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11112
11113   ip = (ip4_header_t *) match;
11114
11115   /* These are realistically matched in practice */
11116   if (src)
11117     ip->src_address.as_u32 = src_val.as_u32;
11118
11119   if (dst)
11120     ip->dst_address.as_u32 = dst_val.as_u32;
11121
11122   if (proto)
11123     ip->protocol = proto_val;
11124
11125
11126   /* These are not, but they're included for completeness */
11127   if (version)
11128     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11129
11130   if (hdr_length)
11131     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11132
11133   if (tos)
11134     ip->tos = tos_val;
11135
11136   if (length)
11137     ip->length = clib_host_to_net_u16 (length_val);
11138
11139   if (ttl)
11140     ip->ttl = ttl_val;
11141
11142   if (checksum)
11143     ip->checksum = clib_host_to_net_u16 (checksum_val);
11144
11145   *matchp = match;
11146   return 1;
11147 }
11148
11149 uword
11150 unformat_ip6_match (unformat_input_t * input, va_list * args)
11151 {
11152   u8 **matchp = va_arg (*args, u8 **);
11153   u8 *match = 0;
11154   ip6_header_t *ip;
11155   int version = 0;
11156   u32 version_val;
11157   u8 traffic_class = 0;
11158   u32 traffic_class_val = 0;
11159   u8 flow_label = 0;
11160   u8 flow_label_val;
11161   int src = 0, dst = 0;
11162   ip6_address_t src_val, dst_val;
11163   int proto = 0;
11164   u32 proto_val;
11165   int payload_length = 0;
11166   u32 payload_length_val;
11167   int hop_limit = 0;
11168   int hop_limit_val;
11169   u32 ip_version_traffic_class_and_flow_label;
11170
11171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11172     {
11173       if (unformat (input, "version %d", &version_val))
11174         version = 1;
11175       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11176         traffic_class = 1;
11177       else if (unformat (input, "flow_label %d", &flow_label_val))
11178         flow_label = 1;
11179       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11180         src = 1;
11181       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11182         dst = 1;
11183       else if (unformat (input, "proto %d", &proto_val))
11184         proto = 1;
11185       else if (unformat (input, "payload_length %d", &payload_length_val))
11186         payload_length = 1;
11187       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11188         hop_limit = 1;
11189       else
11190         break;
11191     }
11192
11193   if (version + traffic_class + flow_label + src + dst + proto +
11194       payload_length + hop_limit == 0)
11195     return 0;
11196
11197   /*
11198    * Aligned because we use the real comparison functions
11199    */
11200   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11201
11202   ip = (ip6_header_t *) match;
11203
11204   if (src)
11205     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11206
11207   if (dst)
11208     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11209
11210   if (proto)
11211     ip->protocol = proto_val;
11212
11213   ip_version_traffic_class_and_flow_label = 0;
11214
11215   if (version)
11216     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11217
11218   if (traffic_class)
11219     ip_version_traffic_class_and_flow_label |=
11220       (traffic_class_val & 0xFF) << 20;
11221
11222   if (flow_label)
11223     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11224
11225   ip->ip_version_traffic_class_and_flow_label =
11226     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11227
11228   if (payload_length)
11229     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11230
11231   if (hop_limit)
11232     ip->hop_limit = hop_limit_val;
11233
11234   *matchp = match;
11235   return 1;
11236 }
11237
11238 uword
11239 unformat_l3_match (unformat_input_t * input, va_list * args)
11240 {
11241   u8 **matchp = va_arg (*args, u8 **);
11242
11243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11244     {
11245       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11246         return 1;
11247       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11248         return 1;
11249       else
11250         break;
11251     }
11252   return 0;
11253 }
11254
11255 uword
11256 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11257 {
11258   u8 *tagp = va_arg (*args, u8 *);
11259   u32 tag;
11260
11261   if (unformat (input, "%d", &tag))
11262     {
11263       tagp[0] = (tag >> 8) & 0x0F;
11264       tagp[1] = tag & 0xFF;
11265       return 1;
11266     }
11267
11268   return 0;
11269 }
11270
11271 uword
11272 unformat_l2_match (unformat_input_t * input, va_list * args)
11273 {
11274   u8 **matchp = va_arg (*args, u8 **);
11275   u8 *match = 0;
11276   u8 src = 0;
11277   u8 src_val[6];
11278   u8 dst = 0;
11279   u8 dst_val[6];
11280   u8 proto = 0;
11281   u16 proto_val;
11282   u8 tag1 = 0;
11283   u8 tag1_val[2];
11284   u8 tag2 = 0;
11285   u8 tag2_val[2];
11286   int len = 14;
11287   u8 ignore_tag1 = 0;
11288   u8 ignore_tag2 = 0;
11289   u8 cos1 = 0;
11290   u8 cos2 = 0;
11291   u32 cos1_val = 0;
11292   u32 cos2_val = 0;
11293
11294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11295     {
11296       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11297         src = 1;
11298       else
11299         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11300         dst = 1;
11301       else if (unformat (input, "proto %U",
11302                          unformat_ethernet_type_host_byte_order, &proto_val))
11303         proto = 1;
11304       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11305         tag1 = 1;
11306       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11307         tag2 = 1;
11308       else if (unformat (input, "ignore-tag1"))
11309         ignore_tag1 = 1;
11310       else if (unformat (input, "ignore-tag2"))
11311         ignore_tag2 = 1;
11312       else if (unformat (input, "cos1 %d", &cos1_val))
11313         cos1 = 1;
11314       else if (unformat (input, "cos2 %d", &cos2_val))
11315         cos2 = 1;
11316       else
11317         break;
11318     }
11319   if ((src + dst + proto + tag1 + tag2 +
11320        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11321     return 0;
11322
11323   if (tag1 || ignore_tag1 || cos1)
11324     len = 18;
11325   if (tag2 || ignore_tag2 || cos2)
11326     len = 22;
11327
11328   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11329
11330   if (dst)
11331     clib_memcpy (match, dst_val, 6);
11332
11333   if (src)
11334     clib_memcpy (match + 6, src_val, 6);
11335
11336   if (tag2)
11337     {
11338       /* inner vlan tag */
11339       match[19] = tag2_val[1];
11340       match[18] = tag2_val[0];
11341       if (cos2)
11342         match[18] |= (cos2_val & 0x7) << 5;
11343       if (proto)
11344         {
11345           match[21] = proto_val & 0xff;
11346           match[20] = proto_val >> 8;
11347         }
11348       if (tag1)
11349         {
11350           match[15] = tag1_val[1];
11351           match[14] = tag1_val[0];
11352         }
11353       if (cos1)
11354         match[14] |= (cos1_val & 0x7) << 5;
11355       *matchp = match;
11356       return 1;
11357     }
11358   if (tag1)
11359     {
11360       match[15] = tag1_val[1];
11361       match[14] = tag1_val[0];
11362       if (proto)
11363         {
11364           match[17] = proto_val & 0xff;
11365           match[16] = proto_val >> 8;
11366         }
11367       if (cos1)
11368         match[14] |= (cos1_val & 0x7) << 5;
11369
11370       *matchp = match;
11371       return 1;
11372     }
11373   if (cos2)
11374     match[18] |= (cos2_val & 0x7) << 5;
11375   if (cos1)
11376     match[14] |= (cos1_val & 0x7) << 5;
11377   if (proto)
11378     {
11379       match[13] = proto_val & 0xff;
11380       match[12] = proto_val >> 8;
11381     }
11382
11383   *matchp = match;
11384   return 1;
11385 }
11386
11387 uword
11388 unformat_qos_source (unformat_input_t * input, va_list * args)
11389 {
11390   int *qs = va_arg (*args, int *);
11391
11392   if (unformat (input, "ip"))
11393     *qs = QOS_SOURCE_IP;
11394   else if (unformat (input, "mpls"))
11395     *qs = QOS_SOURCE_MPLS;
11396   else if (unformat (input, "ext"))
11397     *qs = QOS_SOURCE_EXT;
11398   else if (unformat (input, "vlan"))
11399     *qs = QOS_SOURCE_VLAN;
11400   else
11401     return 0;
11402
11403   return 1;
11404 }
11405 #endif
11406
11407 uword
11408 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11409 {
11410   u8 **matchp = va_arg (*args, u8 **);
11411   u32 skip_n_vectors = va_arg (*args, u32);
11412   u32 match_n_vectors = va_arg (*args, u32);
11413
11414   u8 *match = 0;
11415   u8 *l2 = 0;
11416   u8 *l3 = 0;
11417   u8 *l4 = 0;
11418
11419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11420     {
11421       if (unformat (input, "hex %U", unformat_hex_string, &match))
11422         ;
11423       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11424         ;
11425       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11426         ;
11427       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11428         ;
11429       else
11430         break;
11431     }
11432
11433   if (l4 && !l3)
11434     {
11435       vec_free (match);
11436       vec_free (l2);
11437       vec_free (l4);
11438       return 0;
11439     }
11440
11441   if (match || l2 || l3 || l4)
11442     {
11443       if (l2 || l3 || l4)
11444         {
11445           /* "Win a free Ethernet header in every packet" */
11446           if (l2 == 0)
11447             vec_validate_aligned (l2, 13, sizeof (u32x4));
11448           match = l2;
11449           if (vec_len (l3))
11450             {
11451               vec_append_aligned (match, l3, sizeof (u32x4));
11452               vec_free (l3);
11453             }
11454           if (vec_len (l4))
11455             {
11456               vec_append_aligned (match, l4, sizeof (u32x4));
11457               vec_free (l4);
11458             }
11459         }
11460
11461       /* Make sure the vector is big enough even if key is all 0's */
11462       vec_validate_aligned
11463         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11464          sizeof (u32x4));
11465
11466       /* Set size, include skipped vectors */
11467       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11468
11469       *matchp = match;
11470
11471       return 1;
11472     }
11473
11474   return 0;
11475 }
11476
11477 static int
11478 api_classify_add_del_session (vat_main_t * vam)
11479 {
11480   unformat_input_t *i = vam->input;
11481   vl_api_classify_add_del_session_t *mp;
11482   int is_add = 1;
11483   u32 table_index = ~0;
11484   u32 hit_next_index = ~0;
11485   u32 opaque_index = ~0;
11486   u8 *match = 0;
11487   i32 advance = 0;
11488   u32 skip_n_vectors = 0;
11489   u32 match_n_vectors = 0;
11490   u32 action = 0;
11491   u32 metadata = 0;
11492   int ret;
11493
11494   /*
11495    * Warning: you have to supply skip_n and match_n
11496    * because the API client cant simply look at the classify
11497    * table object.
11498    */
11499
11500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11501     {
11502       if (unformat (i, "del"))
11503         is_add = 0;
11504       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11505                          &hit_next_index))
11506         ;
11507       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11508                          &hit_next_index))
11509         ;
11510       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11511                          &hit_next_index))
11512         ;
11513       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11514         ;
11515       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11516         ;
11517       else if (unformat (i, "opaque-index %d", &opaque_index))
11518         ;
11519       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11520         ;
11521       else if (unformat (i, "match_n %d", &match_n_vectors))
11522         ;
11523       else if (unformat (i, "match %U", api_unformat_classify_match,
11524                          &match, skip_n_vectors, match_n_vectors))
11525         ;
11526       else if (unformat (i, "advance %d", &advance))
11527         ;
11528       else if (unformat (i, "table-index %d", &table_index))
11529         ;
11530       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11531         action = 1;
11532       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11533         action = 2;
11534       else if (unformat (i, "action %d", &action))
11535         ;
11536       else if (unformat (i, "metadata %d", &metadata))
11537         ;
11538       else
11539         break;
11540     }
11541
11542   if (table_index == ~0)
11543     {
11544       errmsg ("Table index required");
11545       return -99;
11546     }
11547
11548   if (is_add && match == 0)
11549     {
11550       errmsg ("Match value required");
11551       return -99;
11552     }
11553
11554   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11555
11556   mp->is_add = is_add;
11557   mp->table_index = ntohl (table_index);
11558   mp->hit_next_index = ntohl (hit_next_index);
11559   mp->opaque_index = ntohl (opaque_index);
11560   mp->advance = ntohl (advance);
11561   mp->action = action;
11562   mp->metadata = ntohl (metadata);
11563   mp->match_len = ntohl (vec_len (match));
11564   clib_memcpy (mp->match, match, vec_len (match));
11565   vec_free (match);
11566
11567   S (mp);
11568   W (ret);
11569   return ret;
11570 }
11571
11572 static int
11573 api_classify_set_interface_ip_table (vat_main_t * vam)
11574 {
11575   unformat_input_t *i = vam->input;
11576   vl_api_classify_set_interface_ip_table_t *mp;
11577   u32 sw_if_index;
11578   int sw_if_index_set;
11579   u32 table_index = ~0;
11580   u8 is_ipv6 = 0;
11581   int ret;
11582
11583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11584     {
11585       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11586         sw_if_index_set = 1;
11587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11588         sw_if_index_set = 1;
11589       else if (unformat (i, "table %d", &table_index))
11590         ;
11591       else
11592         {
11593           clib_warning ("parse error '%U'", format_unformat_error, i);
11594           return -99;
11595         }
11596     }
11597
11598   if (sw_if_index_set == 0)
11599     {
11600       errmsg ("missing interface name or sw_if_index");
11601       return -99;
11602     }
11603
11604
11605   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11606
11607   mp->sw_if_index = ntohl (sw_if_index);
11608   mp->table_index = ntohl (table_index);
11609   mp->is_ipv6 = is_ipv6;
11610
11611   S (mp);
11612   W (ret);
11613   return ret;
11614 }
11615
11616 static int
11617 api_classify_set_interface_l2_tables (vat_main_t * vam)
11618 {
11619   unformat_input_t *i = vam->input;
11620   vl_api_classify_set_interface_l2_tables_t *mp;
11621   u32 sw_if_index;
11622   int sw_if_index_set;
11623   u32 ip4_table_index = ~0;
11624   u32 ip6_table_index = ~0;
11625   u32 other_table_index = ~0;
11626   u32 is_input = 1;
11627   int ret;
11628
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11632         sw_if_index_set = 1;
11633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11634         sw_if_index_set = 1;
11635       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11636         ;
11637       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11638         ;
11639       else if (unformat (i, "other-table %d", &other_table_index))
11640         ;
11641       else if (unformat (i, "is-input %d", &is_input))
11642         ;
11643       else
11644         {
11645           clib_warning ("parse error '%U'", format_unformat_error, i);
11646           return -99;
11647         }
11648     }
11649
11650   if (sw_if_index_set == 0)
11651     {
11652       errmsg ("missing interface name or sw_if_index");
11653       return -99;
11654     }
11655
11656
11657   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11658
11659   mp->sw_if_index = ntohl (sw_if_index);
11660   mp->ip4_table_index = ntohl (ip4_table_index);
11661   mp->ip6_table_index = ntohl (ip6_table_index);
11662   mp->other_table_index = ntohl (other_table_index);
11663   mp->is_input = (u8) is_input;
11664
11665   S (mp);
11666   W (ret);
11667   return ret;
11668 }
11669
11670 static int
11671 api_set_ipfix_exporter (vat_main_t * vam)
11672 {
11673   unformat_input_t *i = vam->input;
11674   vl_api_set_ipfix_exporter_t *mp;
11675   ip4_address_t collector_address;
11676   u8 collector_address_set = 0;
11677   u32 collector_port = ~0;
11678   ip4_address_t src_address;
11679   u8 src_address_set = 0;
11680   u32 vrf_id = ~0;
11681   u32 path_mtu = ~0;
11682   u32 template_interval = ~0;
11683   u8 udp_checksum = 0;
11684   int ret;
11685
11686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11687     {
11688       if (unformat (i, "collector_address %U", unformat_ip4_address,
11689                     &collector_address))
11690         collector_address_set = 1;
11691       else if (unformat (i, "collector_port %d", &collector_port))
11692         ;
11693       else if (unformat (i, "src_address %U", unformat_ip4_address,
11694                          &src_address))
11695         src_address_set = 1;
11696       else if (unformat (i, "vrf_id %d", &vrf_id))
11697         ;
11698       else if (unformat (i, "path_mtu %d", &path_mtu))
11699         ;
11700       else if (unformat (i, "template_interval %d", &template_interval))
11701         ;
11702       else if (unformat (i, "udp_checksum"))
11703         udp_checksum = 1;
11704       else
11705         break;
11706     }
11707
11708   if (collector_address_set == 0)
11709     {
11710       errmsg ("collector_address required");
11711       return -99;
11712     }
11713
11714   if (src_address_set == 0)
11715     {
11716       errmsg ("src_address required");
11717       return -99;
11718     }
11719
11720   M (SET_IPFIX_EXPORTER, mp);
11721
11722   memcpy (mp->collector_address, collector_address.data,
11723           sizeof (collector_address.data));
11724   mp->collector_port = htons ((u16) collector_port);
11725   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11726   mp->vrf_id = htonl (vrf_id);
11727   mp->path_mtu = htonl (path_mtu);
11728   mp->template_interval = htonl (template_interval);
11729   mp->udp_checksum = udp_checksum;
11730
11731   S (mp);
11732   W (ret);
11733   return ret;
11734 }
11735
11736 static int
11737 api_set_ipfix_classify_stream (vat_main_t * vam)
11738 {
11739   unformat_input_t *i = vam->input;
11740   vl_api_set_ipfix_classify_stream_t *mp;
11741   u32 domain_id = 0;
11742   u32 src_port = UDP_DST_PORT_ipfix;
11743   int ret;
11744
11745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11746     {
11747       if (unformat (i, "domain %d", &domain_id))
11748         ;
11749       else if (unformat (i, "src_port %d", &src_port))
11750         ;
11751       else
11752         {
11753           errmsg ("unknown input `%U'", format_unformat_error, i);
11754           return -99;
11755         }
11756     }
11757
11758   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11759
11760   mp->domain_id = htonl (domain_id);
11761   mp->src_port = htons ((u16) src_port);
11762
11763   S (mp);
11764   W (ret);
11765   return ret;
11766 }
11767
11768 static int
11769 api_ipfix_classify_table_add_del (vat_main_t * vam)
11770 {
11771   unformat_input_t *i = vam->input;
11772   vl_api_ipfix_classify_table_add_del_t *mp;
11773   int is_add = -1;
11774   u32 classify_table_index = ~0;
11775   u8 ip_version = 0;
11776   u8 transport_protocol = 255;
11777   int ret;
11778
11779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11780     {
11781       if (unformat (i, "add"))
11782         is_add = 1;
11783       else if (unformat (i, "del"))
11784         is_add = 0;
11785       else if (unformat (i, "table %d", &classify_table_index))
11786         ;
11787       else if (unformat (i, "ip4"))
11788         ip_version = 4;
11789       else if (unformat (i, "ip6"))
11790         ip_version = 6;
11791       else if (unformat (i, "tcp"))
11792         transport_protocol = 6;
11793       else if (unformat (i, "udp"))
11794         transport_protocol = 17;
11795       else
11796         {
11797           errmsg ("unknown input `%U'", format_unformat_error, i);
11798           return -99;
11799         }
11800     }
11801
11802   if (is_add == -1)
11803     {
11804       errmsg ("expecting: add|del");
11805       return -99;
11806     }
11807   if (classify_table_index == ~0)
11808     {
11809       errmsg ("classifier table not specified");
11810       return -99;
11811     }
11812   if (ip_version == 0)
11813     {
11814       errmsg ("IP version not specified");
11815       return -99;
11816     }
11817
11818   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11819
11820   mp->is_add = is_add;
11821   mp->table_id = htonl (classify_table_index);
11822   mp->ip_version = ip_version;
11823   mp->transport_protocol = transport_protocol;
11824
11825   S (mp);
11826   W (ret);
11827   return ret;
11828 }
11829
11830 static int
11831 api_get_node_index (vat_main_t * vam)
11832 {
11833   unformat_input_t *i = vam->input;
11834   vl_api_get_node_index_t *mp;
11835   u8 *name = 0;
11836   int ret;
11837
11838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11839     {
11840       if (unformat (i, "node %s", &name))
11841         ;
11842       else
11843         break;
11844     }
11845   if (name == 0)
11846     {
11847       errmsg ("node name required");
11848       return -99;
11849     }
11850   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11851     {
11852       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11853       return -99;
11854     }
11855
11856   M (GET_NODE_INDEX, mp);
11857   clib_memcpy (mp->node_name, name, vec_len (name));
11858   vec_free (name);
11859
11860   S (mp);
11861   W (ret);
11862   return ret;
11863 }
11864
11865 static int
11866 api_get_next_index (vat_main_t * vam)
11867 {
11868   unformat_input_t *i = vam->input;
11869   vl_api_get_next_index_t *mp;
11870   u8 *node_name = 0, *next_node_name = 0;
11871   int ret;
11872
11873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (i, "node-name %s", &node_name))
11876         ;
11877       else if (unformat (i, "next-node-name %s", &next_node_name))
11878         break;
11879     }
11880
11881   if (node_name == 0)
11882     {
11883       errmsg ("node name required");
11884       return -99;
11885     }
11886   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11887     {
11888       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11889       return -99;
11890     }
11891
11892   if (next_node_name == 0)
11893     {
11894       errmsg ("next node name required");
11895       return -99;
11896     }
11897   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11898     {
11899       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11900       return -99;
11901     }
11902
11903   M (GET_NEXT_INDEX, mp);
11904   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11905   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11906   vec_free (node_name);
11907   vec_free (next_node_name);
11908
11909   S (mp);
11910   W (ret);
11911   return ret;
11912 }
11913
11914 static int
11915 api_add_node_next (vat_main_t * vam)
11916 {
11917   unformat_input_t *i = vam->input;
11918   vl_api_add_node_next_t *mp;
11919   u8 *name = 0;
11920   u8 *next = 0;
11921   int ret;
11922
11923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11924     {
11925       if (unformat (i, "node %s", &name))
11926         ;
11927       else if (unformat (i, "next %s", &next))
11928         ;
11929       else
11930         break;
11931     }
11932   if (name == 0)
11933     {
11934       errmsg ("node name required");
11935       return -99;
11936     }
11937   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11938     {
11939       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11940       return -99;
11941     }
11942   if (next == 0)
11943     {
11944       errmsg ("next node required");
11945       return -99;
11946     }
11947   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11948     {
11949       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11950       return -99;
11951     }
11952
11953   M (ADD_NODE_NEXT, mp);
11954   clib_memcpy (mp->node_name, name, vec_len (name));
11955   clib_memcpy (mp->next_name, next, vec_len (next));
11956   vec_free (name);
11957   vec_free (next);
11958
11959   S (mp);
11960   W (ret);
11961   return ret;
11962 }
11963
11964 static int
11965 api_l2tpv3_create_tunnel (vat_main_t * vam)
11966 {
11967   unformat_input_t *i = vam->input;
11968   ip6_address_t client_address, our_address;
11969   int client_address_set = 0;
11970   int our_address_set = 0;
11971   u32 local_session_id = 0;
11972   u32 remote_session_id = 0;
11973   u64 local_cookie = 0;
11974   u64 remote_cookie = 0;
11975   u8 l2_sublayer_present = 0;
11976   vl_api_l2tpv3_create_tunnel_t *mp;
11977   int ret;
11978
11979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11980     {
11981       if (unformat (i, "client_address %U", unformat_ip6_address,
11982                     &client_address))
11983         client_address_set = 1;
11984       else if (unformat (i, "our_address %U", unformat_ip6_address,
11985                          &our_address))
11986         our_address_set = 1;
11987       else if (unformat (i, "local_session_id %d", &local_session_id))
11988         ;
11989       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11990         ;
11991       else if (unformat (i, "local_cookie %lld", &local_cookie))
11992         ;
11993       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11994         ;
11995       else if (unformat (i, "l2-sublayer-present"))
11996         l2_sublayer_present = 1;
11997       else
11998         break;
11999     }
12000
12001   if (client_address_set == 0)
12002     {
12003       errmsg ("client_address required");
12004       return -99;
12005     }
12006
12007   if (our_address_set == 0)
12008     {
12009       errmsg ("our_address required");
12010       return -99;
12011     }
12012
12013   M (L2TPV3_CREATE_TUNNEL, mp);
12014
12015   clib_memcpy (mp->client_address, client_address.as_u8,
12016                sizeof (mp->client_address));
12017
12018   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12019
12020   mp->local_session_id = ntohl (local_session_id);
12021   mp->remote_session_id = ntohl (remote_session_id);
12022   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12023   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12024   mp->l2_sublayer_present = l2_sublayer_present;
12025   mp->is_ipv6 = 1;
12026
12027   S (mp);
12028   W (ret);
12029   return ret;
12030 }
12031
12032 static int
12033 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12034 {
12035   unformat_input_t *i = vam->input;
12036   u32 sw_if_index;
12037   u8 sw_if_index_set = 0;
12038   u64 new_local_cookie = 0;
12039   u64 new_remote_cookie = 0;
12040   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12041   int ret;
12042
12043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12044     {
12045       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12046         sw_if_index_set = 1;
12047       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12048         sw_if_index_set = 1;
12049       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12050         ;
12051       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12052         ;
12053       else
12054         break;
12055     }
12056
12057   if (sw_if_index_set == 0)
12058     {
12059       errmsg ("missing interface name or sw_if_index");
12060       return -99;
12061     }
12062
12063   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12064
12065   mp->sw_if_index = ntohl (sw_if_index);
12066   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12067   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12068
12069   S (mp);
12070   W (ret);
12071   return ret;
12072 }
12073
12074 static int
12075 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12076 {
12077   unformat_input_t *i = vam->input;
12078   vl_api_l2tpv3_interface_enable_disable_t *mp;
12079   u32 sw_if_index;
12080   u8 sw_if_index_set = 0;
12081   u8 enable_disable = 1;
12082   int ret;
12083
12084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12085     {
12086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12087         sw_if_index_set = 1;
12088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12089         sw_if_index_set = 1;
12090       else if (unformat (i, "enable"))
12091         enable_disable = 1;
12092       else if (unformat (i, "disable"))
12093         enable_disable = 0;
12094       else
12095         break;
12096     }
12097
12098   if (sw_if_index_set == 0)
12099     {
12100       errmsg ("missing interface name or sw_if_index");
12101       return -99;
12102     }
12103
12104   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12105
12106   mp->sw_if_index = ntohl (sw_if_index);
12107   mp->enable_disable = enable_disable;
12108
12109   S (mp);
12110   W (ret);
12111   return ret;
12112 }
12113
12114 static int
12115 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12116 {
12117   unformat_input_t *i = vam->input;
12118   vl_api_l2tpv3_set_lookup_key_t *mp;
12119   u8 key = ~0;
12120   int ret;
12121
12122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12123     {
12124       if (unformat (i, "lookup_v6_src"))
12125         key = L2T_LOOKUP_SRC_ADDRESS;
12126       else if (unformat (i, "lookup_v6_dst"))
12127         key = L2T_LOOKUP_DST_ADDRESS;
12128       else if (unformat (i, "lookup_session_id"))
12129         key = L2T_LOOKUP_SESSION_ID;
12130       else
12131         break;
12132     }
12133
12134   if (key == (u8) ~ 0)
12135     {
12136       errmsg ("l2tp session lookup key unset");
12137       return -99;
12138     }
12139
12140   M (L2TPV3_SET_LOOKUP_KEY, mp);
12141
12142   mp->key = key;
12143
12144   S (mp);
12145   W (ret);
12146   return ret;
12147 }
12148
12149 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12150   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12151 {
12152   vat_main_t *vam = &vat_main;
12153
12154   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12155          format_ip6_address, mp->our_address,
12156          format_ip6_address, mp->client_address,
12157          clib_net_to_host_u32 (mp->sw_if_index));
12158
12159   print (vam->ofp,
12160          "   local cookies %016llx %016llx remote cookie %016llx",
12161          clib_net_to_host_u64 (mp->local_cookie[0]),
12162          clib_net_to_host_u64 (mp->local_cookie[1]),
12163          clib_net_to_host_u64 (mp->remote_cookie));
12164
12165   print (vam->ofp, "   local session-id %d remote session-id %d",
12166          clib_net_to_host_u32 (mp->local_session_id),
12167          clib_net_to_host_u32 (mp->remote_session_id));
12168
12169   print (vam->ofp, "   l2 specific sublayer %s\n",
12170          mp->l2_sublayer_present ? "preset" : "absent");
12171
12172 }
12173
12174 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12175   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12176 {
12177   vat_main_t *vam = &vat_main;
12178   vat_json_node_t *node = NULL;
12179   struct in6_addr addr;
12180
12181   if (VAT_JSON_ARRAY != vam->json_tree.type)
12182     {
12183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12184       vat_json_init_array (&vam->json_tree);
12185     }
12186   node = vat_json_array_add (&vam->json_tree);
12187
12188   vat_json_init_object (node);
12189
12190   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12191   vat_json_object_add_ip6 (node, "our_address", addr);
12192   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12193   vat_json_object_add_ip6 (node, "client_address", addr);
12194
12195   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12196   vat_json_init_array (lc);
12197   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12198   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12199   vat_json_object_add_uint (node, "remote_cookie",
12200                             clib_net_to_host_u64 (mp->remote_cookie));
12201
12202   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12203   vat_json_object_add_uint (node, "local_session_id",
12204                             clib_net_to_host_u32 (mp->local_session_id));
12205   vat_json_object_add_uint (node, "remote_session_id",
12206                             clib_net_to_host_u32 (mp->remote_session_id));
12207   vat_json_object_add_string_copy (node, "l2_sublayer",
12208                                    mp->l2_sublayer_present ? (u8 *) "present"
12209                                    : (u8 *) "absent");
12210 }
12211
12212 static int
12213 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12214 {
12215   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12216   vl_api_control_ping_t *mp_ping;
12217   int ret;
12218
12219   /* Get list of l2tpv3-tunnel interfaces */
12220   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12221   S (mp);
12222
12223   /* Use a control ping for synchronization */
12224   MPING (CONTROL_PING, mp_ping);
12225   S (mp_ping);
12226
12227   W (ret);
12228   return ret;
12229 }
12230
12231
12232 static void vl_api_sw_interface_tap_v2_details_t_handler
12233   (vl_api_sw_interface_tap_v2_details_t * mp)
12234 {
12235   vat_main_t *vam = &vat_main;
12236
12237   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12238                     mp->host_ip4_prefix_len);
12239   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12240                     mp->host_ip6_prefix_len);
12241
12242   print (vam->ofp,
12243          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12244          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12245          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12246          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12247          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12248
12249   vec_free (ip4);
12250   vec_free (ip6);
12251 }
12252
12253 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12254   (vl_api_sw_interface_tap_v2_details_t * mp)
12255 {
12256   vat_main_t *vam = &vat_main;
12257   vat_json_node_t *node = NULL;
12258
12259   if (VAT_JSON_ARRAY != vam->json_tree.type)
12260     {
12261       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12262       vat_json_init_array (&vam->json_tree);
12263     }
12264   node = vat_json_array_add (&vam->json_tree);
12265
12266   vat_json_init_object (node);
12267   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12268   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12269   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12270   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12271   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12272   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12273   vat_json_object_add_string_copy (node, "host_mac_addr",
12274                                    format (0, "%U", format_ethernet_address,
12275                                            &mp->host_mac_addr));
12276   vat_json_object_add_string_copy (node, "host_namespace",
12277                                    mp->host_namespace);
12278   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12279   vat_json_object_add_string_copy (node, "host_ip4_addr",
12280                                    format (0, "%U/%d", format_ip4_address,
12281                                            mp->host_ip4_addr,
12282                                            mp->host_ip4_prefix_len));
12283   vat_json_object_add_string_copy (node, "host_ip6_addr",
12284                                    format (0, "%U/%d", format_ip6_address,
12285                                            mp->host_ip6_addr,
12286                                            mp->host_ip6_prefix_len));
12287
12288 }
12289
12290 static int
12291 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12292 {
12293   vl_api_sw_interface_tap_v2_dump_t *mp;
12294   vl_api_control_ping_t *mp_ping;
12295   int ret;
12296
12297   print (vam->ofp,
12298          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12299          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12300          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12301          "host_ip6_addr");
12302
12303   /* Get list of tap interfaces */
12304   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12305   S (mp);
12306
12307   /* Use a control ping for synchronization */
12308   MPING (CONTROL_PING, mp_ping);
12309   S (mp_ping);
12310
12311   W (ret);
12312   return ret;
12313 }
12314
12315 static void vl_api_sw_interface_virtio_pci_details_t_handler
12316   (vl_api_sw_interface_virtio_pci_details_t * mp)
12317 {
12318   vat_main_t *vam = &vat_main;
12319
12320   typedef union
12321   {
12322     struct
12323     {
12324       u16 domain;
12325       u8 bus;
12326       u8 slot:5;
12327       u8 function:3;
12328     };
12329     u32 as_u32;
12330   } pci_addr_t;
12331   pci_addr_t addr;
12332   addr.as_u32 = ntohl (mp->pci_addr);
12333   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12334                          addr.slot, addr.function);
12335
12336   print (vam->ofp,
12337          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12338          pci_addr, ntohl (mp->sw_if_index),
12339          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12340          format_ethernet_address, mp->mac_addr,
12341          clib_net_to_host_u64 (mp->features));
12342   vec_free (pci_addr);
12343 }
12344
12345 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12346   (vl_api_sw_interface_virtio_pci_details_t * mp)
12347 {
12348   vat_main_t *vam = &vat_main;
12349   vat_json_node_t *node = NULL;
12350
12351   if (VAT_JSON_ARRAY != vam->json_tree.type)
12352     {
12353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12354       vat_json_init_array (&vam->json_tree);
12355     }
12356   node = vat_json_array_add (&vam->json_tree);
12357
12358   vat_json_init_object (node);
12359   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12360   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12361   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12362   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12363   vat_json_object_add_uint (node, "features",
12364                             clib_net_to_host_u64 (mp->features));
12365   vat_json_object_add_string_copy (node, "mac_addr",
12366                                    format (0, "%U", format_ethernet_address,
12367                                            &mp->mac_addr));
12368 }
12369
12370 static int
12371 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12372 {
12373   vl_api_sw_interface_virtio_pci_dump_t *mp;
12374   vl_api_control_ping_t *mp_ping;
12375   int ret;
12376
12377   print (vam->ofp,
12378          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12379          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12380          "mac_addr", "features");
12381
12382   /* Get list of tap interfaces */
12383   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12384   S (mp);
12385
12386   /* Use a control ping for synchronization */
12387   MPING (CONTROL_PING, mp_ping);
12388   S (mp_ping);
12389
12390   W (ret);
12391   return ret;
12392 }
12393
12394 static int
12395 api_vxlan_offload_rx (vat_main_t * vam)
12396 {
12397   unformat_input_t *line_input = vam->input;
12398   vl_api_vxlan_offload_rx_t *mp;
12399   u32 hw_if_index = ~0, rx_if_index = ~0;
12400   u8 is_add = 1;
12401   int ret;
12402
12403   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12404     {
12405       if (unformat (line_input, "del"))
12406         is_add = 0;
12407       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12408                          &hw_if_index))
12409         ;
12410       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12411         ;
12412       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12413                          &rx_if_index))
12414         ;
12415       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12416         ;
12417       else
12418         {
12419           errmsg ("parse error '%U'", format_unformat_error, line_input);
12420           return -99;
12421         }
12422     }
12423
12424   if (hw_if_index == ~0)
12425     {
12426       errmsg ("no hw interface");
12427       return -99;
12428     }
12429
12430   if (rx_if_index == ~0)
12431     {
12432       errmsg ("no rx tunnel");
12433       return -99;
12434     }
12435
12436   M (VXLAN_OFFLOAD_RX, mp);
12437
12438   mp->hw_if_index = ntohl (hw_if_index);
12439   mp->sw_if_index = ntohl (rx_if_index);
12440   mp->enable = is_add;
12441
12442   S (mp);
12443   W (ret);
12444   return ret;
12445 }
12446
12447 static uword unformat_vxlan_decap_next
12448   (unformat_input_t * input, va_list * args)
12449 {
12450   u32 *result = va_arg (*args, u32 *);
12451   u32 tmp;
12452
12453   if (unformat (input, "l2"))
12454     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12455   else if (unformat (input, "%d", &tmp))
12456     *result = tmp;
12457   else
12458     return 0;
12459   return 1;
12460 }
12461
12462 static int
12463 api_vxlan_add_del_tunnel (vat_main_t * vam)
12464 {
12465   unformat_input_t *line_input = vam->input;
12466   vl_api_vxlan_add_del_tunnel_t *mp;
12467   ip46_address_t src, dst;
12468   u8 is_add = 1;
12469   u8 ipv4_set = 0, ipv6_set = 0;
12470   u8 src_set = 0;
12471   u8 dst_set = 0;
12472   u8 grp_set = 0;
12473   u32 instance = ~0;
12474   u32 mcast_sw_if_index = ~0;
12475   u32 encap_vrf_id = 0;
12476   u32 decap_next_index = ~0;
12477   u32 vni = 0;
12478   int ret;
12479
12480   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12481   clib_memset (&src, 0, sizeof src);
12482   clib_memset (&dst, 0, sizeof dst);
12483
12484   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12485     {
12486       if (unformat (line_input, "del"))
12487         is_add = 0;
12488       else if (unformat (line_input, "instance %d", &instance))
12489         ;
12490       else
12491         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12492         {
12493           ipv4_set = 1;
12494           src_set = 1;
12495         }
12496       else
12497         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12498         {
12499           ipv4_set = 1;
12500           dst_set = 1;
12501         }
12502       else
12503         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12504         {
12505           ipv6_set = 1;
12506           src_set = 1;
12507         }
12508       else
12509         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12510         {
12511           ipv6_set = 1;
12512           dst_set = 1;
12513         }
12514       else if (unformat (line_input, "group %U %U",
12515                          unformat_ip4_address, &dst.ip4,
12516                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12517         {
12518           grp_set = dst_set = 1;
12519           ipv4_set = 1;
12520         }
12521       else if (unformat (line_input, "group %U",
12522                          unformat_ip4_address, &dst.ip4))
12523         {
12524           grp_set = dst_set = 1;
12525           ipv4_set = 1;
12526         }
12527       else if (unformat (line_input, "group %U %U",
12528                          unformat_ip6_address, &dst.ip6,
12529                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12530         {
12531           grp_set = dst_set = 1;
12532           ipv6_set = 1;
12533         }
12534       else if (unformat (line_input, "group %U",
12535                          unformat_ip6_address, &dst.ip6))
12536         {
12537           grp_set = dst_set = 1;
12538           ipv6_set = 1;
12539         }
12540       else
12541         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12542         ;
12543       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12544         ;
12545       else if (unformat (line_input, "decap-next %U",
12546                          unformat_vxlan_decap_next, &decap_next_index))
12547         ;
12548       else if (unformat (line_input, "vni %d", &vni))
12549         ;
12550       else
12551         {
12552           errmsg ("parse error '%U'", format_unformat_error, line_input);
12553           return -99;
12554         }
12555     }
12556
12557   if (src_set == 0)
12558     {
12559       errmsg ("tunnel src address not specified");
12560       return -99;
12561     }
12562   if (dst_set == 0)
12563     {
12564       errmsg ("tunnel dst address not specified");
12565       return -99;
12566     }
12567
12568   if (grp_set && !ip46_address_is_multicast (&dst))
12569     {
12570       errmsg ("tunnel group address not multicast");
12571       return -99;
12572     }
12573   if (grp_set && mcast_sw_if_index == ~0)
12574     {
12575       errmsg ("tunnel nonexistent multicast device");
12576       return -99;
12577     }
12578   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12579     {
12580       errmsg ("tunnel dst address must be unicast");
12581       return -99;
12582     }
12583
12584
12585   if (ipv4_set && ipv6_set)
12586     {
12587       errmsg ("both IPv4 and IPv6 addresses specified");
12588       return -99;
12589     }
12590
12591   if ((vni == 0) || (vni >> 24))
12592     {
12593       errmsg ("vni not specified or out of range");
12594       return -99;
12595     }
12596
12597   M (VXLAN_ADD_DEL_TUNNEL, mp);
12598
12599   if (ipv6_set)
12600     {
12601       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12602       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12603     }
12604   else
12605     {
12606       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12607       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12608     }
12609
12610   mp->instance = htonl (instance);
12611   mp->encap_vrf_id = ntohl (encap_vrf_id);
12612   mp->decap_next_index = ntohl (decap_next_index);
12613   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12614   mp->vni = ntohl (vni);
12615   mp->is_add = is_add;
12616   mp->is_ipv6 = ipv6_set;
12617
12618   S (mp);
12619   W (ret);
12620   return ret;
12621 }
12622
12623 static void vl_api_vxlan_tunnel_details_t_handler
12624   (vl_api_vxlan_tunnel_details_t * mp)
12625 {
12626   vat_main_t *vam = &vat_main;
12627   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12628   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12629
12630   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12631          ntohl (mp->sw_if_index),
12632          ntohl (mp->instance),
12633          format_ip46_address, &src, IP46_TYPE_ANY,
12634          format_ip46_address, &dst, IP46_TYPE_ANY,
12635          ntohl (mp->encap_vrf_id),
12636          ntohl (mp->decap_next_index), ntohl (mp->vni),
12637          ntohl (mp->mcast_sw_if_index));
12638 }
12639
12640 static void vl_api_vxlan_tunnel_details_t_handler_json
12641   (vl_api_vxlan_tunnel_details_t * mp)
12642 {
12643   vat_main_t *vam = &vat_main;
12644   vat_json_node_t *node = NULL;
12645
12646   if (VAT_JSON_ARRAY != vam->json_tree.type)
12647     {
12648       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12649       vat_json_init_array (&vam->json_tree);
12650     }
12651   node = vat_json_array_add (&vam->json_tree);
12652
12653   vat_json_init_object (node);
12654   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12655
12656   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12657
12658   if (mp->is_ipv6)
12659     {
12660       struct in6_addr ip6;
12661
12662       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12663       vat_json_object_add_ip6 (node, "src_address", ip6);
12664       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12665       vat_json_object_add_ip6 (node, "dst_address", ip6);
12666     }
12667   else
12668     {
12669       struct in_addr ip4;
12670
12671       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12672       vat_json_object_add_ip4 (node, "src_address", ip4);
12673       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12674       vat_json_object_add_ip4 (node, "dst_address", ip4);
12675     }
12676   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12677   vat_json_object_add_uint (node, "decap_next_index",
12678                             ntohl (mp->decap_next_index));
12679   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12680   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12681   vat_json_object_add_uint (node, "mcast_sw_if_index",
12682                             ntohl (mp->mcast_sw_if_index));
12683 }
12684
12685 static int
12686 api_vxlan_tunnel_dump (vat_main_t * vam)
12687 {
12688   unformat_input_t *i = vam->input;
12689   vl_api_vxlan_tunnel_dump_t *mp;
12690   vl_api_control_ping_t *mp_ping;
12691   u32 sw_if_index;
12692   u8 sw_if_index_set = 0;
12693   int ret;
12694
12695   /* Parse args required to build the message */
12696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12697     {
12698       if (unformat (i, "sw_if_index %d", &sw_if_index))
12699         sw_if_index_set = 1;
12700       else
12701         break;
12702     }
12703
12704   if (sw_if_index_set == 0)
12705     {
12706       sw_if_index = ~0;
12707     }
12708
12709   if (!vam->json_output)
12710     {
12711       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12712              "sw_if_index", "instance", "src_address", "dst_address",
12713              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12714     }
12715
12716   /* Get list of vxlan-tunnel interfaces */
12717   M (VXLAN_TUNNEL_DUMP, mp);
12718
12719   mp->sw_if_index = htonl (sw_if_index);
12720
12721   S (mp);
12722
12723   /* Use a control ping for synchronization */
12724   MPING (CONTROL_PING, mp_ping);
12725   S (mp_ping);
12726
12727   W (ret);
12728   return ret;
12729 }
12730
12731 static uword unformat_geneve_decap_next
12732   (unformat_input_t * input, va_list * args)
12733 {
12734   u32 *result = va_arg (*args, u32 *);
12735   u32 tmp;
12736
12737   if (unformat (input, "l2"))
12738     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12739   else if (unformat (input, "%d", &tmp))
12740     *result = tmp;
12741   else
12742     return 0;
12743   return 1;
12744 }
12745
12746 static int
12747 api_geneve_add_del_tunnel (vat_main_t * vam)
12748 {
12749   unformat_input_t *line_input = vam->input;
12750   vl_api_geneve_add_del_tunnel_t *mp;
12751   ip46_address_t src, dst;
12752   u8 is_add = 1;
12753   u8 ipv4_set = 0, ipv6_set = 0;
12754   u8 src_set = 0;
12755   u8 dst_set = 0;
12756   u8 grp_set = 0;
12757   u32 mcast_sw_if_index = ~0;
12758   u32 encap_vrf_id = 0;
12759   u32 decap_next_index = ~0;
12760   u32 vni = 0;
12761   int ret;
12762
12763   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12764   clib_memset (&src, 0, sizeof src);
12765   clib_memset (&dst, 0, sizeof dst);
12766
12767   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12768     {
12769       if (unformat (line_input, "del"))
12770         is_add = 0;
12771       else
12772         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12773         {
12774           ipv4_set = 1;
12775           src_set = 1;
12776         }
12777       else
12778         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12779         {
12780           ipv4_set = 1;
12781           dst_set = 1;
12782         }
12783       else
12784         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12785         {
12786           ipv6_set = 1;
12787           src_set = 1;
12788         }
12789       else
12790         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12791         {
12792           ipv6_set = 1;
12793           dst_set = 1;
12794         }
12795       else if (unformat (line_input, "group %U %U",
12796                          unformat_ip4_address, &dst.ip4,
12797                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12798         {
12799           grp_set = dst_set = 1;
12800           ipv4_set = 1;
12801         }
12802       else if (unformat (line_input, "group %U",
12803                          unformat_ip4_address, &dst.ip4))
12804         {
12805           grp_set = dst_set = 1;
12806           ipv4_set = 1;
12807         }
12808       else if (unformat (line_input, "group %U %U",
12809                          unformat_ip6_address, &dst.ip6,
12810                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12811         {
12812           grp_set = dst_set = 1;
12813           ipv6_set = 1;
12814         }
12815       else if (unformat (line_input, "group %U",
12816                          unformat_ip6_address, &dst.ip6))
12817         {
12818           grp_set = dst_set = 1;
12819           ipv6_set = 1;
12820         }
12821       else
12822         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12823         ;
12824       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12825         ;
12826       else if (unformat (line_input, "decap-next %U",
12827                          unformat_geneve_decap_next, &decap_next_index))
12828         ;
12829       else if (unformat (line_input, "vni %d", &vni))
12830         ;
12831       else
12832         {
12833           errmsg ("parse error '%U'", format_unformat_error, line_input);
12834           return -99;
12835         }
12836     }
12837
12838   if (src_set == 0)
12839     {
12840       errmsg ("tunnel src address not specified");
12841       return -99;
12842     }
12843   if (dst_set == 0)
12844     {
12845       errmsg ("tunnel dst address not specified");
12846       return -99;
12847     }
12848
12849   if (grp_set && !ip46_address_is_multicast (&dst))
12850     {
12851       errmsg ("tunnel group address not multicast");
12852       return -99;
12853     }
12854   if (grp_set && mcast_sw_if_index == ~0)
12855     {
12856       errmsg ("tunnel nonexistent multicast device");
12857       return -99;
12858     }
12859   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12860     {
12861       errmsg ("tunnel dst address must be unicast");
12862       return -99;
12863     }
12864
12865
12866   if (ipv4_set && ipv6_set)
12867     {
12868       errmsg ("both IPv4 and IPv6 addresses specified");
12869       return -99;
12870     }
12871
12872   if ((vni == 0) || (vni >> 24))
12873     {
12874       errmsg ("vni not specified or out of range");
12875       return -99;
12876     }
12877
12878   M (GENEVE_ADD_DEL_TUNNEL, mp);
12879
12880   if (ipv6_set)
12881     {
12882       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12883       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12884     }
12885   else
12886     {
12887       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12888       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12889     }
12890   mp->encap_vrf_id = ntohl (encap_vrf_id);
12891   mp->decap_next_index = ntohl (decap_next_index);
12892   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12893   mp->vni = ntohl (vni);
12894   mp->is_add = is_add;
12895   mp->is_ipv6 = ipv6_set;
12896
12897   S (mp);
12898   W (ret);
12899   return ret;
12900 }
12901
12902 static void vl_api_geneve_tunnel_details_t_handler
12903   (vl_api_geneve_tunnel_details_t * mp)
12904 {
12905   vat_main_t *vam = &vat_main;
12906   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12907   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12908
12909   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12910          ntohl (mp->sw_if_index),
12911          format_ip46_address, &src, IP46_TYPE_ANY,
12912          format_ip46_address, &dst, IP46_TYPE_ANY,
12913          ntohl (mp->encap_vrf_id),
12914          ntohl (mp->decap_next_index), ntohl (mp->vni),
12915          ntohl (mp->mcast_sw_if_index));
12916 }
12917
12918 static void vl_api_geneve_tunnel_details_t_handler_json
12919   (vl_api_geneve_tunnel_details_t * mp)
12920 {
12921   vat_main_t *vam = &vat_main;
12922   vat_json_node_t *node = NULL;
12923
12924   if (VAT_JSON_ARRAY != vam->json_tree.type)
12925     {
12926       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12927       vat_json_init_array (&vam->json_tree);
12928     }
12929   node = vat_json_array_add (&vam->json_tree);
12930
12931   vat_json_init_object (node);
12932   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12933   if (mp->is_ipv6)
12934     {
12935       struct in6_addr ip6;
12936
12937       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12938       vat_json_object_add_ip6 (node, "src_address", ip6);
12939       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12940       vat_json_object_add_ip6 (node, "dst_address", ip6);
12941     }
12942   else
12943     {
12944       struct in_addr ip4;
12945
12946       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12947       vat_json_object_add_ip4 (node, "src_address", ip4);
12948       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12949       vat_json_object_add_ip4 (node, "dst_address", ip4);
12950     }
12951   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12952   vat_json_object_add_uint (node, "decap_next_index",
12953                             ntohl (mp->decap_next_index));
12954   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12955   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12956   vat_json_object_add_uint (node, "mcast_sw_if_index",
12957                             ntohl (mp->mcast_sw_if_index));
12958 }
12959
12960 static int
12961 api_geneve_tunnel_dump (vat_main_t * vam)
12962 {
12963   unformat_input_t *i = vam->input;
12964   vl_api_geneve_tunnel_dump_t *mp;
12965   vl_api_control_ping_t *mp_ping;
12966   u32 sw_if_index;
12967   u8 sw_if_index_set = 0;
12968   int ret;
12969
12970   /* Parse args required to build the message */
12971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12972     {
12973       if (unformat (i, "sw_if_index %d", &sw_if_index))
12974         sw_if_index_set = 1;
12975       else
12976         break;
12977     }
12978
12979   if (sw_if_index_set == 0)
12980     {
12981       sw_if_index = ~0;
12982     }
12983
12984   if (!vam->json_output)
12985     {
12986       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12987              "sw_if_index", "local_address", "remote_address",
12988              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12989     }
12990
12991   /* Get list of geneve-tunnel interfaces */
12992   M (GENEVE_TUNNEL_DUMP, mp);
12993
12994   mp->sw_if_index = htonl (sw_if_index);
12995
12996   S (mp);
12997
12998   /* Use a control ping for synchronization */
12999   M (CONTROL_PING, mp_ping);
13000   S (mp_ping);
13001
13002   W (ret);
13003   return ret;
13004 }
13005
13006 static int
13007 api_gre_tunnel_add_del (vat_main_t * vam)
13008 {
13009   unformat_input_t *line_input = vam->input;
13010   vl_api_address_t src = { }, dst =
13011   {
13012   };
13013   vl_api_gre_tunnel_add_del_t *mp;
13014   vl_api_gre_tunnel_type_t t_type;
13015   u8 is_add = 1;
13016   u8 src_set = 0;
13017   u8 dst_set = 0;
13018   u32 outer_fib_id = 0;
13019   u32 session_id = 0;
13020   u32 instance = ~0;
13021   int ret;
13022
13023   t_type = GRE_API_TUNNEL_TYPE_L3;
13024
13025   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (line_input, "del"))
13028         is_add = 0;
13029       else if (unformat (line_input, "instance %d", &instance))
13030         ;
13031       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13032         {
13033           src_set = 1;
13034         }
13035       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13036         {
13037           dst_set = 1;
13038         }
13039       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13040         ;
13041       else if (unformat (line_input, "teb"))
13042         t_type = GRE_API_TUNNEL_TYPE_TEB;
13043       else if (unformat (line_input, "erspan %d", &session_id))
13044         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13045       else
13046         {
13047           errmsg ("parse error '%U'", format_unformat_error, line_input);
13048           return -99;
13049         }
13050     }
13051
13052   if (src_set == 0)
13053     {
13054       errmsg ("tunnel src address not specified");
13055       return -99;
13056     }
13057   if (dst_set == 0)
13058     {
13059       errmsg ("tunnel dst address not specified");
13060       return -99;
13061     }
13062
13063   M (GRE_TUNNEL_ADD_DEL, mp);
13064
13065   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13066   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13067
13068   mp->tunnel.instance = htonl (instance);
13069   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13070   mp->is_add = is_add;
13071   mp->tunnel.session_id = htons ((u16) session_id);
13072   mp->tunnel.type = htonl (t_type);
13073
13074   S (mp);
13075   W (ret);
13076   return ret;
13077 }
13078
13079 static void vl_api_gre_tunnel_details_t_handler
13080   (vl_api_gre_tunnel_details_t * mp)
13081 {
13082   vat_main_t *vam = &vat_main;
13083
13084   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13085          ntohl (mp->tunnel.sw_if_index),
13086          ntohl (mp->tunnel.instance),
13087          format_vl_api_address, &mp->tunnel.src,
13088          format_vl_api_address, &mp->tunnel.dst,
13089          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13090          ntohl (mp->tunnel.session_id));
13091 }
13092
13093 static void vl_api_gre_tunnel_details_t_handler_json
13094   (vl_api_gre_tunnel_details_t * mp)
13095 {
13096   vat_main_t *vam = &vat_main;
13097   vat_json_node_t *node = NULL;
13098
13099   if (VAT_JSON_ARRAY != vam->json_tree.type)
13100     {
13101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13102       vat_json_init_array (&vam->json_tree);
13103     }
13104   node = vat_json_array_add (&vam->json_tree);
13105
13106   vat_json_init_object (node);
13107   vat_json_object_add_uint (node, "sw_if_index",
13108                             ntohl (mp->tunnel.sw_if_index));
13109   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13110
13111   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13112   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13113   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13114   vat_json_object_add_uint (node, "outer_fib_id",
13115                             ntohl (mp->tunnel.outer_fib_id));
13116   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13117 }
13118
13119 static int
13120 api_gre_tunnel_dump (vat_main_t * vam)
13121 {
13122   unformat_input_t *i = vam->input;
13123   vl_api_gre_tunnel_dump_t *mp;
13124   vl_api_control_ping_t *mp_ping;
13125   u32 sw_if_index;
13126   u8 sw_if_index_set = 0;
13127   int ret;
13128
13129   /* Parse args required to build the message */
13130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13131     {
13132       if (unformat (i, "sw_if_index %d", &sw_if_index))
13133         sw_if_index_set = 1;
13134       else
13135         break;
13136     }
13137
13138   if (sw_if_index_set == 0)
13139     {
13140       sw_if_index = ~0;
13141     }
13142
13143   if (!vam->json_output)
13144     {
13145       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13146              "sw_if_index", "instance", "src_address", "dst_address",
13147              "tunnel_type", "outer_fib_id", "session_id");
13148     }
13149
13150   /* Get list of gre-tunnel interfaces */
13151   M (GRE_TUNNEL_DUMP, mp);
13152
13153   mp->sw_if_index = htonl (sw_if_index);
13154
13155   S (mp);
13156
13157   /* Use a control ping for synchronization */
13158   MPING (CONTROL_PING, mp_ping);
13159   S (mp_ping);
13160
13161   W (ret);
13162   return ret;
13163 }
13164
13165 static int
13166 api_l2_fib_clear_table (vat_main_t * vam)
13167 {
13168 //  unformat_input_t * i = vam->input;
13169   vl_api_l2_fib_clear_table_t *mp;
13170   int ret;
13171
13172   M (L2_FIB_CLEAR_TABLE, mp);
13173
13174   S (mp);
13175   W (ret);
13176   return ret;
13177 }
13178
13179 static int
13180 api_l2_interface_efp_filter (vat_main_t * vam)
13181 {
13182   unformat_input_t *i = vam->input;
13183   vl_api_l2_interface_efp_filter_t *mp;
13184   u32 sw_if_index;
13185   u8 enable = 1;
13186   u8 sw_if_index_set = 0;
13187   int ret;
13188
13189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13190     {
13191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13192         sw_if_index_set = 1;
13193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13194         sw_if_index_set = 1;
13195       else if (unformat (i, "enable"))
13196         enable = 1;
13197       else if (unformat (i, "disable"))
13198         enable = 0;
13199       else
13200         {
13201           clib_warning ("parse error '%U'", format_unformat_error, i);
13202           return -99;
13203         }
13204     }
13205
13206   if (sw_if_index_set == 0)
13207     {
13208       errmsg ("missing sw_if_index");
13209       return -99;
13210     }
13211
13212   M (L2_INTERFACE_EFP_FILTER, mp);
13213
13214   mp->sw_if_index = ntohl (sw_if_index);
13215   mp->enable_disable = enable;
13216
13217   S (mp);
13218   W (ret);
13219   return ret;
13220 }
13221
13222 #define foreach_vtr_op                          \
13223 _("disable",  L2_VTR_DISABLED)                  \
13224 _("push-1",  L2_VTR_PUSH_1)                     \
13225 _("push-2",  L2_VTR_PUSH_2)                     \
13226 _("pop-1",  L2_VTR_POP_1)                       \
13227 _("pop-2",  L2_VTR_POP_2)                       \
13228 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13229 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13230 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13231 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13232
13233 static int
13234 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13235 {
13236   unformat_input_t *i = vam->input;
13237   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13238   u32 sw_if_index;
13239   u8 sw_if_index_set = 0;
13240   u8 vtr_op_set = 0;
13241   u32 vtr_op = 0;
13242   u32 push_dot1q = 1;
13243   u32 tag1 = ~0;
13244   u32 tag2 = ~0;
13245   int ret;
13246
13247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13248     {
13249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13250         sw_if_index_set = 1;
13251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13252         sw_if_index_set = 1;
13253       else if (unformat (i, "vtr_op %d", &vtr_op))
13254         vtr_op_set = 1;
13255 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13256       foreach_vtr_op
13257 #undef _
13258         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13259         ;
13260       else if (unformat (i, "tag1 %d", &tag1))
13261         ;
13262       else if (unformat (i, "tag2 %d", &tag2))
13263         ;
13264       else
13265         {
13266           clib_warning ("parse error '%U'", format_unformat_error, i);
13267           return -99;
13268         }
13269     }
13270
13271   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13272     {
13273       errmsg ("missing vtr operation or sw_if_index");
13274       return -99;
13275     }
13276
13277   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13278   mp->sw_if_index = ntohl (sw_if_index);
13279   mp->vtr_op = ntohl (vtr_op);
13280   mp->push_dot1q = ntohl (push_dot1q);
13281   mp->tag1 = ntohl (tag1);
13282   mp->tag2 = ntohl (tag2);
13283
13284   S (mp);
13285   W (ret);
13286   return ret;
13287 }
13288
13289 static int
13290 api_create_vhost_user_if (vat_main_t * vam)
13291 {
13292   unformat_input_t *i = vam->input;
13293   vl_api_create_vhost_user_if_t *mp;
13294   u8 *file_name;
13295   u8 is_server = 0;
13296   u8 file_name_set = 0;
13297   u32 custom_dev_instance = ~0;
13298   u8 hwaddr[6];
13299   u8 use_custom_mac = 0;
13300   u8 disable_mrg_rxbuf = 0;
13301   u8 disable_indirect_desc = 0;
13302   u8 *tag = 0;
13303   int ret;
13304
13305   /* Shut up coverity */
13306   clib_memset (hwaddr, 0, sizeof (hwaddr));
13307
13308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13309     {
13310       if (unformat (i, "socket %s", &file_name))
13311         {
13312           file_name_set = 1;
13313         }
13314       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13315         ;
13316       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13317         use_custom_mac = 1;
13318       else if (unformat (i, "server"))
13319         is_server = 1;
13320       else if (unformat (i, "disable_mrg_rxbuf"))
13321         disable_mrg_rxbuf = 1;
13322       else if (unformat (i, "disable_indirect_desc"))
13323         disable_indirect_desc = 1;
13324       else if (unformat (i, "tag %s", &tag))
13325         ;
13326       else
13327         break;
13328     }
13329
13330   if (file_name_set == 0)
13331     {
13332       errmsg ("missing socket file name");
13333       return -99;
13334     }
13335
13336   if (vec_len (file_name) > 255)
13337     {
13338       errmsg ("socket file name too long");
13339       return -99;
13340     }
13341   vec_add1 (file_name, 0);
13342
13343   M (CREATE_VHOST_USER_IF, mp);
13344
13345   mp->is_server = is_server;
13346   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13347   mp->disable_indirect_desc = disable_indirect_desc;
13348   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13349   vec_free (file_name);
13350   if (custom_dev_instance != ~0)
13351     {
13352       mp->renumber = 1;
13353       mp->custom_dev_instance = ntohl (custom_dev_instance);
13354     }
13355
13356   mp->use_custom_mac = use_custom_mac;
13357   clib_memcpy (mp->mac_address, hwaddr, 6);
13358   if (tag)
13359     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13360   vec_free (tag);
13361
13362   S (mp);
13363   W (ret);
13364   return ret;
13365 }
13366
13367 static int
13368 api_modify_vhost_user_if (vat_main_t * vam)
13369 {
13370   unformat_input_t *i = vam->input;
13371   vl_api_modify_vhost_user_if_t *mp;
13372   u8 *file_name;
13373   u8 is_server = 0;
13374   u8 file_name_set = 0;
13375   u32 custom_dev_instance = ~0;
13376   u8 sw_if_index_set = 0;
13377   u32 sw_if_index = (u32) ~ 0;
13378   int ret;
13379
13380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13381     {
13382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13383         sw_if_index_set = 1;
13384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13385         sw_if_index_set = 1;
13386       else if (unformat (i, "socket %s", &file_name))
13387         {
13388           file_name_set = 1;
13389         }
13390       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13391         ;
13392       else if (unformat (i, "server"))
13393         is_server = 1;
13394       else
13395         break;
13396     }
13397
13398   if (sw_if_index_set == 0)
13399     {
13400       errmsg ("missing sw_if_index or interface name");
13401       return -99;
13402     }
13403
13404   if (file_name_set == 0)
13405     {
13406       errmsg ("missing socket file name");
13407       return -99;
13408     }
13409
13410   if (vec_len (file_name) > 255)
13411     {
13412       errmsg ("socket file name too long");
13413       return -99;
13414     }
13415   vec_add1 (file_name, 0);
13416
13417   M (MODIFY_VHOST_USER_IF, mp);
13418
13419   mp->sw_if_index = ntohl (sw_if_index);
13420   mp->is_server = is_server;
13421   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13422   vec_free (file_name);
13423   if (custom_dev_instance != ~0)
13424     {
13425       mp->renumber = 1;
13426       mp->custom_dev_instance = ntohl (custom_dev_instance);
13427     }
13428
13429   S (mp);
13430   W (ret);
13431   return ret;
13432 }
13433
13434 static int
13435 api_delete_vhost_user_if (vat_main_t * vam)
13436 {
13437   unformat_input_t *i = vam->input;
13438   vl_api_delete_vhost_user_if_t *mp;
13439   u32 sw_if_index = ~0;
13440   u8 sw_if_index_set = 0;
13441   int ret;
13442
13443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13444     {
13445       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13446         sw_if_index_set = 1;
13447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13448         sw_if_index_set = 1;
13449       else
13450         break;
13451     }
13452
13453   if (sw_if_index_set == 0)
13454     {
13455       errmsg ("missing sw_if_index or interface name");
13456       return -99;
13457     }
13458
13459
13460   M (DELETE_VHOST_USER_IF, mp);
13461
13462   mp->sw_if_index = ntohl (sw_if_index);
13463
13464   S (mp);
13465   W (ret);
13466   return ret;
13467 }
13468
13469 static void vl_api_sw_interface_vhost_user_details_t_handler
13470   (vl_api_sw_interface_vhost_user_details_t * mp)
13471 {
13472   vat_main_t *vam = &vat_main;
13473
13474   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13475          (char *) mp->interface_name,
13476          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13477          clib_net_to_host_u64 (mp->features), mp->is_server,
13478          ntohl (mp->num_regions), (char *) mp->sock_filename);
13479   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13480 }
13481
13482 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13483   (vl_api_sw_interface_vhost_user_details_t * mp)
13484 {
13485   vat_main_t *vam = &vat_main;
13486   vat_json_node_t *node = NULL;
13487
13488   if (VAT_JSON_ARRAY != vam->json_tree.type)
13489     {
13490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13491       vat_json_init_array (&vam->json_tree);
13492     }
13493   node = vat_json_array_add (&vam->json_tree);
13494
13495   vat_json_init_object (node);
13496   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13497   vat_json_object_add_string_copy (node, "interface_name",
13498                                    mp->interface_name);
13499   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13500                             ntohl (mp->virtio_net_hdr_sz));
13501   vat_json_object_add_uint (node, "features",
13502                             clib_net_to_host_u64 (mp->features));
13503   vat_json_object_add_uint (node, "is_server", mp->is_server);
13504   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13505   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13506   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13507 }
13508
13509 static int
13510 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13511 {
13512   vl_api_sw_interface_vhost_user_dump_t *mp;
13513   vl_api_control_ping_t *mp_ping;
13514   int ret;
13515   print (vam->ofp,
13516          "Interface name            idx hdr_sz features server regions filename");
13517
13518   /* Get list of vhost-user interfaces */
13519   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13520   S (mp);
13521
13522   /* Use a control ping for synchronization */
13523   MPING (CONTROL_PING, mp_ping);
13524   S (mp_ping);
13525
13526   W (ret);
13527   return ret;
13528 }
13529
13530 static int
13531 api_show_version (vat_main_t * vam)
13532 {
13533   vl_api_show_version_t *mp;
13534   int ret;
13535
13536   M (SHOW_VERSION, mp);
13537
13538   S (mp);
13539   W (ret);
13540   return ret;
13541 }
13542
13543
13544 static int
13545 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13546 {
13547   unformat_input_t *line_input = vam->input;
13548   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13549   ip4_address_t local4, remote4;
13550   ip6_address_t local6, remote6;
13551   u8 is_add = 1;
13552   u8 ipv4_set = 0, ipv6_set = 0;
13553   u8 local_set = 0;
13554   u8 remote_set = 0;
13555   u8 grp_set = 0;
13556   u32 mcast_sw_if_index = ~0;
13557   u32 encap_vrf_id = 0;
13558   u32 decap_vrf_id = 0;
13559   u8 protocol = ~0;
13560   u32 vni;
13561   u8 vni_set = 0;
13562   int ret;
13563
13564   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13565   clib_memset (&local4, 0, sizeof local4);
13566   clib_memset (&remote4, 0, sizeof remote4);
13567   clib_memset (&local6, 0, sizeof local6);
13568   clib_memset (&remote6, 0, sizeof remote6);
13569
13570   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13571     {
13572       if (unformat (line_input, "del"))
13573         is_add = 0;
13574       else if (unformat (line_input, "local %U",
13575                          unformat_ip4_address, &local4))
13576         {
13577           local_set = 1;
13578           ipv4_set = 1;
13579         }
13580       else if (unformat (line_input, "remote %U",
13581                          unformat_ip4_address, &remote4))
13582         {
13583           remote_set = 1;
13584           ipv4_set = 1;
13585         }
13586       else if (unformat (line_input, "local %U",
13587                          unformat_ip6_address, &local6))
13588         {
13589           local_set = 1;
13590           ipv6_set = 1;
13591         }
13592       else if (unformat (line_input, "remote %U",
13593                          unformat_ip6_address, &remote6))
13594         {
13595           remote_set = 1;
13596           ipv6_set = 1;
13597         }
13598       else if (unformat (line_input, "group %U %U",
13599                          unformat_ip4_address, &remote4,
13600                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13601         {
13602           grp_set = remote_set = 1;
13603           ipv4_set = 1;
13604         }
13605       else if (unformat (line_input, "group %U",
13606                          unformat_ip4_address, &remote4))
13607         {
13608           grp_set = remote_set = 1;
13609           ipv4_set = 1;
13610         }
13611       else if (unformat (line_input, "group %U %U",
13612                          unformat_ip6_address, &remote6,
13613                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13614         {
13615           grp_set = remote_set = 1;
13616           ipv6_set = 1;
13617         }
13618       else if (unformat (line_input, "group %U",
13619                          unformat_ip6_address, &remote6))
13620         {
13621           grp_set = remote_set = 1;
13622           ipv6_set = 1;
13623         }
13624       else
13625         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13626         ;
13627       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13628         ;
13629       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13630         ;
13631       else if (unformat (line_input, "vni %d", &vni))
13632         vni_set = 1;
13633       else if (unformat (line_input, "next-ip4"))
13634         protocol = 1;
13635       else if (unformat (line_input, "next-ip6"))
13636         protocol = 2;
13637       else if (unformat (line_input, "next-ethernet"))
13638         protocol = 3;
13639       else if (unformat (line_input, "next-nsh"))
13640         protocol = 4;
13641       else
13642         {
13643           errmsg ("parse error '%U'", format_unformat_error, line_input);
13644           return -99;
13645         }
13646     }
13647
13648   if (local_set == 0)
13649     {
13650       errmsg ("tunnel local address not specified");
13651       return -99;
13652     }
13653   if (remote_set == 0)
13654     {
13655       errmsg ("tunnel remote address not specified");
13656       return -99;
13657     }
13658   if (grp_set && mcast_sw_if_index == ~0)
13659     {
13660       errmsg ("tunnel nonexistent multicast device");
13661       return -99;
13662     }
13663   if (ipv4_set && ipv6_set)
13664     {
13665       errmsg ("both IPv4 and IPv6 addresses specified");
13666       return -99;
13667     }
13668
13669   if (vni_set == 0)
13670     {
13671       errmsg ("vni not specified");
13672       return -99;
13673     }
13674
13675   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13676
13677
13678   if (ipv6_set)
13679     {
13680       clib_memcpy (&mp->local, &local6, sizeof (local6));
13681       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13682     }
13683   else
13684     {
13685       clib_memcpy (&mp->local, &local4, sizeof (local4));
13686       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13687     }
13688
13689   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13690   mp->encap_vrf_id = ntohl (encap_vrf_id);
13691   mp->decap_vrf_id = ntohl (decap_vrf_id);
13692   mp->protocol = protocol;
13693   mp->vni = ntohl (vni);
13694   mp->is_add = is_add;
13695   mp->is_ipv6 = ipv6_set;
13696
13697   S (mp);
13698   W (ret);
13699   return ret;
13700 }
13701
13702 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13703   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13704 {
13705   vat_main_t *vam = &vat_main;
13706   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13707   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13708
13709   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13710          ntohl (mp->sw_if_index),
13711          format_ip46_address, &local, IP46_TYPE_ANY,
13712          format_ip46_address, &remote, IP46_TYPE_ANY,
13713          ntohl (mp->vni), mp->protocol,
13714          ntohl (mp->mcast_sw_if_index),
13715          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13716 }
13717
13718
13719 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13720   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13721 {
13722   vat_main_t *vam = &vat_main;
13723   vat_json_node_t *node = NULL;
13724   struct in_addr ip4;
13725   struct in6_addr ip6;
13726
13727   if (VAT_JSON_ARRAY != vam->json_tree.type)
13728     {
13729       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13730       vat_json_init_array (&vam->json_tree);
13731     }
13732   node = vat_json_array_add (&vam->json_tree);
13733
13734   vat_json_init_object (node);
13735   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13736   if (mp->is_ipv6)
13737     {
13738       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13739       vat_json_object_add_ip6 (node, "local", ip6);
13740       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13741       vat_json_object_add_ip6 (node, "remote", ip6);
13742     }
13743   else
13744     {
13745       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13746       vat_json_object_add_ip4 (node, "local", ip4);
13747       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13748       vat_json_object_add_ip4 (node, "remote", ip4);
13749     }
13750   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13751   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13752   vat_json_object_add_uint (node, "mcast_sw_if_index",
13753                             ntohl (mp->mcast_sw_if_index));
13754   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13755   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13756   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13757 }
13758
13759 static int
13760 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13761 {
13762   unformat_input_t *i = vam->input;
13763   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13764   vl_api_control_ping_t *mp_ping;
13765   u32 sw_if_index;
13766   u8 sw_if_index_set = 0;
13767   int ret;
13768
13769   /* Parse args required to build the message */
13770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13771     {
13772       if (unformat (i, "sw_if_index %d", &sw_if_index))
13773         sw_if_index_set = 1;
13774       else
13775         break;
13776     }
13777
13778   if (sw_if_index_set == 0)
13779     {
13780       sw_if_index = ~0;
13781     }
13782
13783   if (!vam->json_output)
13784     {
13785       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13786              "sw_if_index", "local", "remote", "vni",
13787              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13788     }
13789
13790   /* Get list of vxlan-tunnel interfaces */
13791   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13792
13793   mp->sw_if_index = htonl (sw_if_index);
13794
13795   S (mp);
13796
13797   /* Use a control ping for synchronization */
13798   MPING (CONTROL_PING, mp_ping);
13799   S (mp_ping);
13800
13801   W (ret);
13802   return ret;
13803 }
13804
13805 static void vl_api_l2_fib_table_details_t_handler
13806   (vl_api_l2_fib_table_details_t * mp)
13807 {
13808   vat_main_t *vam = &vat_main;
13809
13810   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13811          "       %d       %d     %d",
13812          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13813          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13814          mp->bvi_mac);
13815 }
13816
13817 static void vl_api_l2_fib_table_details_t_handler_json
13818   (vl_api_l2_fib_table_details_t * mp)
13819 {
13820   vat_main_t *vam = &vat_main;
13821   vat_json_node_t *node = NULL;
13822
13823   if (VAT_JSON_ARRAY != vam->json_tree.type)
13824     {
13825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13826       vat_json_init_array (&vam->json_tree);
13827     }
13828   node = vat_json_array_add (&vam->json_tree);
13829
13830   vat_json_init_object (node);
13831   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13832   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13833   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13834   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13835   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13836   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13837 }
13838
13839 static int
13840 api_l2_fib_table_dump (vat_main_t * vam)
13841 {
13842   unformat_input_t *i = vam->input;
13843   vl_api_l2_fib_table_dump_t *mp;
13844   vl_api_control_ping_t *mp_ping;
13845   u32 bd_id;
13846   u8 bd_id_set = 0;
13847   int ret;
13848
13849   /* Parse args required to build the message */
13850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13851     {
13852       if (unformat (i, "bd_id %d", &bd_id))
13853         bd_id_set = 1;
13854       else
13855         break;
13856     }
13857
13858   if (bd_id_set == 0)
13859     {
13860       errmsg ("missing bridge domain");
13861       return -99;
13862     }
13863
13864   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13865
13866   /* Get list of l2 fib entries */
13867   M (L2_FIB_TABLE_DUMP, mp);
13868
13869   mp->bd_id = ntohl (bd_id);
13870   S (mp);
13871
13872   /* Use a control ping for synchronization */
13873   MPING (CONTROL_PING, mp_ping);
13874   S (mp_ping);
13875
13876   W (ret);
13877   return ret;
13878 }
13879
13880
13881 static int
13882 api_interface_name_renumber (vat_main_t * vam)
13883 {
13884   unformat_input_t *line_input = vam->input;
13885   vl_api_interface_name_renumber_t *mp;
13886   u32 sw_if_index = ~0;
13887   u32 new_show_dev_instance = ~0;
13888   int ret;
13889
13890   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13891     {
13892       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13893                     &sw_if_index))
13894         ;
13895       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13896         ;
13897       else if (unformat (line_input, "new_show_dev_instance %d",
13898                          &new_show_dev_instance))
13899         ;
13900       else
13901         break;
13902     }
13903
13904   if (sw_if_index == ~0)
13905     {
13906       errmsg ("missing interface name or sw_if_index");
13907       return -99;
13908     }
13909
13910   if (new_show_dev_instance == ~0)
13911     {
13912       errmsg ("missing new_show_dev_instance");
13913       return -99;
13914     }
13915
13916   M (INTERFACE_NAME_RENUMBER, mp);
13917
13918   mp->sw_if_index = ntohl (sw_if_index);
13919   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13920
13921   S (mp);
13922   W (ret);
13923   return ret;
13924 }
13925
13926 static int
13927 api_ip_probe_neighbor (vat_main_t * vam)
13928 {
13929   unformat_input_t *i = vam->input;
13930   vl_api_ip_probe_neighbor_t *mp;
13931   vl_api_address_t dst_adr = { };
13932   u8 int_set = 0;
13933   u8 adr_set = 0;
13934   u32 sw_if_index;
13935   int ret;
13936
13937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13938     {
13939       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13940         int_set = 1;
13941       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13942         int_set = 1;
13943       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13944         adr_set = 1;
13945       else
13946         break;
13947     }
13948
13949   if (int_set == 0)
13950     {
13951       errmsg ("missing interface");
13952       return -99;
13953     }
13954
13955   if (adr_set == 0)
13956     {
13957       errmsg ("missing addresses");
13958       return -99;
13959     }
13960
13961   M (IP_PROBE_NEIGHBOR, mp);
13962
13963   mp->sw_if_index = ntohl (sw_if_index);
13964   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13965
13966   S (mp);
13967   W (ret);
13968   return ret;
13969 }
13970
13971 static int
13972 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13973 {
13974   unformat_input_t *i = vam->input;
13975   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13976   u8 mode = IP_SCAN_V46_NEIGHBORS;
13977   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13978   int ret;
13979
13980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13981     {
13982       if (unformat (i, "ip4"))
13983         mode = IP_SCAN_V4_NEIGHBORS;
13984       else if (unformat (i, "ip6"))
13985         mode = IP_SCAN_V6_NEIGHBORS;
13986       if (unformat (i, "both"))
13987         mode = IP_SCAN_V46_NEIGHBORS;
13988       else if (unformat (i, "disable"))
13989         mode = IP_SCAN_DISABLED;
13990       else if (unformat (i, "interval %d", &interval))
13991         ;
13992       else if (unformat (i, "max-time %d", &time))
13993         ;
13994       else if (unformat (i, "max-update %d", &update))
13995         ;
13996       else if (unformat (i, "delay %d", &delay))
13997         ;
13998       else if (unformat (i, "stale %d", &stale))
13999         ;
14000       else
14001         break;
14002     }
14003
14004   if (interval > 255)
14005     {
14006       errmsg ("interval cannot exceed 255 minutes.");
14007       return -99;
14008     }
14009   if (time > 255)
14010     {
14011       errmsg ("max-time cannot exceed 255 usec.");
14012       return -99;
14013     }
14014   if (update > 255)
14015     {
14016       errmsg ("max-update cannot exceed 255.");
14017       return -99;
14018     }
14019   if (delay > 255)
14020     {
14021       errmsg ("delay cannot exceed 255 msec.");
14022       return -99;
14023     }
14024   if (stale > 255)
14025     {
14026       errmsg ("stale cannot exceed 255 minutes.");
14027       return -99;
14028     }
14029
14030   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14031   mp->mode = mode;
14032   mp->scan_interval = interval;
14033   mp->max_proc_time = time;
14034   mp->max_update = update;
14035   mp->scan_int_delay = delay;
14036   mp->stale_threshold = stale;
14037
14038   S (mp);
14039   W (ret);
14040   return ret;
14041 }
14042
14043 static int
14044 api_want_ip4_arp_events (vat_main_t * vam)
14045 {
14046   unformat_input_t *line_input = vam->input;
14047   vl_api_want_ip4_arp_events_t *mp;
14048   ip4_address_t address;
14049   int address_set = 0;
14050   u32 enable_disable = 1;
14051   int ret;
14052
14053   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14054     {
14055       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14056         address_set = 1;
14057       else if (unformat (line_input, "del"))
14058         enable_disable = 0;
14059       else
14060         break;
14061     }
14062
14063   if (address_set == 0)
14064     {
14065       errmsg ("missing addresses");
14066       return -99;
14067     }
14068
14069   M (WANT_IP4_ARP_EVENTS, mp);
14070   mp->enable_disable = enable_disable;
14071   mp->pid = htonl (getpid ());
14072   clib_memcpy (mp->ip, &address, sizeof (address));
14073
14074   S (mp);
14075   W (ret);
14076   return ret;
14077 }
14078
14079 static int
14080 api_want_ip6_nd_events (vat_main_t * vam)
14081 {
14082   unformat_input_t *line_input = vam->input;
14083   vl_api_want_ip6_nd_events_t *mp;
14084   vl_api_ip6_address_t address;
14085   int address_set = 0;
14086   u32 enable_disable = 1;
14087   int ret;
14088
14089   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14090     {
14091       if (unformat
14092           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14093         address_set = 1;
14094       else if (unformat (line_input, "del"))
14095         enable_disable = 0;
14096       else
14097         break;
14098     }
14099
14100   if (address_set == 0)
14101     {
14102       errmsg ("missing addresses");
14103       return -99;
14104     }
14105
14106   M (WANT_IP6_ND_EVENTS, mp);
14107   mp->enable_disable = enable_disable;
14108   mp->pid = htonl (getpid ());
14109   clib_memcpy (&mp->ip, &address, sizeof (address));
14110
14111   S (mp);
14112   W (ret);
14113   return ret;
14114 }
14115
14116 static int
14117 api_want_l2_macs_events (vat_main_t * vam)
14118 {
14119   unformat_input_t *line_input = vam->input;
14120   vl_api_want_l2_macs_events_t *mp;
14121   u8 enable_disable = 1;
14122   u32 scan_delay = 0;
14123   u32 max_macs_in_event = 0;
14124   u32 learn_limit = 0;
14125   int ret;
14126
14127   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14128     {
14129       if (unformat (line_input, "learn-limit %d", &learn_limit))
14130         ;
14131       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14132         ;
14133       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14134         ;
14135       else if (unformat (line_input, "disable"))
14136         enable_disable = 0;
14137       else
14138         break;
14139     }
14140
14141   M (WANT_L2_MACS_EVENTS, mp);
14142   mp->enable_disable = enable_disable;
14143   mp->pid = htonl (getpid ());
14144   mp->learn_limit = htonl (learn_limit);
14145   mp->scan_delay = (u8) scan_delay;
14146   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14147   S (mp);
14148   W (ret);
14149   return ret;
14150 }
14151
14152 static int
14153 api_input_acl_set_interface (vat_main_t * vam)
14154 {
14155   unformat_input_t *i = vam->input;
14156   vl_api_input_acl_set_interface_t *mp;
14157   u32 sw_if_index;
14158   int sw_if_index_set;
14159   u32 ip4_table_index = ~0;
14160   u32 ip6_table_index = ~0;
14161   u32 l2_table_index = ~0;
14162   u8 is_add = 1;
14163   int ret;
14164
14165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14166     {
14167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14168         sw_if_index_set = 1;
14169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14170         sw_if_index_set = 1;
14171       else if (unformat (i, "del"))
14172         is_add = 0;
14173       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14174         ;
14175       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14176         ;
14177       else if (unformat (i, "l2-table %d", &l2_table_index))
14178         ;
14179       else
14180         {
14181           clib_warning ("parse error '%U'", format_unformat_error, i);
14182           return -99;
14183         }
14184     }
14185
14186   if (sw_if_index_set == 0)
14187     {
14188       errmsg ("missing interface name or sw_if_index");
14189       return -99;
14190     }
14191
14192   M (INPUT_ACL_SET_INTERFACE, mp);
14193
14194   mp->sw_if_index = ntohl (sw_if_index);
14195   mp->ip4_table_index = ntohl (ip4_table_index);
14196   mp->ip6_table_index = ntohl (ip6_table_index);
14197   mp->l2_table_index = ntohl (l2_table_index);
14198   mp->is_add = is_add;
14199
14200   S (mp);
14201   W (ret);
14202   return ret;
14203 }
14204
14205 static int
14206 api_output_acl_set_interface (vat_main_t * vam)
14207 {
14208   unformat_input_t *i = vam->input;
14209   vl_api_output_acl_set_interface_t *mp;
14210   u32 sw_if_index;
14211   int sw_if_index_set;
14212   u32 ip4_table_index = ~0;
14213   u32 ip6_table_index = ~0;
14214   u32 l2_table_index = ~0;
14215   u8 is_add = 1;
14216   int ret;
14217
14218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14219     {
14220       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14221         sw_if_index_set = 1;
14222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14223         sw_if_index_set = 1;
14224       else if (unformat (i, "del"))
14225         is_add = 0;
14226       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14227         ;
14228       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14229         ;
14230       else if (unformat (i, "l2-table %d", &l2_table_index))
14231         ;
14232       else
14233         {
14234           clib_warning ("parse error '%U'", format_unformat_error, i);
14235           return -99;
14236         }
14237     }
14238
14239   if (sw_if_index_set == 0)
14240     {
14241       errmsg ("missing interface name or sw_if_index");
14242       return -99;
14243     }
14244
14245   M (OUTPUT_ACL_SET_INTERFACE, mp);
14246
14247   mp->sw_if_index = ntohl (sw_if_index);
14248   mp->ip4_table_index = ntohl (ip4_table_index);
14249   mp->ip6_table_index = ntohl (ip6_table_index);
14250   mp->l2_table_index = ntohl (l2_table_index);
14251   mp->is_add = is_add;
14252
14253   S (mp);
14254   W (ret);
14255   return ret;
14256 }
14257
14258 static int
14259 api_ip_address_dump (vat_main_t * vam)
14260 {
14261   unformat_input_t *i = vam->input;
14262   vl_api_ip_address_dump_t *mp;
14263   vl_api_control_ping_t *mp_ping;
14264   u32 sw_if_index = ~0;
14265   u8 sw_if_index_set = 0;
14266   u8 ipv4_set = 0;
14267   u8 ipv6_set = 0;
14268   int ret;
14269
14270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14271     {
14272       if (unformat (i, "sw_if_index %d", &sw_if_index))
14273         sw_if_index_set = 1;
14274       else
14275         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14276         sw_if_index_set = 1;
14277       else if (unformat (i, "ipv4"))
14278         ipv4_set = 1;
14279       else if (unformat (i, "ipv6"))
14280         ipv6_set = 1;
14281       else
14282         break;
14283     }
14284
14285   if (ipv4_set && ipv6_set)
14286     {
14287       errmsg ("ipv4 and ipv6 flags cannot be both set");
14288       return -99;
14289     }
14290
14291   if ((!ipv4_set) && (!ipv6_set))
14292     {
14293       errmsg ("no ipv4 nor ipv6 flag set");
14294       return -99;
14295     }
14296
14297   if (sw_if_index_set == 0)
14298     {
14299       errmsg ("missing interface name or sw_if_index");
14300       return -99;
14301     }
14302
14303   vam->current_sw_if_index = sw_if_index;
14304   vam->is_ipv6 = ipv6_set;
14305
14306   M (IP_ADDRESS_DUMP, mp);
14307   mp->sw_if_index = ntohl (sw_if_index);
14308   mp->is_ipv6 = ipv6_set;
14309   S (mp);
14310
14311   /* Use a control ping for synchronization */
14312   MPING (CONTROL_PING, mp_ping);
14313   S (mp_ping);
14314
14315   W (ret);
14316   return ret;
14317 }
14318
14319 static int
14320 api_ip_dump (vat_main_t * vam)
14321 {
14322   vl_api_ip_dump_t *mp;
14323   vl_api_control_ping_t *mp_ping;
14324   unformat_input_t *in = vam->input;
14325   int ipv4_set = 0;
14326   int ipv6_set = 0;
14327   int is_ipv6;
14328   int i;
14329   int ret;
14330
14331   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14332     {
14333       if (unformat (in, "ipv4"))
14334         ipv4_set = 1;
14335       else if (unformat (in, "ipv6"))
14336         ipv6_set = 1;
14337       else
14338         break;
14339     }
14340
14341   if (ipv4_set && ipv6_set)
14342     {
14343       errmsg ("ipv4 and ipv6 flags cannot be both set");
14344       return -99;
14345     }
14346
14347   if ((!ipv4_set) && (!ipv6_set))
14348     {
14349       errmsg ("no ipv4 nor ipv6 flag set");
14350       return -99;
14351     }
14352
14353   is_ipv6 = ipv6_set;
14354   vam->is_ipv6 = is_ipv6;
14355
14356   /* free old data */
14357   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14358     {
14359       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14360     }
14361   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14362
14363   M (IP_DUMP, mp);
14364   mp->is_ipv6 = ipv6_set;
14365   S (mp);
14366
14367   /* Use a control ping for synchronization */
14368   MPING (CONTROL_PING, mp_ping);
14369   S (mp_ping);
14370
14371   W (ret);
14372   return ret;
14373 }
14374
14375 static int
14376 api_ipsec_spd_add_del (vat_main_t * vam)
14377 {
14378   unformat_input_t *i = vam->input;
14379   vl_api_ipsec_spd_add_del_t *mp;
14380   u32 spd_id = ~0;
14381   u8 is_add = 1;
14382   int ret;
14383
14384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14385     {
14386       if (unformat (i, "spd_id %d", &spd_id))
14387         ;
14388       else if (unformat (i, "del"))
14389         is_add = 0;
14390       else
14391         {
14392           clib_warning ("parse error '%U'", format_unformat_error, i);
14393           return -99;
14394         }
14395     }
14396   if (spd_id == ~0)
14397     {
14398       errmsg ("spd_id must be set");
14399       return -99;
14400     }
14401
14402   M (IPSEC_SPD_ADD_DEL, mp);
14403
14404   mp->spd_id = ntohl (spd_id);
14405   mp->is_add = is_add;
14406
14407   S (mp);
14408   W (ret);
14409   return ret;
14410 }
14411
14412 static int
14413 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14414 {
14415   unformat_input_t *i = vam->input;
14416   vl_api_ipsec_interface_add_del_spd_t *mp;
14417   u32 sw_if_index;
14418   u8 sw_if_index_set = 0;
14419   u32 spd_id = (u32) ~ 0;
14420   u8 is_add = 1;
14421   int ret;
14422
14423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14424     {
14425       if (unformat (i, "del"))
14426         is_add = 0;
14427       else if (unformat (i, "spd_id %d", &spd_id))
14428         ;
14429       else
14430         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14431         sw_if_index_set = 1;
14432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14433         sw_if_index_set = 1;
14434       else
14435         {
14436           clib_warning ("parse error '%U'", format_unformat_error, i);
14437           return -99;
14438         }
14439
14440     }
14441
14442   if (spd_id == (u32) ~ 0)
14443     {
14444       errmsg ("spd_id must be set");
14445       return -99;
14446     }
14447
14448   if (sw_if_index_set == 0)
14449     {
14450       errmsg ("missing interface name or sw_if_index");
14451       return -99;
14452     }
14453
14454   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14455
14456   mp->spd_id = ntohl (spd_id);
14457   mp->sw_if_index = ntohl (sw_if_index);
14458   mp->is_add = is_add;
14459
14460   S (mp);
14461   W (ret);
14462   return ret;
14463 }
14464
14465 static int
14466 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14467 {
14468   unformat_input_t *i = vam->input;
14469   vl_api_ipsec_spd_entry_add_del_t *mp;
14470   u8 is_add = 1, is_outbound = 0;
14471   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14472   i32 priority = 0;
14473   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14474   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14475   vl_api_address_t laddr_start = { }, laddr_stop =
14476   {
14477   }, raddr_start =
14478   {
14479   }, raddr_stop =
14480   {
14481   };
14482   int ret;
14483
14484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14485     {
14486       if (unformat (i, "del"))
14487         is_add = 0;
14488       if (unformat (i, "outbound"))
14489         is_outbound = 1;
14490       if (unformat (i, "inbound"))
14491         is_outbound = 0;
14492       else if (unformat (i, "spd_id %d", &spd_id))
14493         ;
14494       else if (unformat (i, "sa_id %d", &sa_id))
14495         ;
14496       else if (unformat (i, "priority %d", &priority))
14497         ;
14498       else if (unformat (i, "protocol %d", &protocol))
14499         ;
14500       else if (unformat (i, "lport_start %d", &lport_start))
14501         ;
14502       else if (unformat (i, "lport_stop %d", &lport_stop))
14503         ;
14504       else if (unformat (i, "rport_start %d", &rport_start))
14505         ;
14506       else if (unformat (i, "rport_stop %d", &rport_stop))
14507         ;
14508       else if (unformat (i, "laddr_start %U",
14509                          unformat_vl_api_address, &laddr_start))
14510         ;
14511       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14512                          &laddr_stop))
14513         ;
14514       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14515                          &raddr_start))
14516         ;
14517       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14518                          &raddr_stop))
14519         ;
14520       else
14521         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14522         {
14523           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14524             {
14525               clib_warning ("unsupported action: 'resolve'");
14526               return -99;
14527             }
14528         }
14529       else
14530         {
14531           clib_warning ("parse error '%U'", format_unformat_error, i);
14532           return -99;
14533         }
14534
14535     }
14536
14537   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14538
14539   mp->is_add = is_add;
14540
14541   mp->entry.spd_id = ntohl (spd_id);
14542   mp->entry.priority = ntohl (priority);
14543   mp->entry.is_outbound = is_outbound;
14544
14545   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14546                sizeof (vl_api_address_t));
14547   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14548                sizeof (vl_api_address_t));
14549   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14550                sizeof (vl_api_address_t));
14551   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14552                sizeof (vl_api_address_t));
14553
14554   mp->entry.protocol = (u8) protocol;
14555   mp->entry.local_port_start = ntohs ((u16) lport_start);
14556   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14557   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14558   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14559   mp->entry.policy = (u8) policy;
14560   mp->entry.sa_id = ntohl (sa_id);
14561
14562   S (mp);
14563   W (ret);
14564   return ret;
14565 }
14566
14567 static int
14568 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14569 {
14570   unformat_input_t *i = vam->input;
14571   vl_api_ipsec_sad_entry_add_del_t *mp;
14572   u32 sad_id = 0, spi = 0;
14573   u8 *ck = 0, *ik = 0;
14574   u8 is_add = 1;
14575
14576   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14577   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14578   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14579   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14580   vl_api_address_t tun_src, tun_dst;
14581   int ret;
14582
14583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14584     {
14585       if (unformat (i, "del"))
14586         is_add = 0;
14587       else if (unformat (i, "sad_id %d", &sad_id))
14588         ;
14589       else if (unformat (i, "spi %d", &spi))
14590         ;
14591       else if (unformat (i, "esp"))
14592         protocol = IPSEC_API_PROTO_ESP;
14593       else
14594         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14595         {
14596           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14597           if (ADDRESS_IP6 == tun_src.af)
14598             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14599         }
14600       else
14601         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14602         {
14603           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14604           if (ADDRESS_IP6 == tun_src.af)
14605             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14606         }
14607       else
14608         if (unformat (i, "crypto_alg %U",
14609                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14610         ;
14611       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14612         ;
14613       else if (unformat (i, "integ_alg %U",
14614                          unformat_ipsec_api_integ_alg, &integ_alg))
14615         ;
14616       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14617         ;
14618       else
14619         {
14620           clib_warning ("parse error '%U'", format_unformat_error, i);
14621           return -99;
14622         }
14623
14624     }
14625
14626   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14627
14628   mp->is_add = is_add;
14629   mp->entry.sad_id = ntohl (sad_id);
14630   mp->entry.protocol = protocol;
14631   mp->entry.spi = ntohl (spi);
14632   mp->entry.flags = flags;
14633
14634   mp->entry.crypto_algorithm = crypto_alg;
14635   mp->entry.integrity_algorithm = integ_alg;
14636   mp->entry.crypto_key.length = vec_len (ck);
14637   mp->entry.integrity_key.length = vec_len (ik);
14638
14639   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14640     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14641
14642   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14643     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14644
14645   if (ck)
14646     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14647   if (ik)
14648     clib_memcpy (mp->entry.integrity_key.data, ik,
14649                  mp->entry.integrity_key.length);
14650
14651   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14652     {
14653       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14654                    sizeof (mp->entry.tunnel_src));
14655       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14656                    sizeof (mp->entry.tunnel_dst));
14657     }
14658
14659   S (mp);
14660   W (ret);
14661   return ret;
14662 }
14663
14664 static int
14665 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14666 {
14667   unformat_input_t *i = vam->input;
14668   vl_api_ipsec_tunnel_if_add_del_t *mp;
14669   u32 local_spi = 0, remote_spi = 0;
14670   u32 crypto_alg = 0, integ_alg = 0;
14671   u8 *lck = NULL, *rck = NULL;
14672   u8 *lik = NULL, *rik = NULL;
14673   vl_api_address_t local_ip = { 0 };
14674   vl_api_address_t remote_ip = { 0 };
14675   f64 before = 0;
14676   u8 is_add = 1;
14677   u8 esn = 0;
14678   u8 anti_replay = 0;
14679   u8 renumber = 0;
14680   u32 instance = ~0;
14681   u32 count = 1, jj;
14682   int ret = -1;
14683
14684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14685     {
14686       if (unformat (i, "del"))
14687         is_add = 0;
14688       else if (unformat (i, "esn"))
14689         esn = 1;
14690       else if (unformat (i, "anti-replay"))
14691         anti_replay = 1;
14692       else if (unformat (i, "count %d", &count))
14693         ;
14694       else if (unformat (i, "local_spi %d", &local_spi))
14695         ;
14696       else if (unformat (i, "remote_spi %d", &remote_spi))
14697         ;
14698       else
14699         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14700         ;
14701       else
14702         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14703         ;
14704       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14705         ;
14706       else
14707         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14708         ;
14709       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14710         ;
14711       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14712         ;
14713       else
14714         if (unformat
14715             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14716         {
14717           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14718             {
14719               errmsg ("unsupported crypto-alg: '%U'\n",
14720                       format_ipsec_crypto_alg, crypto_alg);
14721               return -99;
14722             }
14723         }
14724       else
14725         if (unformat
14726             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14727         {
14728           if (integ_alg >= IPSEC_INTEG_N_ALG)
14729             {
14730               errmsg ("unsupported integ-alg: '%U'\n",
14731                       format_ipsec_integ_alg, integ_alg);
14732               return -99;
14733             }
14734         }
14735       else if (unformat (i, "instance %u", &instance))
14736         renumber = 1;
14737       else
14738         {
14739           errmsg ("parse error '%U'\n", format_unformat_error, i);
14740           return -99;
14741         }
14742     }
14743
14744   if (count > 1)
14745     {
14746       /* Turn on async mode */
14747       vam->async_mode = 1;
14748       vam->async_errors = 0;
14749       before = vat_time_now (vam);
14750     }
14751
14752   for (jj = 0; jj < count; jj++)
14753     {
14754       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14755
14756       mp->is_add = is_add;
14757       mp->esn = esn;
14758       mp->anti_replay = anti_replay;
14759
14760       if (jj > 0)
14761         increment_address (&remote_ip);
14762
14763       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14764       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14765
14766       mp->local_spi = htonl (local_spi + jj);
14767       mp->remote_spi = htonl (remote_spi + jj);
14768       mp->crypto_alg = (u8) crypto_alg;
14769
14770       mp->local_crypto_key_len = 0;
14771       if (lck)
14772         {
14773           mp->local_crypto_key_len = vec_len (lck);
14774           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14775             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14776           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14777         }
14778
14779       mp->remote_crypto_key_len = 0;
14780       if (rck)
14781         {
14782           mp->remote_crypto_key_len = vec_len (rck);
14783           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14784             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14785           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14786         }
14787
14788       mp->integ_alg = (u8) integ_alg;
14789
14790       mp->local_integ_key_len = 0;
14791       if (lik)
14792         {
14793           mp->local_integ_key_len = vec_len (lik);
14794           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14795             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14796           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14797         }
14798
14799       mp->remote_integ_key_len = 0;
14800       if (rik)
14801         {
14802           mp->remote_integ_key_len = vec_len (rik);
14803           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14804             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14805           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14806         }
14807
14808       if (renumber)
14809         {
14810           mp->renumber = renumber;
14811           mp->show_instance = ntohl (instance);
14812         }
14813       S (mp);
14814     }
14815
14816   /* When testing multiple add/del ops, use a control-ping to sync */
14817   if (count > 1)
14818     {
14819       vl_api_control_ping_t *mp_ping;
14820       f64 after;
14821       f64 timeout;
14822
14823       /* Shut off async mode */
14824       vam->async_mode = 0;
14825
14826       MPING (CONTROL_PING, mp_ping);
14827       S (mp_ping);
14828
14829       timeout = vat_time_now (vam) + 1.0;
14830       while (vat_time_now (vam) < timeout)
14831         if (vam->result_ready == 1)
14832           goto out;
14833       vam->retval = -99;
14834
14835     out:
14836       if (vam->retval == -99)
14837         errmsg ("timeout");
14838
14839       if (vam->async_errors > 0)
14840         {
14841           errmsg ("%d asynchronous errors", vam->async_errors);
14842           vam->retval = -98;
14843         }
14844       vam->async_errors = 0;
14845       after = vat_time_now (vam);
14846
14847       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14848       if (jj > 0)
14849         count = jj;
14850
14851       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14852              count, after - before, count / (after - before));
14853     }
14854   else
14855     {
14856       /* Wait for a reply... */
14857       W (ret);
14858       return ret;
14859     }
14860
14861   return ret;
14862 }
14863
14864 static void
14865 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14866 {
14867   vat_main_t *vam = &vat_main;
14868
14869   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14870          "crypto_key %U integ_alg %u integ_key %U flags %x "
14871          "tunnel_src_addr %U tunnel_dst_addr %U "
14872          "salt %u seq_outbound %lu last_seq_inbound %lu "
14873          "replay_window %lu\n",
14874          ntohl (mp->entry.sad_id),
14875          ntohl (mp->sw_if_index),
14876          ntohl (mp->entry.spi),
14877          ntohl (mp->entry.protocol),
14878          ntohl (mp->entry.crypto_algorithm),
14879          format_hex_bytes, mp->entry.crypto_key.data,
14880          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14881          format_hex_bytes, mp->entry.integrity_key.data,
14882          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14883          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14884          &mp->entry.tunnel_dst, ntohl (mp->salt),
14885          clib_net_to_host_u64 (mp->seq_outbound),
14886          clib_net_to_host_u64 (mp->last_seq_inbound),
14887          clib_net_to_host_u64 (mp->replay_window));
14888 }
14889
14890 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14891 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14892
14893 static void vl_api_ipsec_sa_details_t_handler_json
14894   (vl_api_ipsec_sa_details_t * mp)
14895 {
14896   vat_main_t *vam = &vat_main;
14897   vat_json_node_t *node = NULL;
14898   vl_api_ipsec_sad_flags_t flags;
14899
14900   if (VAT_JSON_ARRAY != vam->json_tree.type)
14901     {
14902       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14903       vat_json_init_array (&vam->json_tree);
14904     }
14905   node = vat_json_array_add (&vam->json_tree);
14906
14907   vat_json_init_object (node);
14908   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14909   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14910   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14911   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14912   vat_json_object_add_uint (node, "crypto_alg",
14913                             ntohl (mp->entry.crypto_algorithm));
14914   vat_json_object_add_uint (node, "integ_alg",
14915                             ntohl (mp->entry.integrity_algorithm));
14916   flags = ntohl (mp->entry.flags);
14917   vat_json_object_add_uint (node, "use_esn",
14918                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14919   vat_json_object_add_uint (node, "use_anti_replay",
14920                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14921   vat_json_object_add_uint (node, "is_tunnel",
14922                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14923   vat_json_object_add_uint (node, "is_tunnel_ip6",
14924                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14925   vat_json_object_add_uint (node, "udp_encap",
14926                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14927   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14928                              mp->entry.crypto_key.length);
14929   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14930                              mp->entry.integrity_key.length);
14931   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14932   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14933   vat_json_object_add_uint (node, "replay_window",
14934                             clib_net_to_host_u64 (mp->replay_window));
14935 }
14936
14937 static int
14938 api_ipsec_sa_dump (vat_main_t * vam)
14939 {
14940   unformat_input_t *i = vam->input;
14941   vl_api_ipsec_sa_dump_t *mp;
14942   vl_api_control_ping_t *mp_ping;
14943   u32 sa_id = ~0;
14944   int ret;
14945
14946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14947     {
14948       if (unformat (i, "sa_id %d", &sa_id))
14949         ;
14950       else
14951         {
14952           clib_warning ("parse error '%U'", format_unformat_error, i);
14953           return -99;
14954         }
14955     }
14956
14957   M (IPSEC_SA_DUMP, mp);
14958
14959   mp->sa_id = ntohl (sa_id);
14960
14961   S (mp);
14962
14963   /* Use a control ping for synchronization */
14964   M (CONTROL_PING, mp_ping);
14965   S (mp_ping);
14966
14967   W (ret);
14968   return ret;
14969 }
14970
14971 static int
14972 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14973 {
14974   unformat_input_t *i = vam->input;
14975   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14976   u32 sw_if_index = ~0;
14977   u32 sa_id = ~0;
14978   u8 is_outbound = (u8) ~ 0;
14979   int ret;
14980
14981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14982     {
14983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14984         ;
14985       else if (unformat (i, "sa_id %d", &sa_id))
14986         ;
14987       else if (unformat (i, "outbound"))
14988         is_outbound = 1;
14989       else if (unformat (i, "inbound"))
14990         is_outbound = 0;
14991       else
14992         {
14993           clib_warning ("parse error '%U'", format_unformat_error, i);
14994           return -99;
14995         }
14996     }
14997
14998   if (sw_if_index == ~0)
14999     {
15000       errmsg ("interface must be specified");
15001       return -99;
15002     }
15003
15004   if (sa_id == ~0)
15005     {
15006       errmsg ("SA ID must be specified");
15007       return -99;
15008     }
15009
15010   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15011
15012   mp->sw_if_index = htonl (sw_if_index);
15013   mp->sa_id = htonl (sa_id);
15014   mp->is_outbound = is_outbound;
15015
15016   S (mp);
15017   W (ret);
15018
15019   return ret;
15020 }
15021
15022 static int
15023 api_get_first_msg_id (vat_main_t * vam)
15024 {
15025   vl_api_get_first_msg_id_t *mp;
15026   unformat_input_t *i = vam->input;
15027   u8 *name;
15028   u8 name_set = 0;
15029   int ret;
15030
15031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15032     {
15033       if (unformat (i, "client %s", &name))
15034         name_set = 1;
15035       else
15036         break;
15037     }
15038
15039   if (name_set == 0)
15040     {
15041       errmsg ("missing client name");
15042       return -99;
15043     }
15044   vec_add1 (name, 0);
15045
15046   if (vec_len (name) > 63)
15047     {
15048       errmsg ("client name too long");
15049       return -99;
15050     }
15051
15052   M (GET_FIRST_MSG_ID, mp);
15053   clib_memcpy (mp->name, name, vec_len (name));
15054   S (mp);
15055   W (ret);
15056   return ret;
15057 }
15058
15059 static int
15060 api_cop_interface_enable_disable (vat_main_t * vam)
15061 {
15062   unformat_input_t *line_input = vam->input;
15063   vl_api_cop_interface_enable_disable_t *mp;
15064   u32 sw_if_index = ~0;
15065   u8 enable_disable = 1;
15066   int ret;
15067
15068   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15069     {
15070       if (unformat (line_input, "disable"))
15071         enable_disable = 0;
15072       if (unformat (line_input, "enable"))
15073         enable_disable = 1;
15074       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15075                          vam, &sw_if_index))
15076         ;
15077       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15078         ;
15079       else
15080         break;
15081     }
15082
15083   if (sw_if_index == ~0)
15084     {
15085       errmsg ("missing interface name or sw_if_index");
15086       return -99;
15087     }
15088
15089   /* Construct the API message */
15090   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15091   mp->sw_if_index = ntohl (sw_if_index);
15092   mp->enable_disable = enable_disable;
15093
15094   /* send it... */
15095   S (mp);
15096   /* Wait for the reply */
15097   W (ret);
15098   return ret;
15099 }
15100
15101 static int
15102 api_cop_whitelist_enable_disable (vat_main_t * vam)
15103 {
15104   unformat_input_t *line_input = vam->input;
15105   vl_api_cop_whitelist_enable_disable_t *mp;
15106   u32 sw_if_index = ~0;
15107   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15108   u32 fib_id = 0;
15109   int ret;
15110
15111   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15112     {
15113       if (unformat (line_input, "ip4"))
15114         ip4 = 1;
15115       else if (unformat (line_input, "ip6"))
15116         ip6 = 1;
15117       else if (unformat (line_input, "default"))
15118         default_cop = 1;
15119       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15120                          vam, &sw_if_index))
15121         ;
15122       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15123         ;
15124       else if (unformat (line_input, "fib-id %d", &fib_id))
15125         ;
15126       else
15127         break;
15128     }
15129
15130   if (sw_if_index == ~0)
15131     {
15132       errmsg ("missing interface name or sw_if_index");
15133       return -99;
15134     }
15135
15136   /* Construct the API message */
15137   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15138   mp->sw_if_index = ntohl (sw_if_index);
15139   mp->fib_id = ntohl (fib_id);
15140   mp->ip4 = ip4;
15141   mp->ip6 = ip6;
15142   mp->default_cop = default_cop;
15143
15144   /* send it... */
15145   S (mp);
15146   /* Wait for the reply */
15147   W (ret);
15148   return ret;
15149 }
15150
15151 static int
15152 api_get_node_graph (vat_main_t * vam)
15153 {
15154   vl_api_get_node_graph_t *mp;
15155   int ret;
15156
15157   M (GET_NODE_GRAPH, mp);
15158
15159   /* send it... */
15160   S (mp);
15161   /* Wait for the reply */
15162   W (ret);
15163   return ret;
15164 }
15165
15166 /* *INDENT-OFF* */
15167 /** Used for parsing LISP eids */
15168 typedef CLIB_PACKED(struct{
15169   u8 addr[16];   /**< eid address */
15170   u32 len;       /**< prefix length if IP */
15171   u8 type;      /**< type of eid */
15172 }) lisp_eid_vat_t;
15173 /* *INDENT-ON* */
15174
15175 static uword
15176 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15177 {
15178   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15179
15180   clib_memset (a, 0, sizeof (a[0]));
15181
15182   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15183     {
15184       a->type = 0;              /* ipv4 type */
15185     }
15186   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15187     {
15188       a->type = 1;              /* ipv6 type */
15189     }
15190   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15191     {
15192       a->type = 2;              /* mac type */
15193     }
15194   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15195     {
15196       a->type = 3;              /* NSH type */
15197       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15198       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15199     }
15200   else
15201     {
15202       return 0;
15203     }
15204
15205   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15206     {
15207       return 0;
15208     }
15209
15210   return 1;
15211 }
15212
15213 static int
15214 lisp_eid_size_vat (u8 type)
15215 {
15216   switch (type)
15217     {
15218     case 0:
15219       return 4;
15220     case 1:
15221       return 16;
15222     case 2:
15223       return 6;
15224     case 3:
15225       return 5;
15226     }
15227   return 0;
15228 }
15229
15230 static void
15231 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15232 {
15233   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15234 }
15235
15236 static int
15237 api_one_add_del_locator_set (vat_main_t * vam)
15238 {
15239   unformat_input_t *input = vam->input;
15240   vl_api_one_add_del_locator_set_t *mp;
15241   u8 is_add = 1;
15242   u8 *locator_set_name = NULL;
15243   u8 locator_set_name_set = 0;
15244   vl_api_local_locator_t locator, *locators = 0;
15245   u32 sw_if_index, priority, weight;
15246   u32 data_len = 0;
15247
15248   int ret;
15249   /* Parse args required to build the message */
15250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15251     {
15252       if (unformat (input, "del"))
15253         {
15254           is_add = 0;
15255         }
15256       else if (unformat (input, "locator-set %s", &locator_set_name))
15257         {
15258           locator_set_name_set = 1;
15259         }
15260       else if (unformat (input, "sw_if_index %u p %u w %u",
15261                          &sw_if_index, &priority, &weight))
15262         {
15263           locator.sw_if_index = htonl (sw_if_index);
15264           locator.priority = priority;
15265           locator.weight = weight;
15266           vec_add1 (locators, locator);
15267         }
15268       else
15269         if (unformat
15270             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15271              &sw_if_index, &priority, &weight))
15272         {
15273           locator.sw_if_index = htonl (sw_if_index);
15274           locator.priority = priority;
15275           locator.weight = weight;
15276           vec_add1 (locators, locator);
15277         }
15278       else
15279         break;
15280     }
15281
15282   if (locator_set_name_set == 0)
15283     {
15284       errmsg ("missing locator-set name");
15285       vec_free (locators);
15286       return -99;
15287     }
15288
15289   if (vec_len (locator_set_name) > 64)
15290     {
15291       errmsg ("locator-set name too long");
15292       vec_free (locator_set_name);
15293       vec_free (locators);
15294       return -99;
15295     }
15296   vec_add1 (locator_set_name, 0);
15297
15298   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15299
15300   /* Construct the API message */
15301   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15302
15303   mp->is_add = is_add;
15304   clib_memcpy (mp->locator_set_name, locator_set_name,
15305                vec_len (locator_set_name));
15306   vec_free (locator_set_name);
15307
15308   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15309   if (locators)
15310     clib_memcpy (mp->locators, locators, data_len);
15311   vec_free (locators);
15312
15313   /* send it... */
15314   S (mp);
15315
15316   /* Wait for a reply... */
15317   W (ret);
15318   return ret;
15319 }
15320
15321 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15322
15323 static int
15324 api_one_add_del_locator (vat_main_t * vam)
15325 {
15326   unformat_input_t *input = vam->input;
15327   vl_api_one_add_del_locator_t *mp;
15328   u32 tmp_if_index = ~0;
15329   u32 sw_if_index = ~0;
15330   u8 sw_if_index_set = 0;
15331   u8 sw_if_index_if_name_set = 0;
15332   u32 priority = ~0;
15333   u8 priority_set = 0;
15334   u32 weight = ~0;
15335   u8 weight_set = 0;
15336   u8 is_add = 1;
15337   u8 *locator_set_name = NULL;
15338   u8 locator_set_name_set = 0;
15339   int ret;
15340
15341   /* Parse args required to build the message */
15342   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15343     {
15344       if (unformat (input, "del"))
15345         {
15346           is_add = 0;
15347         }
15348       else if (unformat (input, "locator-set %s", &locator_set_name))
15349         {
15350           locator_set_name_set = 1;
15351         }
15352       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15353                          &tmp_if_index))
15354         {
15355           sw_if_index_if_name_set = 1;
15356           sw_if_index = tmp_if_index;
15357         }
15358       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15359         {
15360           sw_if_index_set = 1;
15361           sw_if_index = tmp_if_index;
15362         }
15363       else if (unformat (input, "p %d", &priority))
15364         {
15365           priority_set = 1;
15366         }
15367       else if (unformat (input, "w %d", &weight))
15368         {
15369           weight_set = 1;
15370         }
15371       else
15372         break;
15373     }
15374
15375   if (locator_set_name_set == 0)
15376     {
15377       errmsg ("missing locator-set name");
15378       return -99;
15379     }
15380
15381   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15382     {
15383       errmsg ("missing sw_if_index");
15384       vec_free (locator_set_name);
15385       return -99;
15386     }
15387
15388   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15389     {
15390       errmsg ("cannot use both params interface name and sw_if_index");
15391       vec_free (locator_set_name);
15392       return -99;
15393     }
15394
15395   if (priority_set == 0)
15396     {
15397       errmsg ("missing locator-set priority");
15398       vec_free (locator_set_name);
15399       return -99;
15400     }
15401
15402   if (weight_set == 0)
15403     {
15404       errmsg ("missing locator-set weight");
15405       vec_free (locator_set_name);
15406       return -99;
15407     }
15408
15409   if (vec_len (locator_set_name) > 64)
15410     {
15411       errmsg ("locator-set name too long");
15412       vec_free (locator_set_name);
15413       return -99;
15414     }
15415   vec_add1 (locator_set_name, 0);
15416
15417   /* Construct the API message */
15418   M (ONE_ADD_DEL_LOCATOR, mp);
15419
15420   mp->is_add = is_add;
15421   mp->sw_if_index = ntohl (sw_if_index);
15422   mp->priority = priority;
15423   mp->weight = weight;
15424   clib_memcpy (mp->locator_set_name, locator_set_name,
15425                vec_len (locator_set_name));
15426   vec_free (locator_set_name);
15427
15428   /* send it... */
15429   S (mp);
15430
15431   /* Wait for a reply... */
15432   W (ret);
15433   return ret;
15434 }
15435
15436 #define api_lisp_add_del_locator api_one_add_del_locator
15437
15438 uword
15439 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15440 {
15441   u32 *key_id = va_arg (*args, u32 *);
15442   u8 *s = 0;
15443
15444   if (unformat (input, "%s", &s))
15445     {
15446       if (!strcmp ((char *) s, "sha1"))
15447         key_id[0] = HMAC_SHA_1_96;
15448       else if (!strcmp ((char *) s, "sha256"))
15449         key_id[0] = HMAC_SHA_256_128;
15450       else
15451         {
15452           clib_warning ("invalid key_id: '%s'", s);
15453           key_id[0] = HMAC_NO_KEY;
15454         }
15455     }
15456   else
15457     return 0;
15458
15459   vec_free (s);
15460   return 1;
15461 }
15462
15463 static int
15464 api_one_add_del_local_eid (vat_main_t * vam)
15465 {
15466   unformat_input_t *input = vam->input;
15467   vl_api_one_add_del_local_eid_t *mp;
15468   u8 is_add = 1;
15469   u8 eid_set = 0;
15470   lisp_eid_vat_t _eid, *eid = &_eid;
15471   u8 *locator_set_name = 0;
15472   u8 locator_set_name_set = 0;
15473   u32 vni = 0;
15474   u16 key_id = 0;
15475   u8 *key = 0;
15476   int ret;
15477
15478   /* Parse args required to build the message */
15479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15480     {
15481       if (unformat (input, "del"))
15482         {
15483           is_add = 0;
15484         }
15485       else if (unformat (input, "vni %d", &vni))
15486         {
15487           ;
15488         }
15489       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15490         {
15491           eid_set = 1;
15492         }
15493       else if (unformat (input, "locator-set %s", &locator_set_name))
15494         {
15495           locator_set_name_set = 1;
15496         }
15497       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15498         ;
15499       else if (unformat (input, "secret-key %_%v%_", &key))
15500         ;
15501       else
15502         break;
15503     }
15504
15505   if (locator_set_name_set == 0)
15506     {
15507       errmsg ("missing locator-set name");
15508       return -99;
15509     }
15510
15511   if (0 == eid_set)
15512     {
15513       errmsg ("EID address not set!");
15514       vec_free (locator_set_name);
15515       return -99;
15516     }
15517
15518   if (key && (0 == key_id))
15519     {
15520       errmsg ("invalid key_id!");
15521       return -99;
15522     }
15523
15524   if (vec_len (key) > 64)
15525     {
15526       errmsg ("key too long");
15527       vec_free (key);
15528       return -99;
15529     }
15530
15531   if (vec_len (locator_set_name) > 64)
15532     {
15533       errmsg ("locator-set name too long");
15534       vec_free (locator_set_name);
15535       return -99;
15536     }
15537   vec_add1 (locator_set_name, 0);
15538
15539   /* Construct the API message */
15540   M (ONE_ADD_DEL_LOCAL_EID, mp);
15541
15542   mp->is_add = is_add;
15543   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15544   mp->eid_type = eid->type;
15545   mp->prefix_len = eid->len;
15546   mp->vni = clib_host_to_net_u32 (vni);
15547   mp->key_id = clib_host_to_net_u16 (key_id);
15548   clib_memcpy (mp->locator_set_name, locator_set_name,
15549                vec_len (locator_set_name));
15550   clib_memcpy (mp->key, key, vec_len (key));
15551
15552   vec_free (locator_set_name);
15553   vec_free (key);
15554
15555   /* send it... */
15556   S (mp);
15557
15558   /* Wait for a reply... */
15559   W (ret);
15560   return ret;
15561 }
15562
15563 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15564
15565 static int
15566 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15567 {
15568   u32 dp_table = 0, vni = 0;;
15569   unformat_input_t *input = vam->input;
15570   vl_api_gpe_add_del_fwd_entry_t *mp;
15571   u8 is_add = 1;
15572   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15573   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15574   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15575   u32 action = ~0, w;
15576   ip4_address_t rmt_rloc4, lcl_rloc4;
15577   ip6_address_t rmt_rloc6, lcl_rloc6;
15578   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15579   int ret;
15580
15581   clib_memset (&rloc, 0, sizeof (rloc));
15582
15583   /* Parse args required to build the message */
15584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15585     {
15586       if (unformat (input, "del"))
15587         is_add = 0;
15588       else if (unformat (input, "add"))
15589         is_add = 1;
15590       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15591         {
15592           rmt_eid_set = 1;
15593         }
15594       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15595         {
15596           lcl_eid_set = 1;
15597         }
15598       else if (unformat (input, "vrf %d", &dp_table))
15599         ;
15600       else if (unformat (input, "bd %d", &dp_table))
15601         ;
15602       else if (unformat (input, "vni %d", &vni))
15603         ;
15604       else if (unformat (input, "w %d", &w))
15605         {
15606           if (!curr_rloc)
15607             {
15608               errmsg ("No RLOC configured for setting priority/weight!");
15609               return -99;
15610             }
15611           curr_rloc->weight = w;
15612         }
15613       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15614                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15615         {
15616           rloc.is_ip4 = 1;
15617
15618           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15619           rloc.weight = 0;
15620           vec_add1 (lcl_locs, rloc);
15621
15622           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15623           vec_add1 (rmt_locs, rloc);
15624           /* weight saved in rmt loc */
15625           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15626         }
15627       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15628                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15629         {
15630           rloc.is_ip4 = 0;
15631           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15632           rloc.weight = 0;
15633           vec_add1 (lcl_locs, rloc);
15634
15635           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15636           vec_add1 (rmt_locs, rloc);
15637           /* weight saved in rmt loc */
15638           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15639         }
15640       else if (unformat (input, "action %d", &action))
15641         {
15642           ;
15643         }
15644       else
15645         {
15646           clib_warning ("parse error '%U'", format_unformat_error, input);
15647           return -99;
15648         }
15649     }
15650
15651   if (!rmt_eid_set)
15652     {
15653       errmsg ("remote eid addresses not set");
15654       return -99;
15655     }
15656
15657   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15658     {
15659       errmsg ("eid types don't match");
15660       return -99;
15661     }
15662
15663   if (0 == rmt_locs && (u32) ~ 0 == action)
15664     {
15665       errmsg ("action not set for negative mapping");
15666       return -99;
15667     }
15668
15669   /* Construct the API message */
15670   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15671       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15672
15673   mp->is_add = is_add;
15674   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15675   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15676   mp->eid_type = rmt_eid->type;
15677   mp->dp_table = clib_host_to_net_u32 (dp_table);
15678   mp->vni = clib_host_to_net_u32 (vni);
15679   mp->rmt_len = rmt_eid->len;
15680   mp->lcl_len = lcl_eid->len;
15681   mp->action = action;
15682
15683   if (0 != rmt_locs && 0 != lcl_locs)
15684     {
15685       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15686       clib_memcpy (mp->locs, lcl_locs,
15687                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15688
15689       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15690       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15691                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15692     }
15693   vec_free (lcl_locs);
15694   vec_free (rmt_locs);
15695
15696   /* send it... */
15697   S (mp);
15698
15699   /* Wait for a reply... */
15700   W (ret);
15701   return ret;
15702 }
15703
15704 static int
15705 api_one_add_del_map_server (vat_main_t * vam)
15706 {
15707   unformat_input_t *input = vam->input;
15708   vl_api_one_add_del_map_server_t *mp;
15709   u8 is_add = 1;
15710   u8 ipv4_set = 0;
15711   u8 ipv6_set = 0;
15712   ip4_address_t ipv4;
15713   ip6_address_t ipv6;
15714   int ret;
15715
15716   /* Parse args required to build the message */
15717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15718     {
15719       if (unformat (input, "del"))
15720         {
15721           is_add = 0;
15722         }
15723       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15724         {
15725           ipv4_set = 1;
15726         }
15727       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15728         {
15729           ipv6_set = 1;
15730         }
15731       else
15732         break;
15733     }
15734
15735   if (ipv4_set && ipv6_set)
15736     {
15737       errmsg ("both eid v4 and v6 addresses set");
15738       return -99;
15739     }
15740
15741   if (!ipv4_set && !ipv6_set)
15742     {
15743       errmsg ("eid addresses not set");
15744       return -99;
15745     }
15746
15747   /* Construct the API message */
15748   M (ONE_ADD_DEL_MAP_SERVER, mp);
15749
15750   mp->is_add = is_add;
15751   if (ipv6_set)
15752     {
15753       mp->is_ipv6 = 1;
15754       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15755     }
15756   else
15757     {
15758       mp->is_ipv6 = 0;
15759       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15760     }
15761
15762   /* send it... */
15763   S (mp);
15764
15765   /* Wait for a reply... */
15766   W (ret);
15767   return ret;
15768 }
15769
15770 #define api_lisp_add_del_map_server api_one_add_del_map_server
15771
15772 static int
15773 api_one_add_del_map_resolver (vat_main_t * vam)
15774 {
15775   unformat_input_t *input = vam->input;
15776   vl_api_one_add_del_map_resolver_t *mp;
15777   u8 is_add = 1;
15778   u8 ipv4_set = 0;
15779   u8 ipv6_set = 0;
15780   ip4_address_t ipv4;
15781   ip6_address_t ipv6;
15782   int ret;
15783
15784   /* Parse args required to build the message */
15785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15786     {
15787       if (unformat (input, "del"))
15788         {
15789           is_add = 0;
15790         }
15791       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15792         {
15793           ipv4_set = 1;
15794         }
15795       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15796         {
15797           ipv6_set = 1;
15798         }
15799       else
15800         break;
15801     }
15802
15803   if (ipv4_set && ipv6_set)
15804     {
15805       errmsg ("both eid v4 and v6 addresses set");
15806       return -99;
15807     }
15808
15809   if (!ipv4_set && !ipv6_set)
15810     {
15811       errmsg ("eid addresses not set");
15812       return -99;
15813     }
15814
15815   /* Construct the API message */
15816   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15817
15818   mp->is_add = is_add;
15819   if (ipv6_set)
15820     {
15821       mp->is_ipv6 = 1;
15822       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15823     }
15824   else
15825     {
15826       mp->is_ipv6 = 0;
15827       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15828     }
15829
15830   /* send it... */
15831   S (mp);
15832
15833   /* Wait for a reply... */
15834   W (ret);
15835   return ret;
15836 }
15837
15838 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15839
15840 static int
15841 api_lisp_gpe_enable_disable (vat_main_t * vam)
15842 {
15843   unformat_input_t *input = vam->input;
15844   vl_api_gpe_enable_disable_t *mp;
15845   u8 is_set = 0;
15846   u8 is_en = 1;
15847   int ret;
15848
15849   /* Parse args required to build the message */
15850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15851     {
15852       if (unformat (input, "enable"))
15853         {
15854           is_set = 1;
15855           is_en = 1;
15856         }
15857       else if (unformat (input, "disable"))
15858         {
15859           is_set = 1;
15860           is_en = 0;
15861         }
15862       else
15863         break;
15864     }
15865
15866   if (is_set == 0)
15867     {
15868       errmsg ("Value not set");
15869       return -99;
15870     }
15871
15872   /* Construct the API message */
15873   M (GPE_ENABLE_DISABLE, mp);
15874
15875   mp->is_en = is_en;
15876
15877   /* send it... */
15878   S (mp);
15879
15880   /* Wait for a reply... */
15881   W (ret);
15882   return ret;
15883 }
15884
15885 static int
15886 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15887 {
15888   unformat_input_t *input = vam->input;
15889   vl_api_one_rloc_probe_enable_disable_t *mp;
15890   u8 is_set = 0;
15891   u8 is_en = 0;
15892   int ret;
15893
15894   /* Parse args required to build the message */
15895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15896     {
15897       if (unformat (input, "enable"))
15898         {
15899           is_set = 1;
15900           is_en = 1;
15901         }
15902       else if (unformat (input, "disable"))
15903         is_set = 1;
15904       else
15905         break;
15906     }
15907
15908   if (!is_set)
15909     {
15910       errmsg ("Value not set");
15911       return -99;
15912     }
15913
15914   /* Construct the API message */
15915   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15916
15917   mp->is_enabled = is_en;
15918
15919   /* send it... */
15920   S (mp);
15921
15922   /* Wait for a reply... */
15923   W (ret);
15924   return ret;
15925 }
15926
15927 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15928
15929 static int
15930 api_one_map_register_enable_disable (vat_main_t * vam)
15931 {
15932   unformat_input_t *input = vam->input;
15933   vl_api_one_map_register_enable_disable_t *mp;
15934   u8 is_set = 0;
15935   u8 is_en = 0;
15936   int ret;
15937
15938   /* Parse args required to build the message */
15939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15940     {
15941       if (unformat (input, "enable"))
15942         {
15943           is_set = 1;
15944           is_en = 1;
15945         }
15946       else if (unformat (input, "disable"))
15947         is_set = 1;
15948       else
15949         break;
15950     }
15951
15952   if (!is_set)
15953     {
15954       errmsg ("Value not set");
15955       return -99;
15956     }
15957
15958   /* Construct the API message */
15959   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15960
15961   mp->is_enabled = is_en;
15962
15963   /* send it... */
15964   S (mp);
15965
15966   /* Wait for a reply... */
15967   W (ret);
15968   return ret;
15969 }
15970
15971 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15972
15973 static int
15974 api_one_enable_disable (vat_main_t * vam)
15975 {
15976   unformat_input_t *input = vam->input;
15977   vl_api_one_enable_disable_t *mp;
15978   u8 is_set = 0;
15979   u8 is_en = 0;
15980   int ret;
15981
15982   /* Parse args required to build the message */
15983   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15984     {
15985       if (unformat (input, "enable"))
15986         {
15987           is_set = 1;
15988           is_en = 1;
15989         }
15990       else if (unformat (input, "disable"))
15991         {
15992           is_set = 1;
15993         }
15994       else
15995         break;
15996     }
15997
15998   if (!is_set)
15999     {
16000       errmsg ("Value not set");
16001       return -99;
16002     }
16003
16004   /* Construct the API message */
16005   M (ONE_ENABLE_DISABLE, mp);
16006
16007   mp->is_en = is_en;
16008
16009   /* send it... */
16010   S (mp);
16011
16012   /* Wait for a reply... */
16013   W (ret);
16014   return ret;
16015 }
16016
16017 #define api_lisp_enable_disable api_one_enable_disable
16018
16019 static int
16020 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16021 {
16022   unformat_input_t *input = vam->input;
16023   vl_api_one_enable_disable_xtr_mode_t *mp;
16024   u8 is_set = 0;
16025   u8 is_en = 0;
16026   int ret;
16027
16028   /* Parse args required to build the message */
16029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16030     {
16031       if (unformat (input, "enable"))
16032         {
16033           is_set = 1;
16034           is_en = 1;
16035         }
16036       else if (unformat (input, "disable"))
16037         {
16038           is_set = 1;
16039         }
16040       else
16041         break;
16042     }
16043
16044   if (!is_set)
16045     {
16046       errmsg ("Value not set");
16047       return -99;
16048     }
16049
16050   /* Construct the API message */
16051   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16052
16053   mp->is_en = is_en;
16054
16055   /* send it... */
16056   S (mp);
16057
16058   /* Wait for a reply... */
16059   W (ret);
16060   return ret;
16061 }
16062
16063 static int
16064 api_one_show_xtr_mode (vat_main_t * vam)
16065 {
16066   vl_api_one_show_xtr_mode_t *mp;
16067   int ret;
16068
16069   /* Construct the API message */
16070   M (ONE_SHOW_XTR_MODE, mp);
16071
16072   /* send it... */
16073   S (mp);
16074
16075   /* Wait for a reply... */
16076   W (ret);
16077   return ret;
16078 }
16079
16080 static int
16081 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16082 {
16083   unformat_input_t *input = vam->input;
16084   vl_api_one_enable_disable_pitr_mode_t *mp;
16085   u8 is_set = 0;
16086   u8 is_en = 0;
16087   int ret;
16088
16089   /* Parse args required to build the message */
16090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16091     {
16092       if (unformat (input, "enable"))
16093         {
16094           is_set = 1;
16095           is_en = 1;
16096         }
16097       else if (unformat (input, "disable"))
16098         {
16099           is_set = 1;
16100         }
16101       else
16102         break;
16103     }
16104
16105   if (!is_set)
16106     {
16107       errmsg ("Value not set");
16108       return -99;
16109     }
16110
16111   /* Construct the API message */
16112   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16113
16114   mp->is_en = is_en;
16115
16116   /* send it... */
16117   S (mp);
16118
16119   /* Wait for a reply... */
16120   W (ret);
16121   return ret;
16122 }
16123
16124 static int
16125 api_one_show_pitr_mode (vat_main_t * vam)
16126 {
16127   vl_api_one_show_pitr_mode_t *mp;
16128   int ret;
16129
16130   /* Construct the API message */
16131   M (ONE_SHOW_PITR_MODE, mp);
16132
16133   /* send it... */
16134   S (mp);
16135
16136   /* Wait for a reply... */
16137   W (ret);
16138   return ret;
16139 }
16140
16141 static int
16142 api_one_enable_disable_petr_mode (vat_main_t * vam)
16143 {
16144   unformat_input_t *input = vam->input;
16145   vl_api_one_enable_disable_petr_mode_t *mp;
16146   u8 is_set = 0;
16147   u8 is_en = 0;
16148   int ret;
16149
16150   /* Parse args required to build the message */
16151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16152     {
16153       if (unformat (input, "enable"))
16154         {
16155           is_set = 1;
16156           is_en = 1;
16157         }
16158       else if (unformat (input, "disable"))
16159         {
16160           is_set = 1;
16161         }
16162       else
16163         break;
16164     }
16165
16166   if (!is_set)
16167     {
16168       errmsg ("Value not set");
16169       return -99;
16170     }
16171
16172   /* Construct the API message */
16173   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16174
16175   mp->is_en = is_en;
16176
16177   /* send it... */
16178   S (mp);
16179
16180   /* Wait for a reply... */
16181   W (ret);
16182   return ret;
16183 }
16184
16185 static int
16186 api_one_show_petr_mode (vat_main_t * vam)
16187 {
16188   vl_api_one_show_petr_mode_t *mp;
16189   int ret;
16190
16191   /* Construct the API message */
16192   M (ONE_SHOW_PETR_MODE, mp);
16193
16194   /* send it... */
16195   S (mp);
16196
16197   /* Wait for a reply... */
16198   W (ret);
16199   return ret;
16200 }
16201
16202 static int
16203 api_show_one_map_register_state (vat_main_t * vam)
16204 {
16205   vl_api_show_one_map_register_state_t *mp;
16206   int ret;
16207
16208   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16209
16210   /* send */
16211   S (mp);
16212
16213   /* wait for reply */
16214   W (ret);
16215   return ret;
16216 }
16217
16218 #define api_show_lisp_map_register_state api_show_one_map_register_state
16219
16220 static int
16221 api_show_one_rloc_probe_state (vat_main_t * vam)
16222 {
16223   vl_api_show_one_rloc_probe_state_t *mp;
16224   int ret;
16225
16226   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16227
16228   /* send */
16229   S (mp);
16230
16231   /* wait for reply */
16232   W (ret);
16233   return ret;
16234 }
16235
16236 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16237
16238 static int
16239 api_one_add_del_ndp_entry (vat_main_t * vam)
16240 {
16241   vl_api_one_add_del_ndp_entry_t *mp;
16242   unformat_input_t *input = vam->input;
16243   u8 is_add = 1;
16244   u8 mac_set = 0;
16245   u8 bd_set = 0;
16246   u8 ip_set = 0;
16247   u8 mac[6] = { 0, };
16248   u8 ip6[16] = { 0, };
16249   u32 bd = ~0;
16250   int ret;
16251
16252   /* Parse args required to build the message */
16253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16254     {
16255       if (unformat (input, "del"))
16256         is_add = 0;
16257       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16258         mac_set = 1;
16259       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16260         ip_set = 1;
16261       else if (unformat (input, "bd %d", &bd))
16262         bd_set = 1;
16263       else
16264         {
16265           errmsg ("parse error '%U'", format_unformat_error, input);
16266           return -99;
16267         }
16268     }
16269
16270   if (!bd_set || !ip_set || (!mac_set && is_add))
16271     {
16272       errmsg ("Missing BD, IP or MAC!");
16273       return -99;
16274     }
16275
16276   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16277   mp->is_add = is_add;
16278   clib_memcpy (mp->mac, mac, 6);
16279   mp->bd = clib_host_to_net_u32 (bd);
16280   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16281
16282   /* send */
16283   S (mp);
16284
16285   /* wait for reply */
16286   W (ret);
16287   return ret;
16288 }
16289
16290 static int
16291 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16292 {
16293   vl_api_one_add_del_l2_arp_entry_t *mp;
16294   unformat_input_t *input = vam->input;
16295   u8 is_add = 1;
16296   u8 mac_set = 0;
16297   u8 bd_set = 0;
16298   u8 ip_set = 0;
16299   u8 mac[6] = { 0, };
16300   u32 ip4 = 0, bd = ~0;
16301   int ret;
16302
16303   /* Parse args required to build the message */
16304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16305     {
16306       if (unformat (input, "del"))
16307         is_add = 0;
16308       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16309         mac_set = 1;
16310       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16311         ip_set = 1;
16312       else if (unformat (input, "bd %d", &bd))
16313         bd_set = 1;
16314       else
16315         {
16316           errmsg ("parse error '%U'", format_unformat_error, input);
16317           return -99;
16318         }
16319     }
16320
16321   if (!bd_set || !ip_set || (!mac_set && is_add))
16322     {
16323       errmsg ("Missing BD, IP or MAC!");
16324       return -99;
16325     }
16326
16327   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16328   mp->is_add = is_add;
16329   clib_memcpy (mp->mac, mac, 6);
16330   mp->bd = clib_host_to_net_u32 (bd);
16331   mp->ip4 = ip4;
16332
16333   /* send */
16334   S (mp);
16335
16336   /* wait for reply */
16337   W (ret);
16338   return ret;
16339 }
16340
16341 static int
16342 api_one_ndp_bd_get (vat_main_t * vam)
16343 {
16344   vl_api_one_ndp_bd_get_t *mp;
16345   int ret;
16346
16347   M (ONE_NDP_BD_GET, mp);
16348
16349   /* send */
16350   S (mp);
16351
16352   /* wait for reply */
16353   W (ret);
16354   return ret;
16355 }
16356
16357 static int
16358 api_one_ndp_entries_get (vat_main_t * vam)
16359 {
16360   vl_api_one_ndp_entries_get_t *mp;
16361   unformat_input_t *input = vam->input;
16362   u8 bd_set = 0;
16363   u32 bd = ~0;
16364   int ret;
16365
16366   /* Parse args required to build the message */
16367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16368     {
16369       if (unformat (input, "bd %d", &bd))
16370         bd_set = 1;
16371       else
16372         {
16373           errmsg ("parse error '%U'", format_unformat_error, input);
16374           return -99;
16375         }
16376     }
16377
16378   if (!bd_set)
16379     {
16380       errmsg ("Expected bridge domain!");
16381       return -99;
16382     }
16383
16384   M (ONE_NDP_ENTRIES_GET, mp);
16385   mp->bd = clib_host_to_net_u32 (bd);
16386
16387   /* send */
16388   S (mp);
16389
16390   /* wait for reply */
16391   W (ret);
16392   return ret;
16393 }
16394
16395 static int
16396 api_one_l2_arp_bd_get (vat_main_t * vam)
16397 {
16398   vl_api_one_l2_arp_bd_get_t *mp;
16399   int ret;
16400
16401   M (ONE_L2_ARP_BD_GET, mp);
16402
16403   /* send */
16404   S (mp);
16405
16406   /* wait for reply */
16407   W (ret);
16408   return ret;
16409 }
16410
16411 static int
16412 api_one_l2_arp_entries_get (vat_main_t * vam)
16413 {
16414   vl_api_one_l2_arp_entries_get_t *mp;
16415   unformat_input_t *input = vam->input;
16416   u8 bd_set = 0;
16417   u32 bd = ~0;
16418   int ret;
16419
16420   /* Parse args required to build the message */
16421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16422     {
16423       if (unformat (input, "bd %d", &bd))
16424         bd_set = 1;
16425       else
16426         {
16427           errmsg ("parse error '%U'", format_unformat_error, input);
16428           return -99;
16429         }
16430     }
16431
16432   if (!bd_set)
16433     {
16434       errmsg ("Expected bridge domain!");
16435       return -99;
16436     }
16437
16438   M (ONE_L2_ARP_ENTRIES_GET, mp);
16439   mp->bd = clib_host_to_net_u32 (bd);
16440
16441   /* send */
16442   S (mp);
16443
16444   /* wait for reply */
16445   W (ret);
16446   return ret;
16447 }
16448
16449 static int
16450 api_one_stats_enable_disable (vat_main_t * vam)
16451 {
16452   vl_api_one_stats_enable_disable_t *mp;
16453   unformat_input_t *input = vam->input;
16454   u8 is_set = 0;
16455   u8 is_en = 0;
16456   int ret;
16457
16458   /* Parse args required to build the message */
16459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16460     {
16461       if (unformat (input, "enable"))
16462         {
16463           is_set = 1;
16464           is_en = 1;
16465         }
16466       else if (unformat (input, "disable"))
16467         {
16468           is_set = 1;
16469         }
16470       else
16471         break;
16472     }
16473
16474   if (!is_set)
16475     {
16476       errmsg ("Value not set");
16477       return -99;
16478     }
16479
16480   M (ONE_STATS_ENABLE_DISABLE, mp);
16481   mp->is_en = is_en;
16482
16483   /* send */
16484   S (mp);
16485
16486   /* wait for reply */
16487   W (ret);
16488   return ret;
16489 }
16490
16491 static int
16492 api_show_one_stats_enable_disable (vat_main_t * vam)
16493 {
16494   vl_api_show_one_stats_enable_disable_t *mp;
16495   int ret;
16496
16497   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16498
16499   /* send */
16500   S (mp);
16501
16502   /* wait for reply */
16503   W (ret);
16504   return ret;
16505 }
16506
16507 static int
16508 api_show_one_map_request_mode (vat_main_t * vam)
16509 {
16510   vl_api_show_one_map_request_mode_t *mp;
16511   int ret;
16512
16513   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16514
16515   /* send */
16516   S (mp);
16517
16518   /* wait for reply */
16519   W (ret);
16520   return ret;
16521 }
16522
16523 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16524
16525 static int
16526 api_one_map_request_mode (vat_main_t * vam)
16527 {
16528   unformat_input_t *input = vam->input;
16529   vl_api_one_map_request_mode_t *mp;
16530   u8 mode = 0;
16531   int ret;
16532
16533   /* Parse args required to build the message */
16534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16535     {
16536       if (unformat (input, "dst-only"))
16537         mode = 0;
16538       else if (unformat (input, "src-dst"))
16539         mode = 1;
16540       else
16541         {
16542           errmsg ("parse error '%U'", format_unformat_error, input);
16543           return -99;
16544         }
16545     }
16546
16547   M (ONE_MAP_REQUEST_MODE, mp);
16548
16549   mp->mode = mode;
16550
16551   /* send */
16552   S (mp);
16553
16554   /* wait for reply */
16555   W (ret);
16556   return ret;
16557 }
16558
16559 #define api_lisp_map_request_mode api_one_map_request_mode
16560
16561 /**
16562  * Enable/disable ONE proxy ITR.
16563  *
16564  * @param vam vpp API test context
16565  * @return return code
16566  */
16567 static int
16568 api_one_pitr_set_locator_set (vat_main_t * vam)
16569 {
16570   u8 ls_name_set = 0;
16571   unformat_input_t *input = vam->input;
16572   vl_api_one_pitr_set_locator_set_t *mp;
16573   u8 is_add = 1;
16574   u8 *ls_name = 0;
16575   int ret;
16576
16577   /* Parse args required to build the message */
16578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16579     {
16580       if (unformat (input, "del"))
16581         is_add = 0;
16582       else if (unformat (input, "locator-set %s", &ls_name))
16583         ls_name_set = 1;
16584       else
16585         {
16586           errmsg ("parse error '%U'", format_unformat_error, input);
16587           return -99;
16588         }
16589     }
16590
16591   if (!ls_name_set)
16592     {
16593       errmsg ("locator-set name not set!");
16594       return -99;
16595     }
16596
16597   M (ONE_PITR_SET_LOCATOR_SET, mp);
16598
16599   mp->is_add = is_add;
16600   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16601   vec_free (ls_name);
16602
16603   /* send */
16604   S (mp);
16605
16606   /* wait for reply */
16607   W (ret);
16608   return ret;
16609 }
16610
16611 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16612
16613 static int
16614 api_one_nsh_set_locator_set (vat_main_t * vam)
16615 {
16616   u8 ls_name_set = 0;
16617   unformat_input_t *input = vam->input;
16618   vl_api_one_nsh_set_locator_set_t *mp;
16619   u8 is_add = 1;
16620   u8 *ls_name = 0;
16621   int ret;
16622
16623   /* Parse args required to build the message */
16624   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16625     {
16626       if (unformat (input, "del"))
16627         is_add = 0;
16628       else if (unformat (input, "ls %s", &ls_name))
16629         ls_name_set = 1;
16630       else
16631         {
16632           errmsg ("parse error '%U'", format_unformat_error, input);
16633           return -99;
16634         }
16635     }
16636
16637   if (!ls_name_set && is_add)
16638     {
16639       errmsg ("locator-set name not set!");
16640       return -99;
16641     }
16642
16643   M (ONE_NSH_SET_LOCATOR_SET, mp);
16644
16645   mp->is_add = is_add;
16646   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16647   vec_free (ls_name);
16648
16649   /* send */
16650   S (mp);
16651
16652   /* wait for reply */
16653   W (ret);
16654   return ret;
16655 }
16656
16657 static int
16658 api_show_one_pitr (vat_main_t * vam)
16659 {
16660   vl_api_show_one_pitr_t *mp;
16661   int ret;
16662
16663   if (!vam->json_output)
16664     {
16665       print (vam->ofp, "%=20s", "lisp status:");
16666     }
16667
16668   M (SHOW_ONE_PITR, mp);
16669   /* send it... */
16670   S (mp);
16671
16672   /* Wait for a reply... */
16673   W (ret);
16674   return ret;
16675 }
16676
16677 #define api_show_lisp_pitr api_show_one_pitr
16678
16679 static int
16680 api_one_use_petr (vat_main_t * vam)
16681 {
16682   unformat_input_t *input = vam->input;
16683   vl_api_one_use_petr_t *mp;
16684   u8 is_add = 0;
16685   ip_address_t ip;
16686   int ret;
16687
16688   clib_memset (&ip, 0, sizeof (ip));
16689
16690   /* Parse args required to build the message */
16691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16692     {
16693       if (unformat (input, "disable"))
16694         is_add = 0;
16695       else
16696         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16697         {
16698           is_add = 1;
16699           ip_addr_version (&ip) = IP4;
16700         }
16701       else
16702         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16703         {
16704           is_add = 1;
16705           ip_addr_version (&ip) = IP6;
16706         }
16707       else
16708         {
16709           errmsg ("parse error '%U'", format_unformat_error, input);
16710           return -99;
16711         }
16712     }
16713
16714   M (ONE_USE_PETR, mp);
16715
16716   mp->is_add = is_add;
16717   if (is_add)
16718     {
16719       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16720       if (mp->is_ip4)
16721         clib_memcpy (mp->address, &ip, 4);
16722       else
16723         clib_memcpy (mp->address, &ip, 16);
16724     }
16725
16726   /* send */
16727   S (mp);
16728
16729   /* wait for reply */
16730   W (ret);
16731   return ret;
16732 }
16733
16734 #define api_lisp_use_petr api_one_use_petr
16735
16736 static int
16737 api_show_one_nsh_mapping (vat_main_t * vam)
16738 {
16739   vl_api_show_one_use_petr_t *mp;
16740   int ret;
16741
16742   if (!vam->json_output)
16743     {
16744       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16745     }
16746
16747   M (SHOW_ONE_NSH_MAPPING, mp);
16748   /* send it... */
16749   S (mp);
16750
16751   /* Wait for a reply... */
16752   W (ret);
16753   return ret;
16754 }
16755
16756 static int
16757 api_show_one_use_petr (vat_main_t * vam)
16758 {
16759   vl_api_show_one_use_petr_t *mp;
16760   int ret;
16761
16762   if (!vam->json_output)
16763     {
16764       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16765     }
16766
16767   M (SHOW_ONE_USE_PETR, mp);
16768   /* send it... */
16769   S (mp);
16770
16771   /* Wait for a reply... */
16772   W (ret);
16773   return ret;
16774 }
16775
16776 #define api_show_lisp_use_petr api_show_one_use_petr
16777
16778 /**
16779  * Add/delete mapping between vni and vrf
16780  */
16781 static int
16782 api_one_eid_table_add_del_map (vat_main_t * vam)
16783 {
16784   unformat_input_t *input = vam->input;
16785   vl_api_one_eid_table_add_del_map_t *mp;
16786   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16787   u32 vni, vrf, bd_index;
16788   int ret;
16789
16790   /* Parse args required to build the message */
16791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16792     {
16793       if (unformat (input, "del"))
16794         is_add = 0;
16795       else if (unformat (input, "vrf %d", &vrf))
16796         vrf_set = 1;
16797       else if (unformat (input, "bd_index %d", &bd_index))
16798         bd_index_set = 1;
16799       else if (unformat (input, "vni %d", &vni))
16800         vni_set = 1;
16801       else
16802         break;
16803     }
16804
16805   if (!vni_set || (!vrf_set && !bd_index_set))
16806     {
16807       errmsg ("missing arguments!");
16808       return -99;
16809     }
16810
16811   if (vrf_set && bd_index_set)
16812     {
16813       errmsg ("error: both vrf and bd entered!");
16814       return -99;
16815     }
16816
16817   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16818
16819   mp->is_add = is_add;
16820   mp->vni = htonl (vni);
16821   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16822   mp->is_l2 = bd_index_set;
16823
16824   /* send */
16825   S (mp);
16826
16827   /* wait for reply */
16828   W (ret);
16829   return ret;
16830 }
16831
16832 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16833
16834 uword
16835 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16836 {
16837   u32 *action = va_arg (*args, u32 *);
16838   u8 *s = 0;
16839
16840   if (unformat (input, "%s", &s))
16841     {
16842       if (!strcmp ((char *) s, "no-action"))
16843         action[0] = 0;
16844       else if (!strcmp ((char *) s, "natively-forward"))
16845         action[0] = 1;
16846       else if (!strcmp ((char *) s, "send-map-request"))
16847         action[0] = 2;
16848       else if (!strcmp ((char *) s, "drop"))
16849         action[0] = 3;
16850       else
16851         {
16852           clib_warning ("invalid action: '%s'", s);
16853           action[0] = 3;
16854         }
16855     }
16856   else
16857     return 0;
16858
16859   vec_free (s);
16860   return 1;
16861 }
16862
16863 /**
16864  * Add/del remote mapping to/from ONE control plane
16865  *
16866  * @param vam vpp API test context
16867  * @return return code
16868  */
16869 static int
16870 api_one_add_del_remote_mapping (vat_main_t * vam)
16871 {
16872   unformat_input_t *input = vam->input;
16873   vl_api_one_add_del_remote_mapping_t *mp;
16874   u32 vni = 0;
16875   lisp_eid_vat_t _eid, *eid = &_eid;
16876   lisp_eid_vat_t _seid, *seid = &_seid;
16877   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16878   u32 action = ~0, p, w, data_len;
16879   ip4_address_t rloc4;
16880   ip6_address_t rloc6;
16881   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16882   int ret;
16883
16884   clib_memset (&rloc, 0, sizeof (rloc));
16885
16886   /* Parse args required to build the message */
16887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16888     {
16889       if (unformat (input, "del-all"))
16890         {
16891           del_all = 1;
16892         }
16893       else if (unformat (input, "del"))
16894         {
16895           is_add = 0;
16896         }
16897       else if (unformat (input, "add"))
16898         {
16899           is_add = 1;
16900         }
16901       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16902         {
16903           eid_set = 1;
16904         }
16905       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16906         {
16907           seid_set = 1;
16908         }
16909       else if (unformat (input, "vni %d", &vni))
16910         {
16911           ;
16912         }
16913       else if (unformat (input, "p %d w %d", &p, &w))
16914         {
16915           if (!curr_rloc)
16916             {
16917               errmsg ("No RLOC configured for setting priority/weight!");
16918               return -99;
16919             }
16920           curr_rloc->priority = p;
16921           curr_rloc->weight = w;
16922         }
16923       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16924         {
16925           rloc.is_ip4 = 1;
16926           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16927           vec_add1 (rlocs, rloc);
16928           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16929         }
16930       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16931         {
16932           rloc.is_ip4 = 0;
16933           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16934           vec_add1 (rlocs, rloc);
16935           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16936         }
16937       else if (unformat (input, "action %U",
16938                          unformat_negative_mapping_action, &action))
16939         {
16940           ;
16941         }
16942       else
16943         {
16944           clib_warning ("parse error '%U'", format_unformat_error, input);
16945           return -99;
16946         }
16947     }
16948
16949   if (0 == eid_set)
16950     {
16951       errmsg ("missing params!");
16952       return -99;
16953     }
16954
16955   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16956     {
16957       errmsg ("no action set for negative map-reply!");
16958       return -99;
16959     }
16960
16961   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16962
16963   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16964   mp->is_add = is_add;
16965   mp->vni = htonl (vni);
16966   mp->action = (u8) action;
16967   mp->is_src_dst = seid_set;
16968   mp->eid_len = eid->len;
16969   mp->seid_len = seid->len;
16970   mp->del_all = del_all;
16971   mp->eid_type = eid->type;
16972   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16973   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16974
16975   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16976   clib_memcpy (mp->rlocs, rlocs, data_len);
16977   vec_free (rlocs);
16978
16979   /* send it... */
16980   S (mp);
16981
16982   /* Wait for a reply... */
16983   W (ret);
16984   return ret;
16985 }
16986
16987 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16988
16989 /**
16990  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16991  * forwarding entries in data-plane accordingly.
16992  *
16993  * @param vam vpp API test context
16994  * @return return code
16995  */
16996 static int
16997 api_one_add_del_adjacency (vat_main_t * vam)
16998 {
16999   unformat_input_t *input = vam->input;
17000   vl_api_one_add_del_adjacency_t *mp;
17001   u32 vni = 0;
17002   ip4_address_t leid4, reid4;
17003   ip6_address_t leid6, reid6;
17004   u8 reid_mac[6] = { 0 };
17005   u8 leid_mac[6] = { 0 };
17006   u8 reid_type, leid_type;
17007   u32 leid_len = 0, reid_len = 0, len;
17008   u8 is_add = 1;
17009   int ret;
17010
17011   leid_type = reid_type = (u8) ~ 0;
17012
17013   /* Parse args required to build the message */
17014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17015     {
17016       if (unformat (input, "del"))
17017         {
17018           is_add = 0;
17019         }
17020       else if (unformat (input, "add"))
17021         {
17022           is_add = 1;
17023         }
17024       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17025                          &reid4, &len))
17026         {
17027           reid_type = 0;        /* ipv4 */
17028           reid_len = len;
17029         }
17030       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17031                          &reid6, &len))
17032         {
17033           reid_type = 1;        /* ipv6 */
17034           reid_len = len;
17035         }
17036       else if (unformat (input, "reid %U", unformat_ethernet_address,
17037                          reid_mac))
17038         {
17039           reid_type = 2;        /* mac */
17040         }
17041       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17042                          &leid4, &len))
17043         {
17044           leid_type = 0;        /* ipv4 */
17045           leid_len = len;
17046         }
17047       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17048                          &leid6, &len))
17049         {
17050           leid_type = 1;        /* ipv6 */
17051           leid_len = len;
17052         }
17053       else if (unformat (input, "leid %U", unformat_ethernet_address,
17054                          leid_mac))
17055         {
17056           leid_type = 2;        /* mac */
17057         }
17058       else if (unformat (input, "vni %d", &vni))
17059         {
17060           ;
17061         }
17062       else
17063         {
17064           errmsg ("parse error '%U'", format_unformat_error, input);
17065           return -99;
17066         }
17067     }
17068
17069   if ((u8) ~ 0 == reid_type)
17070     {
17071       errmsg ("missing params!");
17072       return -99;
17073     }
17074
17075   if (leid_type != reid_type)
17076     {
17077       errmsg ("remote and local EIDs are of different types!");
17078       return -99;
17079     }
17080
17081   M (ONE_ADD_DEL_ADJACENCY, mp);
17082   mp->is_add = is_add;
17083   mp->vni = htonl (vni);
17084   mp->leid_len = leid_len;
17085   mp->reid_len = reid_len;
17086   mp->eid_type = reid_type;
17087
17088   switch (mp->eid_type)
17089     {
17090     case 0:
17091       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17092       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17093       break;
17094     case 1:
17095       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17096       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17097       break;
17098     case 2:
17099       clib_memcpy (mp->leid, leid_mac, 6);
17100       clib_memcpy (mp->reid, reid_mac, 6);
17101       break;
17102     default:
17103       errmsg ("unknown EID type %d!", mp->eid_type);
17104       return 0;
17105     }
17106
17107   /* send it... */
17108   S (mp);
17109
17110   /* Wait for a reply... */
17111   W (ret);
17112   return ret;
17113 }
17114
17115 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17116
17117 uword
17118 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17119 {
17120   u32 *mode = va_arg (*args, u32 *);
17121
17122   if (unformat (input, "lisp"))
17123     *mode = 0;
17124   else if (unformat (input, "vxlan"))
17125     *mode = 1;
17126   else
17127     return 0;
17128
17129   return 1;
17130 }
17131
17132 static int
17133 api_gpe_get_encap_mode (vat_main_t * vam)
17134 {
17135   vl_api_gpe_get_encap_mode_t *mp;
17136   int ret;
17137
17138   /* Construct the API message */
17139   M (GPE_GET_ENCAP_MODE, mp);
17140
17141   /* send it... */
17142   S (mp);
17143
17144   /* Wait for a reply... */
17145   W (ret);
17146   return ret;
17147 }
17148
17149 static int
17150 api_gpe_set_encap_mode (vat_main_t * vam)
17151 {
17152   unformat_input_t *input = vam->input;
17153   vl_api_gpe_set_encap_mode_t *mp;
17154   int ret;
17155   u32 mode = 0;
17156
17157   /* Parse args required to build the message */
17158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17159     {
17160       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17161         ;
17162       else
17163         break;
17164     }
17165
17166   /* Construct the API message */
17167   M (GPE_SET_ENCAP_MODE, mp);
17168
17169   mp->mode = mode;
17170
17171   /* send it... */
17172   S (mp);
17173
17174   /* Wait for a reply... */
17175   W (ret);
17176   return ret;
17177 }
17178
17179 static int
17180 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17181 {
17182   unformat_input_t *input = vam->input;
17183   vl_api_gpe_add_del_iface_t *mp;
17184   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17185   u32 dp_table = 0, vni = 0;
17186   int ret;
17187
17188   /* Parse args required to build the message */
17189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17190     {
17191       if (unformat (input, "up"))
17192         {
17193           action_set = 1;
17194           is_add = 1;
17195         }
17196       else if (unformat (input, "down"))
17197         {
17198           action_set = 1;
17199           is_add = 0;
17200         }
17201       else if (unformat (input, "table_id %d", &dp_table))
17202         {
17203           dp_table_set = 1;
17204         }
17205       else if (unformat (input, "bd_id %d", &dp_table))
17206         {
17207           dp_table_set = 1;
17208           is_l2 = 1;
17209         }
17210       else if (unformat (input, "vni %d", &vni))
17211         {
17212           vni_set = 1;
17213         }
17214       else
17215         break;
17216     }
17217
17218   if (action_set == 0)
17219     {
17220       errmsg ("Action not set");
17221       return -99;
17222     }
17223   if (dp_table_set == 0 || vni_set == 0)
17224     {
17225       errmsg ("vni and dp_table must be set");
17226       return -99;
17227     }
17228
17229   /* Construct the API message */
17230   M (GPE_ADD_DEL_IFACE, mp);
17231
17232   mp->is_add = is_add;
17233   mp->dp_table = clib_host_to_net_u32 (dp_table);
17234   mp->is_l2 = is_l2;
17235   mp->vni = clib_host_to_net_u32 (vni);
17236
17237   /* send it... */
17238   S (mp);
17239
17240   /* Wait for a reply... */
17241   W (ret);
17242   return ret;
17243 }
17244
17245 static int
17246 api_one_map_register_fallback_threshold (vat_main_t * vam)
17247 {
17248   unformat_input_t *input = vam->input;
17249   vl_api_one_map_register_fallback_threshold_t *mp;
17250   u32 value = 0;
17251   u8 is_set = 0;
17252   int ret;
17253
17254   /* Parse args required to build the message */
17255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17256     {
17257       if (unformat (input, "%u", &value))
17258         is_set = 1;
17259       else
17260         {
17261           clib_warning ("parse error '%U'", format_unformat_error, input);
17262           return -99;
17263         }
17264     }
17265
17266   if (!is_set)
17267     {
17268       errmsg ("fallback threshold value is missing!");
17269       return -99;
17270     }
17271
17272   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17273   mp->value = clib_host_to_net_u32 (value);
17274
17275   /* send it... */
17276   S (mp);
17277
17278   /* Wait for a reply... */
17279   W (ret);
17280   return ret;
17281 }
17282
17283 static int
17284 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17285 {
17286   vl_api_show_one_map_register_fallback_threshold_t *mp;
17287   int ret;
17288
17289   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17290
17291   /* send it... */
17292   S (mp);
17293
17294   /* Wait for a reply... */
17295   W (ret);
17296   return ret;
17297 }
17298
17299 uword
17300 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17301 {
17302   u32 *proto = va_arg (*args, u32 *);
17303
17304   if (unformat (input, "udp"))
17305     *proto = 1;
17306   else if (unformat (input, "api"))
17307     *proto = 2;
17308   else
17309     return 0;
17310
17311   return 1;
17312 }
17313
17314 static int
17315 api_one_set_transport_protocol (vat_main_t * vam)
17316 {
17317   unformat_input_t *input = vam->input;
17318   vl_api_one_set_transport_protocol_t *mp;
17319   u8 is_set = 0;
17320   u32 protocol = 0;
17321   int ret;
17322
17323   /* Parse args required to build the message */
17324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17325     {
17326       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17327         is_set = 1;
17328       else
17329         {
17330           clib_warning ("parse error '%U'", format_unformat_error, input);
17331           return -99;
17332         }
17333     }
17334
17335   if (!is_set)
17336     {
17337       errmsg ("Transport protocol missing!");
17338       return -99;
17339     }
17340
17341   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17342   mp->protocol = (u8) protocol;
17343
17344   /* send it... */
17345   S (mp);
17346
17347   /* Wait for a reply... */
17348   W (ret);
17349   return ret;
17350 }
17351
17352 static int
17353 api_one_get_transport_protocol (vat_main_t * vam)
17354 {
17355   vl_api_one_get_transport_protocol_t *mp;
17356   int ret;
17357
17358   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17359
17360   /* send it... */
17361   S (mp);
17362
17363   /* Wait for a reply... */
17364   W (ret);
17365   return ret;
17366 }
17367
17368 static int
17369 api_one_map_register_set_ttl (vat_main_t * vam)
17370 {
17371   unformat_input_t *input = vam->input;
17372   vl_api_one_map_register_set_ttl_t *mp;
17373   u32 ttl = 0;
17374   u8 is_set = 0;
17375   int ret;
17376
17377   /* Parse args required to build the message */
17378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17379     {
17380       if (unformat (input, "%u", &ttl))
17381         is_set = 1;
17382       else
17383         {
17384           clib_warning ("parse error '%U'", format_unformat_error, input);
17385           return -99;
17386         }
17387     }
17388
17389   if (!is_set)
17390     {
17391       errmsg ("TTL value missing!");
17392       return -99;
17393     }
17394
17395   M (ONE_MAP_REGISTER_SET_TTL, mp);
17396   mp->ttl = clib_host_to_net_u32 (ttl);
17397
17398   /* send it... */
17399   S (mp);
17400
17401   /* Wait for a reply... */
17402   W (ret);
17403   return ret;
17404 }
17405
17406 static int
17407 api_show_one_map_register_ttl (vat_main_t * vam)
17408 {
17409   vl_api_show_one_map_register_ttl_t *mp;
17410   int ret;
17411
17412   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17413
17414   /* send it... */
17415   S (mp);
17416
17417   /* Wait for a reply... */
17418   W (ret);
17419   return ret;
17420 }
17421
17422 /**
17423  * Add/del map request itr rlocs from ONE control plane and updates
17424  *
17425  * @param vam vpp API test context
17426  * @return return code
17427  */
17428 static int
17429 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17430 {
17431   unformat_input_t *input = vam->input;
17432   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17433   u8 *locator_set_name = 0;
17434   u8 locator_set_name_set = 0;
17435   u8 is_add = 1;
17436   int ret;
17437
17438   /* Parse args required to build the message */
17439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17440     {
17441       if (unformat (input, "del"))
17442         {
17443           is_add = 0;
17444         }
17445       else if (unformat (input, "%_%v%_", &locator_set_name))
17446         {
17447           locator_set_name_set = 1;
17448         }
17449       else
17450         {
17451           clib_warning ("parse error '%U'", format_unformat_error, input);
17452           return -99;
17453         }
17454     }
17455
17456   if (is_add && !locator_set_name_set)
17457     {
17458       errmsg ("itr-rloc is not set!");
17459       return -99;
17460     }
17461
17462   if (is_add && vec_len (locator_set_name) > 64)
17463     {
17464       errmsg ("itr-rloc locator-set name too long");
17465       vec_free (locator_set_name);
17466       return -99;
17467     }
17468
17469   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17470   mp->is_add = is_add;
17471   if (is_add)
17472     {
17473       clib_memcpy (mp->locator_set_name, locator_set_name,
17474                    vec_len (locator_set_name));
17475     }
17476   else
17477     {
17478       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17479     }
17480   vec_free (locator_set_name);
17481
17482   /* send it... */
17483   S (mp);
17484
17485   /* Wait for a reply... */
17486   W (ret);
17487   return ret;
17488 }
17489
17490 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17491
17492 static int
17493 api_one_locator_dump (vat_main_t * vam)
17494 {
17495   unformat_input_t *input = vam->input;
17496   vl_api_one_locator_dump_t *mp;
17497   vl_api_control_ping_t *mp_ping;
17498   u8 is_index_set = 0, is_name_set = 0;
17499   u8 *ls_name = 0;
17500   u32 ls_index = ~0;
17501   int ret;
17502
17503   /* Parse args required to build the message */
17504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17505     {
17506       if (unformat (input, "ls_name %_%v%_", &ls_name))
17507         {
17508           is_name_set = 1;
17509         }
17510       else if (unformat (input, "ls_index %d", &ls_index))
17511         {
17512           is_index_set = 1;
17513         }
17514       else
17515         {
17516           errmsg ("parse error '%U'", format_unformat_error, input);
17517           return -99;
17518         }
17519     }
17520
17521   if (!is_index_set && !is_name_set)
17522     {
17523       errmsg ("error: expected one of index or name!");
17524       return -99;
17525     }
17526
17527   if (is_index_set && is_name_set)
17528     {
17529       errmsg ("error: only one param expected!");
17530       return -99;
17531     }
17532
17533   if (vec_len (ls_name) > 62)
17534     {
17535       errmsg ("error: locator set name too long!");
17536       return -99;
17537     }
17538
17539   if (!vam->json_output)
17540     {
17541       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17542     }
17543
17544   M (ONE_LOCATOR_DUMP, mp);
17545   mp->is_index_set = is_index_set;
17546
17547   if (is_index_set)
17548     mp->ls_index = clib_host_to_net_u32 (ls_index);
17549   else
17550     {
17551       vec_add1 (ls_name, 0);
17552       strncpy ((char *) mp->ls_name, (char *) ls_name,
17553                sizeof (mp->ls_name) - 1);
17554     }
17555
17556   /* send it... */
17557   S (mp);
17558
17559   /* Use a control ping for synchronization */
17560   MPING (CONTROL_PING, mp_ping);
17561   S (mp_ping);
17562
17563   /* Wait for a reply... */
17564   W (ret);
17565   return ret;
17566 }
17567
17568 #define api_lisp_locator_dump api_one_locator_dump
17569
17570 static int
17571 api_one_locator_set_dump (vat_main_t * vam)
17572 {
17573   vl_api_one_locator_set_dump_t *mp;
17574   vl_api_control_ping_t *mp_ping;
17575   unformat_input_t *input = vam->input;
17576   u8 filter = 0;
17577   int ret;
17578
17579   /* Parse args required to build the message */
17580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17581     {
17582       if (unformat (input, "local"))
17583         {
17584           filter = 1;
17585         }
17586       else if (unformat (input, "remote"))
17587         {
17588           filter = 2;
17589         }
17590       else
17591         {
17592           errmsg ("parse error '%U'", format_unformat_error, input);
17593           return -99;
17594         }
17595     }
17596
17597   if (!vam->json_output)
17598     {
17599       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17600     }
17601
17602   M (ONE_LOCATOR_SET_DUMP, mp);
17603
17604   mp->filter = filter;
17605
17606   /* send it... */
17607   S (mp);
17608
17609   /* Use a control ping for synchronization */
17610   MPING (CONTROL_PING, mp_ping);
17611   S (mp_ping);
17612
17613   /* Wait for a reply... */
17614   W (ret);
17615   return ret;
17616 }
17617
17618 #define api_lisp_locator_set_dump api_one_locator_set_dump
17619
17620 static int
17621 api_one_eid_table_map_dump (vat_main_t * vam)
17622 {
17623   u8 is_l2 = 0;
17624   u8 mode_set = 0;
17625   unformat_input_t *input = vam->input;
17626   vl_api_one_eid_table_map_dump_t *mp;
17627   vl_api_control_ping_t *mp_ping;
17628   int ret;
17629
17630   /* Parse args required to build the message */
17631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17632     {
17633       if (unformat (input, "l2"))
17634         {
17635           is_l2 = 1;
17636           mode_set = 1;
17637         }
17638       else if (unformat (input, "l3"))
17639         {
17640           is_l2 = 0;
17641           mode_set = 1;
17642         }
17643       else
17644         {
17645           errmsg ("parse error '%U'", format_unformat_error, input);
17646           return -99;
17647         }
17648     }
17649
17650   if (!mode_set)
17651     {
17652       errmsg ("expected one of 'l2' or 'l3' parameter!");
17653       return -99;
17654     }
17655
17656   if (!vam->json_output)
17657     {
17658       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17659     }
17660
17661   M (ONE_EID_TABLE_MAP_DUMP, mp);
17662   mp->is_l2 = is_l2;
17663
17664   /* send it... */
17665   S (mp);
17666
17667   /* Use a control ping for synchronization */
17668   MPING (CONTROL_PING, mp_ping);
17669   S (mp_ping);
17670
17671   /* Wait for a reply... */
17672   W (ret);
17673   return ret;
17674 }
17675
17676 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17677
17678 static int
17679 api_one_eid_table_vni_dump (vat_main_t * vam)
17680 {
17681   vl_api_one_eid_table_vni_dump_t *mp;
17682   vl_api_control_ping_t *mp_ping;
17683   int ret;
17684
17685   if (!vam->json_output)
17686     {
17687       print (vam->ofp, "VNI");
17688     }
17689
17690   M (ONE_EID_TABLE_VNI_DUMP, mp);
17691
17692   /* send it... */
17693   S (mp);
17694
17695   /* Use a control ping for synchronization */
17696   MPING (CONTROL_PING, mp_ping);
17697   S (mp_ping);
17698
17699   /* Wait for a reply... */
17700   W (ret);
17701   return ret;
17702 }
17703
17704 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17705
17706 static int
17707 api_one_eid_table_dump (vat_main_t * vam)
17708 {
17709   unformat_input_t *i = vam->input;
17710   vl_api_one_eid_table_dump_t *mp;
17711   vl_api_control_ping_t *mp_ping;
17712   struct in_addr ip4;
17713   struct in6_addr ip6;
17714   u8 mac[6];
17715   u8 eid_type = ~0, eid_set = 0;
17716   u32 prefix_length = ~0, t, vni = 0;
17717   u8 filter = 0;
17718   int ret;
17719   lisp_nsh_api_t nsh;
17720
17721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17722     {
17723       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17724         {
17725           eid_set = 1;
17726           eid_type = 0;
17727           prefix_length = t;
17728         }
17729       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17730         {
17731           eid_set = 1;
17732           eid_type = 1;
17733           prefix_length = t;
17734         }
17735       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17736         {
17737           eid_set = 1;
17738           eid_type = 2;
17739         }
17740       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17741         {
17742           eid_set = 1;
17743           eid_type = 3;
17744         }
17745       else if (unformat (i, "vni %d", &t))
17746         {
17747           vni = t;
17748         }
17749       else if (unformat (i, "local"))
17750         {
17751           filter = 1;
17752         }
17753       else if (unformat (i, "remote"))
17754         {
17755           filter = 2;
17756         }
17757       else
17758         {
17759           errmsg ("parse error '%U'", format_unformat_error, i);
17760           return -99;
17761         }
17762     }
17763
17764   if (!vam->json_output)
17765     {
17766       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17767              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17768     }
17769
17770   M (ONE_EID_TABLE_DUMP, mp);
17771
17772   mp->filter = filter;
17773   if (eid_set)
17774     {
17775       mp->eid_set = 1;
17776       mp->vni = htonl (vni);
17777       mp->eid_type = eid_type;
17778       switch (eid_type)
17779         {
17780         case 0:
17781           mp->prefix_length = prefix_length;
17782           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17783           break;
17784         case 1:
17785           mp->prefix_length = prefix_length;
17786           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17787           break;
17788         case 2:
17789           clib_memcpy (mp->eid, mac, sizeof (mac));
17790           break;
17791         case 3:
17792           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17793           break;
17794         default:
17795           errmsg ("unknown EID type %d!", eid_type);
17796           return -99;
17797         }
17798     }
17799
17800   /* send it... */
17801   S (mp);
17802
17803   /* Use a control ping for synchronization */
17804   MPING (CONTROL_PING, mp_ping);
17805   S (mp_ping);
17806
17807   /* Wait for a reply... */
17808   W (ret);
17809   return ret;
17810 }
17811
17812 #define api_lisp_eid_table_dump api_one_eid_table_dump
17813
17814 static int
17815 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17816 {
17817   unformat_input_t *i = vam->input;
17818   vl_api_gpe_fwd_entries_get_t *mp;
17819   u8 vni_set = 0;
17820   u32 vni = ~0;
17821   int ret;
17822
17823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17824     {
17825       if (unformat (i, "vni %d", &vni))
17826         {
17827           vni_set = 1;
17828         }
17829       else
17830         {
17831           errmsg ("parse error '%U'", format_unformat_error, i);
17832           return -99;
17833         }
17834     }
17835
17836   if (!vni_set)
17837     {
17838       errmsg ("vni not set!");
17839       return -99;
17840     }
17841
17842   if (!vam->json_output)
17843     {
17844       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17845              "leid", "reid");
17846     }
17847
17848   M (GPE_FWD_ENTRIES_GET, mp);
17849   mp->vni = clib_host_to_net_u32 (vni);
17850
17851   /* send it... */
17852   S (mp);
17853
17854   /* Wait for a reply... */
17855   W (ret);
17856   return ret;
17857 }
17858
17859 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17860 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17861 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17862 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17863 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17864 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17865 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17866 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17867
17868 static int
17869 api_one_adjacencies_get (vat_main_t * vam)
17870 {
17871   unformat_input_t *i = vam->input;
17872   vl_api_one_adjacencies_get_t *mp;
17873   u8 vni_set = 0;
17874   u32 vni = ~0;
17875   int ret;
17876
17877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17878     {
17879       if (unformat (i, "vni %d", &vni))
17880         {
17881           vni_set = 1;
17882         }
17883       else
17884         {
17885           errmsg ("parse error '%U'", format_unformat_error, i);
17886           return -99;
17887         }
17888     }
17889
17890   if (!vni_set)
17891     {
17892       errmsg ("vni not set!");
17893       return -99;
17894     }
17895
17896   if (!vam->json_output)
17897     {
17898       print (vam->ofp, "%s %40s", "leid", "reid");
17899     }
17900
17901   M (ONE_ADJACENCIES_GET, mp);
17902   mp->vni = clib_host_to_net_u32 (vni);
17903
17904   /* send it... */
17905   S (mp);
17906
17907   /* Wait for a reply... */
17908   W (ret);
17909   return ret;
17910 }
17911
17912 #define api_lisp_adjacencies_get api_one_adjacencies_get
17913
17914 static int
17915 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17916 {
17917   unformat_input_t *i = vam->input;
17918   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17919   int ret;
17920   u8 ip_family_set = 0, is_ip4 = 1;
17921
17922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17923     {
17924       if (unformat (i, "ip4"))
17925         {
17926           ip_family_set = 1;
17927           is_ip4 = 1;
17928         }
17929       else if (unformat (i, "ip6"))
17930         {
17931           ip_family_set = 1;
17932           is_ip4 = 0;
17933         }
17934       else
17935         {
17936           errmsg ("parse error '%U'", format_unformat_error, i);
17937           return -99;
17938         }
17939     }
17940
17941   if (!ip_family_set)
17942     {
17943       errmsg ("ip family not set!");
17944       return -99;
17945     }
17946
17947   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17948   mp->is_ip4 = is_ip4;
17949
17950   /* send it... */
17951   S (mp);
17952
17953   /* Wait for a reply... */
17954   W (ret);
17955   return ret;
17956 }
17957
17958 static int
17959 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17960 {
17961   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17962   int ret;
17963
17964   if (!vam->json_output)
17965     {
17966       print (vam->ofp, "VNIs");
17967     }
17968
17969   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17970
17971   /* send it... */
17972   S (mp);
17973
17974   /* Wait for a reply... */
17975   W (ret);
17976   return ret;
17977 }
17978
17979 static int
17980 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17981 {
17982   unformat_input_t *i = vam->input;
17983   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17984   int ret = 0;
17985   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17986   struct in_addr ip4;
17987   struct in6_addr ip6;
17988   u32 table_id = 0, nh_sw_if_index = ~0;
17989
17990   clib_memset (&ip4, 0, sizeof (ip4));
17991   clib_memset (&ip6, 0, sizeof (ip6));
17992
17993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17994     {
17995       if (unformat (i, "del"))
17996         is_add = 0;
17997       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17998                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17999         {
18000           ip_set = 1;
18001           is_ip4 = 1;
18002         }
18003       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18004                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18005         {
18006           ip_set = 1;
18007           is_ip4 = 0;
18008         }
18009       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18010         {
18011           ip_set = 1;
18012           is_ip4 = 1;
18013           nh_sw_if_index = ~0;
18014         }
18015       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18016         {
18017           ip_set = 1;
18018           is_ip4 = 0;
18019           nh_sw_if_index = ~0;
18020         }
18021       else if (unformat (i, "table %d", &table_id))
18022         ;
18023       else
18024         {
18025           errmsg ("parse error '%U'", format_unformat_error, i);
18026           return -99;
18027         }
18028     }
18029
18030   if (!ip_set)
18031     {
18032       errmsg ("nh addr not set!");
18033       return -99;
18034     }
18035
18036   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18037   mp->is_add = is_add;
18038   mp->table_id = clib_host_to_net_u32 (table_id);
18039   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18040   mp->is_ip4 = is_ip4;
18041   if (is_ip4)
18042     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18043   else
18044     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18045
18046   /* send it... */
18047   S (mp);
18048
18049   /* Wait for a reply... */
18050   W (ret);
18051   return ret;
18052 }
18053
18054 static int
18055 api_one_map_server_dump (vat_main_t * vam)
18056 {
18057   vl_api_one_map_server_dump_t *mp;
18058   vl_api_control_ping_t *mp_ping;
18059   int ret;
18060
18061   if (!vam->json_output)
18062     {
18063       print (vam->ofp, "%=20s", "Map server");
18064     }
18065
18066   M (ONE_MAP_SERVER_DUMP, mp);
18067   /* send it... */
18068   S (mp);
18069
18070   /* Use a control ping for synchronization */
18071   MPING (CONTROL_PING, mp_ping);
18072   S (mp_ping);
18073
18074   /* Wait for a reply... */
18075   W (ret);
18076   return ret;
18077 }
18078
18079 #define api_lisp_map_server_dump api_one_map_server_dump
18080
18081 static int
18082 api_one_map_resolver_dump (vat_main_t * vam)
18083 {
18084   vl_api_one_map_resolver_dump_t *mp;
18085   vl_api_control_ping_t *mp_ping;
18086   int ret;
18087
18088   if (!vam->json_output)
18089     {
18090       print (vam->ofp, "%=20s", "Map resolver");
18091     }
18092
18093   M (ONE_MAP_RESOLVER_DUMP, mp);
18094   /* send it... */
18095   S (mp);
18096
18097   /* Use a control ping for synchronization */
18098   MPING (CONTROL_PING, mp_ping);
18099   S (mp_ping);
18100
18101   /* Wait for a reply... */
18102   W (ret);
18103   return ret;
18104 }
18105
18106 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18107
18108 static int
18109 api_one_stats_flush (vat_main_t * vam)
18110 {
18111   vl_api_one_stats_flush_t *mp;
18112   int ret = 0;
18113
18114   M (ONE_STATS_FLUSH, mp);
18115   S (mp);
18116   W (ret);
18117   return ret;
18118 }
18119
18120 static int
18121 api_one_stats_dump (vat_main_t * vam)
18122 {
18123   vl_api_one_stats_dump_t *mp;
18124   vl_api_control_ping_t *mp_ping;
18125   int ret;
18126
18127   M (ONE_STATS_DUMP, mp);
18128   /* send it... */
18129   S (mp);
18130
18131   /* Use a control ping for synchronization */
18132   MPING (CONTROL_PING, mp_ping);
18133   S (mp_ping);
18134
18135   /* Wait for a reply... */
18136   W (ret);
18137   return ret;
18138 }
18139
18140 static int
18141 api_show_one_status (vat_main_t * vam)
18142 {
18143   vl_api_show_one_status_t *mp;
18144   int ret;
18145
18146   if (!vam->json_output)
18147     {
18148       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18149     }
18150
18151   M (SHOW_ONE_STATUS, mp);
18152   /* send it... */
18153   S (mp);
18154   /* Wait for a reply... */
18155   W (ret);
18156   return ret;
18157 }
18158
18159 #define api_show_lisp_status api_show_one_status
18160
18161 static int
18162 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18163 {
18164   vl_api_gpe_fwd_entry_path_dump_t *mp;
18165   vl_api_control_ping_t *mp_ping;
18166   unformat_input_t *i = vam->input;
18167   u32 fwd_entry_index = ~0;
18168   int ret;
18169
18170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18171     {
18172       if (unformat (i, "index %d", &fwd_entry_index))
18173         ;
18174       else
18175         break;
18176     }
18177
18178   if (~0 == fwd_entry_index)
18179     {
18180       errmsg ("no index specified!");
18181       return -99;
18182     }
18183
18184   if (!vam->json_output)
18185     {
18186       print (vam->ofp, "first line");
18187     }
18188
18189   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18190
18191   /* send it... */
18192   S (mp);
18193   /* Use a control ping for synchronization */
18194   MPING (CONTROL_PING, mp_ping);
18195   S (mp_ping);
18196
18197   /* Wait for a reply... */
18198   W (ret);
18199   return ret;
18200 }
18201
18202 static int
18203 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18204 {
18205   vl_api_one_get_map_request_itr_rlocs_t *mp;
18206   int ret;
18207
18208   if (!vam->json_output)
18209     {
18210       print (vam->ofp, "%=20s", "itr-rlocs:");
18211     }
18212
18213   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18214   /* send it... */
18215   S (mp);
18216   /* Wait for a reply... */
18217   W (ret);
18218   return ret;
18219 }
18220
18221 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18222
18223 static int
18224 api_af_packet_create (vat_main_t * vam)
18225 {
18226   unformat_input_t *i = vam->input;
18227   vl_api_af_packet_create_t *mp;
18228   u8 *host_if_name = 0;
18229   u8 hw_addr[6];
18230   u8 random_hw_addr = 1;
18231   int ret;
18232
18233   clib_memset (hw_addr, 0, sizeof (hw_addr));
18234
18235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18236     {
18237       if (unformat (i, "name %s", &host_if_name))
18238         vec_add1 (host_if_name, 0);
18239       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18240         random_hw_addr = 0;
18241       else
18242         break;
18243     }
18244
18245   if (!vec_len (host_if_name))
18246     {
18247       errmsg ("host-interface name must be specified");
18248       return -99;
18249     }
18250
18251   if (vec_len (host_if_name) > 64)
18252     {
18253       errmsg ("host-interface name too long");
18254       return -99;
18255     }
18256
18257   M (AF_PACKET_CREATE, mp);
18258
18259   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18260   clib_memcpy (mp->hw_addr, hw_addr, 6);
18261   mp->use_random_hw_addr = random_hw_addr;
18262   vec_free (host_if_name);
18263
18264   S (mp);
18265
18266   /* *INDENT-OFF* */
18267   W2 (ret,
18268       ({
18269         if (ret == 0)
18270           fprintf (vam->ofp ? vam->ofp : stderr,
18271                    " new sw_if_index = %d\n", vam->sw_if_index);
18272       }));
18273   /* *INDENT-ON* */
18274   return ret;
18275 }
18276
18277 static int
18278 api_af_packet_delete (vat_main_t * vam)
18279 {
18280   unformat_input_t *i = vam->input;
18281   vl_api_af_packet_delete_t *mp;
18282   u8 *host_if_name = 0;
18283   int ret;
18284
18285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18286     {
18287       if (unformat (i, "name %s", &host_if_name))
18288         vec_add1 (host_if_name, 0);
18289       else
18290         break;
18291     }
18292
18293   if (!vec_len (host_if_name))
18294     {
18295       errmsg ("host-interface name must be specified");
18296       return -99;
18297     }
18298
18299   if (vec_len (host_if_name) > 64)
18300     {
18301       errmsg ("host-interface name too long");
18302       return -99;
18303     }
18304
18305   M (AF_PACKET_DELETE, mp);
18306
18307   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18308   vec_free (host_if_name);
18309
18310   S (mp);
18311   W (ret);
18312   return ret;
18313 }
18314
18315 static void vl_api_af_packet_details_t_handler
18316   (vl_api_af_packet_details_t * mp)
18317 {
18318   vat_main_t *vam = &vat_main;
18319
18320   print (vam->ofp, "%-16s %d",
18321          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18322 }
18323
18324 static void vl_api_af_packet_details_t_handler_json
18325   (vl_api_af_packet_details_t * mp)
18326 {
18327   vat_main_t *vam = &vat_main;
18328   vat_json_node_t *node = NULL;
18329
18330   if (VAT_JSON_ARRAY != vam->json_tree.type)
18331     {
18332       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18333       vat_json_init_array (&vam->json_tree);
18334     }
18335   node = vat_json_array_add (&vam->json_tree);
18336
18337   vat_json_init_object (node);
18338   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18339   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18340 }
18341
18342 static int
18343 api_af_packet_dump (vat_main_t * vam)
18344 {
18345   vl_api_af_packet_dump_t *mp;
18346   vl_api_control_ping_t *mp_ping;
18347   int ret;
18348
18349   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18350   /* Get list of tap interfaces */
18351   M (AF_PACKET_DUMP, mp);
18352   S (mp);
18353
18354   /* Use a control ping for synchronization */
18355   MPING (CONTROL_PING, mp_ping);
18356   S (mp_ping);
18357
18358   W (ret);
18359   return ret;
18360 }
18361
18362 static int
18363 api_policer_add_del (vat_main_t * vam)
18364 {
18365   unformat_input_t *i = vam->input;
18366   vl_api_policer_add_del_t *mp;
18367   u8 is_add = 1;
18368   u8 *name = 0;
18369   u32 cir = 0;
18370   u32 eir = 0;
18371   u64 cb = 0;
18372   u64 eb = 0;
18373   u8 rate_type = 0;
18374   u8 round_type = 0;
18375   u8 type = 0;
18376   u8 color_aware = 0;
18377   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18378   int ret;
18379
18380   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18381   conform_action.dscp = 0;
18382   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18383   exceed_action.dscp = 0;
18384   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18385   violate_action.dscp = 0;
18386
18387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18388     {
18389       if (unformat (i, "del"))
18390         is_add = 0;
18391       else if (unformat (i, "name %s", &name))
18392         vec_add1 (name, 0);
18393       else if (unformat (i, "cir %u", &cir))
18394         ;
18395       else if (unformat (i, "eir %u", &eir))
18396         ;
18397       else if (unformat (i, "cb %u", &cb))
18398         ;
18399       else if (unformat (i, "eb %u", &eb))
18400         ;
18401       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18402                          &rate_type))
18403         ;
18404       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18405                          &round_type))
18406         ;
18407       else if (unformat (i, "type %U", unformat_policer_type, &type))
18408         ;
18409       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18410                          &conform_action))
18411         ;
18412       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18413                          &exceed_action))
18414         ;
18415       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18416                          &violate_action))
18417         ;
18418       else if (unformat (i, "color-aware"))
18419         color_aware = 1;
18420       else
18421         break;
18422     }
18423
18424   if (!vec_len (name))
18425     {
18426       errmsg ("policer name must be specified");
18427       return -99;
18428     }
18429
18430   if (vec_len (name) > 64)
18431     {
18432       errmsg ("policer name too long");
18433       return -99;
18434     }
18435
18436   M (POLICER_ADD_DEL, mp);
18437
18438   clib_memcpy (mp->name, name, vec_len (name));
18439   vec_free (name);
18440   mp->is_add = is_add;
18441   mp->cir = ntohl (cir);
18442   mp->eir = ntohl (eir);
18443   mp->cb = clib_net_to_host_u64 (cb);
18444   mp->eb = clib_net_to_host_u64 (eb);
18445   mp->rate_type = rate_type;
18446   mp->round_type = round_type;
18447   mp->type = type;
18448   mp->conform_action_type = conform_action.action_type;
18449   mp->conform_dscp = conform_action.dscp;
18450   mp->exceed_action_type = exceed_action.action_type;
18451   mp->exceed_dscp = exceed_action.dscp;
18452   mp->violate_action_type = violate_action.action_type;
18453   mp->violate_dscp = violate_action.dscp;
18454   mp->color_aware = color_aware;
18455
18456   S (mp);
18457   W (ret);
18458   return ret;
18459 }
18460
18461 static int
18462 api_policer_dump (vat_main_t * vam)
18463 {
18464   unformat_input_t *i = vam->input;
18465   vl_api_policer_dump_t *mp;
18466   vl_api_control_ping_t *mp_ping;
18467   u8 *match_name = 0;
18468   u8 match_name_valid = 0;
18469   int ret;
18470
18471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18472     {
18473       if (unformat (i, "name %s", &match_name))
18474         {
18475           vec_add1 (match_name, 0);
18476           match_name_valid = 1;
18477         }
18478       else
18479         break;
18480     }
18481
18482   M (POLICER_DUMP, mp);
18483   mp->match_name_valid = match_name_valid;
18484   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18485   vec_free (match_name);
18486   /* send it... */
18487   S (mp);
18488
18489   /* Use a control ping for synchronization */
18490   MPING (CONTROL_PING, mp_ping);
18491   S (mp_ping);
18492
18493   /* Wait for a reply... */
18494   W (ret);
18495   return ret;
18496 }
18497
18498 static int
18499 api_policer_classify_set_interface (vat_main_t * vam)
18500 {
18501   unformat_input_t *i = vam->input;
18502   vl_api_policer_classify_set_interface_t *mp;
18503   u32 sw_if_index;
18504   int sw_if_index_set;
18505   u32 ip4_table_index = ~0;
18506   u32 ip6_table_index = ~0;
18507   u32 l2_table_index = ~0;
18508   u8 is_add = 1;
18509   int ret;
18510
18511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18512     {
18513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18514         sw_if_index_set = 1;
18515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18516         sw_if_index_set = 1;
18517       else if (unformat (i, "del"))
18518         is_add = 0;
18519       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18520         ;
18521       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18522         ;
18523       else if (unformat (i, "l2-table %d", &l2_table_index))
18524         ;
18525       else
18526         {
18527           clib_warning ("parse error '%U'", format_unformat_error, i);
18528           return -99;
18529         }
18530     }
18531
18532   if (sw_if_index_set == 0)
18533     {
18534       errmsg ("missing interface name or sw_if_index");
18535       return -99;
18536     }
18537
18538   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18539
18540   mp->sw_if_index = ntohl (sw_if_index);
18541   mp->ip4_table_index = ntohl (ip4_table_index);
18542   mp->ip6_table_index = ntohl (ip6_table_index);
18543   mp->l2_table_index = ntohl (l2_table_index);
18544   mp->is_add = is_add;
18545
18546   S (mp);
18547   W (ret);
18548   return ret;
18549 }
18550
18551 static int
18552 api_policer_classify_dump (vat_main_t * vam)
18553 {
18554   unformat_input_t *i = vam->input;
18555   vl_api_policer_classify_dump_t *mp;
18556   vl_api_control_ping_t *mp_ping;
18557   u8 type = POLICER_CLASSIFY_N_TABLES;
18558   int ret;
18559
18560   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18561     ;
18562   else
18563     {
18564       errmsg ("classify table type must be specified");
18565       return -99;
18566     }
18567
18568   if (!vam->json_output)
18569     {
18570       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18571     }
18572
18573   M (POLICER_CLASSIFY_DUMP, mp);
18574   mp->type = type;
18575   /* send it... */
18576   S (mp);
18577
18578   /* Use a control ping for synchronization */
18579   MPING (CONTROL_PING, mp_ping);
18580   S (mp_ping);
18581
18582   /* Wait for a reply... */
18583   W (ret);
18584   return ret;
18585 }
18586
18587 static int
18588 api_netmap_create (vat_main_t * vam)
18589 {
18590   unformat_input_t *i = vam->input;
18591   vl_api_netmap_create_t *mp;
18592   u8 *if_name = 0;
18593   u8 hw_addr[6];
18594   u8 random_hw_addr = 1;
18595   u8 is_pipe = 0;
18596   u8 is_master = 0;
18597   int ret;
18598
18599   clib_memset (hw_addr, 0, sizeof (hw_addr));
18600
18601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18602     {
18603       if (unformat (i, "name %s", &if_name))
18604         vec_add1 (if_name, 0);
18605       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18606         random_hw_addr = 0;
18607       else if (unformat (i, "pipe"))
18608         is_pipe = 1;
18609       else if (unformat (i, "master"))
18610         is_master = 1;
18611       else if (unformat (i, "slave"))
18612         is_master = 0;
18613       else
18614         break;
18615     }
18616
18617   if (!vec_len (if_name))
18618     {
18619       errmsg ("interface name must be specified");
18620       return -99;
18621     }
18622
18623   if (vec_len (if_name) > 64)
18624     {
18625       errmsg ("interface name too long");
18626       return -99;
18627     }
18628
18629   M (NETMAP_CREATE, mp);
18630
18631   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18632   clib_memcpy (mp->hw_addr, hw_addr, 6);
18633   mp->use_random_hw_addr = random_hw_addr;
18634   mp->is_pipe = is_pipe;
18635   mp->is_master = is_master;
18636   vec_free (if_name);
18637
18638   S (mp);
18639   W (ret);
18640   return ret;
18641 }
18642
18643 static int
18644 api_netmap_delete (vat_main_t * vam)
18645 {
18646   unformat_input_t *i = vam->input;
18647   vl_api_netmap_delete_t *mp;
18648   u8 *if_name = 0;
18649   int ret;
18650
18651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18652     {
18653       if (unformat (i, "name %s", &if_name))
18654         vec_add1 (if_name, 0);
18655       else
18656         break;
18657     }
18658
18659   if (!vec_len (if_name))
18660     {
18661       errmsg ("interface name must be specified");
18662       return -99;
18663     }
18664
18665   if (vec_len (if_name) > 64)
18666     {
18667       errmsg ("interface name too long");
18668       return -99;
18669     }
18670
18671   M (NETMAP_DELETE, mp);
18672
18673   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18674   vec_free (if_name);
18675
18676   S (mp);
18677   W (ret);
18678   return ret;
18679 }
18680
18681 static u8 *
18682 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18683 {
18684   vl_api_fib_path_nh_proto_t proto =
18685     va_arg (*args, vl_api_fib_path_nh_proto_t);
18686
18687   switch (proto)
18688     {
18689     case FIB_API_PATH_NH_PROTO_IP4:
18690       s = format (s, "ip4");
18691       break;
18692     case FIB_API_PATH_NH_PROTO_IP6:
18693       s = format (s, "ip6");
18694       break;
18695     case FIB_API_PATH_NH_PROTO_MPLS:
18696       s = format (s, "mpls");
18697       break;
18698     case FIB_API_PATH_NH_PROTO_BIER:
18699       s = format (s, "bier");
18700       break;
18701     case FIB_API_PATH_NH_PROTO_ETHERNET:
18702       s = format (s, "ethernet");
18703       break;
18704     }
18705
18706   return (s);
18707 }
18708
18709 static u8 *
18710 format_vl_api_ip_address_union (u8 * s, va_list * args)
18711 {
18712   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18713   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18714
18715   switch (af)
18716     {
18717     case ADDRESS_IP4:
18718       s = format (s, "%U", format_ip4_address, u->ip4);
18719       break;
18720     case ADDRESS_IP6:
18721       s = format (s, "%U", format_ip6_address, u->ip6);
18722       break;
18723     }
18724   return (s);
18725 }
18726
18727 static u8 *
18728 format_vl_api_fib_path_type (u8 * s, va_list * args)
18729 {
18730   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18731
18732   switch (t)
18733     {
18734     case FIB_API_PATH_TYPE_NORMAL:
18735       s = format (s, "normal");
18736       break;
18737     case FIB_API_PATH_TYPE_LOCAL:
18738       s = format (s, "local");
18739       break;
18740     case FIB_API_PATH_TYPE_DROP:
18741       s = format (s, "drop");
18742       break;
18743     case FIB_API_PATH_TYPE_UDP_ENCAP:
18744       s = format (s, "udp-encap");
18745       break;
18746     case FIB_API_PATH_TYPE_BIER_IMP:
18747       s = format (s, "bier-imp");
18748       break;
18749     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18750       s = format (s, "unreach");
18751       break;
18752     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18753       s = format (s, "prohibit");
18754       break;
18755     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18756       s = format (s, "src-lookup");
18757       break;
18758     case FIB_API_PATH_TYPE_DVR:
18759       s = format (s, "dvr");
18760       break;
18761     case FIB_API_PATH_TYPE_INTERFACE_RX:
18762       s = format (s, "interface-rx");
18763       break;
18764     case FIB_API_PATH_TYPE_CLASSIFY:
18765       s = format (s, "classify");
18766       break;
18767     }
18768
18769   return (s);
18770 }
18771
18772 static void
18773 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18774 {
18775   print (vam->ofp,
18776          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18777          ntohl (fp->weight), ntohl (fp->sw_if_index),
18778          format_vl_api_fib_path_type, fp->type,
18779          format_fib_api_path_nh_proto, fp->proto,
18780          format_vl_api_ip_address_union, &fp->nh.address);
18781 }
18782
18783 static void
18784 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18785                                  vl_api_fib_path_t * fp)
18786 {
18787   struct in_addr ip4;
18788   struct in6_addr ip6;
18789
18790   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18791   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18792   vat_json_object_add_uint (node, "type", fp->type);
18793   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18794   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18795     {
18796       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18797       vat_json_object_add_ip4 (node, "next_hop", ip4);
18798     }
18799   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18800     {
18801       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18802       vat_json_object_add_ip6 (node, "next_hop", ip6);
18803     }
18804 }
18805
18806 static void
18807 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18808 {
18809   vat_main_t *vam = &vat_main;
18810   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18811   vl_api_fib_path_t *fp;
18812   i32 i;
18813
18814   print (vam->ofp, "sw_if_index %d via:",
18815          ntohl (mp->mt_tunnel.mt_sw_if_index));
18816   fp = mp->mt_tunnel.mt_paths;
18817   for (i = 0; i < count; i++)
18818     {
18819       vl_api_fib_path_print (vam, fp);
18820       fp++;
18821     }
18822
18823   print (vam->ofp, "");
18824 }
18825
18826 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18827 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18828
18829 static void
18830 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18831 {
18832   vat_main_t *vam = &vat_main;
18833   vat_json_node_t *node = NULL;
18834   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18835   vl_api_fib_path_t *fp;
18836   i32 i;
18837
18838   if (VAT_JSON_ARRAY != vam->json_tree.type)
18839     {
18840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18841       vat_json_init_array (&vam->json_tree);
18842     }
18843   node = vat_json_array_add (&vam->json_tree);
18844
18845   vat_json_init_object (node);
18846   vat_json_object_add_uint (node, "sw_if_index",
18847                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18848
18849   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18850
18851   fp = mp->mt_tunnel.mt_paths;
18852   for (i = 0; i < count; i++)
18853     {
18854       vl_api_mpls_fib_path_json_print (node, fp);
18855       fp++;
18856     }
18857 }
18858
18859 static int
18860 api_mpls_tunnel_dump (vat_main_t * vam)
18861 {
18862   vl_api_mpls_tunnel_dump_t *mp;
18863   vl_api_control_ping_t *mp_ping;
18864   int ret;
18865
18866   M (MPLS_TUNNEL_DUMP, mp);
18867
18868   S (mp);
18869
18870   /* Use a control ping for synchronization */
18871   MPING (CONTROL_PING, mp_ping);
18872   S (mp_ping);
18873
18874   W (ret);
18875   return ret;
18876 }
18877
18878 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18879 #define vl_api_mpls_table_details_t_print vl_noop_handler
18880
18881
18882 static void
18883 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18884 {
18885   vat_main_t *vam = &vat_main;
18886
18887   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18888 }
18889
18890 static void vl_api_mpls_table_details_t_handler_json
18891   (vl_api_mpls_table_details_t * mp)
18892 {
18893   vat_main_t *vam = &vat_main;
18894   vat_json_node_t *node = NULL;
18895
18896   if (VAT_JSON_ARRAY != vam->json_tree.type)
18897     {
18898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18899       vat_json_init_array (&vam->json_tree);
18900     }
18901   node = vat_json_array_add (&vam->json_tree);
18902
18903   vat_json_init_object (node);
18904   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18905 }
18906
18907 static int
18908 api_mpls_table_dump (vat_main_t * vam)
18909 {
18910   vl_api_mpls_table_dump_t *mp;
18911   vl_api_control_ping_t *mp_ping;
18912   int ret;
18913
18914   M (MPLS_TABLE_DUMP, mp);
18915   S (mp);
18916
18917   /* Use a control ping for synchronization */
18918   MPING (CONTROL_PING, mp_ping);
18919   S (mp_ping);
18920
18921   W (ret);
18922   return ret;
18923 }
18924
18925 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18926 #define vl_api_mpls_route_details_t_print vl_noop_handler
18927
18928 static void
18929 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18930 {
18931   vat_main_t *vam = &vat_main;
18932   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18933   vl_api_fib_path_t *fp;
18934   int i;
18935
18936   print (vam->ofp,
18937          "table-id %d, label %u, ess_bit %u",
18938          ntohl (mp->mr_route.mr_table_id),
18939          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18940   fp = mp->mr_route.mr_paths;
18941   for (i = 0; i < count; i++)
18942     {
18943       vl_api_fib_path_print (vam, fp);
18944       fp++;
18945     }
18946 }
18947
18948 static void vl_api_mpls_route_details_t_handler_json
18949   (vl_api_mpls_route_details_t * mp)
18950 {
18951   vat_main_t *vam = &vat_main;
18952   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18953   vat_json_node_t *node = NULL;
18954   vl_api_fib_path_t *fp;
18955   int i;
18956
18957   if (VAT_JSON_ARRAY != vam->json_tree.type)
18958     {
18959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18960       vat_json_init_array (&vam->json_tree);
18961     }
18962   node = vat_json_array_add (&vam->json_tree);
18963
18964   vat_json_init_object (node);
18965   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18966   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18967   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18968   vat_json_object_add_uint (node, "path_count", count);
18969   fp = mp->mr_route.mr_paths;
18970   for (i = 0; i < count; i++)
18971     {
18972       vl_api_mpls_fib_path_json_print (node, fp);
18973       fp++;
18974     }
18975 }
18976
18977 static int
18978 api_mpls_route_dump (vat_main_t * vam)
18979 {
18980   unformat_input_t *input = vam->input;
18981   vl_api_mpls_route_dump_t *mp;
18982   vl_api_control_ping_t *mp_ping;
18983   u32 table_id;
18984   int ret;
18985
18986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18987     {
18988       if (unformat (input, "table_id %d", &table_id))
18989         ;
18990       else
18991         break;
18992     }
18993   if (table_id == ~0)
18994     {
18995       errmsg ("missing table id");
18996       return -99;
18997     }
18998
18999   M (MPLS_ROUTE_DUMP, mp);
19000
19001   mp->table.mt_table_id = ntohl (table_id);
19002   S (mp);
19003
19004   /* Use a control ping for synchronization */
19005   MPING (CONTROL_PING, mp_ping);
19006   S (mp_ping);
19007
19008   W (ret);
19009   return ret;
19010 }
19011
19012 #define vl_api_ip_table_details_t_endian vl_noop_handler
19013 #define vl_api_ip_table_details_t_print vl_noop_handler
19014
19015 static void
19016 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19017 {
19018   vat_main_t *vam = &vat_main;
19019
19020   print (vam->ofp,
19021          "%s; table-id %d, prefix %U/%d",
19022          mp->table.name, ntohl (mp->table.table_id));
19023 }
19024
19025
19026 static void vl_api_ip_table_details_t_handler_json
19027   (vl_api_ip_table_details_t * mp)
19028 {
19029   vat_main_t *vam = &vat_main;
19030   vat_json_node_t *node = NULL;
19031
19032   if (VAT_JSON_ARRAY != vam->json_tree.type)
19033     {
19034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19035       vat_json_init_array (&vam->json_tree);
19036     }
19037   node = vat_json_array_add (&vam->json_tree);
19038
19039   vat_json_init_object (node);
19040   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19041 }
19042
19043 static int
19044 api_ip_table_dump (vat_main_t * vam)
19045 {
19046   vl_api_ip_table_dump_t *mp;
19047   vl_api_control_ping_t *mp_ping;
19048   int ret;
19049
19050   M (IP_TABLE_DUMP, mp);
19051   S (mp);
19052
19053   /* Use a control ping for synchronization */
19054   MPING (CONTROL_PING, mp_ping);
19055   S (mp_ping);
19056
19057   W (ret);
19058   return ret;
19059 }
19060
19061 static int
19062 api_ip_mtable_dump (vat_main_t * vam)
19063 {
19064   vl_api_ip_mtable_dump_t *mp;
19065   vl_api_control_ping_t *mp_ping;
19066   int ret;
19067
19068   M (IP_MTABLE_DUMP, mp);
19069   S (mp);
19070
19071   /* Use a control ping for synchronization */
19072   MPING (CONTROL_PING, mp_ping);
19073   S (mp_ping);
19074
19075   W (ret);
19076   return ret;
19077 }
19078
19079 static int
19080 api_ip_mroute_dump (vat_main_t * vam)
19081 {
19082   unformat_input_t *input = vam->input;
19083   vl_api_control_ping_t *mp_ping;
19084   vl_api_ip_mroute_dump_t *mp;
19085   int ret, is_ip6;
19086   u32 table_id;
19087
19088   is_ip6 = 0;
19089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19090     {
19091       if (unformat (input, "table_id %d", &table_id))
19092         ;
19093       else if (unformat (input, "ip6"))
19094         is_ip6 = 1;
19095       else if (unformat (input, "ip4"))
19096         is_ip6 = 0;
19097       else
19098         break;
19099     }
19100   if (table_id == ~0)
19101     {
19102       errmsg ("missing table id");
19103       return -99;
19104     }
19105
19106   M (IP_MROUTE_DUMP, mp);
19107   mp->table.table_id = table_id;
19108   mp->table.is_ip6 = is_ip6;
19109   S (mp);
19110
19111   /* Use a control ping for synchronization */
19112   MPING (CONTROL_PING, mp_ping);
19113   S (mp_ping);
19114
19115   W (ret);
19116   return ret;
19117 }
19118
19119 static void vl_api_ip_neighbor_details_t_handler
19120   (vl_api_ip_neighbor_details_t * mp)
19121 {
19122   vat_main_t *vam = &vat_main;
19123
19124   print (vam->ofp, "%c %U %U",
19125          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19126          format_vl_api_mac_address, &mp->neighbor.mac_address,
19127          format_vl_api_address, &mp->neighbor.ip_address);
19128 }
19129
19130 static void vl_api_ip_neighbor_details_t_handler_json
19131   (vl_api_ip_neighbor_details_t * mp)
19132 {
19133
19134   vat_main_t *vam = &vat_main;
19135   vat_json_node_t *node;
19136
19137   if (VAT_JSON_ARRAY != vam->json_tree.type)
19138     {
19139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19140       vat_json_init_array (&vam->json_tree);
19141     }
19142   node = vat_json_array_add (&vam->json_tree);
19143
19144   vat_json_init_object (node);
19145   vat_json_object_add_string_copy
19146     (node, "flag",
19147      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19148       (u8 *) "static" : (u8 *) "dynamic"));
19149
19150   vat_json_object_add_string_copy (node, "link_layer",
19151                                    format (0, "%U", format_vl_api_mac_address,
19152                                            &mp->neighbor.mac_address));
19153   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19154 }
19155
19156 static int
19157 api_ip_neighbor_dump (vat_main_t * vam)
19158 {
19159   unformat_input_t *i = vam->input;
19160   vl_api_ip_neighbor_dump_t *mp;
19161   vl_api_control_ping_t *mp_ping;
19162   u8 is_ipv6 = 0;
19163   u32 sw_if_index = ~0;
19164   int ret;
19165
19166   /* Parse args required to build the message */
19167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19168     {
19169       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19170         ;
19171       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19172         ;
19173       else if (unformat (i, "ip6"))
19174         is_ipv6 = 1;
19175       else
19176         break;
19177     }
19178
19179   if (sw_if_index == ~0)
19180     {
19181       errmsg ("missing interface name or sw_if_index");
19182       return -99;
19183     }
19184
19185   M (IP_NEIGHBOR_DUMP, mp);
19186   mp->is_ipv6 = (u8) is_ipv6;
19187   mp->sw_if_index = ntohl (sw_if_index);
19188   S (mp);
19189
19190   /* Use a control ping for synchronization */
19191   MPING (CONTROL_PING, mp_ping);
19192   S (mp_ping);
19193
19194   W (ret);
19195   return ret;
19196 }
19197
19198 #define vl_api_ip_route_details_t_endian vl_noop_handler
19199 #define vl_api_ip_route_details_t_print vl_noop_handler
19200
19201 static void
19202 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19203 {
19204   vat_main_t *vam = &vat_main;
19205   u8 count = mp->route.n_paths;
19206   vl_api_fib_path_t *fp;
19207   int i;
19208
19209   print (vam->ofp,
19210          "table-id %d, prefix %U/%d",
19211          ntohl (mp->route.table_id),
19212          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19213   for (i = 0; i < count; i++)
19214     {
19215       fp = &mp->route.paths[i];
19216
19217       vl_api_fib_path_print (vam, fp);
19218       fp++;
19219     }
19220 }
19221
19222 static void vl_api_ip_route_details_t_handler_json
19223   (vl_api_ip_route_details_t * mp)
19224 {
19225   vat_main_t *vam = &vat_main;
19226   u8 count = mp->route.n_paths;
19227   vat_json_node_t *node = NULL;
19228   struct in_addr ip4;
19229   struct in6_addr ip6;
19230   vl_api_fib_path_t *fp;
19231   int i;
19232
19233   if (VAT_JSON_ARRAY != vam->json_tree.type)
19234     {
19235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19236       vat_json_init_array (&vam->json_tree);
19237     }
19238   node = vat_json_array_add (&vam->json_tree);
19239
19240   vat_json_init_object (node);
19241   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19242   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19243     {
19244       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19245       vat_json_object_add_ip6 (node, "prefix", ip6);
19246     }
19247   else
19248     {
19249       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19250       vat_json_object_add_ip4 (node, "prefix", ip4);
19251     }
19252   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19253   vat_json_object_add_uint (node, "path_count", count);
19254   for (i = 0; i < count; i++)
19255     {
19256       fp = &mp->route.paths[i];
19257       vl_api_mpls_fib_path_json_print (node, fp);
19258     }
19259 }
19260
19261 static int
19262 api_ip_route_dump (vat_main_t * vam)
19263 {
19264   unformat_input_t *input = vam->input;
19265   vl_api_ip_route_dump_t *mp;
19266   vl_api_control_ping_t *mp_ping;
19267   u32 table_id;
19268   u8 is_ip6;
19269   int ret;
19270
19271   is_ip6 = 0;
19272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19273     {
19274       if (unformat (input, "table_id %d", &table_id))
19275         ;
19276       else if (unformat (input, "ip6"))
19277         is_ip6 = 1;
19278       else if (unformat (input, "ip4"))
19279         is_ip6 = 0;
19280       else
19281         break;
19282     }
19283   if (table_id == ~0)
19284     {
19285       errmsg ("missing table id");
19286       return -99;
19287     }
19288
19289   M (IP_ROUTE_DUMP, mp);
19290
19291   mp->table.table_id = table_id;
19292   mp->table.is_ip6 = is_ip6;
19293
19294   S (mp);
19295
19296   /* Use a control ping for synchronization */
19297   MPING (CONTROL_PING, mp_ping);
19298   S (mp_ping);
19299
19300   W (ret);
19301   return ret;
19302 }
19303
19304 int
19305 api_classify_table_ids (vat_main_t * vam)
19306 {
19307   vl_api_classify_table_ids_t *mp;
19308   int ret;
19309
19310   /* Construct the API message */
19311   M (CLASSIFY_TABLE_IDS, mp);
19312   mp->context = 0;
19313
19314   S (mp);
19315   W (ret);
19316   return ret;
19317 }
19318
19319 int
19320 api_classify_table_by_interface (vat_main_t * vam)
19321 {
19322   unformat_input_t *input = vam->input;
19323   vl_api_classify_table_by_interface_t *mp;
19324
19325   u32 sw_if_index = ~0;
19326   int ret;
19327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19328     {
19329       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19330         ;
19331       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19332         ;
19333       else
19334         break;
19335     }
19336   if (sw_if_index == ~0)
19337     {
19338       errmsg ("missing interface name or sw_if_index");
19339       return -99;
19340     }
19341
19342   /* Construct the API message */
19343   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19344   mp->context = 0;
19345   mp->sw_if_index = ntohl (sw_if_index);
19346
19347   S (mp);
19348   W (ret);
19349   return ret;
19350 }
19351
19352 int
19353 api_classify_table_info (vat_main_t * vam)
19354 {
19355   unformat_input_t *input = vam->input;
19356   vl_api_classify_table_info_t *mp;
19357
19358   u32 table_id = ~0;
19359   int ret;
19360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19361     {
19362       if (unformat (input, "table_id %d", &table_id))
19363         ;
19364       else
19365         break;
19366     }
19367   if (table_id == ~0)
19368     {
19369       errmsg ("missing table id");
19370       return -99;
19371     }
19372
19373   /* Construct the API message */
19374   M (CLASSIFY_TABLE_INFO, mp);
19375   mp->context = 0;
19376   mp->table_id = ntohl (table_id);
19377
19378   S (mp);
19379   W (ret);
19380   return ret;
19381 }
19382
19383 int
19384 api_classify_session_dump (vat_main_t * vam)
19385 {
19386   unformat_input_t *input = vam->input;
19387   vl_api_classify_session_dump_t *mp;
19388   vl_api_control_ping_t *mp_ping;
19389
19390   u32 table_id = ~0;
19391   int ret;
19392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19393     {
19394       if (unformat (input, "table_id %d", &table_id))
19395         ;
19396       else
19397         break;
19398     }
19399   if (table_id == ~0)
19400     {
19401       errmsg ("missing table id");
19402       return -99;
19403     }
19404
19405   /* Construct the API message */
19406   M (CLASSIFY_SESSION_DUMP, mp);
19407   mp->context = 0;
19408   mp->table_id = ntohl (table_id);
19409   S (mp);
19410
19411   /* Use a control ping for synchronization */
19412   MPING (CONTROL_PING, mp_ping);
19413   S (mp_ping);
19414
19415   W (ret);
19416   return ret;
19417 }
19418
19419 static void
19420 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19421 {
19422   vat_main_t *vam = &vat_main;
19423
19424   print (vam->ofp, "collector_address %U, collector_port %d, "
19425          "src_address %U, vrf_id %d, path_mtu %u, "
19426          "template_interval %u, udp_checksum %d",
19427          format_ip4_address, mp->collector_address,
19428          ntohs (mp->collector_port),
19429          format_ip4_address, mp->src_address,
19430          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19431          ntohl (mp->template_interval), mp->udp_checksum);
19432
19433   vam->retval = 0;
19434   vam->result_ready = 1;
19435 }
19436
19437 static void
19438   vl_api_ipfix_exporter_details_t_handler_json
19439   (vl_api_ipfix_exporter_details_t * mp)
19440 {
19441   vat_main_t *vam = &vat_main;
19442   vat_json_node_t node;
19443   struct in_addr collector_address;
19444   struct in_addr src_address;
19445
19446   vat_json_init_object (&node);
19447   clib_memcpy (&collector_address, &mp->collector_address,
19448                sizeof (collector_address));
19449   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19450   vat_json_object_add_uint (&node, "collector_port",
19451                             ntohs (mp->collector_port));
19452   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19453   vat_json_object_add_ip4 (&node, "src_address", src_address);
19454   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19455   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19456   vat_json_object_add_uint (&node, "template_interval",
19457                             ntohl (mp->template_interval));
19458   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19459
19460   vat_json_print (vam->ofp, &node);
19461   vat_json_free (&node);
19462   vam->retval = 0;
19463   vam->result_ready = 1;
19464 }
19465
19466 int
19467 api_ipfix_exporter_dump (vat_main_t * vam)
19468 {
19469   vl_api_ipfix_exporter_dump_t *mp;
19470   int ret;
19471
19472   /* Construct the API message */
19473   M (IPFIX_EXPORTER_DUMP, mp);
19474   mp->context = 0;
19475
19476   S (mp);
19477   W (ret);
19478   return ret;
19479 }
19480
19481 static int
19482 api_ipfix_classify_stream_dump (vat_main_t * vam)
19483 {
19484   vl_api_ipfix_classify_stream_dump_t *mp;
19485   int ret;
19486
19487   /* Construct the API message */
19488   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19489   mp->context = 0;
19490
19491   S (mp);
19492   W (ret);
19493   return ret;
19494   /* NOTREACHED */
19495   return 0;
19496 }
19497
19498 static void
19499   vl_api_ipfix_classify_stream_details_t_handler
19500   (vl_api_ipfix_classify_stream_details_t * mp)
19501 {
19502   vat_main_t *vam = &vat_main;
19503   print (vam->ofp, "domain_id %d, src_port %d",
19504          ntohl (mp->domain_id), ntohs (mp->src_port));
19505   vam->retval = 0;
19506   vam->result_ready = 1;
19507 }
19508
19509 static void
19510   vl_api_ipfix_classify_stream_details_t_handler_json
19511   (vl_api_ipfix_classify_stream_details_t * mp)
19512 {
19513   vat_main_t *vam = &vat_main;
19514   vat_json_node_t node;
19515
19516   vat_json_init_object (&node);
19517   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19518   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19519
19520   vat_json_print (vam->ofp, &node);
19521   vat_json_free (&node);
19522   vam->retval = 0;
19523   vam->result_ready = 1;
19524 }
19525
19526 static int
19527 api_ipfix_classify_table_dump (vat_main_t * vam)
19528 {
19529   vl_api_ipfix_classify_table_dump_t *mp;
19530   vl_api_control_ping_t *mp_ping;
19531   int ret;
19532
19533   if (!vam->json_output)
19534     {
19535       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19536              "transport_protocol");
19537     }
19538
19539   /* Construct the API message */
19540   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19541
19542   /* send it... */
19543   S (mp);
19544
19545   /* Use a control ping for synchronization */
19546   MPING (CONTROL_PING, mp_ping);
19547   S (mp_ping);
19548
19549   W (ret);
19550   return ret;
19551 }
19552
19553 static void
19554   vl_api_ipfix_classify_table_details_t_handler
19555   (vl_api_ipfix_classify_table_details_t * mp)
19556 {
19557   vat_main_t *vam = &vat_main;
19558   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19559          mp->transport_protocol);
19560 }
19561
19562 static void
19563   vl_api_ipfix_classify_table_details_t_handler_json
19564   (vl_api_ipfix_classify_table_details_t * mp)
19565 {
19566   vat_json_node_t *node = NULL;
19567   vat_main_t *vam = &vat_main;
19568
19569   if (VAT_JSON_ARRAY != vam->json_tree.type)
19570     {
19571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19572       vat_json_init_array (&vam->json_tree);
19573     }
19574
19575   node = vat_json_array_add (&vam->json_tree);
19576   vat_json_init_object (node);
19577
19578   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19579   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19580   vat_json_object_add_uint (node, "transport_protocol",
19581                             mp->transport_protocol);
19582 }
19583
19584 static int
19585 api_sw_interface_span_enable_disable (vat_main_t * vam)
19586 {
19587   unformat_input_t *i = vam->input;
19588   vl_api_sw_interface_span_enable_disable_t *mp;
19589   u32 src_sw_if_index = ~0;
19590   u32 dst_sw_if_index = ~0;
19591   u8 state = 3;
19592   int ret;
19593   u8 is_l2 = 0;
19594
19595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19596     {
19597       if (unformat
19598           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19599         ;
19600       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19601         ;
19602       else
19603         if (unformat
19604             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19605         ;
19606       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19607         ;
19608       else if (unformat (i, "disable"))
19609         state = 0;
19610       else if (unformat (i, "rx"))
19611         state = 1;
19612       else if (unformat (i, "tx"))
19613         state = 2;
19614       else if (unformat (i, "both"))
19615         state = 3;
19616       else if (unformat (i, "l2"))
19617         is_l2 = 1;
19618       else
19619         break;
19620     }
19621
19622   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19623
19624   mp->sw_if_index_from = htonl (src_sw_if_index);
19625   mp->sw_if_index_to = htonl (dst_sw_if_index);
19626   mp->state = state;
19627   mp->is_l2 = is_l2;
19628
19629   S (mp);
19630   W (ret);
19631   return ret;
19632 }
19633
19634 static void
19635 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19636                                             * mp)
19637 {
19638   vat_main_t *vam = &vat_main;
19639   u8 *sw_if_from_name = 0;
19640   u8 *sw_if_to_name = 0;
19641   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19642   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19643   char *states[] = { "none", "rx", "tx", "both" };
19644   hash_pair_t *p;
19645
19646   /* *INDENT-OFF* */
19647   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19648   ({
19649     if ((u32) p->value[0] == sw_if_index_from)
19650       {
19651         sw_if_from_name = (u8 *)(p->key);
19652         if (sw_if_to_name)
19653           break;
19654       }
19655     if ((u32) p->value[0] == sw_if_index_to)
19656       {
19657         sw_if_to_name = (u8 *)(p->key);
19658         if (sw_if_from_name)
19659           break;
19660       }
19661   }));
19662   /* *INDENT-ON* */
19663   print (vam->ofp, "%20s => %20s (%s) %s",
19664          sw_if_from_name, sw_if_to_name, states[mp->state],
19665          mp->is_l2 ? "l2" : "device");
19666 }
19667
19668 static void
19669   vl_api_sw_interface_span_details_t_handler_json
19670   (vl_api_sw_interface_span_details_t * mp)
19671 {
19672   vat_main_t *vam = &vat_main;
19673   vat_json_node_t *node = NULL;
19674   u8 *sw_if_from_name = 0;
19675   u8 *sw_if_to_name = 0;
19676   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19677   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19678   hash_pair_t *p;
19679
19680   /* *INDENT-OFF* */
19681   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19682   ({
19683     if ((u32) p->value[0] == sw_if_index_from)
19684       {
19685         sw_if_from_name = (u8 *)(p->key);
19686         if (sw_if_to_name)
19687           break;
19688       }
19689     if ((u32) p->value[0] == sw_if_index_to)
19690       {
19691         sw_if_to_name = (u8 *)(p->key);
19692         if (sw_if_from_name)
19693           break;
19694       }
19695   }));
19696   /* *INDENT-ON* */
19697
19698   if (VAT_JSON_ARRAY != vam->json_tree.type)
19699     {
19700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19701       vat_json_init_array (&vam->json_tree);
19702     }
19703   node = vat_json_array_add (&vam->json_tree);
19704
19705   vat_json_init_object (node);
19706   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19707   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19708   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19709   if (0 != sw_if_to_name)
19710     {
19711       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19712     }
19713   vat_json_object_add_uint (node, "state", mp->state);
19714   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19715 }
19716
19717 static int
19718 api_sw_interface_span_dump (vat_main_t * vam)
19719 {
19720   unformat_input_t *input = vam->input;
19721   vl_api_sw_interface_span_dump_t *mp;
19722   vl_api_control_ping_t *mp_ping;
19723   u8 is_l2 = 0;
19724   int ret;
19725
19726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19727     {
19728       if (unformat (input, "l2"))
19729         is_l2 = 1;
19730       else
19731         break;
19732     }
19733
19734   M (SW_INTERFACE_SPAN_DUMP, mp);
19735   mp->is_l2 = is_l2;
19736   S (mp);
19737
19738   /* Use a control ping for synchronization */
19739   MPING (CONTROL_PING, mp_ping);
19740   S (mp_ping);
19741
19742   W (ret);
19743   return ret;
19744 }
19745
19746 int
19747 api_pg_create_interface (vat_main_t * vam)
19748 {
19749   unformat_input_t *input = vam->input;
19750   vl_api_pg_create_interface_t *mp;
19751
19752   u32 if_id = ~0, gso_size = 0;
19753   u8 gso_enabled = 0;
19754   int ret;
19755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19756     {
19757       if (unformat (input, "if_id %d", &if_id))
19758         ;
19759       else if (unformat (input, "gso-enabled"))
19760         {
19761           gso_enabled = 1;
19762           if (unformat (input, "gso-size %u", &gso_size))
19763             ;
19764           else
19765             {
19766               errmsg ("missing gso-size");
19767               return -99;
19768             }
19769         }
19770       else
19771         break;
19772     }
19773   if (if_id == ~0)
19774     {
19775       errmsg ("missing pg interface index");
19776       return -99;
19777     }
19778
19779   /* Construct the API message */
19780   M (PG_CREATE_INTERFACE, mp);
19781   mp->context = 0;
19782   mp->interface_id = ntohl (if_id);
19783   mp->gso_enabled = gso_enabled;
19784
19785   S (mp);
19786   W (ret);
19787   return ret;
19788 }
19789
19790 int
19791 api_pg_capture (vat_main_t * vam)
19792 {
19793   unformat_input_t *input = vam->input;
19794   vl_api_pg_capture_t *mp;
19795
19796   u32 if_id = ~0;
19797   u8 enable = 1;
19798   u32 count = 1;
19799   u8 pcap_file_set = 0;
19800   u8 *pcap_file = 0;
19801   int ret;
19802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19803     {
19804       if (unformat (input, "if_id %d", &if_id))
19805         ;
19806       else if (unformat (input, "pcap %s", &pcap_file))
19807         pcap_file_set = 1;
19808       else if (unformat (input, "count %d", &count))
19809         ;
19810       else if (unformat (input, "disable"))
19811         enable = 0;
19812       else
19813         break;
19814     }
19815   if (if_id == ~0)
19816     {
19817       errmsg ("missing pg interface index");
19818       return -99;
19819     }
19820   if (pcap_file_set > 0)
19821     {
19822       if (vec_len (pcap_file) > 255)
19823         {
19824           errmsg ("pcap file name is too long");
19825           return -99;
19826         }
19827     }
19828
19829   u32 name_len = vec_len (pcap_file);
19830   /* Construct the API message */
19831   M (PG_CAPTURE, mp);
19832   mp->context = 0;
19833   mp->interface_id = ntohl (if_id);
19834   mp->is_enabled = enable;
19835   mp->count = ntohl (count);
19836   mp->pcap_name_length = ntohl (name_len);
19837   if (pcap_file_set != 0)
19838     {
19839       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19840     }
19841   vec_free (pcap_file);
19842
19843   S (mp);
19844   W (ret);
19845   return ret;
19846 }
19847
19848 int
19849 api_pg_enable_disable (vat_main_t * vam)
19850 {
19851   unformat_input_t *input = vam->input;
19852   vl_api_pg_enable_disable_t *mp;
19853
19854   u8 enable = 1;
19855   u8 stream_name_set = 0;
19856   u8 *stream_name = 0;
19857   int ret;
19858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19859     {
19860       if (unformat (input, "stream %s", &stream_name))
19861         stream_name_set = 1;
19862       else if (unformat (input, "disable"))
19863         enable = 0;
19864       else
19865         break;
19866     }
19867
19868   if (stream_name_set > 0)
19869     {
19870       if (vec_len (stream_name) > 255)
19871         {
19872           errmsg ("stream name too long");
19873           return -99;
19874         }
19875     }
19876
19877   u32 name_len = vec_len (stream_name);
19878   /* Construct the API message */
19879   M (PG_ENABLE_DISABLE, mp);
19880   mp->context = 0;
19881   mp->is_enabled = enable;
19882   if (stream_name_set != 0)
19883     {
19884       mp->stream_name_length = ntohl (name_len);
19885       clib_memcpy (mp->stream_name, stream_name, name_len);
19886     }
19887   vec_free (stream_name);
19888
19889   S (mp);
19890   W (ret);
19891   return ret;
19892 }
19893
19894 int
19895 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19896 {
19897   unformat_input_t *input = vam->input;
19898   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19899
19900   u16 *low_ports = 0;
19901   u16 *high_ports = 0;
19902   u16 this_low;
19903   u16 this_hi;
19904   vl_api_prefix_t prefix;
19905   u32 tmp, tmp2;
19906   u8 prefix_set = 0;
19907   u32 vrf_id = ~0;
19908   u8 is_add = 1;
19909   int ret;
19910
19911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19912     {
19913       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19914         prefix_set = 1;
19915       else if (unformat (input, "vrf %d", &vrf_id))
19916         ;
19917       else if (unformat (input, "del"))
19918         is_add = 0;
19919       else if (unformat (input, "port %d", &tmp))
19920         {
19921           if (tmp == 0 || tmp > 65535)
19922             {
19923               errmsg ("port %d out of range", tmp);
19924               return -99;
19925             }
19926           this_low = tmp;
19927           this_hi = this_low + 1;
19928           vec_add1 (low_ports, this_low);
19929           vec_add1 (high_ports, this_hi);
19930         }
19931       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19932         {
19933           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19934             {
19935               errmsg ("incorrect range parameters");
19936               return -99;
19937             }
19938           this_low = tmp;
19939           /* Note: in debug CLI +1 is added to high before
19940              passing to real fn that does "the work"
19941              (ip_source_and_port_range_check_add_del).
19942              This fn is a wrapper around the binary API fn a
19943              control plane will call, which expects this increment
19944              to have occurred. Hence letting the binary API control
19945              plane fn do the increment for consistency between VAT
19946              and other control planes.
19947            */
19948           this_hi = tmp2;
19949           vec_add1 (low_ports, this_low);
19950           vec_add1 (high_ports, this_hi);
19951         }
19952       else
19953         break;
19954     }
19955
19956   if (prefix_set == 0)
19957     {
19958       errmsg ("<address>/<mask> not specified");
19959       return -99;
19960     }
19961
19962   if (vrf_id == ~0)
19963     {
19964       errmsg ("VRF ID required, not specified");
19965       return -99;
19966     }
19967
19968   if (vrf_id == 0)
19969     {
19970       errmsg
19971         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19972       return -99;
19973     }
19974
19975   if (vec_len (low_ports) == 0)
19976     {
19977       errmsg ("At least one port or port range required");
19978       return -99;
19979     }
19980
19981   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19982
19983   mp->is_add = is_add;
19984
19985   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19986
19987   mp->number_of_ranges = vec_len (low_ports);
19988
19989   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19990   vec_free (low_ports);
19991
19992   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19993   vec_free (high_ports);
19994
19995   mp->vrf_id = ntohl (vrf_id);
19996
19997   S (mp);
19998   W (ret);
19999   return ret;
20000 }
20001
20002 int
20003 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20004 {
20005   unformat_input_t *input = vam->input;
20006   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20007   u32 sw_if_index = ~0;
20008   int vrf_set = 0;
20009   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20010   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20011   u8 is_add = 1;
20012   int ret;
20013
20014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20015     {
20016       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20017         ;
20018       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20019         ;
20020       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20021         vrf_set = 1;
20022       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20023         vrf_set = 1;
20024       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20025         vrf_set = 1;
20026       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20027         vrf_set = 1;
20028       else if (unformat (input, "del"))
20029         is_add = 0;
20030       else
20031         break;
20032     }
20033
20034   if (sw_if_index == ~0)
20035     {
20036       errmsg ("Interface required but not specified");
20037       return -99;
20038     }
20039
20040   if (vrf_set == 0)
20041     {
20042       errmsg ("VRF ID required but not specified");
20043       return -99;
20044     }
20045
20046   if (tcp_out_vrf_id == 0
20047       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20048     {
20049       errmsg
20050         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20051       return -99;
20052     }
20053
20054   /* Construct the API message */
20055   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20056
20057   mp->sw_if_index = ntohl (sw_if_index);
20058   mp->is_add = is_add;
20059   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20060   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20061   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20062   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20063
20064   /* send it... */
20065   S (mp);
20066
20067   /* Wait for a reply... */
20068   W (ret);
20069   return ret;
20070 }
20071
20072 static int
20073 api_set_punt (vat_main_t * vam)
20074 {
20075   unformat_input_t *i = vam->input;
20076   vl_api_address_family_t af;
20077   vl_api_set_punt_t *mp;
20078   u32 protocol = ~0;
20079   u32 port = ~0;
20080   int is_add = 1;
20081   int ret;
20082
20083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20084     {
20085       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20086         ;
20087       else if (unformat (i, "protocol %d", &protocol))
20088         ;
20089       else if (unformat (i, "port %d", &port))
20090         ;
20091       else if (unformat (i, "del"))
20092         is_add = 0;
20093       else
20094         {
20095           clib_warning ("parse error '%U'", format_unformat_error, i);
20096           return -99;
20097         }
20098     }
20099
20100   M (SET_PUNT, mp);
20101
20102   mp->is_add = (u8) is_add;
20103   mp->punt.type = PUNT_API_TYPE_L4;
20104   mp->punt.punt.l4.af = af;
20105   mp->punt.punt.l4.protocol = (u8) protocol;
20106   mp->punt.punt.l4.port = htons ((u16) port);
20107
20108   S (mp);
20109   W (ret);
20110   return ret;
20111 }
20112
20113 static int
20114 api_delete_subif (vat_main_t * vam)
20115 {
20116   unformat_input_t *i = vam->input;
20117   vl_api_delete_subif_t *mp;
20118   u32 sw_if_index = ~0;
20119   int ret;
20120
20121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20122     {
20123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20124         ;
20125       if (unformat (i, "sw_if_index %d", &sw_if_index))
20126         ;
20127       else
20128         break;
20129     }
20130
20131   if (sw_if_index == ~0)
20132     {
20133       errmsg ("missing sw_if_index");
20134       return -99;
20135     }
20136
20137   /* Construct the API message */
20138   M (DELETE_SUBIF, mp);
20139   mp->sw_if_index = ntohl (sw_if_index);
20140
20141   S (mp);
20142   W (ret);
20143   return ret;
20144 }
20145
20146 #define foreach_pbb_vtr_op      \
20147 _("disable",  L2_VTR_DISABLED)  \
20148 _("pop",  L2_VTR_POP_2)         \
20149 _("push",  L2_VTR_PUSH_2)
20150
20151 static int
20152 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20153 {
20154   unformat_input_t *i = vam->input;
20155   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20156   u32 sw_if_index = ~0, vtr_op = ~0;
20157   u16 outer_tag = ~0;
20158   u8 dmac[6], smac[6];
20159   u8 dmac_set = 0, smac_set = 0;
20160   u16 vlanid = 0;
20161   u32 sid = ~0;
20162   u32 tmp;
20163   int ret;
20164
20165   /* Shut up coverity */
20166   clib_memset (dmac, 0, sizeof (dmac));
20167   clib_memset (smac, 0, sizeof (smac));
20168
20169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20170     {
20171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20172         ;
20173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20174         ;
20175       else if (unformat (i, "vtr_op %d", &vtr_op))
20176         ;
20177 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20178       foreach_pbb_vtr_op
20179 #undef _
20180         else if (unformat (i, "translate_pbb_stag"))
20181         {
20182           if (unformat (i, "%d", &tmp))
20183             {
20184               vtr_op = L2_VTR_TRANSLATE_2_1;
20185               outer_tag = tmp;
20186             }
20187           else
20188             {
20189               errmsg
20190                 ("translate_pbb_stag operation requires outer tag definition");
20191               return -99;
20192             }
20193         }
20194       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20195         dmac_set++;
20196       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20197         smac_set++;
20198       else if (unformat (i, "sid %d", &sid))
20199         ;
20200       else if (unformat (i, "vlanid %d", &tmp))
20201         vlanid = tmp;
20202       else
20203         {
20204           clib_warning ("parse error '%U'", format_unformat_error, i);
20205           return -99;
20206         }
20207     }
20208
20209   if ((sw_if_index == ~0) || (vtr_op == ~0))
20210     {
20211       errmsg ("missing sw_if_index or vtr operation");
20212       return -99;
20213     }
20214   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20215       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20216     {
20217       errmsg
20218         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20219       return -99;
20220     }
20221
20222   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20223   mp->sw_if_index = ntohl (sw_if_index);
20224   mp->vtr_op = ntohl (vtr_op);
20225   mp->outer_tag = ntohs (outer_tag);
20226   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20227   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20228   mp->b_vlanid = ntohs (vlanid);
20229   mp->i_sid = ntohl (sid);
20230
20231   S (mp);
20232   W (ret);
20233   return ret;
20234 }
20235
20236 static int
20237 api_flow_classify_set_interface (vat_main_t * vam)
20238 {
20239   unformat_input_t *i = vam->input;
20240   vl_api_flow_classify_set_interface_t *mp;
20241   u32 sw_if_index;
20242   int sw_if_index_set;
20243   u32 ip4_table_index = ~0;
20244   u32 ip6_table_index = ~0;
20245   u8 is_add = 1;
20246   int ret;
20247
20248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20249     {
20250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20251         sw_if_index_set = 1;
20252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20253         sw_if_index_set = 1;
20254       else if (unformat (i, "del"))
20255         is_add = 0;
20256       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20257         ;
20258       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20259         ;
20260       else
20261         {
20262           clib_warning ("parse error '%U'", format_unformat_error, i);
20263           return -99;
20264         }
20265     }
20266
20267   if (sw_if_index_set == 0)
20268     {
20269       errmsg ("missing interface name or sw_if_index");
20270       return -99;
20271     }
20272
20273   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20274
20275   mp->sw_if_index = ntohl (sw_if_index);
20276   mp->ip4_table_index = ntohl (ip4_table_index);
20277   mp->ip6_table_index = ntohl (ip6_table_index);
20278   mp->is_add = is_add;
20279
20280   S (mp);
20281   W (ret);
20282   return ret;
20283 }
20284
20285 static int
20286 api_flow_classify_dump (vat_main_t * vam)
20287 {
20288   unformat_input_t *i = vam->input;
20289   vl_api_flow_classify_dump_t *mp;
20290   vl_api_control_ping_t *mp_ping;
20291   u8 type = FLOW_CLASSIFY_N_TABLES;
20292   int ret;
20293
20294   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20295     ;
20296   else
20297     {
20298       errmsg ("classify table type must be specified");
20299       return -99;
20300     }
20301
20302   if (!vam->json_output)
20303     {
20304       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20305     }
20306
20307   M (FLOW_CLASSIFY_DUMP, mp);
20308   mp->type = type;
20309   /* send it... */
20310   S (mp);
20311
20312   /* Use a control ping for synchronization */
20313   MPING (CONTROL_PING, mp_ping);
20314   S (mp_ping);
20315
20316   /* Wait for a reply... */
20317   W (ret);
20318   return ret;
20319 }
20320
20321 static int
20322 api_feature_enable_disable (vat_main_t * vam)
20323 {
20324   unformat_input_t *i = vam->input;
20325   vl_api_feature_enable_disable_t *mp;
20326   u8 *arc_name = 0;
20327   u8 *feature_name = 0;
20328   u32 sw_if_index = ~0;
20329   u8 enable = 1;
20330   int ret;
20331
20332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20333     {
20334       if (unformat (i, "arc_name %s", &arc_name))
20335         ;
20336       else if (unformat (i, "feature_name %s", &feature_name))
20337         ;
20338       else
20339         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20340         ;
20341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20342         ;
20343       else if (unformat (i, "disable"))
20344         enable = 0;
20345       else
20346         break;
20347     }
20348
20349   if (arc_name == 0)
20350     {
20351       errmsg ("missing arc name");
20352       return -99;
20353     }
20354   if (vec_len (arc_name) > 63)
20355     {
20356       errmsg ("arc name too long");
20357     }
20358
20359   if (feature_name == 0)
20360     {
20361       errmsg ("missing feature name");
20362       return -99;
20363     }
20364   if (vec_len (feature_name) > 63)
20365     {
20366       errmsg ("feature name too long");
20367     }
20368
20369   if (sw_if_index == ~0)
20370     {
20371       errmsg ("missing interface name or sw_if_index");
20372       return -99;
20373     }
20374
20375   /* Construct the API message */
20376   M (FEATURE_ENABLE_DISABLE, mp);
20377   mp->sw_if_index = ntohl (sw_if_index);
20378   mp->enable = enable;
20379   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20380   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20381   vec_free (arc_name);
20382   vec_free (feature_name);
20383
20384   S (mp);
20385   W (ret);
20386   return ret;
20387 }
20388
20389 static int
20390 api_sw_interface_tag_add_del (vat_main_t * vam)
20391 {
20392   unformat_input_t *i = vam->input;
20393   vl_api_sw_interface_tag_add_del_t *mp;
20394   u32 sw_if_index = ~0;
20395   u8 *tag = 0;
20396   u8 enable = 1;
20397   int ret;
20398
20399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20400     {
20401       if (unformat (i, "tag %s", &tag))
20402         ;
20403       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20404         ;
20405       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20406         ;
20407       else if (unformat (i, "del"))
20408         enable = 0;
20409       else
20410         break;
20411     }
20412
20413   if (sw_if_index == ~0)
20414     {
20415       errmsg ("missing interface name or sw_if_index");
20416       return -99;
20417     }
20418
20419   if (enable && (tag == 0))
20420     {
20421       errmsg ("no tag specified");
20422       return -99;
20423     }
20424
20425   /* Construct the API message */
20426   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20427   mp->sw_if_index = ntohl (sw_if_index);
20428   mp->is_add = enable;
20429   if (enable)
20430     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20431   vec_free (tag);
20432
20433   S (mp);
20434   W (ret);
20435   return ret;
20436 }
20437
20438 static void vl_api_l2_xconnect_details_t_handler
20439   (vl_api_l2_xconnect_details_t * mp)
20440 {
20441   vat_main_t *vam = &vat_main;
20442
20443   print (vam->ofp, "%15d%15d",
20444          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20445 }
20446
20447 static void vl_api_l2_xconnect_details_t_handler_json
20448   (vl_api_l2_xconnect_details_t * mp)
20449 {
20450   vat_main_t *vam = &vat_main;
20451   vat_json_node_t *node = NULL;
20452
20453   if (VAT_JSON_ARRAY != vam->json_tree.type)
20454     {
20455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20456       vat_json_init_array (&vam->json_tree);
20457     }
20458   node = vat_json_array_add (&vam->json_tree);
20459
20460   vat_json_init_object (node);
20461   vat_json_object_add_uint (node, "rx_sw_if_index",
20462                             ntohl (mp->rx_sw_if_index));
20463   vat_json_object_add_uint (node, "tx_sw_if_index",
20464                             ntohl (mp->tx_sw_if_index));
20465 }
20466
20467 static int
20468 api_l2_xconnect_dump (vat_main_t * vam)
20469 {
20470   vl_api_l2_xconnect_dump_t *mp;
20471   vl_api_control_ping_t *mp_ping;
20472   int ret;
20473
20474   if (!vam->json_output)
20475     {
20476       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20477     }
20478
20479   M (L2_XCONNECT_DUMP, mp);
20480
20481   S (mp);
20482
20483   /* Use a control ping for synchronization */
20484   MPING (CONTROL_PING, mp_ping);
20485   S (mp_ping);
20486
20487   W (ret);
20488   return ret;
20489 }
20490
20491 static int
20492 api_hw_interface_set_mtu (vat_main_t * vam)
20493 {
20494   unformat_input_t *i = vam->input;
20495   vl_api_hw_interface_set_mtu_t *mp;
20496   u32 sw_if_index = ~0;
20497   u32 mtu = 0;
20498   int ret;
20499
20500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20501     {
20502       if (unformat (i, "mtu %d", &mtu))
20503         ;
20504       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20505         ;
20506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20507         ;
20508       else
20509         break;
20510     }
20511
20512   if (sw_if_index == ~0)
20513     {
20514       errmsg ("missing interface name or sw_if_index");
20515       return -99;
20516     }
20517
20518   if (mtu == 0)
20519     {
20520       errmsg ("no mtu specified");
20521       return -99;
20522     }
20523
20524   /* Construct the API message */
20525   M (HW_INTERFACE_SET_MTU, mp);
20526   mp->sw_if_index = ntohl (sw_if_index);
20527   mp->mtu = ntohs ((u16) mtu);
20528
20529   S (mp);
20530   W (ret);
20531   return ret;
20532 }
20533
20534 static int
20535 api_p2p_ethernet_add (vat_main_t * vam)
20536 {
20537   unformat_input_t *i = vam->input;
20538   vl_api_p2p_ethernet_add_t *mp;
20539   u32 parent_if_index = ~0;
20540   u32 sub_id = ~0;
20541   u8 remote_mac[6];
20542   u8 mac_set = 0;
20543   int ret;
20544
20545   clib_memset (remote_mac, 0, sizeof (remote_mac));
20546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20547     {
20548       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20549         ;
20550       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20551         ;
20552       else
20553         if (unformat
20554             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20555         mac_set++;
20556       else if (unformat (i, "sub_id %d", &sub_id))
20557         ;
20558       else
20559         {
20560           clib_warning ("parse error '%U'", format_unformat_error, i);
20561           return -99;
20562         }
20563     }
20564
20565   if (parent_if_index == ~0)
20566     {
20567       errmsg ("missing interface name or sw_if_index");
20568       return -99;
20569     }
20570   if (mac_set == 0)
20571     {
20572       errmsg ("missing remote mac address");
20573       return -99;
20574     }
20575   if (sub_id == ~0)
20576     {
20577       errmsg ("missing sub-interface id");
20578       return -99;
20579     }
20580
20581   M (P2P_ETHERNET_ADD, mp);
20582   mp->parent_if_index = ntohl (parent_if_index);
20583   mp->subif_id = ntohl (sub_id);
20584   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20585
20586   S (mp);
20587   W (ret);
20588   return ret;
20589 }
20590
20591 static int
20592 api_p2p_ethernet_del (vat_main_t * vam)
20593 {
20594   unformat_input_t *i = vam->input;
20595   vl_api_p2p_ethernet_del_t *mp;
20596   u32 parent_if_index = ~0;
20597   u8 remote_mac[6];
20598   u8 mac_set = 0;
20599   int ret;
20600
20601   clib_memset (remote_mac, 0, sizeof (remote_mac));
20602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20603     {
20604       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20605         ;
20606       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20607         ;
20608       else
20609         if (unformat
20610             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20611         mac_set++;
20612       else
20613         {
20614           clib_warning ("parse error '%U'", format_unformat_error, i);
20615           return -99;
20616         }
20617     }
20618
20619   if (parent_if_index == ~0)
20620     {
20621       errmsg ("missing interface name or sw_if_index");
20622       return -99;
20623     }
20624   if (mac_set == 0)
20625     {
20626       errmsg ("missing remote mac address");
20627       return -99;
20628     }
20629
20630   M (P2P_ETHERNET_DEL, mp);
20631   mp->parent_if_index = ntohl (parent_if_index);
20632   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20633
20634   S (mp);
20635   W (ret);
20636   return ret;
20637 }
20638
20639 static int
20640 api_lldp_config (vat_main_t * vam)
20641 {
20642   unformat_input_t *i = vam->input;
20643   vl_api_lldp_config_t *mp;
20644   int tx_hold = 0;
20645   int tx_interval = 0;
20646   u8 *sys_name = NULL;
20647   int ret;
20648
20649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20650     {
20651       if (unformat (i, "system-name %s", &sys_name))
20652         ;
20653       else if (unformat (i, "tx-hold %d", &tx_hold))
20654         ;
20655       else if (unformat (i, "tx-interval %d", &tx_interval))
20656         ;
20657       else
20658         {
20659           clib_warning ("parse error '%U'", format_unformat_error, i);
20660           return -99;
20661         }
20662     }
20663
20664   vec_add1 (sys_name, 0);
20665
20666   M (LLDP_CONFIG, mp);
20667   mp->tx_hold = htonl (tx_hold);
20668   mp->tx_interval = htonl (tx_interval);
20669   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20670   vec_free (sys_name);
20671
20672   S (mp);
20673   W (ret);
20674   return ret;
20675 }
20676
20677 static int
20678 api_sw_interface_set_lldp (vat_main_t * vam)
20679 {
20680   unformat_input_t *i = vam->input;
20681   vl_api_sw_interface_set_lldp_t *mp;
20682   u32 sw_if_index = ~0;
20683   u32 enable = 1;
20684   u8 *port_desc = NULL, *mgmt_oid = NULL;
20685   ip4_address_t ip4_addr;
20686   ip6_address_t ip6_addr;
20687   int ret;
20688
20689   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20690   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20691
20692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20693     {
20694       if (unformat (i, "disable"))
20695         enable = 0;
20696       else
20697         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20698         ;
20699       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20700         ;
20701       else if (unformat (i, "port-desc %s", &port_desc))
20702         ;
20703       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20704         ;
20705       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20706         ;
20707       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20708         ;
20709       else
20710         break;
20711     }
20712
20713   if (sw_if_index == ~0)
20714     {
20715       errmsg ("missing interface name or sw_if_index");
20716       return -99;
20717     }
20718
20719   /* Construct the API message */
20720   vec_add1 (port_desc, 0);
20721   vec_add1 (mgmt_oid, 0);
20722   M (SW_INTERFACE_SET_LLDP, mp);
20723   mp->sw_if_index = ntohl (sw_if_index);
20724   mp->enable = enable;
20725   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20726   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20727   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20728   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20729   vec_free (port_desc);
20730   vec_free (mgmt_oid);
20731
20732   S (mp);
20733   W (ret);
20734   return ret;
20735 }
20736
20737 static int
20738 api_tcp_configure_src_addresses (vat_main_t * vam)
20739 {
20740   vl_api_tcp_configure_src_addresses_t *mp;
20741   unformat_input_t *i = vam->input;
20742   ip4_address_t v4first, v4last;
20743   ip6_address_t v6first, v6last;
20744   u8 range_set = 0;
20745   u32 vrf_id = 0;
20746   int ret;
20747
20748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20749     {
20750       if (unformat (i, "%U - %U",
20751                     unformat_ip4_address, &v4first,
20752                     unformat_ip4_address, &v4last))
20753         {
20754           if (range_set)
20755             {
20756               errmsg ("one range per message (range already set)");
20757               return -99;
20758             }
20759           range_set = 1;
20760         }
20761       else if (unformat (i, "%U - %U",
20762                          unformat_ip6_address, &v6first,
20763                          unformat_ip6_address, &v6last))
20764         {
20765           if (range_set)
20766             {
20767               errmsg ("one range per message (range already set)");
20768               return -99;
20769             }
20770           range_set = 2;
20771         }
20772       else if (unformat (i, "vrf %d", &vrf_id))
20773         ;
20774       else
20775         break;
20776     }
20777
20778   if (range_set == 0)
20779     {
20780       errmsg ("address range not set");
20781       return -99;
20782     }
20783
20784   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20785   mp->vrf_id = ntohl (vrf_id);
20786   /* ipv6? */
20787   if (range_set == 2)
20788     {
20789       mp->is_ipv6 = 1;
20790       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20791       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20792     }
20793   else
20794     {
20795       mp->is_ipv6 = 0;
20796       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20797       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20798     }
20799   S (mp);
20800   W (ret);
20801   return ret;
20802 }
20803
20804 static void vl_api_app_namespace_add_del_reply_t_handler
20805   (vl_api_app_namespace_add_del_reply_t * mp)
20806 {
20807   vat_main_t *vam = &vat_main;
20808   i32 retval = ntohl (mp->retval);
20809   if (vam->async_mode)
20810     {
20811       vam->async_errors += (retval < 0);
20812     }
20813   else
20814     {
20815       vam->retval = retval;
20816       if (retval == 0)
20817         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20818       vam->result_ready = 1;
20819     }
20820 }
20821
20822 static void vl_api_app_namespace_add_del_reply_t_handler_json
20823   (vl_api_app_namespace_add_del_reply_t * mp)
20824 {
20825   vat_main_t *vam = &vat_main;
20826   vat_json_node_t node;
20827
20828   vat_json_init_object (&node);
20829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20830   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20831
20832   vat_json_print (vam->ofp, &node);
20833   vat_json_free (&node);
20834
20835   vam->retval = ntohl (mp->retval);
20836   vam->result_ready = 1;
20837 }
20838
20839 static int
20840 api_app_namespace_add_del (vat_main_t * vam)
20841 {
20842   vl_api_app_namespace_add_del_t *mp;
20843   unformat_input_t *i = vam->input;
20844   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20845   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20846   u64 secret;
20847   int ret;
20848
20849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20850     {
20851       if (unformat (i, "id %_%v%_", &ns_id))
20852         ;
20853       else if (unformat (i, "secret %lu", &secret))
20854         secret_set = 1;
20855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20856         sw_if_index_set = 1;
20857       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20858         ;
20859       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20860         ;
20861       else
20862         break;
20863     }
20864   if (!ns_id || !secret_set || !sw_if_index_set)
20865     {
20866       errmsg ("namespace id, secret and sw_if_index must be set");
20867       return -99;
20868     }
20869   if (vec_len (ns_id) > 64)
20870     {
20871       errmsg ("namespace id too long");
20872       return -99;
20873     }
20874   M (APP_NAMESPACE_ADD_DEL, mp);
20875
20876   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20877   mp->namespace_id_len = vec_len (ns_id);
20878   mp->secret = clib_host_to_net_u64 (secret);
20879   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20880   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20881   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20882   vec_free (ns_id);
20883   S (mp);
20884   W (ret);
20885   return ret;
20886 }
20887
20888 static int
20889 api_sock_init_shm (vat_main_t * vam)
20890 {
20891 #if VPP_API_TEST_BUILTIN == 0
20892   unformat_input_t *i = vam->input;
20893   vl_api_shm_elem_config_t *config = 0;
20894   u64 size = 64 << 20;
20895   int rv;
20896
20897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20898     {
20899       if (unformat (i, "size %U", unformat_memory_size, &size))
20900         ;
20901       else
20902         break;
20903     }
20904
20905   /*
20906    * Canned custom ring allocator config.
20907    * Should probably parse all of this
20908    */
20909   vec_validate (config, 6);
20910   config[0].type = VL_API_VLIB_RING;
20911   config[0].size = 256;
20912   config[0].count = 32;
20913
20914   config[1].type = VL_API_VLIB_RING;
20915   config[1].size = 1024;
20916   config[1].count = 16;
20917
20918   config[2].type = VL_API_VLIB_RING;
20919   config[2].size = 4096;
20920   config[2].count = 2;
20921
20922   config[3].type = VL_API_CLIENT_RING;
20923   config[3].size = 256;
20924   config[3].count = 32;
20925
20926   config[4].type = VL_API_CLIENT_RING;
20927   config[4].size = 1024;
20928   config[4].count = 16;
20929
20930   config[5].type = VL_API_CLIENT_RING;
20931   config[5].size = 4096;
20932   config[5].count = 2;
20933
20934   config[6].type = VL_API_QUEUE;
20935   config[6].count = 128;
20936   config[6].size = sizeof (uword);
20937
20938   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20939   if (!rv)
20940     vam->client_index_invalid = 1;
20941   return rv;
20942 #else
20943   return -99;
20944 #endif
20945 }
20946
20947 static int
20948 api_dns_enable_disable (vat_main_t * vam)
20949 {
20950   unformat_input_t *line_input = vam->input;
20951   vl_api_dns_enable_disable_t *mp;
20952   u8 enable_disable = 1;
20953   int ret;
20954
20955   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20956     {
20957       if (unformat (line_input, "disable"))
20958         enable_disable = 0;
20959       if (unformat (line_input, "enable"))
20960         enable_disable = 1;
20961       else
20962         break;
20963     }
20964
20965   /* Construct the API message */
20966   M (DNS_ENABLE_DISABLE, mp);
20967   mp->enable = enable_disable;
20968
20969   /* send it... */
20970   S (mp);
20971   /* Wait for the reply */
20972   W (ret);
20973   return ret;
20974 }
20975
20976 static int
20977 api_dns_resolve_name (vat_main_t * vam)
20978 {
20979   unformat_input_t *line_input = vam->input;
20980   vl_api_dns_resolve_name_t *mp;
20981   u8 *name = 0;
20982   int ret;
20983
20984   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20985     {
20986       if (unformat (line_input, "%s", &name))
20987         ;
20988       else
20989         break;
20990     }
20991
20992   if (vec_len (name) > 127)
20993     {
20994       errmsg ("name too long");
20995       return -99;
20996     }
20997
20998   /* Construct the API message */
20999   M (DNS_RESOLVE_NAME, mp);
21000   memcpy (mp->name, name, vec_len (name));
21001   vec_free (name);
21002
21003   /* send it... */
21004   S (mp);
21005   /* Wait for the reply */
21006   W (ret);
21007   return ret;
21008 }
21009
21010 static int
21011 api_dns_resolve_ip (vat_main_t * vam)
21012 {
21013   unformat_input_t *line_input = vam->input;
21014   vl_api_dns_resolve_ip_t *mp;
21015   int is_ip6 = -1;
21016   ip4_address_t addr4;
21017   ip6_address_t addr6;
21018   int ret;
21019
21020   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21021     {
21022       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21023         is_ip6 = 1;
21024       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21025         is_ip6 = 0;
21026       else
21027         break;
21028     }
21029
21030   if (is_ip6 == -1)
21031     {
21032       errmsg ("missing address");
21033       return -99;
21034     }
21035
21036   /* Construct the API message */
21037   M (DNS_RESOLVE_IP, mp);
21038   mp->is_ip6 = is_ip6;
21039   if (is_ip6)
21040     memcpy (mp->address, &addr6, sizeof (addr6));
21041   else
21042     memcpy (mp->address, &addr4, sizeof (addr4));
21043
21044   /* send it... */
21045   S (mp);
21046   /* Wait for the reply */
21047   W (ret);
21048   return ret;
21049 }
21050
21051 static int
21052 api_dns_name_server_add_del (vat_main_t * vam)
21053 {
21054   unformat_input_t *i = vam->input;
21055   vl_api_dns_name_server_add_del_t *mp;
21056   u8 is_add = 1;
21057   ip6_address_t ip6_server;
21058   ip4_address_t ip4_server;
21059   int ip6_set = 0;
21060   int ip4_set = 0;
21061   int ret = 0;
21062
21063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21064     {
21065       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21066         ip6_set = 1;
21067       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21068         ip4_set = 1;
21069       else if (unformat (i, "del"))
21070         is_add = 0;
21071       else
21072         {
21073           clib_warning ("parse error '%U'", format_unformat_error, i);
21074           return -99;
21075         }
21076     }
21077
21078   if (ip4_set && ip6_set)
21079     {
21080       errmsg ("Only one server address allowed per message");
21081       return -99;
21082     }
21083   if ((ip4_set + ip6_set) == 0)
21084     {
21085       errmsg ("Server address required");
21086       return -99;
21087     }
21088
21089   /* Construct the API message */
21090   M (DNS_NAME_SERVER_ADD_DEL, mp);
21091
21092   if (ip6_set)
21093     {
21094       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21095       mp->is_ip6 = 1;
21096     }
21097   else
21098     {
21099       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21100       mp->is_ip6 = 0;
21101     }
21102
21103   mp->is_add = is_add;
21104
21105   /* send it... */
21106   S (mp);
21107
21108   /* Wait for a reply, return good/bad news  */
21109   W (ret);
21110   return ret;
21111 }
21112
21113 static void
21114 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21115 {
21116   vat_main_t *vam = &vat_main;
21117
21118   if (mp->is_ip4)
21119     {
21120       print (vam->ofp,
21121              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21122              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21123              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21124              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21125              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21126              clib_net_to_host_u32 (mp->action_index), mp->tag);
21127     }
21128   else
21129     {
21130       print (vam->ofp,
21131              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21132              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21133              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21134              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21135              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21136              clib_net_to_host_u32 (mp->action_index), mp->tag);
21137     }
21138 }
21139
21140 static void
21141 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21142                                              mp)
21143 {
21144   vat_main_t *vam = &vat_main;
21145   vat_json_node_t *node = NULL;
21146   struct in6_addr ip6;
21147   struct in_addr ip4;
21148
21149   if (VAT_JSON_ARRAY != vam->json_tree.type)
21150     {
21151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21152       vat_json_init_array (&vam->json_tree);
21153     }
21154   node = vat_json_array_add (&vam->json_tree);
21155   vat_json_init_object (node);
21156
21157   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21158   vat_json_object_add_uint (node, "appns_index",
21159                             clib_net_to_host_u32 (mp->appns_index));
21160   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21161   vat_json_object_add_uint (node, "scope", mp->scope);
21162   vat_json_object_add_uint (node, "action_index",
21163                             clib_net_to_host_u32 (mp->action_index));
21164   vat_json_object_add_uint (node, "lcl_port",
21165                             clib_net_to_host_u16 (mp->lcl_port));
21166   vat_json_object_add_uint (node, "rmt_port",
21167                             clib_net_to_host_u16 (mp->rmt_port));
21168   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21169   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21170   vat_json_object_add_string_copy (node, "tag", mp->tag);
21171   if (mp->is_ip4)
21172     {
21173       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21174       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21175       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21176       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21177     }
21178   else
21179     {
21180       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21181       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21182       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21183       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21184     }
21185 }
21186
21187 static int
21188 api_session_rule_add_del (vat_main_t * vam)
21189 {
21190   vl_api_session_rule_add_del_t *mp;
21191   unformat_input_t *i = vam->input;
21192   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21193   u32 appns_index = 0, scope = 0;
21194   ip4_address_t lcl_ip4, rmt_ip4;
21195   ip6_address_t lcl_ip6, rmt_ip6;
21196   u8 is_ip4 = 1, conn_set = 0;
21197   u8 is_add = 1, *tag = 0;
21198   int ret;
21199
21200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21201     {
21202       if (unformat (i, "del"))
21203         is_add = 0;
21204       else if (unformat (i, "add"))
21205         ;
21206       else if (unformat (i, "proto tcp"))
21207         proto = 0;
21208       else if (unformat (i, "proto udp"))
21209         proto = 1;
21210       else if (unformat (i, "appns %d", &appns_index))
21211         ;
21212       else if (unformat (i, "scope %d", &scope))
21213         ;
21214       else if (unformat (i, "tag %_%v%_", &tag))
21215         ;
21216       else
21217         if (unformat
21218             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21219              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21220              &rmt_port))
21221         {
21222           is_ip4 = 1;
21223           conn_set = 1;
21224         }
21225       else
21226         if (unformat
21227             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21228              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21229              &rmt_port))
21230         {
21231           is_ip4 = 0;
21232           conn_set = 1;
21233         }
21234       else if (unformat (i, "action %d", &action))
21235         ;
21236       else
21237         break;
21238     }
21239   if (proto == ~0 || !conn_set || action == ~0)
21240     {
21241       errmsg ("transport proto, connection and action must be set");
21242       return -99;
21243     }
21244
21245   if (scope > 3)
21246     {
21247       errmsg ("scope should be 0-3");
21248       return -99;
21249     }
21250
21251   M (SESSION_RULE_ADD_DEL, mp);
21252
21253   mp->is_ip4 = is_ip4;
21254   mp->transport_proto = proto;
21255   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21256   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21257   mp->lcl_plen = lcl_plen;
21258   mp->rmt_plen = rmt_plen;
21259   mp->action_index = clib_host_to_net_u32 (action);
21260   mp->appns_index = clib_host_to_net_u32 (appns_index);
21261   mp->scope = scope;
21262   mp->is_add = is_add;
21263   if (is_ip4)
21264     {
21265       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21266       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21267     }
21268   else
21269     {
21270       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21271       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21272     }
21273   if (tag)
21274     {
21275       clib_memcpy (mp->tag, tag, vec_len (tag));
21276       vec_free (tag);
21277     }
21278
21279   S (mp);
21280   W (ret);
21281   return ret;
21282 }
21283
21284 static int
21285 api_session_rules_dump (vat_main_t * vam)
21286 {
21287   vl_api_session_rules_dump_t *mp;
21288   vl_api_control_ping_t *mp_ping;
21289   int ret;
21290
21291   if (!vam->json_output)
21292     {
21293       print (vam->ofp, "%=20s", "Session Rules");
21294     }
21295
21296   M (SESSION_RULES_DUMP, mp);
21297   /* send it... */
21298   S (mp);
21299
21300   /* Use a control ping for synchronization */
21301   MPING (CONTROL_PING, mp_ping);
21302   S (mp_ping);
21303
21304   /* Wait for a reply... */
21305   W (ret);
21306   return ret;
21307 }
21308
21309 static int
21310 api_ip_container_proxy_add_del (vat_main_t * vam)
21311 {
21312   vl_api_ip_container_proxy_add_del_t *mp;
21313   unformat_input_t *i = vam->input;
21314   u32 sw_if_index = ~0;
21315   vl_api_prefix_t pfx = { };
21316   u8 is_add = 1;
21317   int ret;
21318
21319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21320     {
21321       if (unformat (i, "del"))
21322         is_add = 0;
21323       else if (unformat (i, "add"))
21324         ;
21325       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21326         ;
21327       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21328         ;
21329       else
21330         break;
21331     }
21332   if (sw_if_index == ~0 || pfx.len == 0)
21333     {
21334       errmsg ("address and sw_if_index must be set");
21335       return -99;
21336     }
21337
21338   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21339
21340   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21341   mp->is_add = is_add;
21342   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21343
21344   S (mp);
21345   W (ret);
21346   return ret;
21347 }
21348
21349 static int
21350 api_qos_record_enable_disable (vat_main_t * vam)
21351 {
21352   unformat_input_t *i = vam->input;
21353   vl_api_qos_record_enable_disable_t *mp;
21354   u32 sw_if_index, qs = 0xff;
21355   u8 sw_if_index_set = 0;
21356   u8 enable = 1;
21357   int ret;
21358
21359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21360     {
21361       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21362         sw_if_index_set = 1;
21363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21364         sw_if_index_set = 1;
21365       else if (unformat (i, "%U", unformat_qos_source, &qs))
21366         ;
21367       else if (unformat (i, "disable"))
21368         enable = 0;
21369       else
21370         {
21371           clib_warning ("parse error '%U'", format_unformat_error, i);
21372           return -99;
21373         }
21374     }
21375
21376   if (sw_if_index_set == 0)
21377     {
21378       errmsg ("missing interface name or sw_if_index");
21379       return -99;
21380     }
21381   if (qs == 0xff)
21382     {
21383       errmsg ("input location must be specified");
21384       return -99;
21385     }
21386
21387   M (QOS_RECORD_ENABLE_DISABLE, mp);
21388
21389   mp->record.sw_if_index = ntohl (sw_if_index);
21390   mp->record.input_source = qs;
21391   mp->enable = enable;
21392
21393   S (mp);
21394   W (ret);
21395   return ret;
21396 }
21397
21398
21399 static int
21400 q_or_quit (vat_main_t * vam)
21401 {
21402 #if VPP_API_TEST_BUILTIN == 0
21403   longjmp (vam->jump_buf, 1);
21404 #endif
21405   return 0;                     /* not so much */
21406 }
21407
21408 static int
21409 q (vat_main_t * vam)
21410 {
21411   return q_or_quit (vam);
21412 }
21413
21414 static int
21415 quit (vat_main_t * vam)
21416 {
21417   return q_or_quit (vam);
21418 }
21419
21420 static int
21421 comment (vat_main_t * vam)
21422 {
21423   return 0;
21424 }
21425
21426 static int
21427 elog_save (vat_main_t * vam)
21428 {
21429 #if VPP_API_TEST_BUILTIN == 0
21430   elog_main_t *em = &vam->elog_main;
21431   unformat_input_t *i = vam->input;
21432   char *file, *chroot_file;
21433   clib_error_t *error;
21434
21435   if (!unformat (i, "%s", &file))
21436     {
21437       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21438       return 0;
21439     }
21440
21441   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21442   if (strstr (file, "..") || index (file, '/'))
21443     {
21444       errmsg ("illegal characters in filename '%s'", file);
21445       return 0;
21446     }
21447
21448   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21449
21450   vec_free (file);
21451
21452   errmsg ("Saving %wd of %wd events to %s",
21453           elog_n_events_in_buffer (em),
21454           elog_buffer_capacity (em), chroot_file);
21455
21456   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21457   vec_free (chroot_file);
21458
21459   if (error)
21460     clib_error_report (error);
21461 #else
21462   errmsg ("Use the vpp event loger...");
21463 #endif
21464
21465   return 0;
21466 }
21467
21468 static int
21469 elog_setup (vat_main_t * vam)
21470 {
21471 #if VPP_API_TEST_BUILTIN == 0
21472   elog_main_t *em = &vam->elog_main;
21473   unformat_input_t *i = vam->input;
21474   u32 nevents = 128 << 10;
21475
21476   (void) unformat (i, "nevents %d", &nevents);
21477
21478   elog_init (em, nevents);
21479   vl_api_set_elog_main (em);
21480   vl_api_set_elog_trace_api_messages (1);
21481   errmsg ("Event logger initialized with %u events", nevents);
21482 #else
21483   errmsg ("Use the vpp event loger...");
21484 #endif
21485   return 0;
21486 }
21487
21488 static int
21489 elog_enable (vat_main_t * vam)
21490 {
21491 #if VPP_API_TEST_BUILTIN == 0
21492   elog_main_t *em = &vam->elog_main;
21493
21494   elog_enable_disable (em, 1 /* enable */ );
21495   vl_api_set_elog_trace_api_messages (1);
21496   errmsg ("Event logger enabled...");
21497 #else
21498   errmsg ("Use the vpp event loger...");
21499 #endif
21500   return 0;
21501 }
21502
21503 static int
21504 elog_disable (vat_main_t * vam)
21505 {
21506 #if VPP_API_TEST_BUILTIN == 0
21507   elog_main_t *em = &vam->elog_main;
21508
21509   elog_enable_disable (em, 0 /* enable */ );
21510   vl_api_set_elog_trace_api_messages (1);
21511   errmsg ("Event logger disabled...");
21512 #else
21513   errmsg ("Use the vpp event loger...");
21514 #endif
21515   return 0;
21516 }
21517
21518 static int
21519 statseg (vat_main_t * vam)
21520 {
21521   ssvm_private_t *ssvmp = &vam->stat_segment;
21522   ssvm_shared_header_t *shared_header = ssvmp->sh;
21523   vlib_counter_t **counters;
21524   u64 thread0_index1_packets;
21525   u64 thread0_index1_bytes;
21526   f64 vector_rate, input_rate;
21527   uword *p;
21528
21529   uword *counter_vector_by_name;
21530   if (vam->stat_segment_lockp == 0)
21531     {
21532       errmsg ("Stat segment not mapped...");
21533       return -99;
21534     }
21535
21536   /* look up "/if/rx for sw_if_index 1 as a test */
21537
21538   clib_spinlock_lock (vam->stat_segment_lockp);
21539
21540   counter_vector_by_name = (uword *) shared_header->opaque[1];
21541
21542   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21543   if (p == 0)
21544     {
21545       clib_spinlock_unlock (vam->stat_segment_lockp);
21546       errmsg ("/if/tx not found?");
21547       return -99;
21548     }
21549
21550   /* Fish per-thread vector of combined counters from shared memory */
21551   counters = (vlib_counter_t **) p[0];
21552
21553   if (vec_len (counters[0]) < 2)
21554     {
21555       clib_spinlock_unlock (vam->stat_segment_lockp);
21556       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21557       return -99;
21558     }
21559
21560   /* Read thread 0 sw_if_index 1 counter */
21561   thread0_index1_packets = counters[0][1].packets;
21562   thread0_index1_bytes = counters[0][1].bytes;
21563
21564   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21565   if (p == 0)
21566     {
21567       clib_spinlock_unlock (vam->stat_segment_lockp);
21568       errmsg ("vector_rate not found?");
21569       return -99;
21570     }
21571
21572   vector_rate = *(f64 *) (p[0]);
21573   p = hash_get_mem (counter_vector_by_name, "input_rate");
21574   if (p == 0)
21575     {
21576       clib_spinlock_unlock (vam->stat_segment_lockp);
21577       errmsg ("input_rate not found?");
21578       return -99;
21579     }
21580   input_rate = *(f64 *) (p[0]);
21581
21582   clib_spinlock_unlock (vam->stat_segment_lockp);
21583
21584   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21585          vector_rate, input_rate);
21586   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21587          thread0_index1_packets, thread0_index1_bytes);
21588
21589   return 0;
21590 }
21591
21592 static int
21593 cmd_cmp (void *a1, void *a2)
21594 {
21595   u8 **c1 = a1;
21596   u8 **c2 = a2;
21597
21598   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21599 }
21600
21601 static int
21602 help (vat_main_t * vam)
21603 {
21604   u8 **cmds = 0;
21605   u8 *name = 0;
21606   hash_pair_t *p;
21607   unformat_input_t *i = vam->input;
21608   int j;
21609
21610   if (unformat (i, "%s", &name))
21611     {
21612       uword *hs;
21613
21614       vec_add1 (name, 0);
21615
21616       hs = hash_get_mem (vam->help_by_name, name);
21617       if (hs)
21618         print (vam->ofp, "usage: %s %s", name, hs[0]);
21619       else
21620         print (vam->ofp, "No such msg / command '%s'", name);
21621       vec_free (name);
21622       return 0;
21623     }
21624
21625   print (vam->ofp, "Help is available for the following:");
21626
21627     /* *INDENT-OFF* */
21628     hash_foreach_pair (p, vam->function_by_name,
21629     ({
21630       vec_add1 (cmds, (u8 *)(p->key));
21631     }));
21632     /* *INDENT-ON* */
21633
21634   vec_sort_with_function (cmds, cmd_cmp);
21635
21636   for (j = 0; j < vec_len (cmds); j++)
21637     print (vam->ofp, "%s", cmds[j]);
21638
21639   vec_free (cmds);
21640   return 0;
21641 }
21642
21643 static int
21644 set (vat_main_t * vam)
21645 {
21646   u8 *name = 0, *value = 0;
21647   unformat_input_t *i = vam->input;
21648
21649   if (unformat (i, "%s", &name))
21650     {
21651       /* The input buffer is a vector, not a string. */
21652       value = vec_dup (i->buffer);
21653       vec_delete (value, i->index, 0);
21654       /* Almost certainly has a trailing newline */
21655       if (value[vec_len (value) - 1] == '\n')
21656         value[vec_len (value) - 1] = 0;
21657       /* Make sure it's a proper string, one way or the other */
21658       vec_add1 (value, 0);
21659       (void) clib_macro_set_value (&vam->macro_main,
21660                                    (char *) name, (char *) value);
21661     }
21662   else
21663     errmsg ("usage: set <name> <value>");
21664
21665   vec_free (name);
21666   vec_free (value);
21667   return 0;
21668 }
21669
21670 static int
21671 unset (vat_main_t * vam)
21672 {
21673   u8 *name = 0;
21674
21675   if (unformat (vam->input, "%s", &name))
21676     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21677       errmsg ("unset: %s wasn't set", name);
21678   vec_free (name);
21679   return 0;
21680 }
21681
21682 typedef struct
21683 {
21684   u8 *name;
21685   u8 *value;
21686 } macro_sort_t;
21687
21688
21689 static int
21690 macro_sort_cmp (void *a1, void *a2)
21691 {
21692   macro_sort_t *s1 = a1;
21693   macro_sort_t *s2 = a2;
21694
21695   return strcmp ((char *) (s1->name), (char *) (s2->name));
21696 }
21697
21698 static int
21699 dump_macro_table (vat_main_t * vam)
21700 {
21701   macro_sort_t *sort_me = 0, *sm;
21702   int i;
21703   hash_pair_t *p;
21704
21705     /* *INDENT-OFF* */
21706     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21707     ({
21708       vec_add2 (sort_me, sm, 1);
21709       sm->name = (u8 *)(p->key);
21710       sm->value = (u8 *) (p->value[0]);
21711     }));
21712     /* *INDENT-ON* */
21713
21714   vec_sort_with_function (sort_me, macro_sort_cmp);
21715
21716   if (vec_len (sort_me))
21717     print (vam->ofp, "%-15s%s", "Name", "Value");
21718   else
21719     print (vam->ofp, "The macro table is empty...");
21720
21721   for (i = 0; i < vec_len (sort_me); i++)
21722     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21723   return 0;
21724 }
21725
21726 static int
21727 dump_node_table (vat_main_t * vam)
21728 {
21729   int i, j;
21730   vlib_node_t *node, *next_node;
21731
21732   if (vec_len (vam->graph_nodes) == 0)
21733     {
21734       print (vam->ofp, "Node table empty, issue get_node_graph...");
21735       return 0;
21736     }
21737
21738   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21739     {
21740       node = vam->graph_nodes[0][i];
21741       print (vam->ofp, "[%d] %s", i, node->name);
21742       for (j = 0; j < vec_len (node->next_nodes); j++)
21743         {
21744           if (node->next_nodes[j] != ~0)
21745             {
21746               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21747               print (vam->ofp, "  [%d] %s", j, next_node->name);
21748             }
21749         }
21750     }
21751   return 0;
21752 }
21753
21754 static int
21755 value_sort_cmp (void *a1, void *a2)
21756 {
21757   name_sort_t *n1 = a1;
21758   name_sort_t *n2 = a2;
21759
21760   if (n1->value < n2->value)
21761     return -1;
21762   if (n1->value > n2->value)
21763     return 1;
21764   return 0;
21765 }
21766
21767
21768 static int
21769 dump_msg_api_table (vat_main_t * vam)
21770 {
21771   api_main_t *am = &api_main;
21772   name_sort_t *nses = 0, *ns;
21773   hash_pair_t *hp;
21774   int i;
21775
21776   /* *INDENT-OFF* */
21777   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21778   ({
21779     vec_add2 (nses, ns, 1);
21780     ns->name = (u8 *)(hp->key);
21781     ns->value = (u32) hp->value[0];
21782   }));
21783   /* *INDENT-ON* */
21784
21785   vec_sort_with_function (nses, value_sort_cmp);
21786
21787   for (i = 0; i < vec_len (nses); i++)
21788     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21789   vec_free (nses);
21790   return 0;
21791 }
21792
21793 static int
21794 get_msg_id (vat_main_t * vam)
21795 {
21796   u8 *name_and_crc;
21797   u32 message_index;
21798
21799   if (unformat (vam->input, "%s", &name_and_crc))
21800     {
21801       message_index = vl_msg_api_get_msg_index (name_and_crc);
21802       if (message_index == ~0)
21803         {
21804           print (vam->ofp, " '%s' not found", name_and_crc);
21805           return 0;
21806         }
21807       print (vam->ofp, " '%s' has message index %d",
21808              name_and_crc, message_index);
21809       return 0;
21810     }
21811   errmsg ("name_and_crc required...");
21812   return 0;
21813 }
21814
21815 static int
21816 search_node_table (vat_main_t * vam)
21817 {
21818   unformat_input_t *line_input = vam->input;
21819   u8 *node_to_find;
21820   int j;
21821   vlib_node_t *node, *next_node;
21822   uword *p;
21823
21824   if (vam->graph_node_index_by_name == 0)
21825     {
21826       print (vam->ofp, "Node table empty, issue get_node_graph...");
21827       return 0;
21828     }
21829
21830   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21831     {
21832       if (unformat (line_input, "%s", &node_to_find))
21833         {
21834           vec_add1 (node_to_find, 0);
21835           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21836           if (p == 0)
21837             {
21838               print (vam->ofp, "%s not found...", node_to_find);
21839               goto out;
21840             }
21841           node = vam->graph_nodes[0][p[0]];
21842           print (vam->ofp, "[%d] %s", p[0], node->name);
21843           for (j = 0; j < vec_len (node->next_nodes); j++)
21844             {
21845               if (node->next_nodes[j] != ~0)
21846                 {
21847                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21848                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21849                 }
21850             }
21851         }
21852
21853       else
21854         {
21855           clib_warning ("parse error '%U'", format_unformat_error,
21856                         line_input);
21857           return -99;
21858         }
21859
21860     out:
21861       vec_free (node_to_find);
21862
21863     }
21864
21865   return 0;
21866 }
21867
21868
21869 static int
21870 script (vat_main_t * vam)
21871 {
21872 #if (VPP_API_TEST_BUILTIN==0)
21873   u8 *s = 0;
21874   char *save_current_file;
21875   unformat_input_t save_input;
21876   jmp_buf save_jump_buf;
21877   u32 save_line_number;
21878
21879   FILE *new_fp, *save_ifp;
21880
21881   if (unformat (vam->input, "%s", &s))
21882     {
21883       new_fp = fopen ((char *) s, "r");
21884       if (new_fp == 0)
21885         {
21886           errmsg ("Couldn't open script file %s", s);
21887           vec_free (s);
21888           return -99;
21889         }
21890     }
21891   else
21892     {
21893       errmsg ("Missing script name");
21894       return -99;
21895     }
21896
21897   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21898   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21899   save_ifp = vam->ifp;
21900   save_line_number = vam->input_line_number;
21901   save_current_file = (char *) vam->current_file;
21902
21903   vam->input_line_number = 0;
21904   vam->ifp = new_fp;
21905   vam->current_file = s;
21906   do_one_file (vam);
21907
21908   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21909   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21910   vam->ifp = save_ifp;
21911   vam->input_line_number = save_line_number;
21912   vam->current_file = (u8 *) save_current_file;
21913   vec_free (s);
21914
21915   return 0;
21916 #else
21917   clib_warning ("use the exec command...");
21918   return -99;
21919 #endif
21920 }
21921
21922 static int
21923 echo (vat_main_t * vam)
21924 {
21925   print (vam->ofp, "%v", vam->input->buffer);
21926   return 0;
21927 }
21928
21929 /* List of API message constructors, CLI names map to api_xxx */
21930 #define foreach_vpe_api_msg                                             \
21931 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21932 _(sw_interface_dump,"")                                                 \
21933 _(sw_interface_set_flags,                                               \
21934   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21935 _(sw_interface_add_del_address,                                         \
21936   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21937 _(sw_interface_set_rx_mode,                                             \
21938   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21939 _(sw_interface_set_rx_placement,                                        \
21940   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21941 _(sw_interface_rx_placement_dump,                                       \
21942   "[<intfc> | sw_if_index <id>]")                                         \
21943 _(sw_interface_set_table,                                               \
21944   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21945 _(sw_interface_set_mpls_enable,                                         \
21946   "<intfc> | sw_if_index [disable | dis]")                              \
21947 _(sw_interface_set_vpath,                                               \
21948   "<intfc> | sw_if_index <id> enable | disable")                        \
21949 _(sw_interface_set_vxlan_bypass,                                        \
21950   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21951 _(sw_interface_set_geneve_bypass,                                       \
21952   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21953 _(sw_interface_set_l2_xconnect,                                         \
21954   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21955   "enable | disable")                                                   \
21956 _(sw_interface_set_l2_bridge,                                           \
21957   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21958   "[shg <split-horizon-group>] [bvi]\n"                                 \
21959   "enable | disable")                                                   \
21960 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21961 _(bridge_domain_add_del,                                                \
21962   "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") \
21963 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21964 _(l2fib_add_del,                                                        \
21965   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21966 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21967 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21968 _(l2_flags,                                                             \
21969   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21970 _(bridge_flags,                                                         \
21971   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21972 _(tap_create_v2,                                                        \
21973   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21974 _(tap_delete_v2,                                                        \
21975   "<vpp-if-name> | sw_if_index <id>")                                   \
21976 _(sw_interface_tap_v2_dump, "")                                         \
21977 _(virtio_pci_create,                                                    \
21978   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21979 _(virtio_pci_delete,                                                    \
21980   "<vpp-if-name> | sw_if_index <id>")                                   \
21981 _(sw_interface_virtio_pci_dump, "")                                     \
21982 _(bond_create,                                                          \
21983   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21984   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21985   "[id <if-id>]")                                                       \
21986 _(bond_delete,                                                          \
21987   "<vpp-if-name> | sw_if_index <id>")                                   \
21988 _(bond_enslave,                                                         \
21989   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21990 _(bond_detach_slave,                                                    \
21991   "sw_if_index <n>")                                                    \
21992 _(sw_interface_bond_dump, "")                                           \
21993 _(sw_interface_slave_dump,                                              \
21994   "<vpp-if-name> | sw_if_index <id>")                                   \
21995 _(ip_table_add_del,                                                     \
21996   "table <n> [ipv6] [add | del]\n")                                     \
21997 _(ip_route_add_del,                                                     \
21998   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21999   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22000   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22001   "[multipath] [count <n>] [del]")                                      \
22002 _(ip_mroute_add_del,                                                    \
22003   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22004   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22005 _(mpls_table_add_del,                                                   \
22006   "table <n> [add | del]\n")                                            \
22007 _(mpls_route_add_del,                                                   \
22008   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22009   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22010   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22011   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22012   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22013   "[count <n>] [del]")                                                  \
22014 _(mpls_ip_bind_unbind,                                                  \
22015   "<label> <addr/len>")                                                 \
22016 _(mpls_tunnel_add_del,                                                  \
22017   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22018   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22019   "[l2-only]  [out-label <n>]")                                         \
22020 _(sr_mpls_policy_add,                                                   \
22021   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22022 _(sr_mpls_policy_del,                                                   \
22023   "bsid <id>")                                                          \
22024 _(bier_table_add_del,                                                   \
22025   "<label> <sub-domain> <set> <bsl> [del]")                             \
22026 _(bier_route_add_del,                                                   \
22027   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22028   "[<intfc> | sw_if_index <id>]"                                        \
22029   "[weight <n>] [del] [multipath]")                                     \
22030 _(proxy_arp_add_del,                                                    \
22031   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22032 _(proxy_arp_intfc_enable_disable,                                       \
22033   "<intfc> | sw_if_index <id> enable | disable")                        \
22034 _(sw_interface_set_unnumbered,                                          \
22035   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22036 _(ip_neighbor_add_del,                                                  \
22037   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22038   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22039 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22040 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22041   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22042   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22043   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22044 _(reset_fib, "vrf <n> [ipv6]")                                          \
22045 _(dhcp_proxy_config,                                                    \
22046   "svr <v46-address> src <v46-address>\n"                               \
22047    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22048 _(dhcp_proxy_set_vss,                                                   \
22049   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22050 _(dhcp_proxy_dump, "ip6")                                               \
22051 _(dhcp_client_config,                                                   \
22052   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22053 _(set_ip_flow_hash,                                                     \
22054   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22055 _(sw_interface_ip6_enable_disable,                                      \
22056   "<intfc> | sw_if_index <id> enable | disable")                        \
22057 _(ip6nd_proxy_add_del,                                                  \
22058   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22059 _(ip6nd_proxy_dump, "")                                                 \
22060 _(sw_interface_ip6nd_ra_prefix,                                         \
22061   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22062   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22063   "[nolink] [isno]")                                                    \
22064 _(sw_interface_ip6nd_ra_config,                                         \
22065   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22066   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22067   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22068 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22069 _(l2_patch_add_del,                                                     \
22070   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22071   "enable | disable")                                                   \
22072 _(sr_localsid_add_del,                                                  \
22073   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22074   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22075 _(classify_add_del_table,                                               \
22076   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22077   " [del] [del-chain] mask <mask-value>\n"                              \
22078   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22079   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22080 _(classify_add_del_session,                                             \
22081   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22082   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22083   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22084   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22085 _(classify_set_interface_ip_table,                                      \
22086   "<intfc> | sw_if_index <nn> table <nn>")                              \
22087 _(classify_set_interface_l2_tables,                                     \
22088   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22089   "  [other-table <nn>]")                                               \
22090 _(get_node_index, "node <node-name")                                    \
22091 _(add_node_next, "node <node-name> next <next-node-name>")              \
22092 _(l2tpv3_create_tunnel,                                                 \
22093   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22094   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22095   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22096 _(l2tpv3_set_tunnel_cookies,                                            \
22097   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22098   "[new_remote_cookie <nn>]\n")                                         \
22099 _(l2tpv3_interface_enable_disable,                                      \
22100   "<intfc> | sw_if_index <nn> enable | disable")                        \
22101 _(l2tpv3_set_lookup_key,                                                \
22102   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22103 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22104 _(vxlan_offload_rx,                                                     \
22105   "hw { <interface name> | hw_if_index <nn>} "                          \
22106   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22107 _(vxlan_add_del_tunnel,                                                 \
22108   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22109   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22110   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22111 _(geneve_add_del_tunnel,                                                \
22112   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22113   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22114   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22115 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22116 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22117 _(gre_tunnel_add_del,                                                   \
22118   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22119   "[teb | erspan <session-id>] [del]")                                  \
22120 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22121 _(l2_fib_clear_table, "")                                               \
22122 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22123 _(l2_interface_vlan_tag_rewrite,                                        \
22124   "<intfc> | sw_if_index <nn> \n"                                       \
22125   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22126   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22127 _(create_vhost_user_if,                                                 \
22128         "socket <filename> [server] [renumber <dev_instance>] "         \
22129         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22130         "[mac <mac_address>]")                                          \
22131 _(modify_vhost_user_if,                                                 \
22132         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22133         "[server] [renumber <dev_instance>]")                           \
22134 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22135 _(sw_interface_vhost_user_dump, "")                                     \
22136 _(show_version, "")                                                     \
22137 _(show_threads, "")                                                     \
22138 _(vxlan_gpe_add_del_tunnel,                                             \
22139   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22140   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22141   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22142   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22143 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22144 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22145 _(interface_name_renumber,                                              \
22146   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22147 _(input_acl_set_interface,                                              \
22148   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22149   "  [l2-table <nn>] [del]")                                            \
22150 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22151 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22152   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22153 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22154 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22155 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22156 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22157 _(ip_dump, "ipv4 | ipv6")                                               \
22158 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22159 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22160   "  spid_id <n> ")                                                     \
22161 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22162   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22163   "  integ_alg <alg> integ_key <hex>")                                  \
22164 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22165   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22166   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22167   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22168 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22169   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22170   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22171   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22172   "  [instance <n>]")     \
22173 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22174 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22175 _(delete_loopback,"sw_if_index <nn>")                                   \
22176 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22177 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22178 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22179 _(want_interface_events,  "enable|disable")                             \
22180 _(get_first_msg_id, "client <name>")                                    \
22181 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22182 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22183   "fib-id <nn> [ip4][ip6][default]")                                    \
22184 _(get_node_graph, " ")                                                  \
22185 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22186 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22187 _(ioam_disable, "")                                                     \
22188 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22189                             " sw_if_index <sw_if_index> p <priority> "  \
22190                             "w <weight>] [del]")                        \
22191 _(one_add_del_locator, "locator-set <locator_name> "                    \
22192                         "iface <intf> | sw_if_index <sw_if_index> "     \
22193                         "p <priority> w <weight> [del]")                \
22194 _(one_add_del_local_eid,"vni <vni> eid "                                \
22195                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22196                          "locator-set <locator_name> [del]"             \
22197                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22198 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22199 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22200 _(one_enable_disable, "enable|disable")                                 \
22201 _(one_map_register_enable_disable, "enable|disable")                    \
22202 _(one_map_register_fallback_threshold, "<value>")                       \
22203 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22204 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22205                                "[seid <seid>] "                         \
22206                                "rloc <locator> p <prio> "               \
22207                                "w <weight> [rloc <loc> ... ] "          \
22208                                "action <action> [del-all]")             \
22209 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22210                           "<local-eid>")                                \
22211 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22212 _(one_use_petr, "ip-address> | disable")                                \
22213 _(one_map_request_mode, "src-dst|dst-only")                             \
22214 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22215 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22216 _(one_locator_set_dump, "[local | remote]")                             \
22217 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22218 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22219                        "[local] | [remote]")                            \
22220 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22221 _(one_ndp_bd_get, "")                                                   \
22222 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22223 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22224 _(one_l2_arp_bd_get, "")                                                \
22225 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22226 _(one_stats_enable_disable, "enable|disable")                           \
22227 _(show_one_stats_enable_disable, "")                                    \
22228 _(one_eid_table_vni_dump, "")                                           \
22229 _(one_eid_table_map_dump, "l2|l3")                                      \
22230 _(one_map_resolver_dump, "")                                            \
22231 _(one_map_server_dump, "")                                              \
22232 _(one_adjacencies_get, "vni <vni>")                                     \
22233 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22234 _(show_one_rloc_probe_state, "")                                        \
22235 _(show_one_map_register_state, "")                                      \
22236 _(show_one_status, "")                                                  \
22237 _(one_stats_dump, "")                                                   \
22238 _(one_stats_flush, "")                                                  \
22239 _(one_get_map_request_itr_rlocs, "")                                    \
22240 _(one_map_register_set_ttl, "<ttl>")                                    \
22241 _(one_set_transport_protocol, "udp|api")                                \
22242 _(one_get_transport_protocol, "")                                       \
22243 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22244 _(one_show_xtr_mode, "")                                                \
22245 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22246 _(one_show_pitr_mode, "")                                               \
22247 _(one_enable_disable_petr_mode, "enable|disable")                       \
22248 _(one_show_petr_mode, "")                                               \
22249 _(show_one_nsh_mapping, "")                                             \
22250 _(show_one_pitr, "")                                                    \
22251 _(show_one_use_petr, "")                                                \
22252 _(show_one_map_request_mode, "")                                        \
22253 _(show_one_map_register_ttl, "")                                        \
22254 _(show_one_map_register_fallback_threshold, "")                         \
22255 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22256                             " sw_if_index <sw_if_index> p <priority> "  \
22257                             "w <weight>] [del]")                        \
22258 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22259                         "iface <intf> | sw_if_index <sw_if_index> "     \
22260                         "p <priority> w <weight> [del]")                \
22261 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22262                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22263                          "locator-set <locator_name> [del]"             \
22264                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22265 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22266 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22267 _(lisp_enable_disable, "enable|disable")                                \
22268 _(lisp_map_register_enable_disable, "enable|disable")                   \
22269 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22270 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22271                                "[seid <seid>] "                         \
22272                                "rloc <locator> p <prio> "               \
22273                                "w <weight> [rloc <loc> ... ] "          \
22274                                "action <action> [del-all]")             \
22275 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22276                           "<local-eid>")                                \
22277 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22278 _(lisp_use_petr, "<ip-address> | disable")                              \
22279 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22280 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22281 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22282 _(lisp_locator_set_dump, "[local | remote]")                            \
22283 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22284 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22285                        "[local] | [remote]")                            \
22286 _(lisp_eid_table_vni_dump, "")                                          \
22287 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22288 _(lisp_map_resolver_dump, "")                                           \
22289 _(lisp_map_server_dump, "")                                             \
22290 _(lisp_adjacencies_get, "vni <vni>")                                    \
22291 _(gpe_fwd_entry_vnis_get, "")                                           \
22292 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22293 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22294                                 "[table <table-id>]")                   \
22295 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22296 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22297 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22298 _(gpe_get_encap_mode, "")                                               \
22299 _(lisp_gpe_add_del_iface, "up|down")                                    \
22300 _(lisp_gpe_enable_disable, "enable|disable")                            \
22301 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22302   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22303 _(show_lisp_rloc_probe_state, "")                                       \
22304 _(show_lisp_map_register_state, "")                                     \
22305 _(show_lisp_status, "")                                                 \
22306 _(lisp_get_map_request_itr_rlocs, "")                                   \
22307 _(show_lisp_pitr, "")                                                   \
22308 _(show_lisp_use_petr, "")                                               \
22309 _(show_lisp_map_request_mode, "")                                       \
22310 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22311 _(af_packet_delete, "name <host interface name>")                       \
22312 _(af_packet_dump, "")                                                   \
22313 _(policer_add_del, "name <policer name> <params> [del]")                \
22314 _(policer_dump, "[name <policer name>]")                                \
22315 _(policer_classify_set_interface,                                       \
22316   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22317   "  [l2-table <nn>] [del]")                                            \
22318 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22319 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22320     "[master|slave]")                                                   \
22321 _(netmap_delete, "name <interface name>")                               \
22322 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22323 _(mpls_table_dump, "")                                                  \
22324 _(mpls_route_dump, "table-id <ID>")                                     \
22325 _(classify_table_ids, "")                                               \
22326 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22327 _(classify_table_info, "table_id <nn>")                                 \
22328 _(classify_session_dump, "table_id <nn>")                               \
22329 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22330     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22331     "[template_interval <nn>] [udp_checksum]")                          \
22332 _(ipfix_exporter_dump, "")                                              \
22333 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22334 _(ipfix_classify_stream_dump, "")                                       \
22335 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22336 _(ipfix_classify_table_dump, "")                                        \
22337 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22338 _(sw_interface_span_dump, "[l2]")                                           \
22339 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22340 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22341 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22342 _(pg_enable_disable, "[stream <id>] disable")                           \
22343 _(ip_source_and_port_range_check_add_del,                               \
22344   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22345 _(ip_source_and_port_range_check_interface_add_del,                     \
22346   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22347   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22348 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22349 _(l2_interface_pbb_tag_rewrite,                                         \
22350   "<intfc> | sw_if_index <nn> \n"                                       \
22351   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22352   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22353 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22354 _(flow_classify_set_interface,                                          \
22355   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22356 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22357 _(ip_table_dump, "")                                                    \
22358 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22359 _(ip_mtable_dump, "")                                                   \
22360 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22361 _(feature_enable_disable, "arc_name <arc_name> "                        \
22362   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22363 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22364 "[disable]")                                                            \
22365 _(l2_xconnect_dump, "")                                                 \
22366 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22367 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22368 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22369 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22370 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22371 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22372 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22373   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22374 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22375 _(sock_init_shm, "size <nnn>")                                          \
22376 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22377 _(dns_enable_disable, "[enable][disable]")                              \
22378 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22379 _(dns_resolve_name, "<hostname>")                                       \
22380 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22381 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22382 _(dns_resolve_name, "<hostname>")                                       \
22383 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22384   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22385 _(session_rules_dump, "")                                               \
22386 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22387 _(output_acl_set_interface,                                             \
22388   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22389   "  [l2-table <nn>] [del]")                                            \
22390 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22391
22392 /* List of command functions, CLI names map directly to functions */
22393 #define foreach_cli_function                                    \
22394 _(comment, "usage: comment <ignore-rest-of-line>")              \
22395 _(dump_interface_table, "usage: dump_interface_table")          \
22396 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22397 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22398 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22399 _(dump_macro_table, "usage: dump_macro_table ")                 \
22400 _(dump_node_table, "usage: dump_node_table")                    \
22401 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22402 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22403 _(elog_disable, "usage: elog_disable")                          \
22404 _(elog_enable, "usage: elog_enable")                            \
22405 _(elog_save, "usage: elog_save <filename>")                     \
22406 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22407 _(echo, "usage: echo <message>")                                \
22408 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22409 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22410 _(help, "usage: help")                                          \
22411 _(q, "usage: quit")                                             \
22412 _(quit, "usage: quit")                                          \
22413 _(search_node_table, "usage: search_node_table <name>...")      \
22414 _(set, "usage: set <variable-name> <value>")                    \
22415 _(script, "usage: script <file-name>")                          \
22416 _(statseg, "usage: statseg")                                    \
22417 _(unset, "usage: unset <variable-name>")
22418
22419 #define _(N,n)                                  \
22420     static void vl_api_##n##_t_handler_uni      \
22421     (vl_api_##n##_t * mp)                       \
22422     {                                           \
22423         vat_main_t * vam = &vat_main;           \
22424         if (vam->json_output) {                 \
22425             vl_api_##n##_t_handler_json(mp);    \
22426         } else {                                \
22427             vl_api_##n##_t_handler(mp);         \
22428         }                                       \
22429     }
22430 foreach_vpe_api_reply_msg;
22431 #if VPP_API_TEST_BUILTIN == 0
22432 foreach_standalone_reply_msg;
22433 #endif
22434 #undef _
22435
22436 void
22437 vat_api_hookup (vat_main_t * vam)
22438 {
22439 #define _(N,n)                                                  \
22440     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22441                            vl_api_##n##_t_handler_uni,          \
22442                            vl_noop_handler,                     \
22443                            vl_api_##n##_t_endian,               \
22444                            vl_api_##n##_t_print,                \
22445                            sizeof(vl_api_##n##_t), 1);
22446   foreach_vpe_api_reply_msg;
22447 #if VPP_API_TEST_BUILTIN == 0
22448   foreach_standalone_reply_msg;
22449 #endif
22450 #undef _
22451
22452 #if (VPP_API_TEST_BUILTIN==0)
22453   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22454
22455   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22456
22457   vam->function_by_name = hash_create_string (0, sizeof (uword));
22458
22459   vam->help_by_name = hash_create_string (0, sizeof (uword));
22460 #endif
22461
22462   /* API messages we can send */
22463 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22464   foreach_vpe_api_msg;
22465 #undef _
22466
22467   /* Help strings */
22468 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22469   foreach_vpe_api_msg;
22470 #undef _
22471
22472   /* CLI functions */
22473 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22474   foreach_cli_function;
22475 #undef _
22476
22477   /* Help strings */
22478 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22479   foreach_cli_function;
22480 #undef _
22481 }
22482
22483 #if VPP_API_TEST_BUILTIN
22484 static clib_error_t *
22485 vat_api_hookup_shim (vlib_main_t * vm)
22486 {
22487   vat_api_hookup (&vat_main);
22488   return 0;
22489 }
22490
22491 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22492 #endif
22493
22494 /*
22495  * fd.io coding-style-patch-verification: ON
22496  *
22497  * Local Variables:
22498  * eval: (c-set-style "gnu")
22499  * End:
22500  */