api: enforce vla is last and fixed string type
[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->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
996
997       sub->sub_number_of_tags = mp->sub_number_of_tags;
998       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
999       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1000
1001       /* vlan tag rewrite */
1002       sub->vtr_op = ntohl (mp->vtr_op);
1003       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1004       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1005       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1006     }
1007 }
1008
1009 static void vl_api_sw_interface_details_t_handler_json
1010   (vl_api_sw_interface_details_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t *node = NULL;
1014
1015   if (VAT_JSON_ARRAY != vam->json_tree.type)
1016     {
1017       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1018       vat_json_init_array (&vam->json_tree);
1019     }
1020   node = vat_json_array_add (&vam->json_tree);
1021
1022   vat_json_init_object (node);
1023   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1024   vat_json_object_add_uint (node, "sup_sw_if_index",
1025                             ntohl (mp->sup_sw_if_index));
1026   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1027                              sizeof (mp->l2_address));
1028   vat_json_object_add_string_copy (node, "interface_name",
1029                                    mp->interface_name);
1030   vat_json_object_add_uint (node, "flags", mp->flags);
1031   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1032   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1033   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1034   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1035   vat_json_object_add_uint (node, "sub_number_of_tags",
1036                             mp->sub_number_of_tags);
1037   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1038                             ntohs (mp->sub_outer_vlan_id));
1039   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1040                             ntohs (mp->sub_inner_vlan_id));
1041   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1042   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1043   vat_json_object_add_uint (node, "vtr_push_dot1q",
1044                             ntohl (mp->vtr_push_dot1q));
1045   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1046   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1047   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1048     {
1049       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1050                                        format (0, "%U",
1051                                                format_ethernet_address,
1052                                                &mp->b_dmac));
1053       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1054                                        format (0, "%U",
1055                                                format_ethernet_address,
1056                                                &mp->b_smac));
1057       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1058       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1059     }
1060 }
1061
1062 #if VPP_API_TEST_BUILTIN == 0
1063 static void vl_api_sw_interface_event_t_handler
1064   (vl_api_sw_interface_event_t * mp)
1065 {
1066   vat_main_t *vam = &vat_main;
1067   if (vam->interface_event_display)
1068     errmsg ("interface flags: sw_if_index %d %s %s",
1069             ntohl (mp->sw_if_index),
1070             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1071             "admin-up" : "admin-down",
1072             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1073             "link-up" : "link-down");
1074 }
1075 #endif
1076
1077 __clib_unused static void
1078 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1079 {
1080   /* JSON output not supported */
1081 }
1082
1083 static void
1084 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1085 {
1086   vat_main_t *vam = &vat_main;
1087   i32 retval = ntohl (mp->retval);
1088
1089   vam->retval = retval;
1090   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1091   vam->result_ready = 1;
1092 }
1093
1094 static void
1095 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1096 {
1097   vat_main_t *vam = &vat_main;
1098   vat_json_node_t node;
1099   api_main_t *am = &api_main;
1100   void *oldheap;
1101   u8 *reply;
1102
1103   vat_json_init_object (&node);
1104   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1105   vat_json_object_add_uint (&node, "reply_in_shmem",
1106                             ntohl (mp->reply_in_shmem));
1107   /* Toss the shared-memory original... */
1108   pthread_mutex_lock (&am->vlib_rp->mutex);
1109   oldheap = svm_push_data_heap (am->vlib_rp);
1110
1111   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1112   vec_free (reply);
1113
1114   svm_pop_heap (oldheap);
1115   pthread_mutex_unlock (&am->vlib_rp->mutex);
1116
1117   vat_json_print (vam->ofp, &node);
1118   vat_json_free (&node);
1119
1120   vam->retval = ntohl (mp->retval);
1121   vam->result_ready = 1;
1122 }
1123
1124 static void
1125 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1126 {
1127   vat_main_t *vam = &vat_main;
1128   i32 retval = ntohl (mp->retval);
1129   u32 length = vl_api_string_len (&mp->reply);
1130
1131   vec_reset_length (vam->cmd_reply);
1132
1133   vam->retval = retval;
1134   if (retval == 0)
1135     {
1136       vec_validate (vam->cmd_reply, length);
1137       clib_memcpy ((char *) (vam->cmd_reply),
1138                    vl_api_from_api_string (&mp->reply), length);
1139       vam->cmd_reply[length] = 0;
1140     }
1141   vam->result_ready = 1;
1142 }
1143
1144 static void
1145 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   vat_json_node_t node;
1149
1150   vec_reset_length (vam->cmd_reply);
1151
1152   vat_json_init_object (&node);
1153   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1154   vat_json_object_add_string_copy (&node, "reply",
1155                                    vl_api_from_api_string (&mp->reply));
1156
1157   vat_json_print (vam->ofp, &node);
1158   vat_json_free (&node);
1159
1160   vam->retval = ntohl (mp->retval);
1161   vam->result_ready = 1;
1162 }
1163
1164 static void vl_api_classify_add_del_table_reply_t_handler
1165   (vl_api_classify_add_del_table_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   i32 retval = ntohl (mp->retval);
1169   if (vam->async_mode)
1170     {
1171       vam->async_errors += (retval < 0);
1172     }
1173   else
1174     {
1175       vam->retval = retval;
1176       if (retval == 0 &&
1177           ((mp->new_table_index != 0xFFFFFFFF) ||
1178            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1179            (mp->match_n_vectors != 0xFFFFFFFF)))
1180         /*
1181          * Note: this is just barely thread-safe, depends on
1182          * the main thread spinning waiting for an answer...
1183          */
1184         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1185                 ntohl (mp->new_table_index),
1186                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1187       vam->result_ready = 1;
1188     }
1189 }
1190
1191 static void vl_api_classify_add_del_table_reply_t_handler_json
1192   (vl_api_classify_add_del_table_reply_t * mp)
1193 {
1194   vat_main_t *vam = &vat_main;
1195   vat_json_node_t node;
1196
1197   vat_json_init_object (&node);
1198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1199   vat_json_object_add_uint (&node, "new_table_index",
1200                             ntohl (mp->new_table_index));
1201   vat_json_object_add_uint (&node, "skip_n_vectors",
1202                             ntohl (mp->skip_n_vectors));
1203   vat_json_object_add_uint (&node, "match_n_vectors",
1204                             ntohl (mp->match_n_vectors));
1205
1206   vat_json_print (vam->ofp, &node);
1207   vat_json_free (&node);
1208
1209   vam->retval = ntohl (mp->retval);
1210   vam->result_ready = 1;
1211 }
1212
1213 static void vl_api_get_node_index_reply_t_handler
1214   (vl_api_get_node_index_reply_t * mp)
1215 {
1216   vat_main_t *vam = &vat_main;
1217   i32 retval = ntohl (mp->retval);
1218   if (vam->async_mode)
1219     {
1220       vam->async_errors += (retval < 0);
1221     }
1222   else
1223     {
1224       vam->retval = retval;
1225       if (retval == 0)
1226         errmsg ("node index %d", ntohl (mp->node_index));
1227       vam->result_ready = 1;
1228     }
1229 }
1230
1231 static void vl_api_get_node_index_reply_t_handler_json
1232   (vl_api_get_node_index_reply_t * mp)
1233 {
1234   vat_main_t *vam = &vat_main;
1235   vat_json_node_t node;
1236
1237   vat_json_init_object (&node);
1238   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1239   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1240
1241   vat_json_print (vam->ofp, &node);
1242   vat_json_free (&node);
1243
1244   vam->retval = ntohl (mp->retval);
1245   vam->result_ready = 1;
1246 }
1247
1248 static void vl_api_get_next_index_reply_t_handler
1249   (vl_api_get_next_index_reply_t * mp)
1250 {
1251   vat_main_t *vam = &vat_main;
1252   i32 retval = ntohl (mp->retval);
1253   if (vam->async_mode)
1254     {
1255       vam->async_errors += (retval < 0);
1256     }
1257   else
1258     {
1259       vam->retval = retval;
1260       if (retval == 0)
1261         errmsg ("next node index %d", ntohl (mp->next_index));
1262       vam->result_ready = 1;
1263     }
1264 }
1265
1266 static void vl_api_get_next_index_reply_t_handler_json
1267   (vl_api_get_next_index_reply_t * mp)
1268 {
1269   vat_main_t *vam = &vat_main;
1270   vat_json_node_t node;
1271
1272   vat_json_init_object (&node);
1273   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1274   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1275
1276   vat_json_print (vam->ofp, &node);
1277   vat_json_free (&node);
1278
1279   vam->retval = ntohl (mp->retval);
1280   vam->result_ready = 1;
1281 }
1282
1283 static void vl_api_add_node_next_reply_t_handler
1284   (vl_api_add_node_next_reply_t * mp)
1285 {
1286   vat_main_t *vam = &vat_main;
1287   i32 retval = ntohl (mp->retval);
1288   if (vam->async_mode)
1289     {
1290       vam->async_errors += (retval < 0);
1291     }
1292   else
1293     {
1294       vam->retval = retval;
1295       if (retval == 0)
1296         errmsg ("next index %d", ntohl (mp->next_index));
1297       vam->result_ready = 1;
1298     }
1299 }
1300
1301 static void vl_api_add_node_next_reply_t_handler_json
1302   (vl_api_add_node_next_reply_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t node;
1306
1307   vat_json_init_object (&node);
1308   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1309   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1310
1311   vat_json_print (vam->ofp, &node);
1312   vat_json_free (&node);
1313
1314   vam->retval = ntohl (mp->retval);
1315   vam->result_ready = 1;
1316 }
1317
1318 static void vl_api_show_version_reply_t_handler
1319   (vl_api_show_version_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323
1324   if (retval >= 0)
1325     {
1326       errmsg ("        program: %s", mp->program);
1327       errmsg ("        version: %s", mp->version);
1328       errmsg ("     build date: %s", mp->build_date);
1329       errmsg ("build directory: %s", mp->build_directory);
1330     }
1331   vam->retval = retval;
1332   vam->result_ready = 1;
1333 }
1334
1335 static void vl_api_show_version_reply_t_handler_json
1336   (vl_api_show_version_reply_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   vat_json_node_t node;
1340
1341   vat_json_init_object (&node);
1342   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1343   vat_json_object_add_string_copy (&node, "program", mp->program);
1344   vat_json_object_add_string_copy (&node, "version", mp->version);
1345   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1346   vat_json_object_add_string_copy (&node, "build_directory",
1347                                    mp->build_directory);
1348
1349   vat_json_print (vam->ofp, &node);
1350   vat_json_free (&node);
1351
1352   vam->retval = ntohl (mp->retval);
1353   vam->result_ready = 1;
1354 }
1355
1356 static void vl_api_show_threads_reply_t_handler
1357   (vl_api_show_threads_reply_t * mp)
1358 {
1359   vat_main_t *vam = &vat_main;
1360   i32 retval = ntohl (mp->retval);
1361   int i, count = 0;
1362
1363   if (retval >= 0)
1364     count = ntohl (mp->count);
1365
1366   for (i = 0; i < count; i++)
1367     print (vam->ofp,
1368            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1369            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1370            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1371            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1372            ntohl (mp->thread_data[i].cpu_socket));
1373
1374   vam->retval = retval;
1375   vam->result_ready = 1;
1376 }
1377
1378 static void vl_api_show_threads_reply_t_handler_json
1379   (vl_api_show_threads_reply_t * mp)
1380 {
1381   vat_main_t *vam = &vat_main;
1382   vat_json_node_t node;
1383   vl_api_thread_data_t *td;
1384   i32 retval = ntohl (mp->retval);
1385   int i, count = 0;
1386
1387   if (retval >= 0)
1388     count = ntohl (mp->count);
1389
1390   vat_json_init_object (&node);
1391   vat_json_object_add_int (&node, "retval", retval);
1392   vat_json_object_add_uint (&node, "count", count);
1393
1394   for (i = 0; i < count; i++)
1395     {
1396       td = &mp->thread_data[i];
1397       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1398       vat_json_object_add_string_copy (&node, "name", td->name);
1399       vat_json_object_add_string_copy (&node, "type", td->type);
1400       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1401       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1402       vat_json_object_add_int (&node, "core", ntohl (td->id));
1403       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1404     }
1405
1406   vat_json_print (vam->ofp, &node);
1407   vat_json_free (&node);
1408
1409   vam->retval = retval;
1410   vam->result_ready = 1;
1411 }
1412
1413 static int
1414 api_show_threads (vat_main_t * vam)
1415 {
1416   vl_api_show_threads_t *mp;
1417   int ret;
1418
1419   print (vam->ofp,
1420          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1421          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1422
1423   M (SHOW_THREADS, mp);
1424
1425   S (mp);
1426   W (ret);
1427   return ret;
1428 }
1429
1430 static void
1431 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1432 {
1433   u32 sw_if_index = ntohl (mp->sw_if_index);
1434   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1435           mp->mac_ip ? "mac/ip binding" : "address resolution",
1436           ntohl (mp->pid), format_ip4_address, mp->ip,
1437           format_vl_api_mac_address, &mp->mac, sw_if_index);
1438 }
1439
1440 static void
1441 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1442 {
1443   /* JSON output not supported */
1444 }
1445
1446 static void
1447 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1448 {
1449   u32 sw_if_index = ntohl (mp->sw_if_index);
1450   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1451           mp->mac_ip ? "mac/ip binding" : "address resolution",
1452           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1453           format_vl_api_mac_address, mp->mac, sw_if_index);
1454 }
1455
1456 static void
1457 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1458 {
1459   /* JSON output not supported */
1460 }
1461
1462 static void
1463 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1464 {
1465   u32 n_macs = ntohl (mp->n_macs);
1466   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1467           ntohl (mp->pid), mp->client_index, n_macs);
1468   int i;
1469   for (i = 0; i < n_macs; i++)
1470     {
1471       vl_api_mac_entry_t *mac = &mp->mac[i];
1472       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1473               i + 1, ntohl (mac->sw_if_index),
1474               format_ethernet_address, mac->mac_addr, mac->action);
1475       if (i == 1000)
1476         break;
1477     }
1478 }
1479
1480 static void
1481 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1482 {
1483   /* JSON output not supported */
1484 }
1485
1486 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1487 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1488
1489 /*
1490  * Special-case: build the bridge domain table, maintain
1491  * the next bd id vbl.
1492  */
1493 static void vl_api_bridge_domain_details_t_handler
1494   (vl_api_bridge_domain_details_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1498   int i;
1499
1500   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1501          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1502
1503   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1504          ntohl (mp->bd_id), mp->learn, mp->forward,
1505          mp->flood, ntohl (mp->bvi_sw_if_index),
1506          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1507
1508   if (n_sw_ifs)
1509     {
1510       vl_api_bridge_domain_sw_if_t *sw_ifs;
1511       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1512              "Interface Name");
1513
1514       sw_ifs = mp->sw_if_details;
1515       for (i = 0; i < n_sw_ifs; i++)
1516         {
1517           u8 *sw_if_name = 0;
1518           u32 sw_if_index;
1519           hash_pair_t *p;
1520
1521           sw_if_index = ntohl (sw_ifs->sw_if_index);
1522
1523           /* *INDENT-OFF* */
1524           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1525                              ({
1526                                if ((u32) p->value[0] == sw_if_index)
1527                                  {
1528                                    sw_if_name = (u8 *)(p->key);
1529                                    break;
1530                                  }
1531                              }));
1532           /* *INDENT-ON* */
1533           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1534                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1535                  "sw_if_index not found!");
1536
1537           sw_ifs++;
1538         }
1539     }
1540 }
1541
1542 static void vl_api_bridge_domain_details_t_handler_json
1543   (vl_api_bridge_domain_details_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t *node, *array = NULL;
1547   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1548
1549   if (VAT_JSON_ARRAY != vam->json_tree.type)
1550     {
1551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1552       vat_json_init_array (&vam->json_tree);
1553     }
1554   node = vat_json_array_add (&vam->json_tree);
1555
1556   vat_json_init_object (node);
1557   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1558   vat_json_object_add_uint (node, "flood", mp->flood);
1559   vat_json_object_add_uint (node, "forward", mp->forward);
1560   vat_json_object_add_uint (node, "learn", mp->learn);
1561   vat_json_object_add_uint (node, "bvi_sw_if_index",
1562                             ntohl (mp->bvi_sw_if_index));
1563   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1564   array = vat_json_object_add (node, "sw_if");
1565   vat_json_init_array (array);
1566
1567
1568
1569   if (n_sw_ifs)
1570     {
1571       vl_api_bridge_domain_sw_if_t *sw_ifs;
1572       int i;
1573
1574       sw_ifs = mp->sw_if_details;
1575       for (i = 0; i < n_sw_ifs; i++)
1576         {
1577           node = vat_json_array_add (array);
1578           vat_json_init_object (node);
1579           vat_json_object_add_uint (node, "sw_if_index",
1580                                     ntohl (sw_ifs->sw_if_index));
1581           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1582           sw_ifs++;
1583         }
1584     }
1585 }
1586
1587 static void vl_api_control_ping_reply_t_handler
1588   (vl_api_control_ping_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->result_ready = 1;
1600     }
1601   if (vam->socket_client_main)
1602     vam->socket_client_main->control_pings_outstanding--;
1603 }
1604
1605 static void vl_api_control_ping_reply_t_handler_json
1606   (vl_api_control_ping_reply_t * mp)
1607 {
1608   vat_main_t *vam = &vat_main;
1609   i32 retval = ntohl (mp->retval);
1610
1611   if (VAT_JSON_NONE != vam->json_tree.type)
1612     {
1613       vat_json_print (vam->ofp, &vam->json_tree);
1614       vat_json_free (&vam->json_tree);
1615       vam->json_tree.type = VAT_JSON_NONE;
1616     }
1617   else
1618     {
1619       /* just print [] */
1620       vat_json_init_array (&vam->json_tree);
1621       vat_json_print (vam->ofp, &vam->json_tree);
1622       vam->json_tree.type = VAT_JSON_NONE;
1623     }
1624
1625   vam->retval = retval;
1626   vam->result_ready = 1;
1627 }
1628
1629 static void
1630   vl_api_bridge_domain_set_mac_age_reply_t_handler
1631   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   i32 retval = ntohl (mp->retval);
1635   if (vam->async_mode)
1636     {
1637       vam->async_errors += (retval < 0);
1638     }
1639   else
1640     {
1641       vam->retval = retval;
1642       vam->result_ready = 1;
1643     }
1644 }
1645
1646 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1647   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1648 {
1649   vat_main_t *vam = &vat_main;
1650   vat_json_node_t node;
1651
1652   vat_json_init_object (&node);
1653   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1654
1655   vat_json_print (vam->ofp, &node);
1656   vat_json_free (&node);
1657
1658   vam->retval = ntohl (mp->retval);
1659   vam->result_ready = 1;
1660 }
1661
1662 static void
1663 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   i32 retval = ntohl (mp->retval);
1667   if (vam->async_mode)
1668     {
1669       vam->async_errors += (retval < 0);
1670     }
1671   else
1672     {
1673       vam->retval = retval;
1674       vam->result_ready = 1;
1675     }
1676 }
1677
1678 static void vl_api_l2_flags_reply_t_handler_json
1679   (vl_api_l2_flags_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   vat_json_node_t node;
1683
1684   vat_json_init_object (&node);
1685   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1686   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1687                             ntohl (mp->resulting_feature_bitmap));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_bridge_flags_reply_t_handler
1697   (vl_api_bridge_flags_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->result_ready = 1;
1709     }
1710 }
1711
1712 static void vl_api_bridge_flags_reply_t_handler_json
1713   (vl_api_bridge_flags_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   vat_json_node_t node;
1717
1718   vat_json_init_object (&node);
1719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1720   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1721                             ntohl (mp->resulting_feature_bitmap));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728 }
1729
1730 static void
1731 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   i32 retval = ntohl (mp->retval);
1735   if (vam->async_mode)
1736     {
1737       vam->async_errors += (retval < 0);
1738     }
1739   else
1740     {
1741       vam->retval = retval;
1742       vam->sw_if_index = ntohl (mp->sw_if_index);
1743       vam->result_ready = 1;
1744     }
1745
1746 }
1747
1748 static void vl_api_tap_create_v2_reply_t_handler_json
1749   (vl_api_tap_create_v2_reply_t * mp)
1750 {
1751   vat_main_t *vam = &vat_main;
1752   vat_json_node_t node;
1753
1754   vat_json_init_object (&node);
1755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1756   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763
1764 }
1765
1766 static void
1767 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1768 {
1769   vat_main_t *vam = &vat_main;
1770   i32 retval = ntohl (mp->retval);
1771   if (vam->async_mode)
1772     {
1773       vam->async_errors += (retval < 0);
1774     }
1775   else
1776     {
1777       vam->retval = retval;
1778       vam->result_ready = 1;
1779     }
1780 }
1781
1782 static void vl_api_tap_delete_v2_reply_t_handler_json
1783   (vl_api_tap_delete_v2_reply_t * mp)
1784 {
1785   vat_main_t *vam = &vat_main;
1786   vat_json_node_t node;
1787
1788   vat_json_init_object (&node);
1789   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void
1799 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1800                                           mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_virtio_pci_create_reply_t_handler_json
1817   (vl_api_virtio_pci_create_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831
1832 }
1833
1834 static void
1835 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1836                                           mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   i32 retval = ntohl (mp->retval);
1840   if (vam->async_mode)
1841     {
1842       vam->async_errors += (retval < 0);
1843     }
1844   else
1845     {
1846       vam->retval = retval;
1847       vam->result_ready = 1;
1848     }
1849 }
1850
1851 static void vl_api_virtio_pci_delete_reply_t_handler_json
1852   (vl_api_virtio_pci_delete_reply_t * mp)
1853 {
1854   vat_main_t *vam = &vat_main;
1855   vat_json_node_t node;
1856
1857   vat_json_init_object (&node);
1858   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1859
1860   vat_json_print (vam->ofp, &node);
1861   vat_json_free (&node);
1862
1863   vam->retval = ntohl (mp->retval);
1864   vam->result_ready = 1;
1865 }
1866
1867 static void
1868 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   i32 retval = ntohl (mp->retval);
1872
1873   if (vam->async_mode)
1874     {
1875       vam->async_errors += (retval < 0);
1876     }
1877   else
1878     {
1879       vam->retval = retval;
1880       vam->sw_if_index = ntohl (mp->sw_if_index);
1881       vam->result_ready = 1;
1882     }
1883 }
1884
1885 static void vl_api_bond_create_reply_t_handler_json
1886   (vl_api_bond_create_reply_t * mp)
1887 {
1888   vat_main_t *vam = &vat_main;
1889   vat_json_node_t node;
1890
1891   vat_json_init_object (&node);
1892   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1893   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1894
1895   vat_json_print (vam->ofp, &node);
1896   vat_json_free (&node);
1897
1898   vam->retval = ntohl (mp->retval);
1899   vam->result_ready = 1;
1900 }
1901
1902 static void
1903 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1904 {
1905   vat_main_t *vam = &vat_main;
1906   i32 retval = ntohl (mp->retval);
1907
1908   if (vam->async_mode)
1909     {
1910       vam->async_errors += (retval < 0);
1911     }
1912   else
1913     {
1914       vam->retval = retval;
1915       vam->result_ready = 1;
1916     }
1917 }
1918
1919 static void vl_api_bond_delete_reply_t_handler_json
1920   (vl_api_bond_delete_reply_t * mp)
1921 {
1922   vat_main_t *vam = &vat_main;
1923   vat_json_node_t node;
1924
1925   vat_json_init_object (&node);
1926   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1927
1928   vat_json_print (vam->ofp, &node);
1929   vat_json_free (&node);
1930
1931   vam->retval = ntohl (mp->retval);
1932   vam->result_ready = 1;
1933 }
1934
1935 static void
1936 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1937 {
1938   vat_main_t *vam = &vat_main;
1939   i32 retval = ntohl (mp->retval);
1940
1941   if (vam->async_mode)
1942     {
1943       vam->async_errors += (retval < 0);
1944     }
1945   else
1946     {
1947       vam->retval = retval;
1948       vam->result_ready = 1;
1949     }
1950 }
1951
1952 static void vl_api_bond_enslave_reply_t_handler_json
1953   (vl_api_bond_enslave_reply_t * mp)
1954 {
1955   vat_main_t *vam = &vat_main;
1956   vat_json_node_t node;
1957
1958   vat_json_init_object (&node);
1959   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1960
1961   vat_json_print (vam->ofp, &node);
1962   vat_json_free (&node);
1963
1964   vam->retval = ntohl (mp->retval);
1965   vam->result_ready = 1;
1966 }
1967
1968 static void
1969 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1970                                           mp)
1971 {
1972   vat_main_t *vam = &vat_main;
1973   i32 retval = ntohl (mp->retval);
1974
1975   if (vam->async_mode)
1976     {
1977       vam->async_errors += (retval < 0);
1978     }
1979   else
1980     {
1981       vam->retval = retval;
1982       vam->result_ready = 1;
1983     }
1984 }
1985
1986 static void vl_api_bond_detach_slave_reply_t_handler_json
1987   (vl_api_bond_detach_slave_reply_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   vat_json_node_t node;
1991
1992   vat_json_init_object (&node);
1993   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1994
1995   vat_json_print (vam->ofp, &node);
1996   vat_json_free (&node);
1997
1998   vam->retval = ntohl (mp->retval);
1999   vam->result_ready = 1;
2000 }
2001
2002 static void vl_api_sw_interface_bond_details_t_handler
2003   (vl_api_sw_interface_bond_details_t * mp)
2004 {
2005   vat_main_t *vam = &vat_main;
2006
2007   print (vam->ofp,
2008          "%-16s %-12d %-12U %-13U %-14u %-14u",
2009          mp->interface_name, ntohl (mp->sw_if_index),
2010          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2011          ntohl (mp->active_slaves), ntohl (mp->slaves));
2012 }
2013
2014 static void vl_api_sw_interface_bond_details_t_handler_json
2015   (vl_api_sw_interface_bond_details_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018   vat_json_node_t *node = NULL;
2019
2020   if (VAT_JSON_ARRAY != vam->json_tree.type)
2021     {
2022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2023       vat_json_init_array (&vam->json_tree);
2024     }
2025   node = vat_json_array_add (&vam->json_tree);
2026
2027   vat_json_init_object (node);
2028   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2029   vat_json_object_add_string_copy (node, "interface_name",
2030                                    mp->interface_name);
2031   vat_json_object_add_uint (node, "mode", mp->mode);
2032   vat_json_object_add_uint (node, "load_balance", mp->lb);
2033   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2034   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2035 }
2036
2037 static int
2038 api_sw_interface_bond_dump (vat_main_t * vam)
2039 {
2040   vl_api_sw_interface_bond_dump_t *mp;
2041   vl_api_control_ping_t *mp_ping;
2042   int ret;
2043
2044   print (vam->ofp,
2045          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2046          "interface name", "sw_if_index", "mode", "load balance",
2047          "active slaves", "slaves");
2048
2049   /* Get list of bond interfaces */
2050   M (SW_INTERFACE_BOND_DUMP, mp);
2051   S (mp);
2052
2053   /* Use a control ping for synchronization */
2054   MPING (CONTROL_PING, mp_ping);
2055   S (mp_ping);
2056
2057   W (ret);
2058   return ret;
2059 }
2060
2061 static void vl_api_sw_interface_slave_details_t_handler
2062   (vl_api_sw_interface_slave_details_t * mp)
2063 {
2064   vat_main_t *vam = &vat_main;
2065
2066   print (vam->ofp,
2067          "%-25s %-12d %-12d %d", mp->interface_name,
2068          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2069 }
2070
2071 static void vl_api_sw_interface_slave_details_t_handler_json
2072   (vl_api_sw_interface_slave_details_t * mp)
2073 {
2074   vat_main_t *vam = &vat_main;
2075   vat_json_node_t *node = NULL;
2076
2077   if (VAT_JSON_ARRAY != vam->json_tree.type)
2078     {
2079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2080       vat_json_init_array (&vam->json_tree);
2081     }
2082   node = vat_json_array_add (&vam->json_tree);
2083
2084   vat_json_init_object (node);
2085   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2086   vat_json_object_add_string_copy (node, "interface_name",
2087                                    mp->interface_name);
2088   vat_json_object_add_uint (node, "passive", mp->is_passive);
2089   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2090 }
2091
2092 static int
2093 api_sw_interface_slave_dump (vat_main_t * vam)
2094 {
2095   unformat_input_t *i = vam->input;
2096   vl_api_sw_interface_slave_dump_t *mp;
2097   vl_api_control_ping_t *mp_ping;
2098   u32 sw_if_index = ~0;
2099   u8 sw_if_index_set = 0;
2100   int ret;
2101
2102   /* Parse args required to build the message */
2103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2104     {
2105       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2106         sw_if_index_set = 1;
2107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2108         sw_if_index_set = 1;
2109       else
2110         break;
2111     }
2112
2113   if (sw_if_index_set == 0)
2114     {
2115       errmsg ("missing vpp interface name. ");
2116       return -99;
2117     }
2118
2119   print (vam->ofp,
2120          "\n%-25s %-12s %-12s %s",
2121          "slave interface name", "sw_if_index", "passive", "long_timeout");
2122
2123   /* Get list of bond interfaces */
2124   M (SW_INTERFACE_SLAVE_DUMP, mp);
2125   mp->sw_if_index = ntohl (sw_if_index);
2126   S (mp);
2127
2128   /* Use a control ping for synchronization */
2129   MPING (CONTROL_PING, mp_ping);
2130   S (mp_ping);
2131
2132   W (ret);
2133   return ret;
2134 }
2135
2136 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2137   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2138 {
2139   vat_main_t *vam = &vat_main;
2140   i32 retval = ntohl (mp->retval);
2141   if (vam->async_mode)
2142     {
2143       vam->async_errors += (retval < 0);
2144     }
2145   else
2146     {
2147       vam->retval = retval;
2148       vam->sw_if_index = ntohl (mp->sw_if_index);
2149       vam->result_ready = 1;
2150     }
2151   vam->regenerate_interface_table = 1;
2152 }
2153
2154 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2155   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2156 {
2157   vat_main_t *vam = &vat_main;
2158   vat_json_node_t node;
2159
2160   vat_json_init_object (&node);
2161   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2162   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2163                             ntohl (mp->sw_if_index));
2164
2165   vat_json_print (vam->ofp, &node);
2166   vat_json_free (&node);
2167
2168   vam->retval = ntohl (mp->retval);
2169   vam->result_ready = 1;
2170 }
2171
2172 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2173   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2174 {
2175   vat_main_t *vam = &vat_main;
2176   i32 retval = ntohl (mp->retval);
2177   if (vam->async_mode)
2178     {
2179       vam->async_errors += (retval < 0);
2180     }
2181   else
2182     {
2183       vam->retval = retval;
2184       vam->sw_if_index = ntohl (mp->sw_if_index);
2185       vam->result_ready = 1;
2186     }
2187 }
2188
2189 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2190   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2191 {
2192   vat_main_t *vam = &vat_main;
2193   vat_json_node_t node;
2194
2195   vat_json_init_object (&node);
2196   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2197   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2198
2199   vat_json_print (vam->ofp, &node);
2200   vat_json_free (&node);
2201
2202   vam->retval = ntohl (mp->retval);
2203   vam->result_ready = 1;
2204 }
2205
2206 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2207   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2208 {
2209   vat_main_t *vam = &vat_main;
2210   i32 retval = ntohl (mp->retval);
2211   if (vam->async_mode)
2212     {
2213       vam->async_errors += (retval < 0);
2214     }
2215   else
2216     {
2217       vam->retval = retval;
2218       vam->result_ready = 1;
2219     }
2220 }
2221
2222 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2223   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2224 {
2225   vat_main_t *vam = &vat_main;
2226   vat_json_node_t node;
2227
2228   vat_json_init_object (&node);
2229   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2230   vat_json_object_add_uint (&node, "fwd_entry_index",
2231                             clib_net_to_host_u32 (mp->fwd_entry_index));
2232
2233   vat_json_print (vam->ofp, &node);
2234   vat_json_free (&node);
2235
2236   vam->retval = ntohl (mp->retval);
2237   vam->result_ready = 1;
2238 }
2239
2240 u8 *
2241 format_lisp_transport_protocol (u8 * s, va_list * args)
2242 {
2243   u32 proto = va_arg (*args, u32);
2244
2245   switch (proto)
2246     {
2247     case 1:
2248       return format (s, "udp");
2249     case 2:
2250       return format (s, "api");
2251     default:
2252       return 0;
2253     }
2254   return 0;
2255 }
2256
2257 static void vl_api_one_get_transport_protocol_reply_t_handler
2258   (vl_api_one_get_transport_protocol_reply_t * mp)
2259 {
2260   vat_main_t *vam = &vat_main;
2261   i32 retval = ntohl (mp->retval);
2262   if (vam->async_mode)
2263     {
2264       vam->async_errors += (retval < 0);
2265     }
2266   else
2267     {
2268       u32 proto = mp->protocol;
2269       print (vam->ofp, "Transport protocol: %U",
2270              format_lisp_transport_protocol, proto);
2271       vam->retval = retval;
2272       vam->result_ready = 1;
2273     }
2274 }
2275
2276 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2277   (vl_api_one_get_transport_protocol_reply_t * mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   vat_json_node_t node;
2281   u8 *s;
2282
2283   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2284   vec_add1 (s, 0);
2285
2286   vat_json_init_object (&node);
2287   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2288   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2289
2290   vec_free (s);
2291   vat_json_print (vam->ofp, &node);
2292   vat_json_free (&node);
2293
2294   vam->retval = ntohl (mp->retval);
2295   vam->result_ready = 1;
2296 }
2297
2298 static void vl_api_one_add_del_locator_set_reply_t_handler
2299   (vl_api_one_add_del_locator_set_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       vam->retval = retval;
2310       vam->result_ready = 1;
2311     }
2312 }
2313
2314 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2315   (vl_api_one_add_del_locator_set_reply_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   vat_json_node_t node;
2319
2320   vat_json_init_object (&node);
2321   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2322   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2323
2324   vat_json_print (vam->ofp, &node);
2325   vat_json_free (&node);
2326
2327   vam->retval = ntohl (mp->retval);
2328   vam->result_ready = 1;
2329 }
2330
2331 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2332   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2333 {
2334   vat_main_t *vam = &vat_main;
2335   i32 retval = ntohl (mp->retval);
2336   if (vam->async_mode)
2337     {
2338       vam->async_errors += (retval < 0);
2339     }
2340   else
2341     {
2342       vam->retval = retval;
2343       vam->sw_if_index = ntohl (mp->sw_if_index);
2344       vam->result_ready = 1;
2345     }
2346   vam->regenerate_interface_table = 1;
2347 }
2348
2349 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2350   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   vat_json_node_t node;
2354
2355   vat_json_init_object (&node);
2356   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2357   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2358
2359   vat_json_print (vam->ofp, &node);
2360   vat_json_free (&node);
2361
2362   vam->retval = ntohl (mp->retval);
2363   vam->result_ready = 1;
2364 }
2365
2366 static void vl_api_vxlan_offload_rx_reply_t_handler
2367   (vl_api_vxlan_offload_rx_reply_t * mp)
2368 {
2369   vat_main_t *vam = &vat_main;
2370   i32 retval = ntohl (mp->retval);
2371   if (vam->async_mode)
2372     {
2373       vam->async_errors += (retval < 0);
2374     }
2375   else
2376     {
2377       vam->retval = retval;
2378       vam->result_ready = 1;
2379     }
2380 }
2381
2382 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2383   (vl_api_vxlan_offload_rx_reply_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   vat_json_node_t node;
2387
2388   vat_json_init_object (&node);
2389   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2390
2391   vat_json_print (vam->ofp, &node);
2392   vat_json_free (&node);
2393
2394   vam->retval = ntohl (mp->retval);
2395   vam->result_ready = 1;
2396 }
2397
2398 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2399   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   i32 retval = ntohl (mp->retval);
2403   if (vam->async_mode)
2404     {
2405       vam->async_errors += (retval < 0);
2406     }
2407   else
2408     {
2409       vam->retval = retval;
2410       vam->sw_if_index = ntohl (mp->sw_if_index);
2411       vam->result_ready = 1;
2412     }
2413 }
2414
2415 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2416   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419   vat_json_node_t node;
2420
2421   vat_json_init_object (&node);
2422   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2423   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2424
2425   vat_json_print (vam->ofp, &node);
2426   vat_json_free (&node);
2427
2428   vam->retval = ntohl (mp->retval);
2429   vam->result_ready = 1;
2430 }
2431
2432 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2433   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436   i32 retval = ntohl (mp->retval);
2437   if (vam->async_mode)
2438     {
2439       vam->async_errors += (retval < 0);
2440     }
2441   else
2442     {
2443       vam->retval = retval;
2444       vam->sw_if_index = ntohl (mp->sw_if_index);
2445       vam->result_ready = 1;
2446     }
2447   vam->regenerate_interface_table = 1;
2448 }
2449
2450 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2451   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   vat_json_node_t node;
2455
2456   vat_json_init_object (&node);
2457   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2458   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2459
2460   vat_json_print (vam->ofp, &node);
2461   vat_json_free (&node);
2462
2463   vam->retval = ntohl (mp->retval);
2464   vam->result_ready = 1;
2465 }
2466
2467 static void vl_api_gre_tunnel_add_del_reply_t_handler
2468   (vl_api_gre_tunnel_add_del_reply_t * mp)
2469 {
2470   vat_main_t *vam = &vat_main;
2471   i32 retval = ntohl (mp->retval);
2472   if (vam->async_mode)
2473     {
2474       vam->async_errors += (retval < 0);
2475     }
2476   else
2477     {
2478       vam->retval = retval;
2479       vam->sw_if_index = ntohl (mp->sw_if_index);
2480       vam->result_ready = 1;
2481     }
2482 }
2483
2484 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2485   (vl_api_gre_tunnel_add_del_reply_t * mp)
2486 {
2487   vat_main_t *vam = &vat_main;
2488   vat_json_node_t node;
2489
2490   vat_json_init_object (&node);
2491   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2492   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2493
2494   vat_json_print (vam->ofp, &node);
2495   vat_json_free (&node);
2496
2497   vam->retval = ntohl (mp->retval);
2498   vam->result_ready = 1;
2499 }
2500
2501 static void vl_api_create_vhost_user_if_reply_t_handler
2502   (vl_api_create_vhost_user_if_reply_t * mp)
2503 {
2504   vat_main_t *vam = &vat_main;
2505   i32 retval = ntohl (mp->retval);
2506   if (vam->async_mode)
2507     {
2508       vam->async_errors += (retval < 0);
2509     }
2510   else
2511     {
2512       vam->retval = retval;
2513       vam->sw_if_index = ntohl (mp->sw_if_index);
2514       vam->result_ready = 1;
2515     }
2516   vam->regenerate_interface_table = 1;
2517 }
2518
2519 static void vl_api_create_vhost_user_if_reply_t_handler_json
2520   (vl_api_create_vhost_user_if_reply_t * mp)
2521 {
2522   vat_main_t *vam = &vat_main;
2523   vat_json_node_t node;
2524
2525   vat_json_init_object (&node);
2526   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2527   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2528
2529   vat_json_print (vam->ofp, &node);
2530   vat_json_free (&node);
2531
2532   vam->retval = ntohl (mp->retval);
2533   vam->result_ready = 1;
2534 }
2535
2536 static void vl_api_ip_address_details_t_handler
2537   (vl_api_ip_address_details_t * mp)
2538 {
2539   vat_main_t *vam = &vat_main;
2540   static ip_address_details_t empty_ip_address_details = { {0} };
2541   ip_address_details_t *address = NULL;
2542   ip_details_t *current_ip_details = NULL;
2543   ip_details_t *details = NULL;
2544
2545   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2546
2547   if (!details || vam->current_sw_if_index >= vec_len (details)
2548       || !details[vam->current_sw_if_index].present)
2549     {
2550       errmsg ("ip address details arrived but not stored");
2551       errmsg ("ip_dump should be called first");
2552       return;
2553     }
2554
2555   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2556
2557 #define addresses (current_ip_details->addr)
2558
2559   vec_validate_init_empty (addresses, vec_len (addresses),
2560                            empty_ip_address_details);
2561
2562   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2563
2564   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2565   address->prefix_length = mp->prefix.len;
2566 #undef addresses
2567 }
2568
2569 static void vl_api_ip_address_details_t_handler_json
2570   (vl_api_ip_address_details_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t *node = NULL;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581
2582   vat_json_init_object (node);
2583   vat_json_object_add_prefix (node, &mp->prefix);
2584 }
2585
2586 static void
2587 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2588 {
2589   vat_main_t *vam = &vat_main;
2590   static ip_details_t empty_ip_details = { 0 };
2591   ip_details_t *ip = NULL;
2592   u32 sw_if_index = ~0;
2593
2594   sw_if_index = ntohl (mp->sw_if_index);
2595
2596   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2597                            sw_if_index, empty_ip_details);
2598
2599   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2600                          sw_if_index);
2601
2602   ip->present = 1;
2603 }
2604
2605 static void
2606 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2607 {
2608   vat_main_t *vam = &vat_main;
2609
2610   if (VAT_JSON_ARRAY != vam->json_tree.type)
2611     {
2612       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2613       vat_json_init_array (&vam->json_tree);
2614     }
2615   vat_json_array_add_uint (&vam->json_tree,
2616                            clib_net_to_host_u32 (mp->sw_if_index));
2617 }
2618
2619 static void
2620 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2621 {
2622   u8 *s, i;
2623
2624   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2625               "host_mac %U router_addr %U",
2626               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2627               mp->lease.hostname,
2628               format_ip4_address, mp->lease.host_address,
2629               format_ethernet_address, mp->lease.host_mac,
2630               format_ip4_address, mp->lease.router_address);
2631
2632   for (i = 0; i < mp->lease.count; i++)
2633     s =
2634       format (s, " domain_server_addr %U", format_ip4_address,
2635               mp->lease.domain_server[i].address);
2636
2637   errmsg ((char *) s);
2638   vec_free (s);
2639 }
2640
2641 static void vl_api_dhcp_compl_event_t_handler_json
2642   (vl_api_dhcp_compl_event_t * mp)
2643 {
2644   /* JSON output not supported */
2645 }
2646
2647 static void vl_api_get_first_msg_id_reply_t_handler
2648   (vl_api_get_first_msg_id_reply_t * mp)
2649 {
2650   vat_main_t *vam = &vat_main;
2651   i32 retval = ntohl (mp->retval);
2652
2653   if (vam->async_mode)
2654     {
2655       vam->async_errors += (retval < 0);
2656     }
2657   else
2658     {
2659       vam->retval = retval;
2660       vam->result_ready = 1;
2661     }
2662   if (retval >= 0)
2663     {
2664       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2665     }
2666 }
2667
2668 static void vl_api_get_first_msg_id_reply_t_handler_json
2669   (vl_api_get_first_msg_id_reply_t * mp)
2670 {
2671   vat_main_t *vam = &vat_main;
2672   vat_json_node_t node;
2673
2674   vat_json_init_object (&node);
2675   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2676   vat_json_object_add_uint (&node, "first_msg_id",
2677                             (uint) ntohs (mp->first_msg_id));
2678
2679   vat_json_print (vam->ofp, &node);
2680   vat_json_free (&node);
2681
2682   vam->retval = ntohl (mp->retval);
2683   vam->result_ready = 1;
2684 }
2685
2686 static void vl_api_get_node_graph_reply_t_handler
2687   (vl_api_get_node_graph_reply_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   api_main_t *am = &api_main;
2691   i32 retval = ntohl (mp->retval);
2692   u8 *pvt_copy, *reply;
2693   void *oldheap;
2694   vlib_node_t *node;
2695   int i;
2696
2697   if (vam->async_mode)
2698     {
2699       vam->async_errors += (retval < 0);
2700     }
2701   else
2702     {
2703       vam->retval = retval;
2704       vam->result_ready = 1;
2705     }
2706
2707   /* "Should never happen..." */
2708   if (retval != 0)
2709     return;
2710
2711   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2712   pvt_copy = vec_dup (reply);
2713
2714   /* Toss the shared-memory original... */
2715   pthread_mutex_lock (&am->vlib_rp->mutex);
2716   oldheap = svm_push_data_heap (am->vlib_rp);
2717
2718   vec_free (reply);
2719
2720   svm_pop_heap (oldheap);
2721   pthread_mutex_unlock (&am->vlib_rp->mutex);
2722
2723   if (vam->graph_nodes)
2724     {
2725       hash_free (vam->graph_node_index_by_name);
2726
2727       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2728         {
2729           node = vam->graph_nodes[0][i];
2730           vec_free (node->name);
2731           vec_free (node->next_nodes);
2732           vec_free (node);
2733         }
2734       vec_free (vam->graph_nodes[0]);
2735       vec_free (vam->graph_nodes);
2736     }
2737
2738   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2739   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2740   vec_free (pvt_copy);
2741
2742   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2743     {
2744       node = vam->graph_nodes[0][i];
2745       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2746     }
2747 }
2748
2749 static void vl_api_get_node_graph_reply_t_handler_json
2750   (vl_api_get_node_graph_reply_t * mp)
2751 {
2752   vat_main_t *vam = &vat_main;
2753   api_main_t *am = &api_main;
2754   void *oldheap;
2755   vat_json_node_t node;
2756   u8 *reply;
2757
2758   /* $$$$ make this real? */
2759   vat_json_init_object (&node);
2760   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2761   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2762
2763   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2764
2765   /* Toss the shared-memory original... */
2766   pthread_mutex_lock (&am->vlib_rp->mutex);
2767   oldheap = svm_push_data_heap (am->vlib_rp);
2768
2769   vec_free (reply);
2770
2771   svm_pop_heap (oldheap);
2772   pthread_mutex_unlock (&am->vlib_rp->mutex);
2773
2774   vat_json_print (vam->ofp, &node);
2775   vat_json_free (&node);
2776
2777   vam->retval = ntohl (mp->retval);
2778   vam->result_ready = 1;
2779 }
2780
2781 static void
2782 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2783 {
2784   vat_main_t *vam = &vat_main;
2785   u8 *s = 0;
2786
2787   if (mp->local)
2788     {
2789       s = format (s, "%=16d%=16d%=16d",
2790                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2791     }
2792   else
2793     {
2794       s = format (s, "%=16U%=16d%=16d",
2795                   mp->is_ipv6 ? format_ip6_address :
2796                   format_ip4_address,
2797                   mp->ip_address, mp->priority, mp->weight);
2798     }
2799
2800   print (vam->ofp, "%v", s);
2801   vec_free (s);
2802 }
2803
2804 static void
2805 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   vat_json_node_t *node = NULL;
2809   struct in6_addr ip6;
2810   struct in_addr ip4;
2811
2812   if (VAT_JSON_ARRAY != vam->json_tree.type)
2813     {
2814       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2815       vat_json_init_array (&vam->json_tree);
2816     }
2817   node = vat_json_array_add (&vam->json_tree);
2818   vat_json_init_object (node);
2819
2820   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2821   vat_json_object_add_uint (node, "priority", mp->priority);
2822   vat_json_object_add_uint (node, "weight", mp->weight);
2823
2824   if (mp->local)
2825     vat_json_object_add_uint (node, "sw_if_index",
2826                               clib_net_to_host_u32 (mp->sw_if_index));
2827   else
2828     {
2829       if (mp->is_ipv6)
2830         {
2831           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2832           vat_json_object_add_ip6 (node, "address", ip6);
2833         }
2834       else
2835         {
2836           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2837           vat_json_object_add_ip4 (node, "address", ip4);
2838         }
2839     }
2840 }
2841
2842 static void
2843 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2844                                           mp)
2845 {
2846   vat_main_t *vam = &vat_main;
2847   u8 *ls_name = 0;
2848
2849   ls_name = format (0, "%s", mp->ls_name);
2850
2851   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2852          ls_name);
2853   vec_free (ls_name);
2854 }
2855
2856 static void
2857   vl_api_one_locator_set_details_t_handler_json
2858   (vl_api_one_locator_set_details_t * mp)
2859 {
2860   vat_main_t *vam = &vat_main;
2861   vat_json_node_t *node = 0;
2862   u8 *ls_name = 0;
2863
2864   ls_name = format (0, "%s", mp->ls_name);
2865   vec_add1 (ls_name, 0);
2866
2867   if (VAT_JSON_ARRAY != vam->json_tree.type)
2868     {
2869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2870       vat_json_init_array (&vam->json_tree);
2871     }
2872   node = vat_json_array_add (&vam->json_tree);
2873
2874   vat_json_init_object (node);
2875   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2876   vat_json_object_add_uint (node, "ls_index",
2877                             clib_net_to_host_u32 (mp->ls_index));
2878   vec_free (ls_name);
2879 }
2880
2881 typedef struct
2882 {
2883   u32 spi;
2884   u8 si;
2885 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2886
2887 uword
2888 unformat_nsh_address (unformat_input_t * input, va_list * args)
2889 {
2890   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2891   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2892 }
2893
2894 u8 *
2895 format_nsh_address_vat (u8 * s, va_list * args)
2896 {
2897   nsh_t *a = va_arg (*args, nsh_t *);
2898   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2899 }
2900
2901 static u8 *
2902 format_lisp_flat_eid (u8 * s, va_list * args)
2903 {
2904   u32 type = va_arg (*args, u32);
2905   u8 *eid = va_arg (*args, u8 *);
2906   u32 eid_len = va_arg (*args, u32);
2907
2908   switch (type)
2909     {
2910     case 0:
2911       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2912     case 1:
2913       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2914     case 2:
2915       return format (s, "%U", format_ethernet_address, eid);
2916     case 3:
2917       return format (s, "%U", format_nsh_address_vat, eid);
2918     }
2919   return 0;
2920 }
2921
2922 static u8 *
2923 format_lisp_eid_vat (u8 * s, va_list * args)
2924 {
2925   u32 type = va_arg (*args, u32);
2926   u8 *eid = va_arg (*args, u8 *);
2927   u32 eid_len = va_arg (*args, u32);
2928   u8 *seid = va_arg (*args, u8 *);
2929   u32 seid_len = va_arg (*args, u32);
2930   u32 is_src_dst = va_arg (*args, u32);
2931
2932   if (is_src_dst)
2933     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2934
2935   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2936
2937   return s;
2938 }
2939
2940 static void
2941 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2942 {
2943   vat_main_t *vam = &vat_main;
2944   u8 *s = 0, *eid = 0;
2945
2946   if (~0 == mp->locator_set_index)
2947     s = format (0, "action: %d", mp->action);
2948   else
2949     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2950
2951   eid = format (0, "%U", format_lisp_eid_vat,
2952                 mp->eid_type,
2953                 mp->eid,
2954                 mp->eid_prefix_len,
2955                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2956   vec_add1 (eid, 0);
2957
2958   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2959          clib_net_to_host_u32 (mp->vni),
2960          eid,
2961          mp->is_local ? "local" : "remote",
2962          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2963          clib_net_to_host_u16 (mp->key_id), mp->key);
2964
2965   vec_free (s);
2966   vec_free (eid);
2967 }
2968
2969 static void
2970 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2971                                              * mp)
2972 {
2973   vat_main_t *vam = &vat_main;
2974   vat_json_node_t *node = 0;
2975   u8 *eid = 0;
2976
2977   if (VAT_JSON_ARRAY != vam->json_tree.type)
2978     {
2979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2980       vat_json_init_array (&vam->json_tree);
2981     }
2982   node = vat_json_array_add (&vam->json_tree);
2983
2984   vat_json_init_object (node);
2985   if (~0 == mp->locator_set_index)
2986     vat_json_object_add_uint (node, "action", mp->action);
2987   else
2988     vat_json_object_add_uint (node, "locator_set_index",
2989                               clib_net_to_host_u32 (mp->locator_set_index));
2990
2991   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2992   if (mp->eid_type == 3)
2993     {
2994       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2995       vat_json_init_object (nsh_json);
2996       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2997       vat_json_object_add_uint (nsh_json, "spi",
2998                                 clib_net_to_host_u32 (nsh->spi));
2999       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3000     }
3001   else
3002     {
3003       eid = format (0, "%U", format_lisp_eid_vat,
3004                     mp->eid_type,
3005                     mp->eid,
3006                     mp->eid_prefix_len,
3007                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3008       vec_add1 (eid, 0);
3009       vat_json_object_add_string_copy (node, "eid", eid);
3010       vec_free (eid);
3011     }
3012   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3013   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3014   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3015
3016   if (mp->key_id)
3017     {
3018       vat_json_object_add_uint (node, "key_id",
3019                                 clib_net_to_host_u16 (mp->key_id));
3020       vat_json_object_add_string_copy (node, "key", mp->key);
3021     }
3022 }
3023
3024 static void
3025 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   u8 *seid = 0, *deid = 0;
3029   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3030
3031   deid = format (0, "%U", format_lisp_eid_vat,
3032                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3033
3034   seid = format (0, "%U", format_lisp_eid_vat,
3035                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3036
3037   vec_add1 (deid, 0);
3038   vec_add1 (seid, 0);
3039
3040   if (mp->is_ip4)
3041     format_ip_address_fcn = format_ip4_address;
3042   else
3043     format_ip_address_fcn = format_ip6_address;
3044
3045
3046   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3047          clib_net_to_host_u32 (mp->vni),
3048          seid, deid,
3049          format_ip_address_fcn, mp->lloc,
3050          format_ip_address_fcn, mp->rloc,
3051          clib_net_to_host_u32 (mp->pkt_count),
3052          clib_net_to_host_u32 (mp->bytes));
3053
3054   vec_free (deid);
3055   vec_free (seid);
3056 }
3057
3058 static void
3059 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3060 {
3061   struct in6_addr ip6;
3062   struct in_addr ip4;
3063   vat_main_t *vam = &vat_main;
3064   vat_json_node_t *node = 0;
3065   u8 *deid = 0, *seid = 0;
3066
3067   if (VAT_JSON_ARRAY != vam->json_tree.type)
3068     {
3069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3070       vat_json_init_array (&vam->json_tree);
3071     }
3072   node = vat_json_array_add (&vam->json_tree);
3073
3074   vat_json_init_object (node);
3075   deid = format (0, "%U", format_lisp_eid_vat,
3076                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3077
3078   seid = format (0, "%U", format_lisp_eid_vat,
3079                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3080
3081   vec_add1 (deid, 0);
3082   vec_add1 (seid, 0);
3083
3084   vat_json_object_add_string_copy (node, "seid", seid);
3085   vat_json_object_add_string_copy (node, "deid", deid);
3086   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3087
3088   if (mp->is_ip4)
3089     {
3090       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3091       vat_json_object_add_ip4 (node, "lloc", ip4);
3092       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3093       vat_json_object_add_ip4 (node, "rloc", ip4);
3094     }
3095   else
3096     {
3097       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3098       vat_json_object_add_ip6 (node, "lloc", ip6);
3099       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3100       vat_json_object_add_ip6 (node, "rloc", ip6);
3101     }
3102   vat_json_object_add_uint (node, "pkt_count",
3103                             clib_net_to_host_u32 (mp->pkt_count));
3104   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3105
3106   vec_free (deid);
3107   vec_free (seid);
3108 }
3109
3110 static void
3111   vl_api_one_eid_table_map_details_t_handler
3112   (vl_api_one_eid_table_map_details_t * mp)
3113 {
3114   vat_main_t *vam = &vat_main;
3115
3116   u8 *line = format (0, "%=10d%=10d",
3117                      clib_net_to_host_u32 (mp->vni),
3118                      clib_net_to_host_u32 (mp->dp_table));
3119   print (vam->ofp, "%v", line);
3120   vec_free (line);
3121 }
3122
3123 static void
3124   vl_api_one_eid_table_map_details_t_handler_json
3125   (vl_api_one_eid_table_map_details_t * mp)
3126 {
3127   vat_main_t *vam = &vat_main;
3128   vat_json_node_t *node = NULL;
3129
3130   if (VAT_JSON_ARRAY != vam->json_tree.type)
3131     {
3132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133       vat_json_init_array (&vam->json_tree);
3134     }
3135   node = vat_json_array_add (&vam->json_tree);
3136   vat_json_init_object (node);
3137   vat_json_object_add_uint (node, "dp_table",
3138                             clib_net_to_host_u32 (mp->dp_table));
3139   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3140 }
3141
3142 static void
3143   vl_api_one_eid_table_vni_details_t_handler
3144   (vl_api_one_eid_table_vni_details_t * mp)
3145 {
3146   vat_main_t *vam = &vat_main;
3147
3148   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3149   print (vam->ofp, "%v", line);
3150   vec_free (line);
3151 }
3152
3153 static void
3154   vl_api_one_eid_table_vni_details_t_handler_json
3155   (vl_api_one_eid_table_vni_details_t * mp)
3156 {
3157   vat_main_t *vam = &vat_main;
3158   vat_json_node_t *node = NULL;
3159
3160   if (VAT_JSON_ARRAY != vam->json_tree.type)
3161     {
3162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3163       vat_json_init_array (&vam->json_tree);
3164     }
3165   node = vat_json_array_add (&vam->json_tree);
3166   vat_json_init_object (node);
3167   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3168 }
3169
3170 static void
3171   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3172   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3173 {
3174   vat_main_t *vam = &vat_main;
3175   int retval = clib_net_to_host_u32 (mp->retval);
3176
3177   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3178   print (vam->ofp, "fallback threshold value: %d", mp->value);
3179
3180   vam->retval = retval;
3181   vam->result_ready = 1;
3182 }
3183
3184 static void
3185   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3186   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3187 {
3188   vat_main_t *vam = &vat_main;
3189   vat_json_node_t _node, *node = &_node;
3190   int retval = clib_net_to_host_u32 (mp->retval);
3191
3192   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3193   vat_json_init_object (node);
3194   vat_json_object_add_uint (node, "value", mp->value);
3195
3196   vat_json_print (vam->ofp, node);
3197   vat_json_free (node);
3198
3199   vam->retval = retval;
3200   vam->result_ready = 1;
3201 }
3202
3203 static void
3204   vl_api_show_one_map_register_state_reply_t_handler
3205   (vl_api_show_one_map_register_state_reply_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   int retval = clib_net_to_host_u32 (mp->retval);
3209
3210   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3211
3212   vam->retval = retval;
3213   vam->result_ready = 1;
3214 }
3215
3216 static void
3217   vl_api_show_one_map_register_state_reply_t_handler_json
3218   (vl_api_show_one_map_register_state_reply_t * mp)
3219 {
3220   vat_main_t *vam = &vat_main;
3221   vat_json_node_t _node, *node = &_node;
3222   int retval = clib_net_to_host_u32 (mp->retval);
3223
3224   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3225
3226   vat_json_init_object (node);
3227   vat_json_object_add_string_copy (node, "state", s);
3228
3229   vat_json_print (vam->ofp, node);
3230   vat_json_free (node);
3231
3232   vam->retval = retval;
3233   vam->result_ready = 1;
3234   vec_free (s);
3235 }
3236
3237 static void
3238   vl_api_show_one_rloc_probe_state_reply_t_handler
3239   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242   int retval = clib_net_to_host_u32 (mp->retval);
3243
3244   if (retval)
3245     goto end;
3246
3247   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3248 end:
3249   vam->retval = retval;
3250   vam->result_ready = 1;
3251 }
3252
3253 static void
3254   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3255   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3256 {
3257   vat_main_t *vam = &vat_main;
3258   vat_json_node_t _node, *node = &_node;
3259   int retval = clib_net_to_host_u32 (mp->retval);
3260
3261   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3262   vat_json_init_object (node);
3263   vat_json_object_add_string_copy (node, "state", s);
3264
3265   vat_json_print (vam->ofp, node);
3266   vat_json_free (node);
3267
3268   vam->retval = retval;
3269   vam->result_ready = 1;
3270   vec_free (s);
3271 }
3272
3273 static void
3274   vl_api_show_one_stats_enable_disable_reply_t_handler
3275   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278   int retval = clib_net_to_host_u32 (mp->retval);
3279
3280   if (retval)
3281     goto end;
3282
3283   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3284 end:
3285   vam->retval = retval;
3286   vam->result_ready = 1;
3287 }
3288
3289 static void
3290   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3291   (vl_api_show_one_stats_enable_disable_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   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3298   vat_json_init_object (node);
3299   vat_json_object_add_string_copy (node, "state", s);
3300
3301   vat_json_print (vam->ofp, node);
3302   vat_json_free (node);
3303
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306   vec_free (s);
3307 }
3308
3309 static void
3310 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3311 {
3312   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3313   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3314   e->vni = clib_net_to_host_u32 (e->vni);
3315 }
3316
3317 static void
3318   gpe_fwd_entries_get_reply_t_net_to_host
3319   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3320 {
3321   u32 i;
3322
3323   mp->count = clib_net_to_host_u32 (mp->count);
3324   for (i = 0; i < mp->count; i++)
3325     {
3326       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3327     }
3328 }
3329
3330 static u8 *
3331 format_gpe_encap_mode (u8 * s, va_list * args)
3332 {
3333   u32 mode = va_arg (*args, u32);
3334
3335   switch (mode)
3336     {
3337     case 0:
3338       return format (s, "lisp");
3339     case 1:
3340       return format (s, "vxlan");
3341     }
3342   return 0;
3343 }
3344
3345 static void
3346   vl_api_gpe_get_encap_mode_reply_t_handler
3347   (vl_api_gpe_get_encap_mode_reply_t * mp)
3348 {
3349   vat_main_t *vam = &vat_main;
3350
3351   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3352   vam->retval = ntohl (mp->retval);
3353   vam->result_ready = 1;
3354 }
3355
3356 static void
3357   vl_api_gpe_get_encap_mode_reply_t_handler_json
3358   (vl_api_gpe_get_encap_mode_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   vat_json_node_t node;
3362
3363   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3364   vec_add1 (encap_mode, 0);
3365
3366   vat_json_init_object (&node);
3367   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3368
3369   vec_free (encap_mode);
3370   vat_json_print (vam->ofp, &node);
3371   vat_json_free (&node);
3372
3373   vam->retval = ntohl (mp->retval);
3374   vam->result_ready = 1;
3375 }
3376
3377 static void
3378   vl_api_gpe_fwd_entry_path_details_t_handler
3379   (vl_api_gpe_fwd_entry_path_details_t * mp)
3380 {
3381   vat_main_t *vam = &vat_main;
3382   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3383
3384   if (mp->lcl_loc.is_ip4)
3385     format_ip_address_fcn = format_ip4_address;
3386   else
3387     format_ip_address_fcn = format_ip6_address;
3388
3389   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3390          format_ip_address_fcn, &mp->lcl_loc,
3391          format_ip_address_fcn, &mp->rmt_loc);
3392 }
3393
3394 static void
3395 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3396 {
3397   struct in6_addr ip6;
3398   struct in_addr ip4;
3399
3400   if (loc->is_ip4)
3401     {
3402       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3403       vat_json_object_add_ip4 (n, "address", ip4);
3404     }
3405   else
3406     {
3407       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3408       vat_json_object_add_ip6 (n, "address", ip6);
3409     }
3410   vat_json_object_add_uint (n, "weight", loc->weight);
3411 }
3412
3413 static void
3414   vl_api_gpe_fwd_entry_path_details_t_handler_json
3415   (vl_api_gpe_fwd_entry_path_details_t * mp)
3416 {
3417   vat_main_t *vam = &vat_main;
3418   vat_json_node_t *node = NULL;
3419   vat_json_node_t *loc_node;
3420
3421   if (VAT_JSON_ARRAY != vam->json_tree.type)
3422     {
3423       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3424       vat_json_init_array (&vam->json_tree);
3425     }
3426   node = vat_json_array_add (&vam->json_tree);
3427   vat_json_init_object (node);
3428
3429   loc_node = vat_json_object_add (node, "local_locator");
3430   vat_json_init_object (loc_node);
3431   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3432
3433   loc_node = vat_json_object_add (node, "remote_locator");
3434   vat_json_init_object (loc_node);
3435   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3436 }
3437
3438 static void
3439   vl_api_gpe_fwd_entries_get_reply_t_handler
3440   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3441 {
3442   vat_main_t *vam = &vat_main;
3443   u32 i;
3444   int retval = clib_net_to_host_u32 (mp->retval);
3445   vl_api_gpe_fwd_entry_t *e;
3446
3447   if (retval)
3448     goto end;
3449
3450   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3451
3452   for (i = 0; i < mp->count; i++)
3453     {
3454       e = &mp->entries[i];
3455       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3456              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3457              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3458     }
3459
3460 end:
3461   vam->retval = retval;
3462   vam->result_ready = 1;
3463 }
3464
3465 static void
3466   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3467   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3468 {
3469   u8 *s = 0;
3470   vat_main_t *vam = &vat_main;
3471   vat_json_node_t *e = 0, root;
3472   u32 i;
3473   int retval = clib_net_to_host_u32 (mp->retval);
3474   vl_api_gpe_fwd_entry_t *fwd;
3475
3476   if (retval)
3477     goto end;
3478
3479   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3480   vat_json_init_array (&root);
3481
3482   for (i = 0; i < mp->count; i++)
3483     {
3484       e = vat_json_array_add (&root);
3485       fwd = &mp->entries[i];
3486
3487       vat_json_init_object (e);
3488       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3489       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3490       vat_json_object_add_int (e, "vni", fwd->vni);
3491       vat_json_object_add_int (e, "action", fwd->action);
3492
3493       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3494                   fwd->leid_prefix_len);
3495       vec_add1 (s, 0);
3496       vat_json_object_add_string_copy (e, "leid", s);
3497       vec_free (s);
3498
3499       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3500                   fwd->reid_prefix_len);
3501       vec_add1 (s, 0);
3502       vat_json_object_add_string_copy (e, "reid", s);
3503       vec_free (s);
3504     }
3505
3506   vat_json_print (vam->ofp, &root);
3507   vat_json_free (&root);
3508
3509 end:
3510   vam->retval = retval;
3511   vam->result_ready = 1;
3512 }
3513
3514 static void
3515   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3516   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3517 {
3518   vat_main_t *vam = &vat_main;
3519   u32 i, n;
3520   int retval = clib_net_to_host_u32 (mp->retval);
3521   vl_api_gpe_native_fwd_rpath_t *r;
3522
3523   if (retval)
3524     goto end;
3525
3526   n = clib_net_to_host_u32 (mp->count);
3527
3528   for (i = 0; i < n; i++)
3529     {
3530       r = &mp->entries[i];
3531       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3532              clib_net_to_host_u32 (r->fib_index),
3533              clib_net_to_host_u32 (r->nh_sw_if_index),
3534              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3535     }
3536
3537 end:
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540 }
3541
3542 static void
3543   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3544   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3545 {
3546   vat_main_t *vam = &vat_main;
3547   vat_json_node_t root, *e;
3548   u32 i, n;
3549   int retval = clib_net_to_host_u32 (mp->retval);
3550   vl_api_gpe_native_fwd_rpath_t *r;
3551   u8 *s;
3552
3553   if (retval)
3554     goto end;
3555
3556   n = clib_net_to_host_u32 (mp->count);
3557   vat_json_init_array (&root);
3558
3559   for (i = 0; i < n; i++)
3560     {
3561       e = vat_json_array_add (&root);
3562       vat_json_init_object (e);
3563       r = &mp->entries[i];
3564       s =
3565         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3566                 r->nh_addr);
3567       vec_add1 (s, 0);
3568       vat_json_object_add_string_copy (e, "ip4", s);
3569       vec_free (s);
3570
3571       vat_json_object_add_uint (e, "fib_index",
3572                                 clib_net_to_host_u32 (r->fib_index));
3573       vat_json_object_add_uint (e, "nh_sw_if_index",
3574                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3575     }
3576
3577   vat_json_print (vam->ofp, &root);
3578   vat_json_free (&root);
3579
3580 end:
3581   vam->retval = retval;
3582   vam->result_ready = 1;
3583 }
3584
3585 static void
3586   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3587   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3588 {
3589   vat_main_t *vam = &vat_main;
3590   u32 i, n;
3591   int retval = clib_net_to_host_u32 (mp->retval);
3592
3593   if (retval)
3594     goto end;
3595
3596   n = clib_net_to_host_u32 (mp->count);
3597
3598   for (i = 0; i < n; i++)
3599     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3600
3601 end:
3602   vam->retval = retval;
3603   vam->result_ready = 1;
3604 }
3605
3606 static void
3607   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3608   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3609 {
3610   vat_main_t *vam = &vat_main;
3611   vat_json_node_t root;
3612   u32 i, n;
3613   int retval = clib_net_to_host_u32 (mp->retval);
3614
3615   if (retval)
3616     goto end;
3617
3618   n = clib_net_to_host_u32 (mp->count);
3619   vat_json_init_array (&root);
3620
3621   for (i = 0; i < n; i++)
3622     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3623
3624   vat_json_print (vam->ofp, &root);
3625   vat_json_free (&root);
3626
3627 end:
3628   vam->retval = retval;
3629   vam->result_ready = 1;
3630 }
3631
3632 static void
3633   vl_api_one_ndp_entries_get_reply_t_handler
3634   (vl_api_one_ndp_entries_get_reply_t * mp)
3635 {
3636   vat_main_t *vam = &vat_main;
3637   u32 i, n;
3638   int retval = clib_net_to_host_u32 (mp->retval);
3639
3640   if (retval)
3641     goto end;
3642
3643   n = clib_net_to_host_u32 (mp->count);
3644
3645   for (i = 0; i < n; i++)
3646     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3647            format_ethernet_address, mp->entries[i].mac);
3648
3649 end:
3650   vam->retval = retval;
3651   vam->result_ready = 1;
3652 }
3653
3654 static void
3655   vl_api_one_ndp_entries_get_reply_t_handler_json
3656   (vl_api_one_ndp_entries_get_reply_t * mp)
3657 {
3658   u8 *s = 0;
3659   vat_main_t *vam = &vat_main;
3660   vat_json_node_t *e = 0, root;
3661   u32 i, n;
3662   int retval = clib_net_to_host_u32 (mp->retval);
3663   vl_api_one_ndp_entry_t *arp_entry;
3664
3665   if (retval)
3666     goto end;
3667
3668   n = clib_net_to_host_u32 (mp->count);
3669   vat_json_init_array (&root);
3670
3671   for (i = 0; i < n; i++)
3672     {
3673       e = vat_json_array_add (&root);
3674       arp_entry = &mp->entries[i];
3675
3676       vat_json_init_object (e);
3677       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3678       vec_add1 (s, 0);
3679
3680       vat_json_object_add_string_copy (e, "mac", s);
3681       vec_free (s);
3682
3683       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3684       vec_add1 (s, 0);
3685       vat_json_object_add_string_copy (e, "ip6", s);
3686       vec_free (s);
3687     }
3688
3689   vat_json_print (vam->ofp, &root);
3690   vat_json_free (&root);
3691
3692 end:
3693   vam->retval = retval;
3694   vam->result_ready = 1;
3695 }
3696
3697 static void
3698   vl_api_one_l2_arp_entries_get_reply_t_handler
3699   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3700 {
3701   vat_main_t *vam = &vat_main;
3702   u32 i, n;
3703   int retval = clib_net_to_host_u32 (mp->retval);
3704
3705   if (retval)
3706     goto end;
3707
3708   n = clib_net_to_host_u32 (mp->count);
3709
3710   for (i = 0; i < n; i++)
3711     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3712            format_ethernet_address, mp->entries[i].mac);
3713
3714 end:
3715   vam->retval = retval;
3716   vam->result_ready = 1;
3717 }
3718
3719 static void
3720   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3721   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3722 {
3723   u8 *s = 0;
3724   vat_main_t *vam = &vat_main;
3725   vat_json_node_t *e = 0, root;
3726   u32 i, n;
3727   int retval = clib_net_to_host_u32 (mp->retval);
3728   vl_api_one_l2_arp_entry_t *arp_entry;
3729
3730   if (retval)
3731     goto end;
3732
3733   n = clib_net_to_host_u32 (mp->count);
3734   vat_json_init_array (&root);
3735
3736   for (i = 0; i < n; i++)
3737     {
3738       e = vat_json_array_add (&root);
3739       arp_entry = &mp->entries[i];
3740
3741       vat_json_init_object (e);
3742       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3743       vec_add1 (s, 0);
3744
3745       vat_json_object_add_string_copy (e, "mac", s);
3746       vec_free (s);
3747
3748       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3749       vec_add1 (s, 0);
3750       vat_json_object_add_string_copy (e, "ip4", s);
3751       vec_free (s);
3752     }
3753
3754   vat_json_print (vam->ofp, &root);
3755   vat_json_free (&root);
3756
3757 end:
3758   vam->retval = retval;
3759   vam->result_ready = 1;
3760 }
3761
3762 static void
3763 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3764 {
3765   vat_main_t *vam = &vat_main;
3766   u32 i, n;
3767   int retval = clib_net_to_host_u32 (mp->retval);
3768
3769   if (retval)
3770     goto end;
3771
3772   n = clib_net_to_host_u32 (mp->count);
3773
3774   for (i = 0; i < n; i++)
3775     {
3776       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3777     }
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_one_ndp_bd_get_reply_t_handler_json
3786   (vl_api_one_ndp_bd_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   vat_json_node_t root;
3790   u32 i, n;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797   vat_json_init_array (&root);
3798
3799   for (i = 0; i < n; i++)
3800     {
3801       vat_json_array_add_uint (&root,
3802                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3803     }
3804
3805   vat_json_print (vam->ofp, &root);
3806   vat_json_free (&root);
3807
3808 end:
3809   vam->retval = retval;
3810   vam->result_ready = 1;
3811 }
3812
3813 static void
3814   vl_api_one_l2_arp_bd_get_reply_t_handler
3815   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3816 {
3817   vat_main_t *vam = &vat_main;
3818   u32 i, n;
3819   int retval = clib_net_to_host_u32 (mp->retval);
3820
3821   if (retval)
3822     goto end;
3823
3824   n = clib_net_to_host_u32 (mp->count);
3825
3826   for (i = 0; i < n; i++)
3827     {
3828       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3829     }
3830
3831 end:
3832   vam->retval = retval;
3833   vam->result_ready = 1;
3834 }
3835
3836 static void
3837   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3838   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3839 {
3840   vat_main_t *vam = &vat_main;
3841   vat_json_node_t root;
3842   u32 i, n;
3843   int retval = clib_net_to_host_u32 (mp->retval);
3844
3845   if (retval)
3846     goto end;
3847
3848   n = clib_net_to_host_u32 (mp->count);
3849   vat_json_init_array (&root);
3850
3851   for (i = 0; i < n; i++)
3852     {
3853       vat_json_array_add_uint (&root,
3854                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3855     }
3856
3857   vat_json_print (vam->ofp, &root);
3858   vat_json_free (&root);
3859
3860 end:
3861   vam->retval = retval;
3862   vam->result_ready = 1;
3863 }
3864
3865 static void
3866   vl_api_one_adjacencies_get_reply_t_handler
3867   (vl_api_one_adjacencies_get_reply_t * mp)
3868 {
3869   vat_main_t *vam = &vat_main;
3870   u32 i, n;
3871   int retval = clib_net_to_host_u32 (mp->retval);
3872   vl_api_one_adjacency_t *a;
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       a = &mp->adjacencies[i];
3882       print (vam->ofp, "%U %40U",
3883              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3884              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3885     }
3886
3887 end:
3888   vam->retval = retval;
3889   vam->result_ready = 1;
3890 }
3891
3892 static void
3893   vl_api_one_adjacencies_get_reply_t_handler_json
3894   (vl_api_one_adjacencies_get_reply_t * mp)
3895 {
3896   u8 *s = 0;
3897   vat_main_t *vam = &vat_main;
3898   vat_json_node_t *e = 0, root;
3899   u32 i, n;
3900   int retval = clib_net_to_host_u32 (mp->retval);
3901   vl_api_one_adjacency_t *a;
3902
3903   if (retval)
3904     goto end;
3905
3906   n = clib_net_to_host_u32 (mp->count);
3907   vat_json_init_array (&root);
3908
3909   for (i = 0; i < n; i++)
3910     {
3911       e = vat_json_array_add (&root);
3912       a = &mp->adjacencies[i];
3913
3914       vat_json_init_object (e);
3915       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3916                   a->leid_prefix_len);
3917       vec_add1 (s, 0);
3918       vat_json_object_add_string_copy (e, "leid", s);
3919       vec_free (s);
3920
3921       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3922                   a->reid_prefix_len);
3923       vec_add1 (s, 0);
3924       vat_json_object_add_string_copy (e, "reid", s);
3925       vec_free (s);
3926     }
3927
3928   vat_json_print (vam->ofp, &root);
3929   vat_json_free (&root);
3930
3931 end:
3932   vam->retval = retval;
3933   vam->result_ready = 1;
3934 }
3935
3936 static void
3937 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3938 {
3939   vat_main_t *vam = &vat_main;
3940
3941   print (vam->ofp, "%=20U",
3942          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3943          mp->ip_address);
3944 }
3945
3946 static void
3947   vl_api_one_map_server_details_t_handler_json
3948   (vl_api_one_map_server_details_t * mp)
3949 {
3950   vat_main_t *vam = &vat_main;
3951   vat_json_node_t *node = NULL;
3952   struct in6_addr ip6;
3953   struct in_addr ip4;
3954
3955   if (VAT_JSON_ARRAY != vam->json_tree.type)
3956     {
3957       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3958       vat_json_init_array (&vam->json_tree);
3959     }
3960   node = vat_json_array_add (&vam->json_tree);
3961
3962   vat_json_init_object (node);
3963   if (mp->is_ipv6)
3964     {
3965       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3966       vat_json_object_add_ip6 (node, "map-server", ip6);
3967     }
3968   else
3969     {
3970       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3971       vat_json_object_add_ip4 (node, "map-server", ip4);
3972     }
3973 }
3974
3975 static void
3976 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3977                                            * mp)
3978 {
3979   vat_main_t *vam = &vat_main;
3980
3981   print (vam->ofp, "%=20U",
3982          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3983          mp->ip_address);
3984 }
3985
3986 static void
3987   vl_api_one_map_resolver_details_t_handler_json
3988   (vl_api_one_map_resolver_details_t * mp)
3989 {
3990   vat_main_t *vam = &vat_main;
3991   vat_json_node_t *node = NULL;
3992   struct in6_addr ip6;
3993   struct in_addr ip4;
3994
3995   if (VAT_JSON_ARRAY != vam->json_tree.type)
3996     {
3997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3998       vat_json_init_array (&vam->json_tree);
3999     }
4000   node = vat_json_array_add (&vam->json_tree);
4001
4002   vat_json_init_object (node);
4003   if (mp->is_ipv6)
4004     {
4005       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4006       vat_json_object_add_ip6 (node, "map resolver", ip6);
4007     }
4008   else
4009     {
4010       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4011       vat_json_object_add_ip4 (node, "map resolver", ip4);
4012     }
4013 }
4014
4015 static void
4016 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019   i32 retval = ntohl (mp->retval);
4020
4021   if (0 <= retval)
4022     {
4023       print (vam->ofp, "feature: %s\ngpe: %s",
4024              mp->feature_status ? "enabled" : "disabled",
4025              mp->gpe_status ? "enabled" : "disabled");
4026     }
4027
4028   vam->retval = retval;
4029   vam->result_ready = 1;
4030 }
4031
4032 static void
4033   vl_api_show_one_status_reply_t_handler_json
4034   (vl_api_show_one_status_reply_t * mp)
4035 {
4036   vat_main_t *vam = &vat_main;
4037   vat_json_node_t node;
4038   u8 *gpe_status = NULL;
4039   u8 *feature_status = NULL;
4040
4041   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4042   feature_status = format (0, "%s",
4043                            mp->feature_status ? "enabled" : "disabled");
4044   vec_add1 (gpe_status, 0);
4045   vec_add1 (feature_status, 0);
4046
4047   vat_json_init_object (&node);
4048   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4049   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4050
4051   vec_free (gpe_status);
4052   vec_free (feature_status);
4053
4054   vat_json_print (vam->ofp, &node);
4055   vat_json_free (&node);
4056
4057   vam->retval = ntohl (mp->retval);
4058   vam->result_ready = 1;
4059 }
4060
4061 static void
4062   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4063   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4064 {
4065   vat_main_t *vam = &vat_main;
4066   i32 retval = ntohl (mp->retval);
4067
4068   if (retval >= 0)
4069     {
4070       print (vam->ofp, "%=20s", mp->locator_set_name);
4071     }
4072
4073   vam->retval = retval;
4074   vam->result_ready = 1;
4075 }
4076
4077 static void
4078   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4079   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4080 {
4081   vat_main_t *vam = &vat_main;
4082   vat_json_node_t *node = NULL;
4083
4084   if (VAT_JSON_ARRAY != vam->json_tree.type)
4085     {
4086       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4087       vat_json_init_array (&vam->json_tree);
4088     }
4089   node = vat_json_array_add (&vam->json_tree);
4090
4091   vat_json_init_object (node);
4092   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4093
4094   vat_json_print (vam->ofp, node);
4095   vat_json_free (node);
4096
4097   vam->retval = ntohl (mp->retval);
4098   vam->result_ready = 1;
4099 }
4100
4101 static u8 *
4102 format_lisp_map_request_mode (u8 * s, va_list * args)
4103 {
4104   u32 mode = va_arg (*args, u32);
4105
4106   switch (mode)
4107     {
4108     case 0:
4109       return format (0, "dst-only");
4110     case 1:
4111       return format (0, "src-dst");
4112     }
4113   return 0;
4114 }
4115
4116 static void
4117   vl_api_show_one_map_request_mode_reply_t_handler
4118   (vl_api_show_one_map_request_mode_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   i32 retval = ntohl (mp->retval);
4122
4123   if (0 <= retval)
4124     {
4125       u32 mode = mp->mode;
4126       print (vam->ofp, "map_request_mode: %U",
4127              format_lisp_map_request_mode, mode);
4128     }
4129
4130   vam->retval = retval;
4131   vam->result_ready = 1;
4132 }
4133
4134 static void
4135   vl_api_show_one_map_request_mode_reply_t_handler_json
4136   (vl_api_show_one_map_request_mode_reply_t * mp)
4137 {
4138   vat_main_t *vam = &vat_main;
4139   vat_json_node_t node;
4140   u8 *s = 0;
4141   u32 mode;
4142
4143   mode = mp->mode;
4144   s = format (0, "%U", format_lisp_map_request_mode, mode);
4145   vec_add1 (s, 0);
4146
4147   vat_json_init_object (&node);
4148   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4149   vat_json_print (vam->ofp, &node);
4150   vat_json_free (&node);
4151
4152   vec_free (s);
4153   vam->retval = ntohl (mp->retval);
4154   vam->result_ready = 1;
4155 }
4156
4157 static void
4158   vl_api_one_show_xtr_mode_reply_t_handler
4159   (vl_api_one_show_xtr_mode_reply_t * mp)
4160 {
4161   vat_main_t *vam = &vat_main;
4162   i32 retval = ntohl (mp->retval);
4163
4164   if (0 <= retval)
4165     {
4166       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4167     }
4168
4169   vam->retval = retval;
4170   vam->result_ready = 1;
4171 }
4172
4173 static void
4174   vl_api_one_show_xtr_mode_reply_t_handler_json
4175   (vl_api_one_show_xtr_mode_reply_t * mp)
4176 {
4177   vat_main_t *vam = &vat_main;
4178   vat_json_node_t node;
4179   u8 *status = 0;
4180
4181   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4182   vec_add1 (status, 0);
4183
4184   vat_json_init_object (&node);
4185   vat_json_object_add_string_copy (&node, "status", status);
4186
4187   vec_free (status);
4188
4189   vat_json_print (vam->ofp, &node);
4190   vat_json_free (&node);
4191
4192   vam->retval = ntohl (mp->retval);
4193   vam->result_ready = 1;
4194 }
4195
4196 static void
4197   vl_api_one_show_pitr_mode_reply_t_handler
4198   (vl_api_one_show_pitr_mode_reply_t * mp)
4199 {
4200   vat_main_t *vam = &vat_main;
4201   i32 retval = ntohl (mp->retval);
4202
4203   if (0 <= retval)
4204     {
4205       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4206     }
4207
4208   vam->retval = retval;
4209   vam->result_ready = 1;
4210 }
4211
4212 static void
4213   vl_api_one_show_pitr_mode_reply_t_handler_json
4214   (vl_api_one_show_pitr_mode_reply_t * mp)
4215 {
4216   vat_main_t *vam = &vat_main;
4217   vat_json_node_t node;
4218   u8 *status = 0;
4219
4220   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4221   vec_add1 (status, 0);
4222
4223   vat_json_init_object (&node);
4224   vat_json_object_add_string_copy (&node, "status", status);
4225
4226   vec_free (status);
4227
4228   vat_json_print (vam->ofp, &node);
4229   vat_json_free (&node);
4230
4231   vam->retval = ntohl (mp->retval);
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_one_show_petr_mode_reply_t_handler
4237   (vl_api_one_show_petr_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   i32 retval = ntohl (mp->retval);
4241
4242   if (0 <= retval)
4243     {
4244       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4245     }
4246
4247   vam->retval = retval;
4248   vam->result_ready = 1;
4249 }
4250
4251 static void
4252   vl_api_one_show_petr_mode_reply_t_handler_json
4253   (vl_api_one_show_petr_mode_reply_t * mp)
4254 {
4255   vat_main_t *vam = &vat_main;
4256   vat_json_node_t node;
4257   u8 *status = 0;
4258
4259   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4260   vec_add1 (status, 0);
4261
4262   vat_json_init_object (&node);
4263   vat_json_object_add_string_copy (&node, "status", status);
4264
4265   vec_free (status);
4266
4267   vat_json_print (vam->ofp, &node);
4268   vat_json_free (&node);
4269
4270   vam->retval = ntohl (mp->retval);
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_show_one_use_petr_reply_t_handler
4276   (vl_api_show_one_use_petr_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   i32 retval = ntohl (mp->retval);
4280
4281   if (0 <= retval)
4282     {
4283       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4284       if (mp->status)
4285         {
4286           print (vam->ofp, "Proxy-ETR address; %U",
4287                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4288                  mp->address);
4289         }
4290     }
4291
4292   vam->retval = retval;
4293   vam->result_ready = 1;
4294 }
4295
4296 static void
4297   vl_api_show_one_use_petr_reply_t_handler_json
4298   (vl_api_show_one_use_petr_reply_t * mp)
4299 {
4300   vat_main_t *vam = &vat_main;
4301   vat_json_node_t node;
4302   u8 *status = 0;
4303   struct in_addr ip4;
4304   struct in6_addr ip6;
4305
4306   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4307   vec_add1 (status, 0);
4308
4309   vat_json_init_object (&node);
4310   vat_json_object_add_string_copy (&node, "status", status);
4311   if (mp->status)
4312     {
4313       if (mp->is_ip4)
4314         {
4315           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4316           vat_json_object_add_ip6 (&node, "address", ip6);
4317         }
4318       else
4319         {
4320           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4321           vat_json_object_add_ip4 (&node, "address", ip4);
4322         }
4323     }
4324
4325   vec_free (status);
4326
4327   vat_json_print (vam->ofp, &node);
4328   vat_json_free (&node);
4329
4330   vam->retval = ntohl (mp->retval);
4331   vam->result_ready = 1;
4332 }
4333
4334 static void
4335   vl_api_show_one_nsh_mapping_reply_t_handler
4336   (vl_api_show_one_nsh_mapping_reply_t * mp)
4337 {
4338   vat_main_t *vam = &vat_main;
4339   i32 retval = ntohl (mp->retval);
4340
4341   if (0 <= retval)
4342     {
4343       print (vam->ofp, "%-20s%-16s",
4344              mp->is_set ? "set" : "not-set",
4345              mp->is_set ? (char *) mp->locator_set_name : "");
4346     }
4347
4348   vam->retval = retval;
4349   vam->result_ready = 1;
4350 }
4351
4352 static void
4353   vl_api_show_one_nsh_mapping_reply_t_handler_json
4354   (vl_api_show_one_nsh_mapping_reply_t * mp)
4355 {
4356   vat_main_t *vam = &vat_main;
4357   vat_json_node_t node;
4358   u8 *status = 0;
4359
4360   status = format (0, "%s", mp->is_set ? "yes" : "no");
4361   vec_add1 (status, 0);
4362
4363   vat_json_init_object (&node);
4364   vat_json_object_add_string_copy (&node, "is_set", status);
4365   if (mp->is_set)
4366     {
4367       vat_json_object_add_string_copy (&node, "locator_set",
4368                                        mp->locator_set_name);
4369     }
4370
4371   vec_free (status);
4372
4373   vat_json_print (vam->ofp, &node);
4374   vat_json_free (&node);
4375
4376   vam->retval = ntohl (mp->retval);
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_show_one_map_register_ttl_reply_t_handler
4382   (vl_api_show_one_map_register_ttl_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   i32 retval = ntohl (mp->retval);
4386
4387   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4388
4389   if (0 <= retval)
4390     {
4391       print (vam->ofp, "ttl: %u", mp->ttl);
4392     }
4393
4394   vam->retval = retval;
4395   vam->result_ready = 1;
4396 }
4397
4398 static void
4399   vl_api_show_one_map_register_ttl_reply_t_handler_json
4400   (vl_api_show_one_map_register_ttl_reply_t * mp)
4401 {
4402   vat_main_t *vam = &vat_main;
4403   vat_json_node_t node;
4404
4405   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4406   vat_json_init_object (&node);
4407   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4408
4409   vat_json_print (vam->ofp, &node);
4410   vat_json_free (&node);
4411
4412   vam->retval = ntohl (mp->retval);
4413   vam->result_ready = 1;
4414 }
4415
4416 static void
4417 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4418 {
4419   vat_main_t *vam = &vat_main;
4420   i32 retval = ntohl (mp->retval);
4421
4422   if (0 <= retval)
4423     {
4424       print (vam->ofp, "%-20s%-16s",
4425              mp->status ? "enabled" : "disabled",
4426              mp->status ? (char *) mp->locator_set_name : "");
4427     }
4428
4429   vam->retval = retval;
4430   vam->result_ready = 1;
4431 }
4432
4433 static void
4434 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4435 {
4436   vat_main_t *vam = &vat_main;
4437   vat_json_node_t node;
4438   u8 *status = 0;
4439
4440   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4441   vec_add1 (status, 0);
4442
4443   vat_json_init_object (&node);
4444   vat_json_object_add_string_copy (&node, "status", status);
4445   if (mp->status)
4446     {
4447       vat_json_object_add_string_copy (&node, "locator_set",
4448                                        mp->locator_set_name);
4449     }
4450
4451   vec_free (status);
4452
4453   vat_json_print (vam->ofp, &node);
4454   vat_json_free (&node);
4455
4456   vam->retval = ntohl (mp->retval);
4457   vam->result_ready = 1;
4458 }
4459
4460 static u8 *
4461 format_policer_type (u8 * s, va_list * va)
4462 {
4463   u32 i = va_arg (*va, u32);
4464
4465   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4466     s = format (s, "1r2c");
4467   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4468     s = format (s, "1r3c");
4469   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4470     s = format (s, "2r3c-2698");
4471   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4472     s = format (s, "2r3c-4115");
4473   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4474     s = format (s, "2r3c-mef5cf1");
4475   else
4476     s = format (s, "ILLEGAL");
4477   return s;
4478 }
4479
4480 static u8 *
4481 format_policer_rate_type (u8 * s, va_list * va)
4482 {
4483   u32 i = va_arg (*va, u32);
4484
4485   if (i == SSE2_QOS_RATE_KBPS)
4486     s = format (s, "kbps");
4487   else if (i == SSE2_QOS_RATE_PPS)
4488     s = format (s, "pps");
4489   else
4490     s = format (s, "ILLEGAL");
4491   return s;
4492 }
4493
4494 static u8 *
4495 format_policer_round_type (u8 * s, va_list * va)
4496 {
4497   u32 i = va_arg (*va, u32);
4498
4499   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4500     s = format (s, "closest");
4501   else if (i == SSE2_QOS_ROUND_TO_UP)
4502     s = format (s, "up");
4503   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4504     s = format (s, "down");
4505   else
4506     s = format (s, "ILLEGAL");
4507   return s;
4508 }
4509
4510 static u8 *
4511 format_policer_action_type (u8 * s, va_list * va)
4512 {
4513   u32 i = va_arg (*va, u32);
4514
4515   if (i == SSE2_QOS_ACTION_DROP)
4516     s = format (s, "drop");
4517   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4518     s = format (s, "transmit");
4519   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4520     s = format (s, "mark-and-transmit");
4521   else
4522     s = format (s, "ILLEGAL");
4523   return s;
4524 }
4525
4526 static u8 *
4527 format_dscp (u8 * s, va_list * va)
4528 {
4529   u32 i = va_arg (*va, u32);
4530   char *t = 0;
4531
4532   switch (i)
4533     {
4534 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4535       foreach_vnet_dscp
4536 #undef _
4537     default:
4538       return format (s, "ILLEGAL");
4539     }
4540   s = format (s, "%s", t);
4541   return s;
4542 }
4543
4544 static void
4545 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4546 {
4547   vat_main_t *vam = &vat_main;
4548   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4549
4550   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4551     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4552   else
4553     conform_dscp_str = format (0, "");
4554
4555   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4556     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4557   else
4558     exceed_dscp_str = format (0, "");
4559
4560   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4561     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4562   else
4563     violate_dscp_str = format (0, "");
4564
4565   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4566          "rate type %U, round type %U, %s rate, %s color-aware, "
4567          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4568          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4569          "conform action %U%s, exceed action %U%s, violate action %U%s",
4570          mp->name,
4571          format_policer_type, mp->type,
4572          ntohl (mp->cir),
4573          ntohl (mp->eir),
4574          clib_net_to_host_u64 (mp->cb),
4575          clib_net_to_host_u64 (mp->eb),
4576          format_policer_rate_type, mp->rate_type,
4577          format_policer_round_type, mp->round_type,
4578          mp->single_rate ? "single" : "dual",
4579          mp->color_aware ? "is" : "not",
4580          ntohl (mp->cir_tokens_per_period),
4581          ntohl (mp->pir_tokens_per_period),
4582          ntohl (mp->scale),
4583          ntohl (mp->current_limit),
4584          ntohl (mp->current_bucket),
4585          ntohl (mp->extended_limit),
4586          ntohl (mp->extended_bucket),
4587          clib_net_to_host_u64 (mp->last_update_time),
4588          format_policer_action_type, mp->conform_action_type,
4589          conform_dscp_str,
4590          format_policer_action_type, mp->exceed_action_type,
4591          exceed_dscp_str,
4592          format_policer_action_type, mp->violate_action_type,
4593          violate_dscp_str);
4594
4595   vec_free (conform_dscp_str);
4596   vec_free (exceed_dscp_str);
4597   vec_free (violate_dscp_str);
4598 }
4599
4600 static void vl_api_policer_details_t_handler_json
4601   (vl_api_policer_details_t * mp)
4602 {
4603   vat_main_t *vam = &vat_main;
4604   vat_json_node_t *node;
4605   u8 *rate_type_str, *round_type_str, *type_str;
4606   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4607
4608   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4609   round_type_str =
4610     format (0, "%U", format_policer_round_type, mp->round_type);
4611   type_str = format (0, "%U", format_policer_type, mp->type);
4612   conform_action_str = format (0, "%U", format_policer_action_type,
4613                                mp->conform_action_type);
4614   exceed_action_str = format (0, "%U", format_policer_action_type,
4615                               mp->exceed_action_type);
4616   violate_action_str = format (0, "%U", format_policer_action_type,
4617                                mp->violate_action_type);
4618
4619   if (VAT_JSON_ARRAY != vam->json_tree.type)
4620     {
4621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4622       vat_json_init_array (&vam->json_tree);
4623     }
4624   node = vat_json_array_add (&vam->json_tree);
4625
4626   vat_json_init_object (node);
4627   vat_json_object_add_string_copy (node, "name", mp->name);
4628   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4629   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4630   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4631   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4632   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4633   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4634   vat_json_object_add_string_copy (node, "type", type_str);
4635   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4636   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4637   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4638   vat_json_object_add_uint (node, "cir_tokens_per_period",
4639                             ntohl (mp->cir_tokens_per_period));
4640   vat_json_object_add_uint (node, "eir_tokens_per_period",
4641                             ntohl (mp->pir_tokens_per_period));
4642   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4643   vat_json_object_add_uint (node, "current_bucket",
4644                             ntohl (mp->current_bucket));
4645   vat_json_object_add_uint (node, "extended_limit",
4646                             ntohl (mp->extended_limit));
4647   vat_json_object_add_uint (node, "extended_bucket",
4648                             ntohl (mp->extended_bucket));
4649   vat_json_object_add_uint (node, "last_update_time",
4650                             ntohl (mp->last_update_time));
4651   vat_json_object_add_string_copy (node, "conform_action",
4652                                    conform_action_str);
4653   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4654     {
4655       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4656       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4657       vec_free (dscp_str);
4658     }
4659   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4660   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4661     {
4662       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4663       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4664       vec_free (dscp_str);
4665     }
4666   vat_json_object_add_string_copy (node, "violate_action",
4667                                    violate_action_str);
4668   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4669     {
4670       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4671       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4672       vec_free (dscp_str);
4673     }
4674
4675   vec_free (rate_type_str);
4676   vec_free (round_type_str);
4677   vec_free (type_str);
4678   vec_free (conform_action_str);
4679   vec_free (exceed_action_str);
4680   vec_free (violate_action_str);
4681 }
4682
4683 static void
4684 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4685                                            mp)
4686 {
4687   vat_main_t *vam = &vat_main;
4688   int i, count = ntohl (mp->count);
4689
4690   if (count > 0)
4691     print (vam->ofp, "classify table ids (%d) : ", count);
4692   for (i = 0; i < count; i++)
4693     {
4694       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4695       print (vam->ofp, (i < count - 1) ? "," : "");
4696     }
4697   vam->retval = ntohl (mp->retval);
4698   vam->result_ready = 1;
4699 }
4700
4701 static void
4702   vl_api_classify_table_ids_reply_t_handler_json
4703   (vl_api_classify_table_ids_reply_t * mp)
4704 {
4705   vat_main_t *vam = &vat_main;
4706   int i, count = ntohl (mp->count);
4707
4708   if (count > 0)
4709     {
4710       vat_json_node_t node;
4711
4712       vat_json_init_object (&node);
4713       for (i = 0; i < count; i++)
4714         {
4715           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4716         }
4717       vat_json_print (vam->ofp, &node);
4718       vat_json_free (&node);
4719     }
4720   vam->retval = ntohl (mp->retval);
4721   vam->result_ready = 1;
4722 }
4723
4724 static void
4725   vl_api_classify_table_by_interface_reply_t_handler
4726   (vl_api_classify_table_by_interface_reply_t * mp)
4727 {
4728   vat_main_t *vam = &vat_main;
4729   u32 table_id;
4730
4731   table_id = ntohl (mp->l2_table_id);
4732   if (table_id != ~0)
4733     print (vam->ofp, "l2 table id : %d", table_id);
4734   else
4735     print (vam->ofp, "l2 table id : No input ACL tables configured");
4736   table_id = ntohl (mp->ip4_table_id);
4737   if (table_id != ~0)
4738     print (vam->ofp, "ip4 table id : %d", table_id);
4739   else
4740     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4741   table_id = ntohl (mp->ip6_table_id);
4742   if (table_id != ~0)
4743     print (vam->ofp, "ip6 table id : %d", table_id);
4744   else
4745     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4746   vam->retval = ntohl (mp->retval);
4747   vam->result_ready = 1;
4748 }
4749
4750 static void
4751   vl_api_classify_table_by_interface_reply_t_handler_json
4752   (vl_api_classify_table_by_interface_reply_t * mp)
4753 {
4754   vat_main_t *vam = &vat_main;
4755   vat_json_node_t node;
4756
4757   vat_json_init_object (&node);
4758
4759   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4760   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4761   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4762
4763   vat_json_print (vam->ofp, &node);
4764   vat_json_free (&node);
4765
4766   vam->retval = ntohl (mp->retval);
4767   vam->result_ready = 1;
4768 }
4769
4770 static void vl_api_policer_add_del_reply_t_handler
4771   (vl_api_policer_add_del_reply_t * mp)
4772 {
4773   vat_main_t *vam = &vat_main;
4774   i32 retval = ntohl (mp->retval);
4775   if (vam->async_mode)
4776     {
4777       vam->async_errors += (retval < 0);
4778     }
4779   else
4780     {
4781       vam->retval = retval;
4782       vam->result_ready = 1;
4783       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4784         /*
4785          * Note: this is just barely thread-safe, depends on
4786          * the main thread spinning waiting for an answer...
4787          */
4788         errmsg ("policer index %d", ntohl (mp->policer_index));
4789     }
4790 }
4791
4792 static void vl_api_policer_add_del_reply_t_handler_json
4793   (vl_api_policer_add_del_reply_t * mp)
4794 {
4795   vat_main_t *vam = &vat_main;
4796   vat_json_node_t node;
4797
4798   vat_json_init_object (&node);
4799   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4800   vat_json_object_add_uint (&node, "policer_index",
4801                             ntohl (mp->policer_index));
4802
4803   vat_json_print (vam->ofp, &node);
4804   vat_json_free (&node);
4805
4806   vam->retval = ntohl (mp->retval);
4807   vam->result_ready = 1;
4808 }
4809
4810 /* Format hex dump. */
4811 u8 *
4812 format_hex_bytes (u8 * s, va_list * va)
4813 {
4814   u8 *bytes = va_arg (*va, u8 *);
4815   int n_bytes = va_arg (*va, int);
4816   uword i;
4817
4818   /* Print short or long form depending on byte count. */
4819   uword short_form = n_bytes <= 32;
4820   u32 indent = format_get_indent (s);
4821
4822   if (n_bytes == 0)
4823     return s;
4824
4825   for (i = 0; i < n_bytes; i++)
4826     {
4827       if (!short_form && (i % 32) == 0)
4828         s = format (s, "%08x: ", i);
4829       s = format (s, "%02x", bytes[i]);
4830       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4831         s = format (s, "\n%U", format_white_space, indent);
4832     }
4833
4834   return s;
4835 }
4836
4837 static void
4838 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4839                                             * mp)
4840 {
4841   vat_main_t *vam = &vat_main;
4842   i32 retval = ntohl (mp->retval);
4843   if (retval == 0)
4844     {
4845       print (vam->ofp, "classify table info :");
4846       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4847              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4848              ntohl (mp->miss_next_index));
4849       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4850              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4851              ntohl (mp->match_n_vectors));
4852       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4853              ntohl (mp->mask_length));
4854     }
4855   vam->retval = retval;
4856   vam->result_ready = 1;
4857 }
4858
4859 static void
4860   vl_api_classify_table_info_reply_t_handler_json
4861   (vl_api_classify_table_info_reply_t * mp)
4862 {
4863   vat_main_t *vam = &vat_main;
4864   vat_json_node_t node;
4865
4866   i32 retval = ntohl (mp->retval);
4867   if (retval == 0)
4868     {
4869       vat_json_init_object (&node);
4870
4871       vat_json_object_add_int (&node, "sessions",
4872                                ntohl (mp->active_sessions));
4873       vat_json_object_add_int (&node, "nexttbl",
4874                                ntohl (mp->next_table_index));
4875       vat_json_object_add_int (&node, "nextnode",
4876                                ntohl (mp->miss_next_index));
4877       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4878       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4879       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4880       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4881                       ntohl (mp->mask_length), 0);
4882       vat_json_object_add_string_copy (&node, "mask", s);
4883
4884       vat_json_print (vam->ofp, &node);
4885       vat_json_free (&node);
4886     }
4887   vam->retval = ntohl (mp->retval);
4888   vam->result_ready = 1;
4889 }
4890
4891 static void
4892 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4893                                            mp)
4894 {
4895   vat_main_t *vam = &vat_main;
4896
4897   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4898          ntohl (mp->hit_next_index), ntohl (mp->advance),
4899          ntohl (mp->opaque_index));
4900   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4901          ntohl (mp->match_length));
4902 }
4903
4904 static void
4905   vl_api_classify_session_details_t_handler_json
4906   (vl_api_classify_session_details_t * mp)
4907 {
4908   vat_main_t *vam = &vat_main;
4909   vat_json_node_t *node = NULL;
4910
4911   if (VAT_JSON_ARRAY != vam->json_tree.type)
4912     {
4913       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4914       vat_json_init_array (&vam->json_tree);
4915     }
4916   node = vat_json_array_add (&vam->json_tree);
4917
4918   vat_json_init_object (node);
4919   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4920   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4921   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4922   u8 *s =
4923     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4924             0);
4925   vat_json_object_add_string_copy (node, "match", s);
4926 }
4927
4928 static void vl_api_pg_create_interface_reply_t_handler
4929   (vl_api_pg_create_interface_reply_t * mp)
4930 {
4931   vat_main_t *vam = &vat_main;
4932
4933   vam->retval = ntohl (mp->retval);
4934   vam->result_ready = 1;
4935 }
4936
4937 static void vl_api_pg_create_interface_reply_t_handler_json
4938   (vl_api_pg_create_interface_reply_t * mp)
4939 {
4940   vat_main_t *vam = &vat_main;
4941   vat_json_node_t node;
4942
4943   i32 retval = ntohl (mp->retval);
4944   if (retval == 0)
4945     {
4946       vat_json_init_object (&node);
4947
4948       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4949
4950       vat_json_print (vam->ofp, &node);
4951       vat_json_free (&node);
4952     }
4953   vam->retval = ntohl (mp->retval);
4954   vam->result_ready = 1;
4955 }
4956
4957 static void vl_api_policer_classify_details_t_handler
4958   (vl_api_policer_classify_details_t * mp)
4959 {
4960   vat_main_t *vam = &vat_main;
4961
4962   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4963          ntohl (mp->table_index));
4964 }
4965
4966 static void vl_api_policer_classify_details_t_handler_json
4967   (vl_api_policer_classify_details_t * mp)
4968 {
4969   vat_main_t *vam = &vat_main;
4970   vat_json_node_t *node;
4971
4972   if (VAT_JSON_ARRAY != vam->json_tree.type)
4973     {
4974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4975       vat_json_init_array (&vam->json_tree);
4976     }
4977   node = vat_json_array_add (&vam->json_tree);
4978
4979   vat_json_init_object (node);
4980   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4981   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4982 }
4983
4984 static void vl_api_flow_classify_details_t_handler
4985   (vl_api_flow_classify_details_t * mp)
4986 {
4987   vat_main_t *vam = &vat_main;
4988
4989   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4990          ntohl (mp->table_index));
4991 }
4992
4993 static void vl_api_flow_classify_details_t_handler_json
4994   (vl_api_flow_classify_details_t * mp)
4995 {
4996   vat_main_t *vam = &vat_main;
4997   vat_json_node_t *node;
4998
4999   if (VAT_JSON_ARRAY != vam->json_tree.type)
5000     {
5001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5002       vat_json_init_array (&vam->json_tree);
5003     }
5004   node = vat_json_array_add (&vam->json_tree);
5005
5006   vat_json_init_object (node);
5007   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5008   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5009 }
5010
5011 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5012 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5013 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5014 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5015 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5016 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5017 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5018 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5019 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5020 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5021
5022 /*
5023  * Generate boilerplate reply handlers, which
5024  * dig the return value out of the xxx_reply_t API message,
5025  * stick it into vam->retval, and set vam->result_ready
5026  *
5027  * Could also do this by pointing N message decode slots at
5028  * a single function, but that could break in subtle ways.
5029  */
5030
5031 #define foreach_standard_reply_retval_handler           \
5032 _(sw_interface_set_flags_reply)                         \
5033 _(sw_interface_add_del_address_reply)                   \
5034 _(sw_interface_set_rx_mode_reply)                       \
5035 _(sw_interface_set_rx_placement_reply)                  \
5036 _(sw_interface_set_table_reply)                         \
5037 _(sw_interface_set_mpls_enable_reply)                   \
5038 _(sw_interface_set_vpath_reply)                         \
5039 _(sw_interface_set_vxlan_bypass_reply)                  \
5040 _(sw_interface_set_geneve_bypass_reply)                 \
5041 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5042 _(sw_interface_set_l2_bridge_reply)                     \
5043 _(bridge_domain_add_del_reply)                          \
5044 _(sw_interface_set_l2_xconnect_reply)                   \
5045 _(l2fib_add_del_reply)                                  \
5046 _(l2fib_flush_int_reply)                                \
5047 _(l2fib_flush_bd_reply)                                 \
5048 _(ip_route_add_del_reply)                               \
5049 _(ip_table_add_del_reply)                               \
5050 _(ip_mroute_add_del_reply)                              \
5051 _(mpls_route_add_del_reply)                             \
5052 _(mpls_table_add_del_reply)                             \
5053 _(mpls_ip_bind_unbind_reply)                            \
5054 _(bier_route_add_del_reply)                             \
5055 _(bier_table_add_del_reply)                             \
5056 _(proxy_arp_add_del_reply)                              \
5057 _(proxy_arp_intfc_enable_disable_reply)                 \
5058 _(sw_interface_set_unnumbered_reply)                    \
5059 _(ip_neighbor_add_del_reply)                            \
5060 _(reset_fib_reply)                                      \
5061 _(dhcp_proxy_config_reply)                              \
5062 _(dhcp_proxy_set_vss_reply)                             \
5063 _(dhcp_client_config_reply)                             \
5064 _(set_ip_flow_hash_reply)                               \
5065 _(sw_interface_ip6_enable_disable_reply)                \
5066 _(ip6nd_proxy_add_del_reply)                            \
5067 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5068 _(sw_interface_ip6nd_ra_config_reply)                   \
5069 _(set_arp_neighbor_limit_reply)                         \
5070 _(l2_patch_add_del_reply)                               \
5071 _(sr_mpls_policy_add_reply)                             \
5072 _(sr_mpls_policy_mod_reply)                             \
5073 _(sr_mpls_policy_del_reply)                             \
5074 _(sr_policy_add_reply)                                  \
5075 _(sr_policy_mod_reply)                                  \
5076 _(sr_policy_del_reply)                                  \
5077 _(sr_localsid_add_del_reply)                            \
5078 _(sr_steering_add_del_reply)                            \
5079 _(classify_add_del_session_reply)                       \
5080 _(classify_set_interface_ip_table_reply)                \
5081 _(classify_set_interface_l2_tables_reply)               \
5082 _(l2tpv3_set_tunnel_cookies_reply)                      \
5083 _(l2tpv3_interface_enable_disable_reply)                \
5084 _(l2tpv3_set_lookup_key_reply)                          \
5085 _(l2_fib_clear_table_reply)                             \
5086 _(l2_interface_efp_filter_reply)                        \
5087 _(l2_interface_vlan_tag_rewrite_reply)                  \
5088 _(modify_vhost_user_if_reply)                           \
5089 _(delete_vhost_user_if_reply)                           \
5090 _(ip_probe_neighbor_reply)                              \
5091 _(ip_scan_neighbor_enable_disable_reply)                \
5092 _(want_ip4_arp_events_reply)                            \
5093 _(want_ip6_nd_events_reply)                             \
5094 _(want_l2_macs_events_reply)                            \
5095 _(input_acl_set_interface_reply)                        \
5096 _(ipsec_spd_add_del_reply)                              \
5097 _(ipsec_interface_add_del_spd_reply)                    \
5098 _(ipsec_spd_entry_add_del_reply)                        \
5099 _(ipsec_sad_entry_add_del_reply)                        \
5100 _(ipsec_tunnel_if_add_del_reply)                        \
5101 _(ipsec_tunnel_if_set_sa_reply)                         \
5102 _(delete_loopback_reply)                                \
5103 _(bd_ip_mac_add_del_reply)                              \
5104 _(bd_ip_mac_flush_reply)                                \
5105 _(want_interface_events_reply)                          \
5106 _(cop_interface_enable_disable_reply)                   \
5107 _(cop_whitelist_enable_disable_reply)                   \
5108 _(sw_interface_clear_stats_reply)                       \
5109 _(ioam_enable_reply)                                    \
5110 _(ioam_disable_reply)                                   \
5111 _(one_add_del_locator_reply)                            \
5112 _(one_add_del_local_eid_reply)                          \
5113 _(one_add_del_remote_mapping_reply)                     \
5114 _(one_add_del_adjacency_reply)                          \
5115 _(one_add_del_map_resolver_reply)                       \
5116 _(one_add_del_map_server_reply)                         \
5117 _(one_enable_disable_reply)                             \
5118 _(one_rloc_probe_enable_disable_reply)                  \
5119 _(one_map_register_enable_disable_reply)                \
5120 _(one_map_register_set_ttl_reply)                       \
5121 _(one_set_transport_protocol_reply)                     \
5122 _(one_map_register_fallback_threshold_reply)            \
5123 _(one_pitr_set_locator_set_reply)                       \
5124 _(one_map_request_mode_reply)                           \
5125 _(one_add_del_map_request_itr_rlocs_reply)              \
5126 _(one_eid_table_add_del_map_reply)                      \
5127 _(one_use_petr_reply)                                   \
5128 _(one_stats_enable_disable_reply)                       \
5129 _(one_add_del_l2_arp_entry_reply)                       \
5130 _(one_add_del_ndp_entry_reply)                          \
5131 _(one_stats_flush_reply)                                \
5132 _(one_enable_disable_xtr_mode_reply)                    \
5133 _(one_enable_disable_pitr_mode_reply)                   \
5134 _(one_enable_disable_petr_mode_reply)                   \
5135 _(gpe_enable_disable_reply)                             \
5136 _(gpe_set_encap_mode_reply)                             \
5137 _(gpe_add_del_iface_reply)                              \
5138 _(gpe_add_del_native_fwd_rpath_reply)                   \
5139 _(af_packet_delete_reply)                               \
5140 _(policer_classify_set_interface_reply)                 \
5141 _(netmap_create_reply)                                  \
5142 _(netmap_delete_reply)                                  \
5143 _(set_ipfix_exporter_reply)                             \
5144 _(set_ipfix_classify_stream_reply)                      \
5145 _(ipfix_classify_table_add_del_reply)                   \
5146 _(flow_classify_set_interface_reply)                    \
5147 _(sw_interface_span_enable_disable_reply)               \
5148 _(pg_capture_reply)                                     \
5149 _(pg_enable_disable_reply)                              \
5150 _(ip_source_and_port_range_check_add_del_reply)         \
5151 _(ip_source_and_port_range_check_interface_add_del_reply)\
5152 _(delete_subif_reply)                                   \
5153 _(l2_interface_pbb_tag_rewrite_reply)                   \
5154 _(set_punt_reply)                                       \
5155 _(feature_enable_disable_reply)                         \
5156 _(sw_interface_tag_add_del_reply)                       \
5157 _(hw_interface_set_mtu_reply)                           \
5158 _(p2p_ethernet_add_reply)                               \
5159 _(p2p_ethernet_del_reply)                               \
5160 _(lldp_config_reply)                                    \
5161 _(sw_interface_set_lldp_reply)                          \
5162 _(tcp_configure_src_addresses_reply)                    \
5163 _(session_rule_add_del_reply)                           \
5164 _(ip_container_proxy_add_del_reply)                     \
5165 _(output_acl_set_interface_reply)                       \
5166 _(qos_record_enable_disable_reply)
5167
5168 #define _(n)                                    \
5169     static void vl_api_##n##_t_handler          \
5170     (vl_api_##n##_t * mp)                       \
5171     {                                           \
5172         vat_main_t * vam = &vat_main;           \
5173         i32 retval = ntohl(mp->retval);         \
5174         if (vam->async_mode) {                  \
5175             vam->async_errors += (retval < 0);  \
5176         } else {                                \
5177             vam->retval = retval;               \
5178             vam->result_ready = 1;              \
5179         }                                       \
5180     }
5181 foreach_standard_reply_retval_handler;
5182 #undef _
5183
5184 #define _(n)                                    \
5185     static void vl_api_##n##_t_handler_json     \
5186     (vl_api_##n##_t * mp)                       \
5187     {                                           \
5188         vat_main_t * vam = &vat_main;           \
5189         vat_json_node_t node;                   \
5190         vat_json_init_object(&node);            \
5191         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5192         vat_json_print(vam->ofp, &node);        \
5193         vam->retval = ntohl(mp->retval);        \
5194         vam->result_ready = 1;                  \
5195     }
5196 foreach_standard_reply_retval_handler;
5197 #undef _
5198
5199 /*
5200  * Table of message reply handlers, must include boilerplate handlers
5201  * we just generated
5202  */
5203
5204 #define foreach_vpe_api_reply_msg                                       \
5205 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5206 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5207 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5208 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5209 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5210 _(CLI_REPLY, cli_reply)                                                 \
5211 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5212 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5213   sw_interface_add_del_address_reply)                                   \
5214 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5215 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5216 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5217 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5218 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5219 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5220 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5221 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5222 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5223 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5224   sw_interface_set_l2_xconnect_reply)                                   \
5225 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5226   sw_interface_set_l2_bridge_reply)                                     \
5227 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5228 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5229 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5230 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5231 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5232 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5233 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5234 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5235 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5236 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5237 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5238 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5239 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5240 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5241 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5242 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5243 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5244 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5245 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5246 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5247 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5248 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5249 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5250 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5251 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5252 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5253 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5254 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5255 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5256 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5257   proxy_arp_intfc_enable_disable_reply)                                 \
5258 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5259 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5260   sw_interface_set_unnumbered_reply)                                    \
5261 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5262 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5263 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5264 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5265 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5266 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5267 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5268 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5269 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5270 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5271   sw_interface_ip6_enable_disable_reply)                                \
5272 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5273 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5274 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5275   sw_interface_ip6nd_ra_prefix_reply)                                   \
5276 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5277   sw_interface_ip6nd_ra_config_reply)                                   \
5278 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5279 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5280 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5281 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5282 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5283 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5284 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5285 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5286 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5287 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5288 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5289 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5290 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5291 classify_set_interface_ip_table_reply)                                  \
5292 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5293   classify_set_interface_l2_tables_reply)                               \
5294 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5295 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5296 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5297 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5298 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5299   l2tpv3_interface_enable_disable_reply)                                \
5300 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5301 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5302 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5303 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5304 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5305 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5306 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5307 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5308 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5309 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5310 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5311 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5312 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5313 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5314 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5315 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5316 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5317 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5318 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5319 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5320 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5321 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5322 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5323 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5324 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5325 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5326 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5327 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5328 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5329 _(L2_MACS_EVENT, l2_macs_event)                                         \
5330 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5331 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5332 _(IP_DETAILS, ip_details)                                               \
5333 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5334 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5335 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5336 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5337 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5338 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5339 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5340 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5341 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5342 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5343 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5344 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5345 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5346 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5347 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5348 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5349 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5350 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5351 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5352 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5353 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5354 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5355 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5356 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5357 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5358 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5359 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5360 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5361 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5362   one_map_register_enable_disable_reply)                                \
5363 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5364 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5365 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5366 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5367   one_map_register_fallback_threshold_reply)                            \
5368 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5369   one_rloc_probe_enable_disable_reply)                                  \
5370 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5371 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5372 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5373 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5374 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5375 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5376 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5377 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5378 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5379 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5380 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5381 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5382 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5383 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5384 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5385 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5386   show_one_stats_enable_disable_reply)                                  \
5387 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5388 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5389 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5390 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5391 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5392 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5393 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5394 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5395   one_enable_disable_pitr_mode_reply)                                   \
5396 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5397   one_enable_disable_petr_mode_reply)                                   \
5398 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5399 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5400 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5401 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5402 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5403 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5404 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5405 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5406 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5407 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5408 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5409 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5410   gpe_add_del_native_fwd_rpath_reply)                                   \
5411 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5412   gpe_fwd_entry_path_details)                                           \
5413 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5414 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5415   one_add_del_map_request_itr_rlocs_reply)                              \
5416 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5417   one_get_map_request_itr_rlocs_reply)                                  \
5418 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5419 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5420 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5421 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5422 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5423 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5424   show_one_map_register_state_reply)                                    \
5425 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5426 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5427   show_one_map_register_fallback_threshold_reply)                       \
5428 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5429 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5430 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5431 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5432 _(POLICER_DETAILS, policer_details)                                     \
5433 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5434 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5435 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5436 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5437 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5438 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5439 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5440 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5441 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5442 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5443 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5444 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5445 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5446 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5447 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5448 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5449 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5450 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5451 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5452 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5453 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5454 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5455 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5456 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5457 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5458 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5459  ip_source_and_port_range_check_add_del_reply)                          \
5460 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5461  ip_source_and_port_range_check_interface_add_del_reply)                \
5462 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5463 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5464 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5465 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5466 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5467 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5468 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5469 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5470 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5471 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5472 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5473 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5474 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5475 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5476 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5477 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5478 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5479 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5480 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5481 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5482 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5483 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5484
5485 #define foreach_standalone_reply_msg                                    \
5486 _(SW_INTERFACE_EVENT, sw_interface_event)
5487
5488 typedef struct
5489 {
5490   u8 *name;
5491   u32 value;
5492 } name_sort_t;
5493
5494 #define STR_VTR_OP_CASE(op)     \
5495     case L2_VTR_ ## op:         \
5496         return "" # op;
5497
5498 static const char *
5499 str_vtr_op (u32 vtr_op)
5500 {
5501   switch (vtr_op)
5502     {
5503       STR_VTR_OP_CASE (DISABLED);
5504       STR_VTR_OP_CASE (PUSH_1);
5505       STR_VTR_OP_CASE (PUSH_2);
5506       STR_VTR_OP_CASE (POP_1);
5507       STR_VTR_OP_CASE (POP_2);
5508       STR_VTR_OP_CASE (TRANSLATE_1_1);
5509       STR_VTR_OP_CASE (TRANSLATE_1_2);
5510       STR_VTR_OP_CASE (TRANSLATE_2_1);
5511       STR_VTR_OP_CASE (TRANSLATE_2_2);
5512     }
5513
5514   return "UNKNOWN";
5515 }
5516
5517 static int
5518 dump_sub_interface_table (vat_main_t * vam)
5519 {
5520   const sw_interface_subif_t *sub = NULL;
5521
5522   if (vam->json_output)
5523     {
5524       clib_warning
5525         ("JSON output supported only for VPE API calls and dump_stats_table");
5526       return -99;
5527     }
5528
5529   print (vam->ofp,
5530          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5531          "Interface", "sw_if_index",
5532          "sub id", "dot1ad", "tags", "outer id",
5533          "inner id", "exact", "default", "outer any", "inner any");
5534
5535   vec_foreach (sub, vam->sw_if_subif_table)
5536   {
5537     print (vam->ofp,
5538            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5539            sub->interface_name,
5540            sub->sw_if_index,
5541            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5542            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5543            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5544            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5545     if (sub->vtr_op != L2_VTR_DISABLED)
5546       {
5547         print (vam->ofp,
5548                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5549                "tag1: %d tag2: %d ]",
5550                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5551                sub->vtr_tag1, sub->vtr_tag2);
5552       }
5553   }
5554
5555   return 0;
5556 }
5557
5558 static int
5559 name_sort_cmp (void *a1, void *a2)
5560 {
5561   name_sort_t *n1 = a1;
5562   name_sort_t *n2 = a2;
5563
5564   return strcmp ((char *) n1->name, (char *) n2->name);
5565 }
5566
5567 static int
5568 dump_interface_table (vat_main_t * vam)
5569 {
5570   hash_pair_t *p;
5571   name_sort_t *nses = 0, *ns;
5572
5573   if (vam->json_output)
5574     {
5575       clib_warning
5576         ("JSON output supported only for VPE API calls and dump_stats_table");
5577       return -99;
5578     }
5579
5580   /* *INDENT-OFF* */
5581   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5582   ({
5583     vec_add2 (nses, ns, 1);
5584     ns->name = (u8 *)(p->key);
5585     ns->value = (u32) p->value[0];
5586   }));
5587   /* *INDENT-ON* */
5588
5589   vec_sort_with_function (nses, name_sort_cmp);
5590
5591   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5592   vec_foreach (ns, nses)
5593   {
5594     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5595   }
5596   vec_free (nses);
5597   return 0;
5598 }
5599
5600 static int
5601 dump_ip_table (vat_main_t * vam, int is_ipv6)
5602 {
5603   const ip_details_t *det = NULL;
5604   const ip_address_details_t *address = NULL;
5605   u32 i = ~0;
5606
5607   print (vam->ofp, "%-12s", "sw_if_index");
5608
5609   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5610   {
5611     i++;
5612     if (!det->present)
5613       {
5614         continue;
5615       }
5616     print (vam->ofp, "%-12d", i);
5617     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5618     if (!det->addr)
5619       {
5620         continue;
5621       }
5622     vec_foreach (address, det->addr)
5623     {
5624       print (vam->ofp,
5625              "            %-30U%-13d",
5626              is_ipv6 ? format_ip6_address : format_ip4_address,
5627              address->ip, address->prefix_length);
5628     }
5629   }
5630
5631   return 0;
5632 }
5633
5634 static int
5635 dump_ipv4_table (vat_main_t * vam)
5636 {
5637   if (vam->json_output)
5638     {
5639       clib_warning
5640         ("JSON output supported only for VPE API calls and dump_stats_table");
5641       return -99;
5642     }
5643
5644   return dump_ip_table (vam, 0);
5645 }
5646
5647 static int
5648 dump_ipv6_table (vat_main_t * vam)
5649 {
5650   if (vam->json_output)
5651     {
5652       clib_warning
5653         ("JSON output supported only for VPE API calls and dump_stats_table");
5654       return -99;
5655     }
5656
5657   return dump_ip_table (vam, 1);
5658 }
5659
5660 /*
5661  * Pass CLI buffers directly in the CLI_INBAND API message,
5662  * instead of an additional shared memory area.
5663  */
5664 static int
5665 exec_inband (vat_main_t * vam)
5666 {
5667   vl_api_cli_inband_t *mp;
5668   unformat_input_t *i = vam->input;
5669   int ret;
5670
5671   if (vec_len (i->buffer) == 0)
5672     return -1;
5673
5674   if (vam->exec_mode == 0 && unformat (i, "mode"))
5675     {
5676       vam->exec_mode = 1;
5677       return 0;
5678     }
5679   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5680     {
5681       vam->exec_mode = 0;
5682       return 0;
5683     }
5684
5685   /*
5686    * In order for the CLI command to work, it
5687    * must be a vector ending in \n, not a C-string ending
5688    * in \n\0.
5689    */
5690   u32 len = vec_len (vam->input->buffer);
5691   M2 (CLI_INBAND, mp, len);
5692   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5693
5694   S (mp);
5695   W (ret);
5696   /* json responses may or may not include a useful reply... */
5697   if (vec_len (vam->cmd_reply))
5698     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5699   return ret;
5700 }
5701
5702 int
5703 exec (vat_main_t * vam)
5704 {
5705   return exec_inband (vam);
5706 }
5707
5708 static int
5709 api_create_loopback (vat_main_t * vam)
5710 {
5711   unformat_input_t *i = vam->input;
5712   vl_api_create_loopback_t *mp;
5713   vl_api_create_loopback_instance_t *mp_lbi;
5714   u8 mac_address[6];
5715   u8 mac_set = 0;
5716   u8 is_specified = 0;
5717   u32 user_instance = 0;
5718   int ret;
5719
5720   clib_memset (mac_address, 0, sizeof (mac_address));
5721
5722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723     {
5724       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5725         mac_set = 1;
5726       if (unformat (i, "instance %d", &user_instance))
5727         is_specified = 1;
5728       else
5729         break;
5730     }
5731
5732   if (is_specified)
5733     {
5734       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5735       mp_lbi->is_specified = is_specified;
5736       if (is_specified)
5737         mp_lbi->user_instance = htonl (user_instance);
5738       if (mac_set)
5739         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5740       S (mp_lbi);
5741     }
5742   else
5743     {
5744       /* Construct the API message */
5745       M (CREATE_LOOPBACK, mp);
5746       if (mac_set)
5747         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5748       S (mp);
5749     }
5750
5751   W (ret);
5752   return ret;
5753 }
5754
5755 static int
5756 api_delete_loopback (vat_main_t * vam)
5757 {
5758   unformat_input_t *i = vam->input;
5759   vl_api_delete_loopback_t *mp;
5760   u32 sw_if_index = ~0;
5761   int ret;
5762
5763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5764     {
5765       if (unformat (i, "sw_if_index %d", &sw_if_index))
5766         ;
5767       else
5768         break;
5769     }
5770
5771   if (sw_if_index == ~0)
5772     {
5773       errmsg ("missing sw_if_index");
5774       return -99;
5775     }
5776
5777   /* Construct the API message */
5778   M (DELETE_LOOPBACK, mp);
5779   mp->sw_if_index = ntohl (sw_if_index);
5780
5781   S (mp);
5782   W (ret);
5783   return ret;
5784 }
5785
5786 static int
5787 api_want_interface_events (vat_main_t * vam)
5788 {
5789   unformat_input_t *i = vam->input;
5790   vl_api_want_interface_events_t *mp;
5791   int enable = -1;
5792   int ret;
5793
5794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5795     {
5796       if (unformat (i, "enable"))
5797         enable = 1;
5798       else if (unformat (i, "disable"))
5799         enable = 0;
5800       else
5801         break;
5802     }
5803
5804   if (enable == -1)
5805     {
5806       errmsg ("missing enable|disable");
5807       return -99;
5808     }
5809
5810   M (WANT_INTERFACE_EVENTS, mp);
5811   mp->enable_disable = enable;
5812
5813   vam->interface_event_display = enable;
5814
5815   S (mp);
5816   W (ret);
5817   return ret;
5818 }
5819
5820
5821 /* Note: non-static, called once to set up the initial intfc table */
5822 int
5823 api_sw_interface_dump (vat_main_t * vam)
5824 {
5825   vl_api_sw_interface_dump_t *mp;
5826   vl_api_control_ping_t *mp_ping;
5827   hash_pair_t *p;
5828   name_sort_t *nses = 0, *ns;
5829   sw_interface_subif_t *sub = NULL;
5830   int ret;
5831
5832   /* Toss the old name table */
5833   /* *INDENT-OFF* */
5834   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5835   ({
5836     vec_add2 (nses, ns, 1);
5837     ns->name = (u8 *)(p->key);
5838     ns->value = (u32) p->value[0];
5839   }));
5840   /* *INDENT-ON* */
5841
5842   hash_free (vam->sw_if_index_by_interface_name);
5843
5844   vec_foreach (ns, nses) vec_free (ns->name);
5845
5846   vec_free (nses);
5847
5848   vec_foreach (sub, vam->sw_if_subif_table)
5849   {
5850     vec_free (sub->interface_name);
5851   }
5852   vec_free (vam->sw_if_subif_table);
5853
5854   /* recreate the interface name hash table */
5855   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5856
5857   /*
5858    * Ask for all interface names. Otherwise, the epic catalog of
5859    * name filters becomes ridiculously long, and vat ends up needing
5860    * to be taught about new interface types.
5861    */
5862   M (SW_INTERFACE_DUMP, mp);
5863   S (mp);
5864
5865   /* Use a control ping for synchronization */
5866   MPING (CONTROL_PING, mp_ping);
5867   S (mp_ping);
5868
5869   W (ret);
5870   return ret;
5871 }
5872
5873 static int
5874 api_sw_interface_set_flags (vat_main_t * vam)
5875 {
5876   unformat_input_t *i = vam->input;
5877   vl_api_sw_interface_set_flags_t *mp;
5878   u32 sw_if_index;
5879   u8 sw_if_index_set = 0;
5880   u8 admin_up = 0;
5881   int ret;
5882
5883   /* Parse args required to build the message */
5884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5885     {
5886       if (unformat (i, "admin-up"))
5887         admin_up = 1;
5888       else if (unformat (i, "admin-down"))
5889         admin_up = 0;
5890       else
5891         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5892         sw_if_index_set = 1;
5893       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5894         sw_if_index_set = 1;
5895       else
5896         break;
5897     }
5898
5899   if (sw_if_index_set == 0)
5900     {
5901       errmsg ("missing interface name or sw_if_index");
5902       return -99;
5903     }
5904
5905   /* Construct the API message */
5906   M (SW_INTERFACE_SET_FLAGS, mp);
5907   mp->sw_if_index = ntohl (sw_if_index);
5908   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5909
5910   /* send it... */
5911   S (mp);
5912
5913   /* Wait for a reply, return the good/bad news... */
5914   W (ret);
5915   return ret;
5916 }
5917
5918 static int
5919 api_sw_interface_set_rx_mode (vat_main_t * vam)
5920 {
5921   unformat_input_t *i = vam->input;
5922   vl_api_sw_interface_set_rx_mode_t *mp;
5923   u32 sw_if_index;
5924   u8 sw_if_index_set = 0;
5925   int ret;
5926   u8 queue_id_valid = 0;
5927   u32 queue_id;
5928   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5929
5930   /* Parse args required to build the message */
5931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5932     {
5933       if (unformat (i, "queue %d", &queue_id))
5934         queue_id_valid = 1;
5935       else if (unformat (i, "polling"))
5936         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5937       else if (unformat (i, "interrupt"))
5938         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5939       else if (unformat (i, "adaptive"))
5940         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5941       else
5942         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5943         sw_if_index_set = 1;
5944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5945         sw_if_index_set = 1;
5946       else
5947         break;
5948     }
5949
5950   if (sw_if_index_set == 0)
5951     {
5952       errmsg ("missing interface name or sw_if_index");
5953       return -99;
5954     }
5955   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5956     {
5957       errmsg ("missing rx-mode");
5958       return -99;
5959     }
5960
5961   /* Construct the API message */
5962   M (SW_INTERFACE_SET_RX_MODE, mp);
5963   mp->sw_if_index = ntohl (sw_if_index);
5964   mp->mode = (vl_api_rx_mode_t) mode;
5965   mp->queue_id_valid = queue_id_valid;
5966   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5967
5968   /* send it... */
5969   S (mp);
5970
5971   /* Wait for a reply, return the good/bad news... */
5972   W (ret);
5973   return ret;
5974 }
5975
5976 static int
5977 api_sw_interface_set_rx_placement (vat_main_t * vam)
5978 {
5979   unformat_input_t *i = vam->input;
5980   vl_api_sw_interface_set_rx_placement_t *mp;
5981   u32 sw_if_index;
5982   u8 sw_if_index_set = 0;
5983   int ret;
5984   u8 is_main = 0;
5985   u32 queue_id, thread_index;
5986
5987   /* Parse args required to build the message */
5988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5989     {
5990       if (unformat (i, "queue %d", &queue_id))
5991         ;
5992       else if (unformat (i, "main"))
5993         is_main = 1;
5994       else if (unformat (i, "worker %d", &thread_index))
5995         ;
5996       else
5997         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5998         sw_if_index_set = 1;
5999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6000         sw_if_index_set = 1;
6001       else
6002         break;
6003     }
6004
6005   if (sw_if_index_set == 0)
6006     {
6007       errmsg ("missing interface name or sw_if_index");
6008       return -99;
6009     }
6010
6011   if (is_main)
6012     thread_index = 0;
6013   /* Construct the API message */
6014   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6015   mp->sw_if_index = ntohl (sw_if_index);
6016   mp->worker_id = ntohl (thread_index);
6017   mp->queue_id = ntohl (queue_id);
6018   mp->is_main = is_main;
6019
6020   /* send it... */
6021   S (mp);
6022   /* Wait for a reply, return the good/bad news... */
6023   W (ret);
6024   return ret;
6025 }
6026
6027 static void vl_api_sw_interface_rx_placement_details_t_handler
6028   (vl_api_sw_interface_rx_placement_details_t * mp)
6029 {
6030   vat_main_t *vam = &vat_main;
6031   u32 worker_id = ntohl (mp->worker_id);
6032
6033   print (vam->ofp,
6034          "\n%-11d %-11s %-6d %-5d %-9s",
6035          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6036          worker_id, ntohl (mp->queue_id),
6037          (mp->mode ==
6038           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6039 }
6040
6041 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6042   (vl_api_sw_interface_rx_placement_details_t * mp)
6043 {
6044   vat_main_t *vam = &vat_main;
6045   vat_json_node_t *node = NULL;
6046
6047   if (VAT_JSON_ARRAY != vam->json_tree.type)
6048     {
6049       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6050       vat_json_init_array (&vam->json_tree);
6051     }
6052   node = vat_json_array_add (&vam->json_tree);
6053
6054   vat_json_init_object (node);
6055   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6056   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6057   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6058   vat_json_object_add_uint (node, "mode", mp->mode);
6059 }
6060
6061 static int
6062 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6063 {
6064   unformat_input_t *i = vam->input;
6065   vl_api_sw_interface_rx_placement_dump_t *mp;
6066   vl_api_control_ping_t *mp_ping;
6067   int ret;
6068   u32 sw_if_index;
6069   u8 sw_if_index_set = 0;
6070
6071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6072     {
6073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6074         sw_if_index_set++;
6075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6076         sw_if_index_set++;
6077       else
6078         break;
6079     }
6080
6081   print (vam->ofp,
6082          "\n%-11s %-11s %-6s %-5s %-4s",
6083          "sw_if_index", "main/worker", "thread", "queue", "mode");
6084
6085   /* Dump Interface rx placement */
6086   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6087
6088   if (sw_if_index_set)
6089     mp->sw_if_index = htonl (sw_if_index);
6090   else
6091     mp->sw_if_index = ~0;
6092
6093   S (mp);
6094
6095   /* Use a control ping for synchronization */
6096   MPING (CONTROL_PING, mp_ping);
6097   S (mp_ping);
6098
6099   W (ret);
6100   return ret;
6101 }
6102
6103 static int
6104 api_sw_interface_clear_stats (vat_main_t * vam)
6105 {
6106   unformat_input_t *i = vam->input;
6107   vl_api_sw_interface_clear_stats_t *mp;
6108   u32 sw_if_index;
6109   u8 sw_if_index_set = 0;
6110   int ret;
6111
6112   /* Parse args required to build the message */
6113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6114     {
6115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6116         sw_if_index_set = 1;
6117       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6118         sw_if_index_set = 1;
6119       else
6120         break;
6121     }
6122
6123   /* Construct the API message */
6124   M (SW_INTERFACE_CLEAR_STATS, mp);
6125
6126   if (sw_if_index_set == 1)
6127     mp->sw_if_index = ntohl (sw_if_index);
6128   else
6129     mp->sw_if_index = ~0;
6130
6131   /* send it... */
6132   S (mp);
6133
6134   /* Wait for a reply, return the good/bad news... */
6135   W (ret);
6136   return ret;
6137 }
6138
6139 static int
6140 api_sw_interface_add_del_address (vat_main_t * vam)
6141 {
6142   unformat_input_t *i = vam->input;
6143   vl_api_sw_interface_add_del_address_t *mp;
6144   u32 sw_if_index;
6145   u8 sw_if_index_set = 0;
6146   u8 is_add = 1, del_all = 0;
6147   u32 address_length = 0;
6148   u8 v4_address_set = 0;
6149   u8 v6_address_set = 0;
6150   ip4_address_t v4address;
6151   ip6_address_t v6address;
6152   int ret;
6153
6154   /* Parse args required to build the message */
6155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6156     {
6157       if (unformat (i, "del-all"))
6158         del_all = 1;
6159       else if (unformat (i, "del"))
6160         is_add = 0;
6161       else
6162         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6163         sw_if_index_set = 1;
6164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6165         sw_if_index_set = 1;
6166       else if (unformat (i, "%U/%d",
6167                          unformat_ip4_address, &v4address, &address_length))
6168         v4_address_set = 1;
6169       else if (unformat (i, "%U/%d",
6170                          unformat_ip6_address, &v6address, &address_length))
6171         v6_address_set = 1;
6172       else
6173         break;
6174     }
6175
6176   if (sw_if_index_set == 0)
6177     {
6178       errmsg ("missing interface name or sw_if_index");
6179       return -99;
6180     }
6181   if (v4_address_set && v6_address_set)
6182     {
6183       errmsg ("both v4 and v6 addresses set");
6184       return -99;
6185     }
6186   if (!v4_address_set && !v6_address_set && !del_all)
6187     {
6188       errmsg ("no addresses set");
6189       return -99;
6190     }
6191
6192   /* Construct the API message */
6193   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6194
6195   mp->sw_if_index = ntohl (sw_if_index);
6196   mp->is_add = is_add;
6197   mp->del_all = del_all;
6198   if (v6_address_set)
6199     {
6200       mp->prefix.address.af = ADDRESS_IP6;
6201       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6202     }
6203   else
6204     {
6205       mp->prefix.address.af = ADDRESS_IP4;
6206       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6207     }
6208   mp->prefix.len = address_length;
6209
6210   /* send it... */
6211   S (mp);
6212
6213   /* Wait for a reply, return good/bad news  */
6214   W (ret);
6215   return ret;
6216 }
6217
6218 static int
6219 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6220 {
6221   unformat_input_t *i = vam->input;
6222   vl_api_sw_interface_set_mpls_enable_t *mp;
6223   u32 sw_if_index;
6224   u8 sw_if_index_set = 0;
6225   u8 enable = 1;
6226   int ret;
6227
6228   /* Parse args required to build the message */
6229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6230     {
6231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6232         sw_if_index_set = 1;
6233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6234         sw_if_index_set = 1;
6235       else if (unformat (i, "disable"))
6236         enable = 0;
6237       else if (unformat (i, "dis"))
6238         enable = 0;
6239       else
6240         break;
6241     }
6242
6243   if (sw_if_index_set == 0)
6244     {
6245       errmsg ("missing interface name or sw_if_index");
6246       return -99;
6247     }
6248
6249   /* Construct the API message */
6250   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6251
6252   mp->sw_if_index = ntohl (sw_if_index);
6253   mp->enable = enable;
6254
6255   /* send it... */
6256   S (mp);
6257
6258   /* Wait for a reply... */
6259   W (ret);
6260   return ret;
6261 }
6262
6263 static int
6264 api_sw_interface_set_table (vat_main_t * vam)
6265 {
6266   unformat_input_t *i = vam->input;
6267   vl_api_sw_interface_set_table_t *mp;
6268   u32 sw_if_index, vrf_id = 0;
6269   u8 sw_if_index_set = 0;
6270   u8 is_ipv6 = 0;
6271   int ret;
6272
6273   /* Parse args required to build the message */
6274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6275     {
6276       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6277         sw_if_index_set = 1;
6278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6279         sw_if_index_set = 1;
6280       else if (unformat (i, "vrf %d", &vrf_id))
6281         ;
6282       else if (unformat (i, "ipv6"))
6283         is_ipv6 = 1;
6284       else
6285         break;
6286     }
6287
6288   if (sw_if_index_set == 0)
6289     {
6290       errmsg ("missing interface name or sw_if_index");
6291       return -99;
6292     }
6293
6294   /* Construct the API message */
6295   M (SW_INTERFACE_SET_TABLE, mp);
6296
6297   mp->sw_if_index = ntohl (sw_if_index);
6298   mp->is_ipv6 = is_ipv6;
6299   mp->vrf_id = ntohl (vrf_id);
6300
6301   /* send it... */
6302   S (mp);
6303
6304   /* Wait for a reply... */
6305   W (ret);
6306   return ret;
6307 }
6308
6309 static void vl_api_sw_interface_get_table_reply_t_handler
6310   (vl_api_sw_interface_get_table_reply_t * mp)
6311 {
6312   vat_main_t *vam = &vat_main;
6313
6314   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6315
6316   vam->retval = ntohl (mp->retval);
6317   vam->result_ready = 1;
6318
6319 }
6320
6321 static void vl_api_sw_interface_get_table_reply_t_handler_json
6322   (vl_api_sw_interface_get_table_reply_t * mp)
6323 {
6324   vat_main_t *vam = &vat_main;
6325   vat_json_node_t node;
6326
6327   vat_json_init_object (&node);
6328   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6329   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6330
6331   vat_json_print (vam->ofp, &node);
6332   vat_json_free (&node);
6333
6334   vam->retval = ntohl (mp->retval);
6335   vam->result_ready = 1;
6336 }
6337
6338 static int
6339 api_sw_interface_get_table (vat_main_t * vam)
6340 {
6341   unformat_input_t *i = vam->input;
6342   vl_api_sw_interface_get_table_t *mp;
6343   u32 sw_if_index;
6344   u8 sw_if_index_set = 0;
6345   u8 is_ipv6 = 0;
6346   int ret;
6347
6348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6349     {
6350       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6351         sw_if_index_set = 1;
6352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6353         sw_if_index_set = 1;
6354       else if (unformat (i, "ipv6"))
6355         is_ipv6 = 1;
6356       else
6357         break;
6358     }
6359
6360   if (sw_if_index_set == 0)
6361     {
6362       errmsg ("missing interface name or sw_if_index");
6363       return -99;
6364     }
6365
6366   M (SW_INTERFACE_GET_TABLE, mp);
6367   mp->sw_if_index = htonl (sw_if_index);
6368   mp->is_ipv6 = is_ipv6;
6369
6370   S (mp);
6371   W (ret);
6372   return ret;
6373 }
6374
6375 static int
6376 api_sw_interface_set_vpath (vat_main_t * vam)
6377 {
6378   unformat_input_t *i = vam->input;
6379   vl_api_sw_interface_set_vpath_t *mp;
6380   u32 sw_if_index = 0;
6381   u8 sw_if_index_set = 0;
6382   u8 is_enable = 0;
6383   int ret;
6384
6385   /* Parse args required to build the message */
6386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6387     {
6388       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6389         sw_if_index_set = 1;
6390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6391         sw_if_index_set = 1;
6392       else if (unformat (i, "enable"))
6393         is_enable = 1;
6394       else if (unformat (i, "disable"))
6395         is_enable = 0;
6396       else
6397         break;
6398     }
6399
6400   if (sw_if_index_set == 0)
6401     {
6402       errmsg ("missing interface name or sw_if_index");
6403       return -99;
6404     }
6405
6406   /* Construct the API message */
6407   M (SW_INTERFACE_SET_VPATH, mp);
6408
6409   mp->sw_if_index = ntohl (sw_if_index);
6410   mp->enable = is_enable;
6411
6412   /* send it... */
6413   S (mp);
6414
6415   /* Wait for a reply... */
6416   W (ret);
6417   return ret;
6418 }
6419
6420 static int
6421 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6422 {
6423   unformat_input_t *i = vam->input;
6424   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6425   u32 sw_if_index = 0;
6426   u8 sw_if_index_set = 0;
6427   u8 is_enable = 1;
6428   u8 is_ipv6 = 0;
6429   int ret;
6430
6431   /* Parse args required to build the message */
6432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6433     {
6434       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6435         sw_if_index_set = 1;
6436       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6437         sw_if_index_set = 1;
6438       else if (unformat (i, "enable"))
6439         is_enable = 1;
6440       else if (unformat (i, "disable"))
6441         is_enable = 0;
6442       else if (unformat (i, "ip4"))
6443         is_ipv6 = 0;
6444       else if (unformat (i, "ip6"))
6445         is_ipv6 = 1;
6446       else
6447         break;
6448     }
6449
6450   if (sw_if_index_set == 0)
6451     {
6452       errmsg ("missing interface name or sw_if_index");
6453       return -99;
6454     }
6455
6456   /* Construct the API message */
6457   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6458
6459   mp->sw_if_index = ntohl (sw_if_index);
6460   mp->enable = is_enable;
6461   mp->is_ipv6 = is_ipv6;
6462
6463   /* send it... */
6464   S (mp);
6465
6466   /* Wait for a reply... */
6467   W (ret);
6468   return ret;
6469 }
6470
6471 static int
6472 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6473 {
6474   unformat_input_t *i = vam->input;
6475   vl_api_sw_interface_set_geneve_bypass_t *mp;
6476   u32 sw_if_index = 0;
6477   u8 sw_if_index_set = 0;
6478   u8 is_enable = 1;
6479   u8 is_ipv6 = 0;
6480   int ret;
6481
6482   /* Parse args required to build the message */
6483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6484     {
6485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6486         sw_if_index_set = 1;
6487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6488         sw_if_index_set = 1;
6489       else if (unformat (i, "enable"))
6490         is_enable = 1;
6491       else if (unformat (i, "disable"))
6492         is_enable = 0;
6493       else if (unformat (i, "ip4"))
6494         is_ipv6 = 0;
6495       else if (unformat (i, "ip6"))
6496         is_ipv6 = 1;
6497       else
6498         break;
6499     }
6500
6501   if (sw_if_index_set == 0)
6502     {
6503       errmsg ("missing interface name or sw_if_index");
6504       return -99;
6505     }
6506
6507   /* Construct the API message */
6508   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6509
6510   mp->sw_if_index = ntohl (sw_if_index);
6511   mp->enable = is_enable;
6512   mp->is_ipv6 = is_ipv6;
6513
6514   /* send it... */
6515   S (mp);
6516
6517   /* Wait for a reply... */
6518   W (ret);
6519   return ret;
6520 }
6521
6522 static int
6523 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6524 {
6525   unformat_input_t *i = vam->input;
6526   vl_api_sw_interface_set_l2_xconnect_t *mp;
6527   u32 rx_sw_if_index;
6528   u8 rx_sw_if_index_set = 0;
6529   u32 tx_sw_if_index;
6530   u8 tx_sw_if_index_set = 0;
6531   u8 enable = 1;
6532   int ret;
6533
6534   /* Parse args required to build the message */
6535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6536     {
6537       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6538         rx_sw_if_index_set = 1;
6539       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6540         tx_sw_if_index_set = 1;
6541       else if (unformat (i, "rx"))
6542         {
6543           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6544             {
6545               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6546                             &rx_sw_if_index))
6547                 rx_sw_if_index_set = 1;
6548             }
6549           else
6550             break;
6551         }
6552       else if (unformat (i, "tx"))
6553         {
6554           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6555             {
6556               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6557                             &tx_sw_if_index))
6558                 tx_sw_if_index_set = 1;
6559             }
6560           else
6561             break;
6562         }
6563       else if (unformat (i, "enable"))
6564         enable = 1;
6565       else if (unformat (i, "disable"))
6566         enable = 0;
6567       else
6568         break;
6569     }
6570
6571   if (rx_sw_if_index_set == 0)
6572     {
6573       errmsg ("missing rx interface name or rx_sw_if_index");
6574       return -99;
6575     }
6576
6577   if (enable && (tx_sw_if_index_set == 0))
6578     {
6579       errmsg ("missing tx interface name or tx_sw_if_index");
6580       return -99;
6581     }
6582
6583   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6584
6585   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6586   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6587   mp->enable = enable;
6588
6589   S (mp);
6590   W (ret);
6591   return ret;
6592 }
6593
6594 static int
6595 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6596 {
6597   unformat_input_t *i = vam->input;
6598   vl_api_sw_interface_set_l2_bridge_t *mp;
6599   vl_api_l2_port_type_t port_type;
6600   u32 rx_sw_if_index;
6601   u8 rx_sw_if_index_set = 0;
6602   u32 bd_id;
6603   u8 bd_id_set = 0;
6604   u32 shg = 0;
6605   u8 enable = 1;
6606   int ret;
6607
6608   port_type = L2_API_PORT_TYPE_NORMAL;
6609
6610   /* Parse args required to build the message */
6611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6612     {
6613       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6614         rx_sw_if_index_set = 1;
6615       else if (unformat (i, "bd_id %d", &bd_id))
6616         bd_id_set = 1;
6617       else
6618         if (unformat
6619             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6620         rx_sw_if_index_set = 1;
6621       else if (unformat (i, "shg %d", &shg))
6622         ;
6623       else if (unformat (i, "bvi"))
6624         port_type = L2_API_PORT_TYPE_BVI;
6625       else if (unformat (i, "uu-fwd"))
6626         port_type = L2_API_PORT_TYPE_UU_FWD;
6627       else if (unformat (i, "enable"))
6628         enable = 1;
6629       else if (unformat (i, "disable"))
6630         enable = 0;
6631       else
6632         break;
6633     }
6634
6635   if (rx_sw_if_index_set == 0)
6636     {
6637       errmsg ("missing rx interface name or sw_if_index");
6638       return -99;
6639     }
6640
6641   if (enable && (bd_id_set == 0))
6642     {
6643       errmsg ("missing bridge domain");
6644       return -99;
6645     }
6646
6647   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6648
6649   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6650   mp->bd_id = ntohl (bd_id);
6651   mp->shg = (u8) shg;
6652   mp->port_type = ntohl (port_type);
6653   mp->enable = enable;
6654
6655   S (mp);
6656   W (ret);
6657   return ret;
6658 }
6659
6660 static int
6661 api_bridge_domain_dump (vat_main_t * vam)
6662 {
6663   unformat_input_t *i = vam->input;
6664   vl_api_bridge_domain_dump_t *mp;
6665   vl_api_control_ping_t *mp_ping;
6666   u32 bd_id = ~0;
6667   int ret;
6668
6669   /* Parse args required to build the message */
6670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6671     {
6672       if (unformat (i, "bd_id %d", &bd_id))
6673         ;
6674       else
6675         break;
6676     }
6677
6678   M (BRIDGE_DOMAIN_DUMP, mp);
6679   mp->bd_id = ntohl (bd_id);
6680   S (mp);
6681
6682   /* Use a control ping for synchronization */
6683   MPING (CONTROL_PING, mp_ping);
6684   S (mp_ping);
6685
6686   W (ret);
6687   return ret;
6688 }
6689
6690 static int
6691 api_bridge_domain_add_del (vat_main_t * vam)
6692 {
6693   unformat_input_t *i = vam->input;
6694   vl_api_bridge_domain_add_del_t *mp;
6695   u32 bd_id = ~0;
6696   u8 is_add = 1;
6697   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6698   u8 *bd_tag = NULL;
6699   u32 mac_age = 0;
6700   int ret;
6701
6702   /* Parse args required to build the message */
6703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6704     {
6705       if (unformat (i, "bd_id %d", &bd_id))
6706         ;
6707       else if (unformat (i, "flood %d", &flood))
6708         ;
6709       else if (unformat (i, "uu-flood %d", &uu_flood))
6710         ;
6711       else if (unformat (i, "forward %d", &forward))
6712         ;
6713       else if (unformat (i, "learn %d", &learn))
6714         ;
6715       else if (unformat (i, "arp-term %d", &arp_term))
6716         ;
6717       else if (unformat (i, "mac-age %d", &mac_age))
6718         ;
6719       else if (unformat (i, "bd-tag %s", &bd_tag))
6720         ;
6721       else if (unformat (i, "del"))
6722         {
6723           is_add = 0;
6724           flood = uu_flood = forward = learn = 0;
6725         }
6726       else
6727         break;
6728     }
6729
6730   if (bd_id == ~0)
6731     {
6732       errmsg ("missing bridge domain");
6733       ret = -99;
6734       goto done;
6735     }
6736
6737   if (mac_age > 255)
6738     {
6739       errmsg ("mac age must be less than 256 ");
6740       ret = -99;
6741       goto done;
6742     }
6743
6744   if ((bd_tag) && (vec_len (bd_tag) > 63))
6745     {
6746       errmsg ("bd-tag cannot be longer than 63");
6747       ret = -99;
6748       goto done;
6749     }
6750
6751   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6752
6753   mp->bd_id = ntohl (bd_id);
6754   mp->flood = flood;
6755   mp->uu_flood = uu_flood;
6756   mp->forward = forward;
6757   mp->learn = learn;
6758   mp->arp_term = arp_term;
6759   mp->is_add = is_add;
6760   mp->mac_age = (u8) mac_age;
6761   if (bd_tag)
6762     {
6763       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6764       mp->bd_tag[vec_len (bd_tag)] = 0;
6765     }
6766   S (mp);
6767   W (ret);
6768
6769 done:
6770   vec_free (bd_tag);
6771   return ret;
6772 }
6773
6774 static int
6775 api_l2fib_flush_bd (vat_main_t * vam)
6776 {
6777   unformat_input_t *i = vam->input;
6778   vl_api_l2fib_flush_bd_t *mp;
6779   u32 bd_id = ~0;
6780   int ret;
6781
6782   /* Parse args required to build the message */
6783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6784     {
6785       if (unformat (i, "bd_id %d", &bd_id));
6786       else
6787         break;
6788     }
6789
6790   if (bd_id == ~0)
6791     {
6792       errmsg ("missing bridge domain");
6793       return -99;
6794     }
6795
6796   M (L2FIB_FLUSH_BD, mp);
6797
6798   mp->bd_id = htonl (bd_id);
6799
6800   S (mp);
6801   W (ret);
6802   return ret;
6803 }
6804
6805 static int
6806 api_l2fib_flush_int (vat_main_t * vam)
6807 {
6808   unformat_input_t *i = vam->input;
6809   vl_api_l2fib_flush_int_t *mp;
6810   u32 sw_if_index = ~0;
6811   int ret;
6812
6813   /* Parse args required to build the message */
6814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6815     {
6816       if (unformat (i, "sw_if_index %d", &sw_if_index));
6817       else
6818         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6819       else
6820         break;
6821     }
6822
6823   if (sw_if_index == ~0)
6824     {
6825       errmsg ("missing interface name or sw_if_index");
6826       return -99;
6827     }
6828
6829   M (L2FIB_FLUSH_INT, mp);
6830
6831   mp->sw_if_index = ntohl (sw_if_index);
6832
6833   S (mp);
6834   W (ret);
6835   return ret;
6836 }
6837
6838 static int
6839 api_l2fib_add_del (vat_main_t * vam)
6840 {
6841   unformat_input_t *i = vam->input;
6842   vl_api_l2fib_add_del_t *mp;
6843   f64 timeout;
6844   u8 mac[6] = { 0 };
6845   u8 mac_set = 0;
6846   u32 bd_id;
6847   u8 bd_id_set = 0;
6848   u32 sw_if_index = 0;
6849   u8 sw_if_index_set = 0;
6850   u8 is_add = 1;
6851   u8 static_mac = 0;
6852   u8 filter_mac = 0;
6853   u8 bvi_mac = 0;
6854   int count = 1;
6855   f64 before = 0;
6856   int j;
6857
6858   /* Parse args required to build the message */
6859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6860     {
6861       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6862         mac_set = 1;
6863       else if (unformat (i, "bd_id %d", &bd_id))
6864         bd_id_set = 1;
6865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6866         sw_if_index_set = 1;
6867       else if (unformat (i, "sw_if"))
6868         {
6869           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6870             {
6871               if (unformat
6872                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6873                 sw_if_index_set = 1;
6874             }
6875           else
6876             break;
6877         }
6878       else if (unformat (i, "static"))
6879         static_mac = 1;
6880       else if (unformat (i, "filter"))
6881         {
6882           filter_mac = 1;
6883           static_mac = 1;
6884         }
6885       else if (unformat (i, "bvi"))
6886         {
6887           bvi_mac = 1;
6888           static_mac = 1;
6889         }
6890       else if (unformat (i, "del"))
6891         is_add = 0;
6892       else if (unformat (i, "count %d", &count))
6893         ;
6894       else
6895         break;
6896     }
6897
6898   if (mac_set == 0)
6899     {
6900       errmsg ("missing mac address");
6901       return -99;
6902     }
6903
6904   if (bd_id_set == 0)
6905     {
6906       errmsg ("missing bridge domain");
6907       return -99;
6908     }
6909
6910   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6911     {
6912       errmsg ("missing interface name or sw_if_index");
6913       return -99;
6914     }
6915
6916   if (count > 1)
6917     {
6918       /* Turn on async mode */
6919       vam->async_mode = 1;
6920       vam->async_errors = 0;
6921       before = vat_time_now (vam);
6922     }
6923
6924   for (j = 0; j < count; j++)
6925     {
6926       M (L2FIB_ADD_DEL, mp);
6927
6928       clib_memcpy (mp->mac, mac, 6);
6929       mp->bd_id = ntohl (bd_id);
6930       mp->is_add = is_add;
6931       mp->sw_if_index = ntohl (sw_if_index);
6932
6933       if (is_add)
6934         {
6935           mp->static_mac = static_mac;
6936           mp->filter_mac = filter_mac;
6937           mp->bvi_mac = bvi_mac;
6938         }
6939       increment_mac_address (mac);
6940       /* send it... */
6941       S (mp);
6942     }
6943
6944   if (count > 1)
6945     {
6946       vl_api_control_ping_t *mp_ping;
6947       f64 after;
6948
6949       /* Shut off async mode */
6950       vam->async_mode = 0;
6951
6952       MPING (CONTROL_PING, mp_ping);
6953       S (mp_ping);
6954
6955       timeout = vat_time_now (vam) + 1.0;
6956       while (vat_time_now (vam) < timeout)
6957         if (vam->result_ready == 1)
6958           goto out;
6959       vam->retval = -99;
6960
6961     out:
6962       if (vam->retval == -99)
6963         errmsg ("timeout");
6964
6965       if (vam->async_errors > 0)
6966         {
6967           errmsg ("%d asynchronous errors", vam->async_errors);
6968           vam->retval = -98;
6969         }
6970       vam->async_errors = 0;
6971       after = vat_time_now (vam);
6972
6973       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6974              count, after - before, count / (after - before));
6975     }
6976   else
6977     {
6978       int ret;
6979
6980       /* Wait for a reply... */
6981       W (ret);
6982       return ret;
6983     }
6984   /* Return the good/bad news */
6985   return (vam->retval);
6986 }
6987
6988 static int
6989 api_bridge_domain_set_mac_age (vat_main_t * vam)
6990 {
6991   unformat_input_t *i = vam->input;
6992   vl_api_bridge_domain_set_mac_age_t *mp;
6993   u32 bd_id = ~0;
6994   u32 mac_age = 0;
6995   int ret;
6996
6997   /* Parse args required to build the message */
6998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6999     {
7000       if (unformat (i, "bd_id %d", &bd_id));
7001       else if (unformat (i, "mac-age %d", &mac_age));
7002       else
7003         break;
7004     }
7005
7006   if (bd_id == ~0)
7007     {
7008       errmsg ("missing bridge domain");
7009       return -99;
7010     }
7011
7012   if (mac_age > 255)
7013     {
7014       errmsg ("mac age must be less than 256 ");
7015       return -99;
7016     }
7017
7018   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7019
7020   mp->bd_id = htonl (bd_id);
7021   mp->mac_age = (u8) mac_age;
7022
7023   S (mp);
7024   W (ret);
7025   return ret;
7026 }
7027
7028 static int
7029 api_l2_flags (vat_main_t * vam)
7030 {
7031   unformat_input_t *i = vam->input;
7032   vl_api_l2_flags_t *mp;
7033   u32 sw_if_index;
7034   u32 flags = 0;
7035   u8 sw_if_index_set = 0;
7036   u8 is_set = 0;
7037   int ret;
7038
7039   /* Parse args required to build the message */
7040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7041     {
7042       if (unformat (i, "sw_if_index %d", &sw_if_index))
7043         sw_if_index_set = 1;
7044       else if (unformat (i, "sw_if"))
7045         {
7046           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7047             {
7048               if (unformat
7049                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7050                 sw_if_index_set = 1;
7051             }
7052           else
7053             break;
7054         }
7055       else if (unformat (i, "learn"))
7056         flags |= L2_LEARN;
7057       else if (unformat (i, "forward"))
7058         flags |= L2_FWD;
7059       else if (unformat (i, "flood"))
7060         flags |= L2_FLOOD;
7061       else if (unformat (i, "uu-flood"))
7062         flags |= L2_UU_FLOOD;
7063       else if (unformat (i, "arp-term"))
7064         flags |= L2_ARP_TERM;
7065       else if (unformat (i, "off"))
7066         is_set = 0;
7067       else if (unformat (i, "disable"))
7068         is_set = 0;
7069       else
7070         break;
7071     }
7072
7073   if (sw_if_index_set == 0)
7074     {
7075       errmsg ("missing interface name or sw_if_index");
7076       return -99;
7077     }
7078
7079   M (L2_FLAGS, mp);
7080
7081   mp->sw_if_index = ntohl (sw_if_index);
7082   mp->feature_bitmap = ntohl (flags);
7083   mp->is_set = is_set;
7084
7085   S (mp);
7086   W (ret);
7087   return ret;
7088 }
7089
7090 static int
7091 api_bridge_flags (vat_main_t * vam)
7092 {
7093   unformat_input_t *i = vam->input;
7094   vl_api_bridge_flags_t *mp;
7095   u32 bd_id;
7096   u8 bd_id_set = 0;
7097   u8 is_set = 1;
7098   bd_flags_t flags = 0;
7099   int ret;
7100
7101   /* Parse args required to build the message */
7102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7103     {
7104       if (unformat (i, "bd_id %d", &bd_id))
7105         bd_id_set = 1;
7106       else if (unformat (i, "learn"))
7107         flags |= BRIDGE_API_FLAG_LEARN;
7108       else if (unformat (i, "forward"))
7109         flags |= BRIDGE_API_FLAG_FWD;
7110       else if (unformat (i, "flood"))
7111         flags |= BRIDGE_API_FLAG_FLOOD;
7112       else if (unformat (i, "uu-flood"))
7113         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7114       else if (unformat (i, "arp-term"))
7115         flags |= BRIDGE_API_FLAG_ARP_TERM;
7116       else if (unformat (i, "off"))
7117         is_set = 0;
7118       else if (unformat (i, "disable"))
7119         is_set = 0;
7120       else
7121         break;
7122     }
7123
7124   if (bd_id_set == 0)
7125     {
7126       errmsg ("missing bridge domain");
7127       return -99;
7128     }
7129
7130   M (BRIDGE_FLAGS, mp);
7131
7132   mp->bd_id = ntohl (bd_id);
7133   mp->flags = ntohl (flags);
7134   mp->is_set = is_set;
7135
7136   S (mp);
7137   W (ret);
7138   return ret;
7139 }
7140
7141 static int
7142 api_bd_ip_mac_add_del (vat_main_t * vam)
7143 {
7144   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7145   vl_api_mac_address_t mac = { 0 };
7146   unformat_input_t *i = vam->input;
7147   vl_api_bd_ip_mac_add_del_t *mp;
7148   u32 bd_id;
7149   u8 is_add = 1;
7150   u8 bd_id_set = 0;
7151   u8 ip_set = 0;
7152   u8 mac_set = 0;
7153   int ret;
7154
7155
7156   /* Parse args required to build the message */
7157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7158     {
7159       if (unformat (i, "bd_id %d", &bd_id))
7160         {
7161           bd_id_set++;
7162         }
7163       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7164         {
7165           ip_set++;
7166         }
7167       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7168         {
7169           mac_set++;
7170         }
7171       else if (unformat (i, "del"))
7172         is_add = 0;
7173       else
7174         break;
7175     }
7176
7177   if (bd_id_set == 0)
7178     {
7179       errmsg ("missing bridge domain");
7180       return -99;
7181     }
7182   else if (ip_set == 0)
7183     {
7184       errmsg ("missing IP address");
7185       return -99;
7186     }
7187   else if (mac_set == 0)
7188     {
7189       errmsg ("missing MAC address");
7190       return -99;
7191     }
7192
7193   M (BD_IP_MAC_ADD_DEL, mp);
7194
7195   mp->entry.bd_id = ntohl (bd_id);
7196   mp->is_add = is_add;
7197
7198   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7199   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7200
7201   S (mp);
7202   W (ret);
7203   return ret;
7204 }
7205
7206 static int
7207 api_bd_ip_mac_flush (vat_main_t * vam)
7208 {
7209   unformat_input_t *i = vam->input;
7210   vl_api_bd_ip_mac_flush_t *mp;
7211   u32 bd_id;
7212   u8 bd_id_set = 0;
7213   int ret;
7214
7215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7216     {
7217       if (unformat (i, "bd_id %d", &bd_id))
7218         {
7219           bd_id_set++;
7220         }
7221       else
7222         break;
7223     }
7224
7225   if (bd_id_set == 0)
7226     {
7227       errmsg ("missing bridge domain");
7228       return -99;
7229     }
7230
7231   M (BD_IP_MAC_FLUSH, mp);
7232
7233   mp->bd_id = ntohl (bd_id);
7234
7235   S (mp);
7236   W (ret);
7237   return ret;
7238 }
7239
7240 static void vl_api_bd_ip_mac_details_t_handler
7241   (vl_api_bd_ip_mac_details_t * mp)
7242 {
7243   vat_main_t *vam = &vat_main;
7244
7245   print (vam->ofp,
7246          "\n%-5d %U %U",
7247          ntohl (mp->entry.bd_id),
7248          format_vl_api_mac_address, mp->entry.mac,
7249          format_vl_api_address, &mp->entry.ip);
7250 }
7251
7252 static void vl_api_bd_ip_mac_details_t_handler_json
7253   (vl_api_bd_ip_mac_details_t * mp)
7254 {
7255   vat_main_t *vam = &vat_main;
7256   vat_json_node_t *node = NULL;
7257
7258   if (VAT_JSON_ARRAY != vam->json_tree.type)
7259     {
7260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7261       vat_json_init_array (&vam->json_tree);
7262     }
7263   node = vat_json_array_add (&vam->json_tree);
7264
7265   vat_json_init_object (node);
7266   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7267   vat_json_object_add_string_copy (node, "mac_address",
7268                                    format (0, "%U", format_vl_api_mac_address,
7269                                            &mp->entry.mac));
7270   u8 *ip = 0;
7271
7272   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7273   vat_json_object_add_string_copy (node, "ip_address", ip);
7274   vec_free (ip);
7275 }
7276
7277 static int
7278 api_bd_ip_mac_dump (vat_main_t * vam)
7279 {
7280   unformat_input_t *i = vam->input;
7281   vl_api_bd_ip_mac_dump_t *mp;
7282   vl_api_control_ping_t *mp_ping;
7283   int ret;
7284   u32 bd_id;
7285   u8 bd_id_set = 0;
7286
7287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7288     {
7289       if (unformat (i, "bd_id %d", &bd_id))
7290         {
7291           bd_id_set++;
7292         }
7293       else
7294         break;
7295     }
7296
7297   print (vam->ofp,
7298          "\n%-5s %-7s %-20s %-30s",
7299          "bd_id", "is_ipv6", "mac_address", "ip_address");
7300
7301   /* Dump Bridge Domain Ip to Mac entries */
7302   M (BD_IP_MAC_DUMP, mp);
7303
7304   if (bd_id_set)
7305     mp->bd_id = htonl (bd_id);
7306   else
7307     mp->bd_id = ~0;
7308
7309   S (mp);
7310
7311   /* Use a control ping for synchronization */
7312   MPING (CONTROL_PING, mp_ping);
7313   S (mp_ping);
7314
7315   W (ret);
7316   return ret;
7317 }
7318
7319 static int
7320 api_tap_create_v2 (vat_main_t * vam)
7321 {
7322   unformat_input_t *i = vam->input;
7323   vl_api_tap_create_v2_t *mp;
7324 #define TAP_FLAG_GSO (1 << 0)
7325   u8 mac_address[6];
7326   u8 random_mac = 1;
7327   u32 id = ~0;
7328   u8 *host_if_name = 0;
7329   u8 *host_ns = 0;
7330   u8 host_mac_addr[6];
7331   u8 host_mac_addr_set = 0;
7332   u8 *host_bridge = 0;
7333   ip4_address_t host_ip4_addr;
7334   ip4_address_t host_ip4_gw;
7335   u8 host_ip4_gw_set = 0;
7336   u32 host_ip4_prefix_len = 0;
7337   ip6_address_t host_ip6_addr;
7338   ip6_address_t host_ip6_gw;
7339   u8 host_ip6_gw_set = 0;
7340   u32 host_ip6_prefix_len = 0;
7341   u8 host_mtu_set = 0;
7342   u32 host_mtu_size = 0;
7343   u32 tap_flags = 0;
7344   int ret;
7345   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7346
7347   clib_memset (mac_address, 0, sizeof (mac_address));
7348
7349   /* Parse args required to build the message */
7350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7351     {
7352       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7353         {
7354           random_mac = 0;
7355         }
7356       else if (unformat (i, "id %u", &id))
7357         ;
7358       else if (unformat (i, "host-if-name %s", &host_if_name))
7359         ;
7360       else if (unformat (i, "host-ns %s", &host_ns))
7361         ;
7362       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7363                          host_mac_addr))
7364         host_mac_addr_set = 1;
7365       else if (unformat (i, "host-bridge %s", &host_bridge))
7366         ;
7367       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7368                          &host_ip4_addr, &host_ip4_prefix_len))
7369         ;
7370       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7371                          &host_ip6_addr, &host_ip6_prefix_len))
7372         ;
7373       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7374                          &host_ip4_gw))
7375         host_ip4_gw_set = 1;
7376       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7377                          &host_ip6_gw))
7378         host_ip6_gw_set = 1;
7379       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7380         ;
7381       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7382         ;
7383       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7384         host_mtu_set = 1;
7385       else if (unformat (i, "no-gso"))
7386         tap_flags &= ~TAP_FLAG_GSO;
7387       else if (unformat (i, "gso"))
7388         tap_flags |= TAP_FLAG_GSO;
7389       else
7390         break;
7391     }
7392
7393   if (vec_len (host_if_name) > 63)
7394     {
7395       errmsg ("tap name too long. ");
7396       return -99;
7397     }
7398   if (vec_len (host_ns) > 63)
7399     {
7400       errmsg ("host name space too long. ");
7401       return -99;
7402     }
7403   if (vec_len (host_bridge) > 63)
7404     {
7405       errmsg ("host bridge name too long. ");
7406       return -99;
7407     }
7408   if (host_ip4_prefix_len > 32)
7409     {
7410       errmsg ("host ip4 prefix length not valid. ");
7411       return -99;
7412     }
7413   if (host_ip6_prefix_len > 128)
7414     {
7415       errmsg ("host ip6 prefix length not valid. ");
7416       return -99;
7417     }
7418   if (!is_pow2 (rx_ring_sz))
7419     {
7420       errmsg ("rx ring size must be power of 2. ");
7421       return -99;
7422     }
7423   if (rx_ring_sz > 32768)
7424     {
7425       errmsg ("rx ring size must be 32768 or lower. ");
7426       return -99;
7427     }
7428   if (!is_pow2 (tx_ring_sz))
7429     {
7430       errmsg ("tx ring size must be power of 2. ");
7431       return -99;
7432     }
7433   if (tx_ring_sz > 32768)
7434     {
7435       errmsg ("tx ring size must be 32768 or lower. ");
7436       return -99;
7437     }
7438   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7439     {
7440       errmsg ("host MTU size must be in between 64 and 65355. ");
7441       return -99;
7442     }
7443
7444   /* Construct the API message */
7445   M (TAP_CREATE_V2, mp);
7446
7447   mp->use_random_mac = random_mac;
7448
7449   mp->id = ntohl (id);
7450   mp->host_namespace_set = host_ns != 0;
7451   mp->host_bridge_set = host_bridge != 0;
7452   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7453   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7454   mp->rx_ring_sz = ntohs (rx_ring_sz);
7455   mp->tx_ring_sz = ntohs (tx_ring_sz);
7456   mp->host_mtu_set = host_mtu_set;
7457   mp->host_mtu_size = ntohl (host_mtu_size);
7458   mp->tap_flags = ntohl (tap_flags);
7459
7460   if (random_mac == 0)
7461     clib_memcpy (mp->mac_address, mac_address, 6);
7462   if (host_mac_addr_set)
7463     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7464   if (host_if_name)
7465     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7466   if (host_ns)
7467     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7468   if (host_bridge)
7469     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7470   if (host_ip4_prefix_len)
7471     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7472   if (host_ip6_prefix_len)
7473     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7474   if (host_ip4_gw_set)
7475     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7476   if (host_ip6_gw_set)
7477     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7478
7479   vec_free (host_ns);
7480   vec_free (host_if_name);
7481   vec_free (host_bridge);
7482
7483   /* send it... */
7484   S (mp);
7485
7486   /* Wait for a reply... */
7487   W (ret);
7488   return ret;
7489 }
7490
7491 static int
7492 api_tap_delete_v2 (vat_main_t * vam)
7493 {
7494   unformat_input_t *i = vam->input;
7495   vl_api_tap_delete_v2_t *mp;
7496   u32 sw_if_index = ~0;
7497   u8 sw_if_index_set = 0;
7498   int ret;
7499
7500   /* Parse args required to build the message */
7501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7502     {
7503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7504         sw_if_index_set = 1;
7505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7506         sw_if_index_set = 1;
7507       else
7508         break;
7509     }
7510
7511   if (sw_if_index_set == 0)
7512     {
7513       errmsg ("missing vpp interface name. ");
7514       return -99;
7515     }
7516
7517   /* Construct the API message */
7518   M (TAP_DELETE_V2, mp);
7519
7520   mp->sw_if_index = ntohl (sw_if_index);
7521
7522   /* send it... */
7523   S (mp);
7524
7525   /* Wait for a reply... */
7526   W (ret);
7527   return ret;
7528 }
7529
7530 uword
7531 unformat_pci_addr (unformat_input_t * input, va_list * args)
7532 {
7533   struct pci_addr_t
7534   {
7535     u16 domain;
7536     u8 bus;
7537     u8 slot:5;
7538     u8 function:3;
7539   } *addr;
7540   addr = va_arg (*args, struct pci_addr_t *);
7541   u32 x[4];
7542
7543   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7544     return 0;
7545
7546   addr->domain = x[0];
7547   addr->bus = x[1];
7548   addr->slot = x[2];
7549   addr->function = x[3];
7550
7551   return 1;
7552 }
7553
7554 static int
7555 api_virtio_pci_create (vat_main_t * vam)
7556 {
7557   unformat_input_t *i = vam->input;
7558   vl_api_virtio_pci_create_t *mp;
7559   u8 mac_address[6];
7560   u8 random_mac = 1;
7561   u8 gso_enabled = 0;
7562   u32 pci_addr = 0;
7563   u64 features = (u64) ~ (0ULL);
7564   int ret;
7565
7566   clib_memset (mac_address, 0, sizeof (mac_address));
7567
7568   /* Parse args required to build the message */
7569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7570     {
7571       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7572         {
7573           random_mac = 0;
7574         }
7575       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7576         ;
7577       else if (unformat (i, "features 0x%llx", &features))
7578         ;
7579       else if (unformat (i, "gso-enabled"))
7580         gso_enabled = 1;
7581       else
7582         break;
7583     }
7584
7585   if (pci_addr == 0)
7586     {
7587       errmsg ("pci address must be non zero. ");
7588       return -99;
7589     }
7590
7591   /* Construct the API message */
7592   M (VIRTIO_PCI_CREATE, mp);
7593
7594   mp->use_random_mac = random_mac;
7595
7596   mp->pci_addr = htonl (pci_addr);
7597   mp->features = clib_host_to_net_u64 (features);
7598   mp->gso_enabled = gso_enabled;
7599
7600   if (random_mac == 0)
7601     clib_memcpy (mp->mac_address, mac_address, 6);
7602
7603   /* send it... */
7604   S (mp);
7605
7606   /* Wait for a reply... */
7607   W (ret);
7608   return ret;
7609 }
7610
7611 static int
7612 api_virtio_pci_delete (vat_main_t * vam)
7613 {
7614   unformat_input_t *i = vam->input;
7615   vl_api_virtio_pci_delete_t *mp;
7616   u32 sw_if_index = ~0;
7617   u8 sw_if_index_set = 0;
7618   int ret;
7619
7620   /* Parse args required to build the message */
7621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7622     {
7623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7624         sw_if_index_set = 1;
7625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7626         sw_if_index_set = 1;
7627       else
7628         break;
7629     }
7630
7631   if (sw_if_index_set == 0)
7632     {
7633       errmsg ("missing vpp interface name. ");
7634       return -99;
7635     }
7636
7637   /* Construct the API message */
7638   M (VIRTIO_PCI_DELETE, mp);
7639
7640   mp->sw_if_index = htonl (sw_if_index);
7641
7642   /* send it... */
7643   S (mp);
7644
7645   /* Wait for a reply... */
7646   W (ret);
7647   return ret;
7648 }
7649
7650 static int
7651 api_bond_create (vat_main_t * vam)
7652 {
7653   unformat_input_t *i = vam->input;
7654   vl_api_bond_create_t *mp;
7655   u8 mac_address[6];
7656   u8 custom_mac = 0;
7657   int ret;
7658   u8 mode;
7659   u8 lb;
7660   u8 mode_is_set = 0;
7661   u32 id = ~0;
7662   u8 numa_only = 0;
7663
7664   clib_memset (mac_address, 0, sizeof (mac_address));
7665   lb = BOND_LB_L2;
7666
7667   /* Parse args required to build the message */
7668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7671         mode_is_set = 1;
7672       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7673                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7674         ;
7675       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7676                          mac_address))
7677         custom_mac = 1;
7678       else if (unformat (i, "numa-only"))
7679         numa_only = 1;
7680       else if (unformat (i, "id %u", &id))
7681         ;
7682       else
7683         break;
7684     }
7685
7686   if (mode_is_set == 0)
7687     {
7688       errmsg ("Missing bond mode. ");
7689       return -99;
7690     }
7691
7692   /* Construct the API message */
7693   M (BOND_CREATE, mp);
7694
7695   mp->use_custom_mac = custom_mac;
7696
7697   mp->mode = mode;
7698   mp->lb = lb;
7699   mp->id = htonl (id);
7700   mp->numa_only = numa_only;
7701
7702   if (custom_mac)
7703     clib_memcpy (mp->mac_address, mac_address, 6);
7704
7705   /* send it... */
7706   S (mp);
7707
7708   /* Wait for a reply... */
7709   W (ret);
7710   return ret;
7711 }
7712
7713 static int
7714 api_bond_delete (vat_main_t * vam)
7715 {
7716   unformat_input_t *i = vam->input;
7717   vl_api_bond_delete_t *mp;
7718   u32 sw_if_index = ~0;
7719   u8 sw_if_index_set = 0;
7720   int ret;
7721
7722   /* Parse args required to build the message */
7723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7724     {
7725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7726         sw_if_index_set = 1;
7727       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7728         sw_if_index_set = 1;
7729       else
7730         break;
7731     }
7732
7733   if (sw_if_index_set == 0)
7734     {
7735       errmsg ("missing vpp interface name. ");
7736       return -99;
7737     }
7738
7739   /* Construct the API message */
7740   M (BOND_DELETE, mp);
7741
7742   mp->sw_if_index = ntohl (sw_if_index);
7743
7744   /* send it... */
7745   S (mp);
7746
7747   /* Wait for a reply... */
7748   W (ret);
7749   return ret;
7750 }
7751
7752 static int
7753 api_bond_enslave (vat_main_t * vam)
7754 {
7755   unformat_input_t *i = vam->input;
7756   vl_api_bond_enslave_t *mp;
7757   u32 bond_sw_if_index;
7758   int ret;
7759   u8 is_passive;
7760   u8 is_long_timeout;
7761   u32 bond_sw_if_index_is_set = 0;
7762   u32 sw_if_index;
7763   u8 sw_if_index_is_set = 0;
7764
7765   /* Parse args required to build the message */
7766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7767     {
7768       if (unformat (i, "sw_if_index %d", &sw_if_index))
7769         sw_if_index_is_set = 1;
7770       else if (unformat (i, "bond %u", &bond_sw_if_index))
7771         bond_sw_if_index_is_set = 1;
7772       else if (unformat (i, "passive %d", &is_passive))
7773         ;
7774       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7775         ;
7776       else
7777         break;
7778     }
7779
7780   if (bond_sw_if_index_is_set == 0)
7781     {
7782       errmsg ("Missing bond sw_if_index. ");
7783       return -99;
7784     }
7785   if (sw_if_index_is_set == 0)
7786     {
7787       errmsg ("Missing slave sw_if_index. ");
7788       return -99;
7789     }
7790
7791   /* Construct the API message */
7792   M (BOND_ENSLAVE, mp);
7793
7794   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7795   mp->sw_if_index = ntohl (sw_if_index);
7796   mp->is_long_timeout = is_long_timeout;
7797   mp->is_passive = is_passive;
7798
7799   /* send it... */
7800   S (mp);
7801
7802   /* Wait for a reply... */
7803   W (ret);
7804   return ret;
7805 }
7806
7807 static int
7808 api_bond_detach_slave (vat_main_t * vam)
7809 {
7810   unformat_input_t *i = vam->input;
7811   vl_api_bond_detach_slave_t *mp;
7812   u32 sw_if_index = ~0;
7813   u8 sw_if_index_set = 0;
7814   int ret;
7815
7816   /* Parse args required to build the message */
7817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7818     {
7819       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7820         sw_if_index_set = 1;
7821       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7822         sw_if_index_set = 1;
7823       else
7824         break;
7825     }
7826
7827   if (sw_if_index_set == 0)
7828     {
7829       errmsg ("missing vpp interface name. ");
7830       return -99;
7831     }
7832
7833   /* Construct the API message */
7834   M (BOND_DETACH_SLAVE, mp);
7835
7836   mp->sw_if_index = ntohl (sw_if_index);
7837
7838   /* send it... */
7839   S (mp);
7840
7841   /* Wait for a reply... */
7842   W (ret);
7843   return ret;
7844 }
7845
7846 static int
7847 api_ip_table_add_del (vat_main_t * vam)
7848 {
7849   unformat_input_t *i = vam->input;
7850   vl_api_ip_table_add_del_t *mp;
7851   u32 table_id = ~0;
7852   u8 is_ipv6 = 0;
7853   u8 is_add = 1;
7854   int ret = 0;
7855
7856   /* Parse args required to build the message */
7857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7858     {
7859       if (unformat (i, "ipv6"))
7860         is_ipv6 = 1;
7861       else if (unformat (i, "del"))
7862         is_add = 0;
7863       else if (unformat (i, "add"))
7864         is_add = 1;
7865       else if (unformat (i, "table %d", &table_id))
7866         ;
7867       else
7868         {
7869           clib_warning ("parse error '%U'", format_unformat_error, i);
7870           return -99;
7871         }
7872     }
7873
7874   if (~0 == table_id)
7875     {
7876       errmsg ("missing table-ID");
7877       return -99;
7878     }
7879
7880   /* Construct the API message */
7881   M (IP_TABLE_ADD_DEL, mp);
7882
7883   mp->table.table_id = ntohl (table_id);
7884   mp->table.is_ip6 = is_ipv6;
7885   mp->is_add = is_add;
7886
7887   /* send it... */
7888   S (mp);
7889
7890   /* Wait for a reply... */
7891   W (ret);
7892
7893   return ret;
7894 }
7895
7896 uword
7897 unformat_fib_path (unformat_input_t * input, va_list * args)
7898 {
7899   vat_main_t *vam = va_arg (*args, vat_main_t *);
7900   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7901   u32 weight, preference;
7902   mpls_label_t out_label;
7903
7904   clib_memset (path, 0, sizeof (*path));
7905   path->weight = 1;
7906   path->sw_if_index = ~0;
7907   path->rpf_id = ~0;
7908   path->n_labels = 0;
7909
7910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7911     {
7912       if (unformat (input, "%U %U",
7913                     unformat_vl_api_ip4_address,
7914                     &path->nh.address.ip4,
7915                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7916         {
7917           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7918         }
7919       else if (unformat (input, "%U %U",
7920                          unformat_vl_api_ip6_address,
7921                          &path->nh.address.ip6,
7922                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7923         {
7924           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7925         }
7926       else if (unformat (input, "weight %u", &weight))
7927         {
7928           path->weight = weight;
7929         }
7930       else if (unformat (input, "preference %u", &preference))
7931         {
7932           path->preference = preference;
7933         }
7934       else if (unformat (input, "%U next-hop-table %d",
7935                          unformat_vl_api_ip4_address,
7936                          &path->nh.address.ip4, &path->table_id))
7937         {
7938           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7939         }
7940       else if (unformat (input, "%U next-hop-table %d",
7941                          unformat_vl_api_ip6_address,
7942                          &path->nh.address.ip6, &path->table_id))
7943         {
7944           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7945         }
7946       else if (unformat (input, "%U",
7947                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7948         {
7949           /*
7950            * the recursive next-hops are by default in the default table
7951            */
7952           path->table_id = 0;
7953           path->sw_if_index = ~0;
7954           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7955         }
7956       else if (unformat (input, "%U",
7957                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7958         {
7959           /*
7960            * the recursive next-hops are by default in the default table
7961            */
7962           path->table_id = 0;
7963           path->sw_if_index = ~0;
7964           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7965         }
7966       else if (unformat (input, "resolve-via-host"))
7967         {
7968           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7969         }
7970       else if (unformat (input, "resolve-via-attached"))
7971         {
7972           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7973         }
7974       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7975         {
7976           path->type = FIB_API_PATH_TYPE_LOCAL;
7977           path->sw_if_index = ~0;
7978           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7979         }
7980       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7981         {
7982           path->type = FIB_API_PATH_TYPE_LOCAL;
7983           path->sw_if_index = ~0;
7984           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7985         }
7986       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7987         ;
7988       else if (unformat (input, "via-label %d", &path->nh.via_label))
7989         {
7990           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7991           path->sw_if_index = ~0;
7992         }
7993       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7994         {
7995           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7996           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7997         }
7998       else if (unformat (input, "local"))
7999         {
8000           path->type = FIB_API_PATH_TYPE_LOCAL;
8001         }
8002       else if (unformat (input, "out-labels"))
8003         {
8004           while (unformat (input, "%d", &out_label))
8005             {
8006               path->label_stack[path->n_labels].label = out_label;
8007               path->label_stack[path->n_labels].is_uniform = 0;
8008               path->label_stack[path->n_labels].ttl = 64;
8009               path->n_labels++;
8010             }
8011         }
8012       else if (unformat (input, "via"))
8013         {
8014           /* new path, back up and return */
8015           unformat_put_input (input);
8016           unformat_put_input (input);
8017           unformat_put_input (input);
8018           unformat_put_input (input);
8019           break;
8020         }
8021       else
8022         {
8023           return (0);
8024         }
8025     }
8026
8027   path->proto = ntohl (path->proto);
8028   path->type = ntohl (path->type);
8029   path->flags = ntohl (path->flags);
8030   path->table_id = ntohl (path->table_id);
8031   path->sw_if_index = ntohl (path->sw_if_index);
8032
8033   return (1);
8034 }
8035
8036 static int
8037 api_ip_route_add_del (vat_main_t * vam)
8038 {
8039   unformat_input_t *i = vam->input;
8040   vl_api_ip_route_add_del_t *mp;
8041   u32 vrf_id = 0;
8042   u8 is_add = 1;
8043   u8 is_multipath = 0;
8044   u8 prefix_set = 0;
8045   u8 path_count = 0;
8046   vl_api_prefix_t pfx = { };
8047   vl_api_fib_path_t paths[8];
8048   int count = 1;
8049   int j;
8050   f64 before = 0;
8051   u32 random_add_del = 0;
8052   u32 *random_vector = 0;
8053   u32 random_seed = 0xdeaddabe;
8054
8055   /* Parse args required to build the message */
8056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8057     {
8058       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8059         prefix_set = 1;
8060       else if (unformat (i, "del"))
8061         is_add = 0;
8062       else if (unformat (i, "add"))
8063         is_add = 1;
8064       else if (unformat (i, "vrf %d", &vrf_id))
8065         ;
8066       else if (unformat (i, "count %d", &count))
8067         ;
8068       else if (unformat (i, "random"))
8069         random_add_del = 1;
8070       else if (unformat (i, "multipath"))
8071         is_multipath = 1;
8072       else if (unformat (i, "seed %d", &random_seed))
8073         ;
8074       else
8075         if (unformat
8076             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8077         {
8078           path_count++;
8079           if (8 == path_count)
8080             {
8081               errmsg ("max 8 paths");
8082               return -99;
8083             }
8084         }
8085       else
8086         {
8087           clib_warning ("parse error '%U'", format_unformat_error, i);
8088           return -99;
8089         }
8090     }
8091
8092   if (!path_count)
8093     {
8094       errmsg ("specify a path; via ...");
8095       return -99;
8096     }
8097   if (prefix_set == 0)
8098     {
8099       errmsg ("missing prefix");
8100       return -99;
8101     }
8102
8103   /* Generate a pile of unique, random routes */
8104   if (random_add_del)
8105     {
8106       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8107       u32 this_random_address;
8108       uword *random_hash;
8109
8110       random_hash = hash_create (count, sizeof (uword));
8111
8112       hash_set (random_hash, i->as_u32, 1);
8113       for (j = 0; j <= count; j++)
8114         {
8115           do
8116             {
8117               this_random_address = random_u32 (&random_seed);
8118               this_random_address =
8119                 clib_host_to_net_u32 (this_random_address);
8120             }
8121           while (hash_get (random_hash, this_random_address));
8122           vec_add1 (random_vector, this_random_address);
8123           hash_set (random_hash, this_random_address, 1);
8124         }
8125       hash_free (random_hash);
8126       set_ip4_address (&pfx.address, random_vector[0]);
8127     }
8128
8129   if (count > 1)
8130     {
8131       /* Turn on async mode */
8132       vam->async_mode = 1;
8133       vam->async_errors = 0;
8134       before = vat_time_now (vam);
8135     }
8136
8137   for (j = 0; j < count; j++)
8138     {
8139       /* Construct the API message */
8140       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8141
8142       mp->is_add = is_add;
8143       mp->is_multipath = is_multipath;
8144
8145       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8146       mp->route.table_id = ntohl (vrf_id);
8147       mp->route.n_paths = path_count;
8148
8149       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8150
8151       if (random_add_del)
8152         set_ip4_address (&pfx.address, random_vector[j + 1]);
8153       else
8154         increment_address (&pfx.address);
8155       /* send it... */
8156       S (mp);
8157       /* If we receive SIGTERM, stop now... */
8158       if (vam->do_exit)
8159         break;
8160     }
8161
8162   /* When testing multiple add/del ops, use a control-ping to sync */
8163   if (count > 1)
8164     {
8165       vl_api_control_ping_t *mp_ping;
8166       f64 after;
8167       f64 timeout;
8168
8169       /* Shut off async mode */
8170       vam->async_mode = 0;
8171
8172       MPING (CONTROL_PING, mp_ping);
8173       S (mp_ping);
8174
8175       timeout = vat_time_now (vam) + 1.0;
8176       while (vat_time_now (vam) < timeout)
8177         if (vam->result_ready == 1)
8178           goto out;
8179       vam->retval = -99;
8180
8181     out:
8182       if (vam->retval == -99)
8183         errmsg ("timeout");
8184
8185       if (vam->async_errors > 0)
8186         {
8187           errmsg ("%d asynchronous errors", vam->async_errors);
8188           vam->retval = -98;
8189         }
8190       vam->async_errors = 0;
8191       after = vat_time_now (vam);
8192
8193       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8194       if (j > 0)
8195         count = j;
8196
8197       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8198              count, after - before, count / (after - before));
8199     }
8200   else
8201     {
8202       int ret;
8203
8204       /* Wait for a reply... */
8205       W (ret);
8206       return ret;
8207     }
8208
8209   /* Return the good/bad news */
8210   return (vam->retval);
8211 }
8212
8213 static int
8214 api_ip_mroute_add_del (vat_main_t * vam)
8215 {
8216   unformat_input_t *i = vam->input;
8217   u8 path_set = 0, prefix_set = 0, is_add = 1;
8218   vl_api_ip_mroute_add_del_t *mp;
8219   mfib_entry_flags_t eflags = 0;
8220   vl_api_mfib_path_t path;
8221   vl_api_mprefix_t pfx = { };
8222   u32 vrf_id = 0;
8223   int ret;
8224
8225   /* Parse args required to build the message */
8226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8227     {
8228       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8229         {
8230           prefix_set = 1;
8231           pfx.grp_address_length = htons (pfx.grp_address_length);
8232         }
8233       else if (unformat (i, "del"))
8234         is_add = 0;
8235       else if (unformat (i, "add"))
8236         is_add = 1;
8237       else if (unformat (i, "vrf %d", &vrf_id))
8238         ;
8239       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8240         path.itf_flags = htonl (path.itf_flags);
8241       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8242         ;
8243       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8244         path_set = 1;
8245       else
8246         {
8247           clib_warning ("parse error '%U'", format_unformat_error, i);
8248           return -99;
8249         }
8250     }
8251
8252   if (prefix_set == 0)
8253     {
8254       errmsg ("missing addresses\n");
8255       return -99;
8256     }
8257   if (path_set == 0)
8258     {
8259       errmsg ("missing path\n");
8260       return -99;
8261     }
8262
8263   /* Construct the API message */
8264   M (IP_MROUTE_ADD_DEL, mp);
8265
8266   mp->is_add = is_add;
8267   mp->is_multipath = 1;
8268
8269   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8270   mp->route.table_id = htonl (vrf_id);
8271   mp->route.n_paths = 1;
8272   mp->route.entry_flags = htonl (eflags);
8273
8274   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8275
8276   /* send it... */
8277   S (mp);
8278   /* Wait for a reply... */
8279   W (ret);
8280   return ret;
8281 }
8282
8283 static int
8284 api_mpls_table_add_del (vat_main_t * vam)
8285 {
8286   unformat_input_t *i = vam->input;
8287   vl_api_mpls_table_add_del_t *mp;
8288   u32 table_id = ~0;
8289   u8 is_add = 1;
8290   int ret = 0;
8291
8292   /* Parse args required to build the message */
8293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8294     {
8295       if (unformat (i, "table %d", &table_id))
8296         ;
8297       else if (unformat (i, "del"))
8298         is_add = 0;
8299       else if (unformat (i, "add"))
8300         is_add = 1;
8301       else
8302         {
8303           clib_warning ("parse error '%U'", format_unformat_error, i);
8304           return -99;
8305         }
8306     }
8307
8308   if (~0 == table_id)
8309     {
8310       errmsg ("missing table-ID");
8311       return -99;
8312     }
8313
8314   /* Construct the API message */
8315   M (MPLS_TABLE_ADD_DEL, mp);
8316
8317   mp->mt_table.mt_table_id = ntohl (table_id);
8318   mp->mt_is_add = is_add;
8319
8320   /* send it... */
8321   S (mp);
8322
8323   /* Wait for a reply... */
8324   W (ret);
8325
8326   return ret;
8327 }
8328
8329 static int
8330 api_mpls_route_add_del (vat_main_t * vam)
8331 {
8332   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8333   mpls_label_t local_label = MPLS_LABEL_INVALID;
8334   unformat_input_t *i = vam->input;
8335   vl_api_mpls_route_add_del_t *mp;
8336   vl_api_fib_path_t paths[8];
8337   int count = 1, j;
8338   f64 before = 0;
8339
8340   /* Parse args required to build the message */
8341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8342     {
8343       if (unformat (i, "%d", &local_label))
8344         ;
8345       else if (unformat (i, "eos"))
8346         is_eos = 1;
8347       else if (unformat (i, "non-eos"))
8348         is_eos = 0;
8349       else if (unformat (i, "del"))
8350         is_add = 0;
8351       else if (unformat (i, "add"))
8352         is_add = 1;
8353       else if (unformat (i, "multipath"))
8354         is_multipath = 1;
8355       else if (unformat (i, "count %d", &count))
8356         ;
8357       else
8358         if (unformat
8359             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8360         {
8361           path_count++;
8362           if (8 == path_count)
8363             {
8364               errmsg ("max 8 paths");
8365               return -99;
8366             }
8367         }
8368       else
8369         {
8370           clib_warning ("parse error '%U'", format_unformat_error, i);
8371           return -99;
8372         }
8373     }
8374
8375   if (!path_count)
8376     {
8377       errmsg ("specify a path; via ...");
8378       return -99;
8379     }
8380
8381   if (MPLS_LABEL_INVALID == local_label)
8382     {
8383       errmsg ("missing label");
8384       return -99;
8385     }
8386
8387   if (count > 1)
8388     {
8389       /* Turn on async mode */
8390       vam->async_mode = 1;
8391       vam->async_errors = 0;
8392       before = vat_time_now (vam);
8393     }
8394
8395   for (j = 0; j < count; j++)
8396     {
8397       /* Construct the API message */
8398       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8399
8400       mp->mr_is_add = is_add;
8401       mp->mr_is_multipath = is_multipath;
8402
8403       mp->mr_route.mr_label = local_label;
8404       mp->mr_route.mr_eos = is_eos;
8405       mp->mr_route.mr_table_id = 0;
8406       mp->mr_route.mr_n_paths = path_count;
8407
8408       clib_memcpy (&mp->mr_route.mr_paths, paths,
8409                    sizeof (paths[0]) * path_count);
8410
8411       local_label++;
8412
8413       /* send it... */
8414       S (mp);
8415       /* If we receive SIGTERM, stop now... */
8416       if (vam->do_exit)
8417         break;
8418     }
8419
8420   /* When testing multiple add/del ops, use a control-ping to sync */
8421   if (count > 1)
8422     {
8423       vl_api_control_ping_t *mp_ping;
8424       f64 after;
8425       f64 timeout;
8426
8427       /* Shut off async mode */
8428       vam->async_mode = 0;
8429
8430       MPING (CONTROL_PING, mp_ping);
8431       S (mp_ping);
8432
8433       timeout = vat_time_now (vam) + 1.0;
8434       while (vat_time_now (vam) < timeout)
8435         if (vam->result_ready == 1)
8436           goto out;
8437       vam->retval = -99;
8438
8439     out:
8440       if (vam->retval == -99)
8441         errmsg ("timeout");
8442
8443       if (vam->async_errors > 0)
8444         {
8445           errmsg ("%d asynchronous errors", vam->async_errors);
8446           vam->retval = -98;
8447         }
8448       vam->async_errors = 0;
8449       after = vat_time_now (vam);
8450
8451       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8452       if (j > 0)
8453         count = j;
8454
8455       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8456              count, after - before, count / (after - before));
8457     }
8458   else
8459     {
8460       int ret;
8461
8462       /* Wait for a reply... */
8463       W (ret);
8464       return ret;
8465     }
8466
8467   /* Return the good/bad news */
8468   return (vam->retval);
8469   return (0);
8470 }
8471
8472 static int
8473 api_mpls_ip_bind_unbind (vat_main_t * vam)
8474 {
8475   unformat_input_t *i = vam->input;
8476   vl_api_mpls_ip_bind_unbind_t *mp;
8477   u32 ip_table_id = 0;
8478   u8 is_bind = 1;
8479   vl_api_prefix_t pfx;
8480   u8 prefix_set = 0;
8481   mpls_label_t local_label = MPLS_LABEL_INVALID;
8482   int ret;
8483
8484   /* Parse args required to build the message */
8485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8486     {
8487       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8488         prefix_set = 1;
8489       else if (unformat (i, "%d", &local_label))
8490         ;
8491       else if (unformat (i, "table-id %d", &ip_table_id))
8492         ;
8493       else if (unformat (i, "unbind"))
8494         is_bind = 0;
8495       else if (unformat (i, "bind"))
8496         is_bind = 1;
8497       else
8498         {
8499           clib_warning ("parse error '%U'", format_unformat_error, i);
8500           return -99;
8501         }
8502     }
8503
8504   if (!prefix_set)
8505     {
8506       errmsg ("IP prefix not set");
8507       return -99;
8508     }
8509
8510   if (MPLS_LABEL_INVALID == local_label)
8511     {
8512       errmsg ("missing label");
8513       return -99;
8514     }
8515
8516   /* Construct the API message */
8517   M (MPLS_IP_BIND_UNBIND, mp);
8518
8519   mp->mb_is_bind = is_bind;
8520   mp->mb_ip_table_id = ntohl (ip_table_id);
8521   mp->mb_mpls_table_id = 0;
8522   mp->mb_label = ntohl (local_label);
8523   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8524
8525   /* send it... */
8526   S (mp);
8527
8528   /* Wait for a reply... */
8529   W (ret);
8530   return ret;
8531   return (0);
8532 }
8533
8534 static int
8535 api_sr_mpls_policy_add (vat_main_t * vam)
8536 {
8537   unformat_input_t *i = vam->input;
8538   vl_api_sr_mpls_policy_add_t *mp;
8539   u32 bsid = 0;
8540   u32 weight = 1;
8541   u8 type = 0;
8542   u8 n_segments = 0;
8543   u32 sid;
8544   u32 *segments = NULL;
8545   int ret;
8546
8547   /* Parse args required to build the message */
8548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8549     {
8550       if (unformat (i, "bsid %d", &bsid))
8551         ;
8552       else if (unformat (i, "weight %d", &weight))
8553         ;
8554       else if (unformat (i, "spray"))
8555         type = 1;
8556       else if (unformat (i, "next %d", &sid))
8557         {
8558           n_segments += 1;
8559           vec_add1 (segments, htonl (sid));
8560         }
8561       else
8562         {
8563           clib_warning ("parse error '%U'", format_unformat_error, i);
8564           return -99;
8565         }
8566     }
8567
8568   if (bsid == 0)
8569     {
8570       errmsg ("bsid not set");
8571       return -99;
8572     }
8573
8574   if (n_segments == 0)
8575     {
8576       errmsg ("no sid in segment stack");
8577       return -99;
8578     }
8579
8580   /* Construct the API message */
8581   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8582
8583   mp->bsid = htonl (bsid);
8584   mp->weight = htonl (weight);
8585   mp->type = type;
8586   mp->n_segments = n_segments;
8587   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8588   vec_free (segments);
8589
8590   /* send it... */
8591   S (mp);
8592
8593   /* Wait for a reply... */
8594   W (ret);
8595   return ret;
8596 }
8597
8598 static int
8599 api_sr_mpls_policy_del (vat_main_t * vam)
8600 {
8601   unformat_input_t *i = vam->input;
8602   vl_api_sr_mpls_policy_del_t *mp;
8603   u32 bsid = 0;
8604   int ret;
8605
8606   /* Parse args required to build the message */
8607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8608     {
8609       if (unformat (i, "bsid %d", &bsid))
8610         ;
8611       else
8612         {
8613           clib_warning ("parse error '%U'", format_unformat_error, i);
8614           return -99;
8615         }
8616     }
8617
8618   if (bsid == 0)
8619     {
8620       errmsg ("bsid not set");
8621       return -99;
8622     }
8623
8624   /* Construct the API message */
8625   M (SR_MPLS_POLICY_DEL, mp);
8626
8627   mp->bsid = htonl (bsid);
8628
8629   /* send it... */
8630   S (mp);
8631
8632   /* Wait for a reply... */
8633   W (ret);
8634   return ret;
8635 }
8636
8637 static int
8638 api_bier_table_add_del (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_bier_table_add_del_t *mp;
8642   u8 is_add = 1;
8643   u32 set = 0, sub_domain = 0, hdr_len = 3;
8644   mpls_label_t local_label = MPLS_LABEL_INVALID;
8645   int ret;
8646
8647   /* Parse args required to build the message */
8648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8649     {
8650       if (unformat (i, "sub-domain %d", &sub_domain))
8651         ;
8652       else if (unformat (i, "set %d", &set))
8653         ;
8654       else if (unformat (i, "label %d", &local_label))
8655         ;
8656       else if (unformat (i, "hdr-len %d", &hdr_len))
8657         ;
8658       else if (unformat (i, "add"))
8659         is_add = 1;
8660       else if (unformat (i, "del"))
8661         is_add = 0;
8662       else
8663         {
8664           clib_warning ("parse error '%U'", format_unformat_error, i);
8665           return -99;
8666         }
8667     }
8668
8669   if (MPLS_LABEL_INVALID == local_label)
8670     {
8671       errmsg ("missing label\n");
8672       return -99;
8673     }
8674
8675   /* Construct the API message */
8676   M (BIER_TABLE_ADD_DEL, mp);
8677
8678   mp->bt_is_add = is_add;
8679   mp->bt_label = ntohl (local_label);
8680   mp->bt_tbl_id.bt_set = set;
8681   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8682   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8683
8684   /* send it... */
8685   S (mp);
8686
8687   /* Wait for a reply... */
8688   W (ret);
8689
8690   return (ret);
8691 }
8692
8693 static int
8694 api_bier_route_add_del (vat_main_t * vam)
8695 {
8696   unformat_input_t *i = vam->input;
8697   vl_api_bier_route_add_del_t *mp;
8698   u8 is_add = 1;
8699   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8700   ip4_address_t v4_next_hop_address;
8701   ip6_address_t v6_next_hop_address;
8702   u8 next_hop_set = 0;
8703   u8 next_hop_proto_is_ip4 = 1;
8704   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8705   int ret;
8706
8707   /* Parse args required to build the message */
8708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8709     {
8710       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8711         {
8712           next_hop_proto_is_ip4 = 1;
8713           next_hop_set = 1;
8714         }
8715       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8716         {
8717           next_hop_proto_is_ip4 = 0;
8718           next_hop_set = 1;
8719         }
8720       if (unformat (i, "sub-domain %d", &sub_domain))
8721         ;
8722       else if (unformat (i, "set %d", &set))
8723         ;
8724       else if (unformat (i, "hdr-len %d", &hdr_len))
8725         ;
8726       else if (unformat (i, "bp %d", &bp))
8727         ;
8728       else if (unformat (i, "add"))
8729         is_add = 1;
8730       else if (unformat (i, "del"))
8731         is_add = 0;
8732       else if (unformat (i, "out-label %d", &next_hop_out_label))
8733         ;
8734       else
8735         {
8736           clib_warning ("parse error '%U'", format_unformat_error, i);
8737           return -99;
8738         }
8739     }
8740
8741   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8742     {
8743       errmsg ("next hop / label set\n");
8744       return -99;
8745     }
8746   if (0 == bp)
8747     {
8748       errmsg ("bit=position not set\n");
8749       return -99;
8750     }
8751
8752   /* Construct the API message */
8753   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8754
8755   mp->br_is_add = is_add;
8756   mp->br_route.br_tbl_id.bt_set = set;
8757   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8758   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8759   mp->br_route.br_bp = ntohs (bp);
8760   mp->br_route.br_n_paths = 1;
8761   mp->br_route.br_paths[0].n_labels = 1;
8762   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8763   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8764                                     FIB_API_PATH_NH_PROTO_IP4 :
8765                                     FIB_API_PATH_NH_PROTO_IP6);
8766
8767   if (next_hop_proto_is_ip4)
8768     {
8769       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8770                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8771     }
8772   else
8773     {
8774       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8775                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8776     }
8777
8778   /* send it... */
8779   S (mp);
8780
8781   /* Wait for a reply... */
8782   W (ret);
8783
8784   return (ret);
8785 }
8786
8787 static int
8788 api_proxy_arp_add_del (vat_main_t * vam)
8789 {
8790   unformat_input_t *i = vam->input;
8791   vl_api_proxy_arp_add_del_t *mp;
8792   u32 vrf_id = 0;
8793   u8 is_add = 1;
8794   vl_api_ip4_address_t lo, hi;
8795   u8 range_set = 0;
8796   int ret;
8797
8798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8799     {
8800       if (unformat (i, "vrf %d", &vrf_id))
8801         ;
8802       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8803                          unformat_vl_api_ip4_address, &hi))
8804         range_set = 1;
8805       else if (unformat (i, "del"))
8806         is_add = 0;
8807       else
8808         {
8809           clib_warning ("parse error '%U'", format_unformat_error, i);
8810           return -99;
8811         }
8812     }
8813
8814   if (range_set == 0)
8815     {
8816       errmsg ("address range not set");
8817       return -99;
8818     }
8819
8820   M (PROXY_ARP_ADD_DEL, mp);
8821
8822   mp->proxy.table_id = ntohl (vrf_id);
8823   mp->is_add = is_add;
8824   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8825   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8826
8827   S (mp);
8828   W (ret);
8829   return ret;
8830 }
8831
8832 static int
8833 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8834 {
8835   unformat_input_t *i = vam->input;
8836   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8837   u32 sw_if_index;
8838   u8 enable = 1;
8839   u8 sw_if_index_set = 0;
8840   int ret;
8841
8842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8843     {
8844       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8845         sw_if_index_set = 1;
8846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8847         sw_if_index_set = 1;
8848       else if (unformat (i, "enable"))
8849         enable = 1;
8850       else if (unformat (i, "disable"))
8851         enable = 0;
8852       else
8853         {
8854           clib_warning ("parse error '%U'", format_unformat_error, i);
8855           return -99;
8856         }
8857     }
8858
8859   if (sw_if_index_set == 0)
8860     {
8861       errmsg ("missing interface name or sw_if_index");
8862       return -99;
8863     }
8864
8865   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8866
8867   mp->sw_if_index = ntohl (sw_if_index);
8868   mp->enable_disable = enable;
8869
8870   S (mp);
8871   W (ret);
8872   return ret;
8873 }
8874
8875 static int
8876 api_mpls_tunnel_add_del (vat_main_t * vam)
8877 {
8878   unformat_input_t *i = vam->input;
8879   vl_api_mpls_tunnel_add_del_t *mp;
8880
8881   vl_api_fib_path_t paths[8];
8882   u32 sw_if_index = ~0;
8883   u8 path_count = 0;
8884   u8 l2_only = 0;
8885   u8 is_add = 1;
8886   int ret;
8887
8888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8889     {
8890       if (unformat (i, "add"))
8891         is_add = 1;
8892       else
8893         if (unformat
8894             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8895         is_add = 0;
8896       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8897         is_add = 0;
8898       else if (unformat (i, "l2-only"))
8899         l2_only = 1;
8900       else
8901         if (unformat
8902             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8903         {
8904           path_count++;
8905           if (8 == path_count)
8906             {
8907               errmsg ("max 8 paths");
8908               return -99;
8909             }
8910         }
8911       else
8912         {
8913           clib_warning ("parse error '%U'", format_unformat_error, i);
8914           return -99;
8915         }
8916     }
8917
8918   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8919
8920   mp->mt_is_add = is_add;
8921   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8922   mp->mt_tunnel.mt_l2_only = l2_only;
8923   mp->mt_tunnel.mt_is_multicast = 0;
8924   mp->mt_tunnel.mt_n_paths = path_count;
8925
8926   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8927                sizeof (paths[0]) * path_count);
8928
8929   S (mp);
8930   W (ret);
8931   return ret;
8932 }
8933
8934 static int
8935 api_sw_interface_set_unnumbered (vat_main_t * vam)
8936 {
8937   unformat_input_t *i = vam->input;
8938   vl_api_sw_interface_set_unnumbered_t *mp;
8939   u32 sw_if_index;
8940   u32 unnum_sw_index = ~0;
8941   u8 is_add = 1;
8942   u8 sw_if_index_set = 0;
8943   int ret;
8944
8945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8946     {
8947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8948         sw_if_index_set = 1;
8949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8950         sw_if_index_set = 1;
8951       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8952         ;
8953       else if (unformat (i, "del"))
8954         is_add = 0;
8955       else
8956         {
8957           clib_warning ("parse error '%U'", format_unformat_error, i);
8958           return -99;
8959         }
8960     }
8961
8962   if (sw_if_index_set == 0)
8963     {
8964       errmsg ("missing interface name or sw_if_index");
8965       return -99;
8966     }
8967
8968   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8969
8970   mp->sw_if_index = ntohl (sw_if_index);
8971   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8972   mp->is_add = is_add;
8973
8974   S (mp);
8975   W (ret);
8976   return ret;
8977 }
8978
8979 static int
8980 api_ip_neighbor_add_del (vat_main_t * vam)
8981 {
8982   vl_api_mac_address_t mac_address;
8983   unformat_input_t *i = vam->input;
8984   vl_api_ip_neighbor_add_del_t *mp;
8985   vl_api_address_t ip_address;
8986   u32 sw_if_index;
8987   u8 sw_if_index_set = 0;
8988   u8 is_add = 1;
8989   u8 mac_set = 0;
8990   u8 address_set = 0;
8991   int ret;
8992   ip_neighbor_flags_t flags;
8993
8994   flags = IP_NEIGHBOR_FLAG_NONE;
8995   clib_memset (&ip_address, 0, sizeof (ip_address));
8996   clib_memset (&mac_address, 0, sizeof (mac_address));
8997
8998   /* Parse args required to build the message */
8999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9000     {
9001       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9002         {
9003           mac_set = 1;
9004         }
9005       else if (unformat (i, "del"))
9006         is_add = 0;
9007       else
9008         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9009         sw_if_index_set = 1;
9010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9011         sw_if_index_set = 1;
9012       else if (unformat (i, "static"))
9013         flags |= IP_NEIGHBOR_FLAG_STATIC;
9014       else if (unformat (i, "no-fib-entry"))
9015         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9016       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9017         address_set = 1;
9018       else
9019         {
9020           clib_warning ("parse error '%U'", format_unformat_error, i);
9021           return -99;
9022         }
9023     }
9024
9025   if (sw_if_index_set == 0)
9026     {
9027       errmsg ("missing interface name or sw_if_index");
9028       return -99;
9029     }
9030   if (!address_set)
9031     {
9032       errmsg ("no address set");
9033       return -99;
9034     }
9035
9036   /* Construct the API message */
9037   M (IP_NEIGHBOR_ADD_DEL, mp);
9038
9039   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9040   mp->is_add = is_add;
9041   mp->neighbor.flags = htonl (flags);
9042   if (mac_set)
9043     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9044                  sizeof (mac_address));
9045   if (address_set)
9046     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9047
9048   /* send it... */
9049   S (mp);
9050
9051   /* Wait for a reply, return good/bad news  */
9052   W (ret);
9053   return ret;
9054 }
9055
9056 static int
9057 api_create_vlan_subif (vat_main_t * vam)
9058 {
9059   unformat_input_t *i = vam->input;
9060   vl_api_create_vlan_subif_t *mp;
9061   u32 sw_if_index;
9062   u8 sw_if_index_set = 0;
9063   u32 vlan_id;
9064   u8 vlan_id_set = 0;
9065   int ret;
9066
9067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9068     {
9069       if (unformat (i, "sw_if_index %d", &sw_if_index))
9070         sw_if_index_set = 1;
9071       else
9072         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9073         sw_if_index_set = 1;
9074       else if (unformat (i, "vlan %d", &vlan_id))
9075         vlan_id_set = 1;
9076       else
9077         {
9078           clib_warning ("parse error '%U'", format_unformat_error, i);
9079           return -99;
9080         }
9081     }
9082
9083   if (sw_if_index_set == 0)
9084     {
9085       errmsg ("missing interface name or sw_if_index");
9086       return -99;
9087     }
9088
9089   if (vlan_id_set == 0)
9090     {
9091       errmsg ("missing vlan_id");
9092       return -99;
9093     }
9094   M (CREATE_VLAN_SUBIF, mp);
9095
9096   mp->sw_if_index = ntohl (sw_if_index);
9097   mp->vlan_id = ntohl (vlan_id);
9098
9099   S (mp);
9100   W (ret);
9101   return ret;
9102 }
9103
9104 #define foreach_create_subif_bit                \
9105 _(no_tags)                                      \
9106 _(one_tag)                                      \
9107 _(two_tags)                                     \
9108 _(dot1ad)                                       \
9109 _(exact_match)                                  \
9110 _(default_sub)                                  \
9111 _(outer_vlan_id_any)                            \
9112 _(inner_vlan_id_any)
9113
9114 #define foreach_create_subif_flag               \
9115 _(0, "no_tags")                                 \
9116 _(1, "one_tag")                                 \
9117 _(2, "two_tags")                                \
9118 _(3, "dot1ad")                                  \
9119 _(4, "exact_match")                             \
9120 _(5, "default_sub")                             \
9121 _(6, "outer_vlan_id_any")                       \
9122 _(7, "inner_vlan_id_any")
9123
9124 static int
9125 api_create_subif (vat_main_t * vam)
9126 {
9127   unformat_input_t *i = vam->input;
9128   vl_api_create_subif_t *mp;
9129   u32 sw_if_index;
9130   u8 sw_if_index_set = 0;
9131   u32 sub_id;
9132   u8 sub_id_set = 0;
9133   u32 __attribute__ ((unused)) no_tags = 0;
9134   u32 __attribute__ ((unused)) one_tag = 0;
9135   u32 __attribute__ ((unused)) two_tags = 0;
9136   u32 __attribute__ ((unused)) dot1ad = 0;
9137   u32 __attribute__ ((unused)) exact_match = 0;
9138   u32 __attribute__ ((unused)) default_sub = 0;
9139   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9140   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9141   u32 tmp;
9142   u16 outer_vlan_id = 0;
9143   u16 inner_vlan_id = 0;
9144   int ret;
9145
9146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (i, "sw_if_index %d", &sw_if_index))
9149         sw_if_index_set = 1;
9150       else
9151         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9152         sw_if_index_set = 1;
9153       else if (unformat (i, "sub_id %d", &sub_id))
9154         sub_id_set = 1;
9155       else if (unformat (i, "outer_vlan_id %d", &tmp))
9156         outer_vlan_id = tmp;
9157       else if (unformat (i, "inner_vlan_id %d", &tmp))
9158         inner_vlan_id = tmp;
9159
9160 #define _(a) else if (unformat (i, #a)) a = 1 ;
9161       foreach_create_subif_bit
9162 #undef _
9163         else
9164         {
9165           clib_warning ("parse error '%U'", format_unformat_error, i);
9166           return -99;
9167         }
9168     }
9169
9170   if (sw_if_index_set == 0)
9171     {
9172       errmsg ("missing interface name or sw_if_index");
9173       return -99;
9174     }
9175
9176   if (sub_id_set == 0)
9177     {
9178       errmsg ("missing sub_id");
9179       return -99;
9180     }
9181   M (CREATE_SUBIF, mp);
9182
9183   mp->sw_if_index = ntohl (sw_if_index);
9184   mp->sub_id = ntohl (sub_id);
9185
9186 #define _(a,b) mp->sub_if_flags |= (1 << a);
9187   foreach_create_subif_flag;
9188 #undef _
9189
9190   mp->outer_vlan_id = ntohs (outer_vlan_id);
9191   mp->inner_vlan_id = ntohs (inner_vlan_id);
9192
9193   S (mp);
9194   W (ret);
9195   return ret;
9196 }
9197
9198 static int
9199 api_reset_fib (vat_main_t * vam)
9200 {
9201   unformat_input_t *i = vam->input;
9202   vl_api_reset_fib_t *mp;
9203   u32 vrf_id = 0;
9204   u8 is_ipv6 = 0;
9205   u8 vrf_id_set = 0;
9206
9207   int ret;
9208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9209     {
9210       if (unformat (i, "vrf %d", &vrf_id))
9211         vrf_id_set = 1;
9212       else if (unformat (i, "ipv6"))
9213         is_ipv6 = 1;
9214       else
9215         {
9216           clib_warning ("parse error '%U'", format_unformat_error, i);
9217           return -99;
9218         }
9219     }
9220
9221   if (vrf_id_set == 0)
9222     {
9223       errmsg ("missing vrf id");
9224       return -99;
9225     }
9226
9227   M (RESET_FIB, mp);
9228
9229   mp->vrf_id = ntohl (vrf_id);
9230   mp->is_ipv6 = is_ipv6;
9231
9232   S (mp);
9233   W (ret);
9234   return ret;
9235 }
9236
9237 static int
9238 api_dhcp_proxy_config (vat_main_t * vam)
9239 {
9240   unformat_input_t *i = vam->input;
9241   vl_api_dhcp_proxy_config_t *mp;
9242   u32 rx_vrf_id = 0;
9243   u32 server_vrf_id = 0;
9244   u8 is_add = 1;
9245   u8 v4_address_set = 0;
9246   u8 v6_address_set = 0;
9247   ip4_address_t v4address;
9248   ip6_address_t v6address;
9249   u8 v4_src_address_set = 0;
9250   u8 v6_src_address_set = 0;
9251   ip4_address_t v4srcaddress;
9252   ip6_address_t v6srcaddress;
9253   int ret;
9254
9255   /* Parse args required to build the message */
9256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9257     {
9258       if (unformat (i, "del"))
9259         is_add = 0;
9260       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9261         ;
9262       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9263         ;
9264       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9265         v4_address_set = 1;
9266       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9267         v6_address_set = 1;
9268       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9269         v4_src_address_set = 1;
9270       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9271         v6_src_address_set = 1;
9272       else
9273         break;
9274     }
9275
9276   if (v4_address_set && v6_address_set)
9277     {
9278       errmsg ("both v4 and v6 server addresses set");
9279       return -99;
9280     }
9281   if (!v4_address_set && !v6_address_set)
9282     {
9283       errmsg ("no server addresses set");
9284       return -99;
9285     }
9286
9287   if (v4_src_address_set && v6_src_address_set)
9288     {
9289       errmsg ("both v4 and v6  src addresses set");
9290       return -99;
9291     }
9292   if (!v4_src_address_set && !v6_src_address_set)
9293     {
9294       errmsg ("no src addresses set");
9295       return -99;
9296     }
9297
9298   if (!(v4_src_address_set && v4_address_set) &&
9299       !(v6_src_address_set && v6_address_set))
9300     {
9301       errmsg ("no matching server and src addresses set");
9302       return -99;
9303     }
9304
9305   /* Construct the API message */
9306   M (DHCP_PROXY_CONFIG, mp);
9307
9308   mp->is_add = is_add;
9309   mp->rx_vrf_id = ntohl (rx_vrf_id);
9310   mp->server_vrf_id = ntohl (server_vrf_id);
9311   if (v6_address_set)
9312     {
9313       mp->is_ipv6 = 1;
9314       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9315       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9316     }
9317   else
9318     {
9319       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9320       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9321     }
9322
9323   /* send it... */
9324   S (mp);
9325
9326   /* Wait for a reply, return good/bad news  */
9327   W (ret);
9328   return ret;
9329 }
9330
9331 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9332 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9333
9334 static void
9335 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9336 {
9337   vat_main_t *vam = &vat_main;
9338   u32 i, count = mp->count;
9339   vl_api_dhcp_server_t *s;
9340
9341   if (mp->is_ipv6)
9342     print (vam->ofp,
9343            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9344            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9345            ntohl (mp->rx_vrf_id),
9346            format_ip6_address, mp->dhcp_src_address,
9347            mp->vss_type, mp->vss_vpn_ascii_id,
9348            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9349   else
9350     print (vam->ofp,
9351            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9352            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9353            ntohl (mp->rx_vrf_id),
9354            format_ip4_address, mp->dhcp_src_address,
9355            mp->vss_type, mp->vss_vpn_ascii_id,
9356            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9357
9358   for (i = 0; i < count; i++)
9359     {
9360       s = &mp->servers[i];
9361
9362       if (mp->is_ipv6)
9363         print (vam->ofp,
9364                " Server Table-ID %d, Server Address %U",
9365                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9366       else
9367         print (vam->ofp,
9368                " Server Table-ID %d, Server Address %U",
9369                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9370     }
9371 }
9372
9373 static void vl_api_dhcp_proxy_details_t_handler_json
9374   (vl_api_dhcp_proxy_details_t * mp)
9375 {
9376   vat_main_t *vam = &vat_main;
9377   vat_json_node_t *node = NULL;
9378   u32 i, count = mp->count;
9379   struct in_addr ip4;
9380   struct in6_addr ip6;
9381   vl_api_dhcp_server_t *s;
9382
9383   if (VAT_JSON_ARRAY != vam->json_tree.type)
9384     {
9385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9386       vat_json_init_array (&vam->json_tree);
9387     }
9388   node = vat_json_array_add (&vam->json_tree);
9389
9390   vat_json_init_object (node);
9391   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9392   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9393                              sizeof (mp->vss_type));
9394   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9395                                    mp->vss_vpn_ascii_id);
9396   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9397   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9398
9399   if (mp->is_ipv6)
9400     {
9401       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9402       vat_json_object_add_ip6 (node, "src_address", ip6);
9403     }
9404   else
9405     {
9406       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9407       vat_json_object_add_ip4 (node, "src_address", ip4);
9408     }
9409
9410   for (i = 0; i < count; i++)
9411     {
9412       s = &mp->servers[i];
9413
9414       vat_json_object_add_uint (node, "server-table-id",
9415                                 ntohl (s->server_vrf_id));
9416
9417       if (mp->is_ipv6)
9418         {
9419           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9420           vat_json_object_add_ip4 (node, "src_address", ip4);
9421         }
9422       else
9423         {
9424           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9425           vat_json_object_add_ip6 (node, "server_address", ip6);
9426         }
9427     }
9428 }
9429
9430 static int
9431 api_dhcp_proxy_dump (vat_main_t * vam)
9432 {
9433   unformat_input_t *i = vam->input;
9434   vl_api_control_ping_t *mp_ping;
9435   vl_api_dhcp_proxy_dump_t *mp;
9436   u8 is_ipv6 = 0;
9437   int ret;
9438
9439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (i, "ipv6"))
9442         is_ipv6 = 1;
9443       else
9444         {
9445           clib_warning ("parse error '%U'", format_unformat_error, i);
9446           return -99;
9447         }
9448     }
9449
9450   M (DHCP_PROXY_DUMP, mp);
9451
9452   mp->is_ip6 = is_ipv6;
9453   S (mp);
9454
9455   /* Use a control ping for synchronization */
9456   MPING (CONTROL_PING, mp_ping);
9457   S (mp_ping);
9458
9459   W (ret);
9460   return ret;
9461 }
9462
9463 static int
9464 api_dhcp_proxy_set_vss (vat_main_t * vam)
9465 {
9466   unformat_input_t *i = vam->input;
9467   vl_api_dhcp_proxy_set_vss_t *mp;
9468   u8 is_ipv6 = 0;
9469   u8 is_add = 1;
9470   u32 tbl_id = ~0;
9471   u8 vss_type = VSS_TYPE_DEFAULT;
9472   u8 *vpn_ascii_id = 0;
9473   u32 oui = 0;
9474   u32 fib_id = 0;
9475   int ret;
9476
9477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9478     {
9479       if (unformat (i, "tbl_id %d", &tbl_id))
9480         ;
9481       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9482         vss_type = VSS_TYPE_ASCII;
9483       else if (unformat (i, "fib_id %d", &fib_id))
9484         vss_type = VSS_TYPE_VPN_ID;
9485       else if (unformat (i, "oui %d", &oui))
9486         vss_type = VSS_TYPE_VPN_ID;
9487       else if (unformat (i, "ipv6"))
9488         is_ipv6 = 1;
9489       else if (unformat (i, "del"))
9490         is_add = 0;
9491       else
9492         break;
9493     }
9494
9495   if (tbl_id == ~0)
9496     {
9497       errmsg ("missing tbl_id ");
9498       vec_free (vpn_ascii_id);
9499       return -99;
9500     }
9501
9502   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9503     {
9504       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9505       vec_free (vpn_ascii_id);
9506       return -99;
9507     }
9508
9509   M (DHCP_PROXY_SET_VSS, mp);
9510   mp->tbl_id = ntohl (tbl_id);
9511   mp->vss_type = vss_type;
9512   if (vpn_ascii_id)
9513     {
9514       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9515       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9516     }
9517   mp->vpn_index = ntohl (fib_id);
9518   mp->oui = ntohl (oui);
9519   mp->is_ipv6 = is_ipv6;
9520   mp->is_add = is_add;
9521
9522   S (mp);
9523   W (ret);
9524
9525   vec_free (vpn_ascii_id);
9526   return ret;
9527 }
9528
9529 static int
9530 api_dhcp_client_config (vat_main_t * vam)
9531 {
9532   unformat_input_t *i = vam->input;
9533   vl_api_dhcp_client_config_t *mp;
9534   u32 sw_if_index;
9535   u8 sw_if_index_set = 0;
9536   u8 is_add = 1;
9537   u8 *hostname = 0;
9538   u8 disable_event = 0;
9539   int ret;
9540
9541   /* Parse args required to build the message */
9542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9543     {
9544       if (unformat (i, "del"))
9545         is_add = 0;
9546       else
9547         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9548         sw_if_index_set = 1;
9549       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9550         sw_if_index_set = 1;
9551       else if (unformat (i, "hostname %s", &hostname))
9552         ;
9553       else if (unformat (i, "disable_event"))
9554         disable_event = 1;
9555       else
9556         break;
9557     }
9558
9559   if (sw_if_index_set == 0)
9560     {
9561       errmsg ("missing interface name or sw_if_index");
9562       return -99;
9563     }
9564
9565   if (vec_len (hostname) > 63)
9566     {
9567       errmsg ("hostname too long");
9568     }
9569   vec_add1 (hostname, 0);
9570
9571   /* Construct the API message */
9572   M (DHCP_CLIENT_CONFIG, mp);
9573
9574   mp->is_add = is_add;
9575   mp->client.sw_if_index = htonl (sw_if_index);
9576   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9577   vec_free (hostname);
9578   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9579   mp->client.pid = htonl (getpid ());
9580
9581   /* send it... */
9582   S (mp);
9583
9584   /* Wait for a reply, return good/bad news  */
9585   W (ret);
9586   return ret;
9587 }
9588
9589 static int
9590 api_set_ip_flow_hash (vat_main_t * vam)
9591 {
9592   unformat_input_t *i = vam->input;
9593   vl_api_set_ip_flow_hash_t *mp;
9594   u32 vrf_id = 0;
9595   u8 is_ipv6 = 0;
9596   u8 vrf_id_set = 0;
9597   u8 src = 0;
9598   u8 dst = 0;
9599   u8 sport = 0;
9600   u8 dport = 0;
9601   u8 proto = 0;
9602   u8 reverse = 0;
9603   int ret;
9604
9605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9606     {
9607       if (unformat (i, "vrf %d", &vrf_id))
9608         vrf_id_set = 1;
9609       else if (unformat (i, "ipv6"))
9610         is_ipv6 = 1;
9611       else if (unformat (i, "src"))
9612         src = 1;
9613       else if (unformat (i, "dst"))
9614         dst = 1;
9615       else if (unformat (i, "sport"))
9616         sport = 1;
9617       else if (unformat (i, "dport"))
9618         dport = 1;
9619       else if (unformat (i, "proto"))
9620         proto = 1;
9621       else if (unformat (i, "reverse"))
9622         reverse = 1;
9623
9624       else
9625         {
9626           clib_warning ("parse error '%U'", format_unformat_error, i);
9627           return -99;
9628         }
9629     }
9630
9631   if (vrf_id_set == 0)
9632     {
9633       errmsg ("missing vrf id");
9634       return -99;
9635     }
9636
9637   M (SET_IP_FLOW_HASH, mp);
9638   mp->src = src;
9639   mp->dst = dst;
9640   mp->sport = sport;
9641   mp->dport = dport;
9642   mp->proto = proto;
9643   mp->reverse = reverse;
9644   mp->vrf_id = ntohl (vrf_id);
9645   mp->is_ipv6 = is_ipv6;
9646
9647   S (mp);
9648   W (ret);
9649   return ret;
9650 }
9651
9652 static int
9653 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9654 {
9655   unformat_input_t *i = vam->input;
9656   vl_api_sw_interface_ip6_enable_disable_t *mp;
9657   u32 sw_if_index;
9658   u8 sw_if_index_set = 0;
9659   u8 enable = 0;
9660   int ret;
9661
9662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9663     {
9664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9665         sw_if_index_set = 1;
9666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9667         sw_if_index_set = 1;
9668       else if (unformat (i, "enable"))
9669         enable = 1;
9670       else if (unformat (i, "disable"))
9671         enable = 0;
9672       else
9673         {
9674           clib_warning ("parse error '%U'", format_unformat_error, i);
9675           return -99;
9676         }
9677     }
9678
9679   if (sw_if_index_set == 0)
9680     {
9681       errmsg ("missing interface name or sw_if_index");
9682       return -99;
9683     }
9684
9685   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9686
9687   mp->sw_if_index = ntohl (sw_if_index);
9688   mp->enable = enable;
9689
9690   S (mp);
9691   W (ret);
9692   return ret;
9693 }
9694
9695 static int
9696 api_ip6nd_proxy_add_del (vat_main_t * vam)
9697 {
9698   unformat_input_t *i = vam->input;
9699   vl_api_ip6nd_proxy_add_del_t *mp;
9700   u32 sw_if_index = ~0;
9701   u8 v6_address_set = 0;
9702   vl_api_ip6_address_t v6address;
9703   u8 is_del = 0;
9704   int ret;
9705
9706   /* Parse args required to build the message */
9707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9708     {
9709       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9710         ;
9711       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9712         ;
9713       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9714         v6_address_set = 1;
9715       if (unformat (i, "del"))
9716         is_del = 1;
9717       else
9718         {
9719           clib_warning ("parse error '%U'", format_unformat_error, i);
9720           return -99;
9721         }
9722     }
9723
9724   if (sw_if_index == ~0)
9725     {
9726       errmsg ("missing interface name or sw_if_index");
9727       return -99;
9728     }
9729   if (!v6_address_set)
9730     {
9731       errmsg ("no address set");
9732       return -99;
9733     }
9734
9735   /* Construct the API message */
9736   M (IP6ND_PROXY_ADD_DEL, mp);
9737
9738   mp->is_del = is_del;
9739   mp->sw_if_index = ntohl (sw_if_index);
9740   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9741
9742   /* send it... */
9743   S (mp);
9744
9745   /* Wait for a reply, return good/bad news  */
9746   W (ret);
9747   return ret;
9748 }
9749
9750 static int
9751 api_ip6nd_proxy_dump (vat_main_t * vam)
9752 {
9753   vl_api_ip6nd_proxy_dump_t *mp;
9754   vl_api_control_ping_t *mp_ping;
9755   int ret;
9756
9757   M (IP6ND_PROXY_DUMP, mp);
9758
9759   S (mp);
9760
9761   /* Use a control ping for synchronization */
9762   MPING (CONTROL_PING, mp_ping);
9763   S (mp_ping);
9764
9765   W (ret);
9766   return ret;
9767 }
9768
9769 static void vl_api_ip6nd_proxy_details_t_handler
9770   (vl_api_ip6nd_proxy_details_t * mp)
9771 {
9772   vat_main_t *vam = &vat_main;
9773
9774   print (vam->ofp, "host %U sw_if_index %d",
9775          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9776 }
9777
9778 static void vl_api_ip6nd_proxy_details_t_handler_json
9779   (vl_api_ip6nd_proxy_details_t * mp)
9780 {
9781   vat_main_t *vam = &vat_main;
9782   struct in6_addr ip6;
9783   vat_json_node_t *node = NULL;
9784
9785   if (VAT_JSON_ARRAY != vam->json_tree.type)
9786     {
9787       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9788       vat_json_init_array (&vam->json_tree);
9789     }
9790   node = vat_json_array_add (&vam->json_tree);
9791
9792   vat_json_init_object (node);
9793   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9794
9795   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9796   vat_json_object_add_ip6 (node, "host", ip6);
9797 }
9798
9799 static int
9800 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9801 {
9802   unformat_input_t *i = vam->input;
9803   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9804   u32 sw_if_index;
9805   u8 sw_if_index_set = 0;
9806   u8 v6_address_set = 0;
9807   vl_api_prefix_t pfx;
9808   u8 use_default = 0;
9809   u8 no_advertise = 0;
9810   u8 off_link = 0;
9811   u8 no_autoconfig = 0;
9812   u8 no_onlink = 0;
9813   u8 is_no = 0;
9814   u32 val_lifetime = 0;
9815   u32 pref_lifetime = 0;
9816   int ret;
9817
9818   /* Parse args required to build the message */
9819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9820     {
9821       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9822         sw_if_index_set = 1;
9823       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9824         sw_if_index_set = 1;
9825       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9826         v6_address_set = 1;
9827       else if (unformat (i, "val_life %d", &val_lifetime))
9828         ;
9829       else if (unformat (i, "pref_life %d", &pref_lifetime))
9830         ;
9831       else if (unformat (i, "def"))
9832         use_default = 1;
9833       else if (unformat (i, "noadv"))
9834         no_advertise = 1;
9835       else if (unformat (i, "offl"))
9836         off_link = 1;
9837       else if (unformat (i, "noauto"))
9838         no_autoconfig = 1;
9839       else if (unformat (i, "nolink"))
9840         no_onlink = 1;
9841       else if (unformat (i, "isno"))
9842         is_no = 1;
9843       else
9844         {
9845           clib_warning ("parse error '%U'", format_unformat_error, i);
9846           return -99;
9847         }
9848     }
9849
9850   if (sw_if_index_set == 0)
9851     {
9852       errmsg ("missing interface name or sw_if_index");
9853       return -99;
9854     }
9855   if (!v6_address_set)
9856     {
9857       errmsg ("no address set");
9858       return -99;
9859     }
9860
9861   /* Construct the API message */
9862   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9863
9864   mp->sw_if_index = ntohl (sw_if_index);
9865   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9866   mp->use_default = use_default;
9867   mp->no_advertise = no_advertise;
9868   mp->off_link = off_link;
9869   mp->no_autoconfig = no_autoconfig;
9870   mp->no_onlink = no_onlink;
9871   mp->is_no = is_no;
9872   mp->val_lifetime = ntohl (val_lifetime);
9873   mp->pref_lifetime = ntohl (pref_lifetime);
9874
9875   /* send it... */
9876   S (mp);
9877
9878   /* Wait for a reply, return good/bad news  */
9879   W (ret);
9880   return ret;
9881 }
9882
9883 static int
9884 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9885 {
9886   unformat_input_t *i = vam->input;
9887   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9888   u32 sw_if_index;
9889   u8 sw_if_index_set = 0;
9890   u8 suppress = 0;
9891   u8 managed = 0;
9892   u8 other = 0;
9893   u8 ll_option = 0;
9894   u8 send_unicast = 0;
9895   u8 cease = 0;
9896   u8 is_no = 0;
9897   u8 default_router = 0;
9898   u32 max_interval = 0;
9899   u32 min_interval = 0;
9900   u32 lifetime = 0;
9901   u32 initial_count = 0;
9902   u32 initial_interval = 0;
9903   int ret;
9904
9905
9906   /* Parse args required to build the message */
9907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9908     {
9909       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9910         sw_if_index_set = 1;
9911       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9912         sw_if_index_set = 1;
9913       else if (unformat (i, "maxint %d", &max_interval))
9914         ;
9915       else if (unformat (i, "minint %d", &min_interval))
9916         ;
9917       else if (unformat (i, "life %d", &lifetime))
9918         ;
9919       else if (unformat (i, "count %d", &initial_count))
9920         ;
9921       else if (unformat (i, "interval %d", &initial_interval))
9922         ;
9923       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9924         suppress = 1;
9925       else if (unformat (i, "managed"))
9926         managed = 1;
9927       else if (unformat (i, "other"))
9928         other = 1;
9929       else if (unformat (i, "ll"))
9930         ll_option = 1;
9931       else if (unformat (i, "send"))
9932         send_unicast = 1;
9933       else if (unformat (i, "cease"))
9934         cease = 1;
9935       else if (unformat (i, "isno"))
9936         is_no = 1;
9937       else if (unformat (i, "def"))
9938         default_router = 1;
9939       else
9940         {
9941           clib_warning ("parse error '%U'", format_unformat_error, i);
9942           return -99;
9943         }
9944     }
9945
9946   if (sw_if_index_set == 0)
9947     {
9948       errmsg ("missing interface name or sw_if_index");
9949       return -99;
9950     }
9951
9952   /* Construct the API message */
9953   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9954
9955   mp->sw_if_index = ntohl (sw_if_index);
9956   mp->max_interval = ntohl (max_interval);
9957   mp->min_interval = ntohl (min_interval);
9958   mp->lifetime = ntohl (lifetime);
9959   mp->initial_count = ntohl (initial_count);
9960   mp->initial_interval = ntohl (initial_interval);
9961   mp->suppress = suppress;
9962   mp->managed = managed;
9963   mp->other = other;
9964   mp->ll_option = ll_option;
9965   mp->send_unicast = send_unicast;
9966   mp->cease = cease;
9967   mp->is_no = is_no;
9968   mp->default_router = default_router;
9969
9970   /* send it... */
9971   S (mp);
9972
9973   /* Wait for a reply, return good/bad news  */
9974   W (ret);
9975   return ret;
9976 }
9977
9978 static int
9979 api_set_arp_neighbor_limit (vat_main_t * vam)
9980 {
9981   unformat_input_t *i = vam->input;
9982   vl_api_set_arp_neighbor_limit_t *mp;
9983   u32 arp_nbr_limit;
9984   u8 limit_set = 0;
9985   u8 is_ipv6 = 0;
9986   int ret;
9987
9988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9989     {
9990       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9991         limit_set = 1;
9992       else if (unformat (i, "ipv6"))
9993         is_ipv6 = 1;
9994       else
9995         {
9996           clib_warning ("parse error '%U'", format_unformat_error, i);
9997           return -99;
9998         }
9999     }
10000
10001   if (limit_set == 0)
10002     {
10003       errmsg ("missing limit value");
10004       return -99;
10005     }
10006
10007   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10008
10009   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10010   mp->is_ipv6 = is_ipv6;
10011
10012   S (mp);
10013   W (ret);
10014   return ret;
10015 }
10016
10017 static int
10018 api_l2_patch_add_del (vat_main_t * vam)
10019 {
10020   unformat_input_t *i = vam->input;
10021   vl_api_l2_patch_add_del_t *mp;
10022   u32 rx_sw_if_index;
10023   u8 rx_sw_if_index_set = 0;
10024   u32 tx_sw_if_index;
10025   u8 tx_sw_if_index_set = 0;
10026   u8 is_add = 1;
10027   int ret;
10028
10029   /* Parse args required to build the message */
10030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10031     {
10032       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10033         rx_sw_if_index_set = 1;
10034       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10035         tx_sw_if_index_set = 1;
10036       else if (unformat (i, "rx"))
10037         {
10038           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10039             {
10040               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10041                             &rx_sw_if_index))
10042                 rx_sw_if_index_set = 1;
10043             }
10044           else
10045             break;
10046         }
10047       else if (unformat (i, "tx"))
10048         {
10049           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10050             {
10051               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10052                             &tx_sw_if_index))
10053                 tx_sw_if_index_set = 1;
10054             }
10055           else
10056             break;
10057         }
10058       else if (unformat (i, "del"))
10059         is_add = 0;
10060       else
10061         break;
10062     }
10063
10064   if (rx_sw_if_index_set == 0)
10065     {
10066       errmsg ("missing rx interface name or rx_sw_if_index");
10067       return -99;
10068     }
10069
10070   if (tx_sw_if_index_set == 0)
10071     {
10072       errmsg ("missing tx interface name or tx_sw_if_index");
10073       return -99;
10074     }
10075
10076   M (L2_PATCH_ADD_DEL, mp);
10077
10078   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10079   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10080   mp->is_add = is_add;
10081
10082   S (mp);
10083   W (ret);
10084   return ret;
10085 }
10086
10087 u8 is_del;
10088 u8 localsid_addr[16];
10089 u8 end_psp;
10090 u8 behavior;
10091 u32 sw_if_index;
10092 u32 vlan_index;
10093 u32 fib_table;
10094 u8 nh_addr[16];
10095
10096 static int
10097 api_sr_localsid_add_del (vat_main_t * vam)
10098 {
10099   unformat_input_t *i = vam->input;
10100   vl_api_sr_localsid_add_del_t *mp;
10101
10102   u8 is_del;
10103   ip6_address_t localsid;
10104   u8 end_psp = 0;
10105   u8 behavior = ~0;
10106   u32 sw_if_index;
10107   u32 fib_table = ~(u32) 0;
10108   ip6_address_t nh_addr6;
10109   ip4_address_t nh_addr4;
10110   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10111   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10112
10113   bool nexthop_set = 0;
10114
10115   int ret;
10116
10117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10118     {
10119       if (unformat (i, "del"))
10120         is_del = 1;
10121       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10122       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10123         nexthop_set = 1;
10124       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10125         nexthop_set = 1;
10126       else if (unformat (i, "behavior %u", &behavior));
10127       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10128       else if (unformat (i, "fib-table %u", &fib_table));
10129       else if (unformat (i, "end.psp %u", &behavior));
10130       else
10131         break;
10132     }
10133
10134   M (SR_LOCALSID_ADD_DEL, mp);
10135
10136   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10137   if (nexthop_set)
10138     {
10139       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10140       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10141     }
10142   mp->behavior = behavior;
10143   mp->sw_if_index = ntohl (sw_if_index);
10144   mp->fib_table = ntohl (fib_table);
10145   mp->end_psp = end_psp;
10146   mp->is_del = is_del;
10147
10148   S (mp);
10149   W (ret);
10150   return ret;
10151 }
10152
10153 static int
10154 api_ioam_enable (vat_main_t * vam)
10155 {
10156   unformat_input_t *input = vam->input;
10157   vl_api_ioam_enable_t *mp;
10158   u32 id = 0;
10159   int has_trace_option = 0;
10160   int has_pot_option = 0;
10161   int has_seqno_option = 0;
10162   int has_analyse_option = 0;
10163   int ret;
10164
10165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10166     {
10167       if (unformat (input, "trace"))
10168         has_trace_option = 1;
10169       else if (unformat (input, "pot"))
10170         has_pot_option = 1;
10171       else if (unformat (input, "seqno"))
10172         has_seqno_option = 1;
10173       else if (unformat (input, "analyse"))
10174         has_analyse_option = 1;
10175       else
10176         break;
10177     }
10178   M (IOAM_ENABLE, mp);
10179   mp->id = htons (id);
10180   mp->seqno = has_seqno_option;
10181   mp->analyse = has_analyse_option;
10182   mp->pot_enable = has_pot_option;
10183   mp->trace_enable = has_trace_option;
10184
10185   S (mp);
10186   W (ret);
10187   return ret;
10188 }
10189
10190
10191 static int
10192 api_ioam_disable (vat_main_t * vam)
10193 {
10194   vl_api_ioam_disable_t *mp;
10195   int ret;
10196
10197   M (IOAM_DISABLE, mp);
10198   S (mp);
10199   W (ret);
10200   return ret;
10201 }
10202
10203 #define foreach_tcp_proto_field                 \
10204 _(src_port)                                     \
10205 _(dst_port)
10206
10207 #define foreach_udp_proto_field                 \
10208 _(src_port)                                     \
10209 _(dst_port)
10210
10211 #define foreach_ip4_proto_field                 \
10212 _(src_address)                                  \
10213 _(dst_address)                                  \
10214 _(tos)                                          \
10215 _(length)                                       \
10216 _(fragment_id)                                  \
10217 _(ttl)                                          \
10218 _(protocol)                                     \
10219 _(checksum)
10220
10221 typedef struct
10222 {
10223   u16 src_port, dst_port;
10224 } tcpudp_header_t;
10225
10226 #if VPP_API_TEST_BUILTIN == 0
10227 uword
10228 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10229 {
10230   u8 **maskp = va_arg (*args, u8 **);
10231   u8 *mask = 0;
10232   u8 found_something = 0;
10233   tcp_header_t *tcp;
10234
10235 #define _(a) u8 a=0;
10236   foreach_tcp_proto_field;
10237 #undef _
10238
10239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10240     {
10241       if (0);
10242 #define _(a) else if (unformat (input, #a)) a=1;
10243       foreach_tcp_proto_field
10244 #undef _
10245         else
10246         break;
10247     }
10248
10249 #define _(a) found_something += a;
10250   foreach_tcp_proto_field;
10251 #undef _
10252
10253   if (found_something == 0)
10254     return 0;
10255
10256   vec_validate (mask, sizeof (*tcp) - 1);
10257
10258   tcp = (tcp_header_t *) mask;
10259
10260 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10261   foreach_tcp_proto_field;
10262 #undef _
10263
10264   *maskp = mask;
10265   return 1;
10266 }
10267
10268 uword
10269 unformat_udp_mask (unformat_input_t * input, va_list * args)
10270 {
10271   u8 **maskp = va_arg (*args, u8 **);
10272   u8 *mask = 0;
10273   u8 found_something = 0;
10274   udp_header_t *udp;
10275
10276 #define _(a) u8 a=0;
10277   foreach_udp_proto_field;
10278 #undef _
10279
10280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10281     {
10282       if (0);
10283 #define _(a) else if (unformat (input, #a)) a=1;
10284       foreach_udp_proto_field
10285 #undef _
10286         else
10287         break;
10288     }
10289
10290 #define _(a) found_something += a;
10291   foreach_udp_proto_field;
10292 #undef _
10293
10294   if (found_something == 0)
10295     return 0;
10296
10297   vec_validate (mask, sizeof (*udp) - 1);
10298
10299   udp = (udp_header_t *) mask;
10300
10301 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10302   foreach_udp_proto_field;
10303 #undef _
10304
10305   *maskp = mask;
10306   return 1;
10307 }
10308
10309 uword
10310 unformat_l4_mask (unformat_input_t * input, va_list * args)
10311 {
10312   u8 **maskp = va_arg (*args, u8 **);
10313   u16 src_port = 0, dst_port = 0;
10314   tcpudp_header_t *tcpudp;
10315
10316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10317     {
10318       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10319         return 1;
10320       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10321         return 1;
10322       else if (unformat (input, "src_port"))
10323         src_port = 0xFFFF;
10324       else if (unformat (input, "dst_port"))
10325         dst_port = 0xFFFF;
10326       else
10327         return 0;
10328     }
10329
10330   if (!src_port && !dst_port)
10331     return 0;
10332
10333   u8 *mask = 0;
10334   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10335
10336   tcpudp = (tcpudp_header_t *) mask;
10337   tcpudp->src_port = src_port;
10338   tcpudp->dst_port = dst_port;
10339
10340   *maskp = mask;
10341
10342   return 1;
10343 }
10344
10345 uword
10346 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10347 {
10348   u8 **maskp = va_arg (*args, u8 **);
10349   u8 *mask = 0;
10350   u8 found_something = 0;
10351   ip4_header_t *ip;
10352
10353 #define _(a) u8 a=0;
10354   foreach_ip4_proto_field;
10355 #undef _
10356   u8 version = 0;
10357   u8 hdr_length = 0;
10358
10359
10360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10361     {
10362       if (unformat (input, "version"))
10363         version = 1;
10364       else if (unformat (input, "hdr_length"))
10365         hdr_length = 1;
10366       else if (unformat (input, "src"))
10367         src_address = 1;
10368       else if (unformat (input, "dst"))
10369         dst_address = 1;
10370       else if (unformat (input, "proto"))
10371         protocol = 1;
10372
10373 #define _(a) else if (unformat (input, #a)) a=1;
10374       foreach_ip4_proto_field
10375 #undef _
10376         else
10377         break;
10378     }
10379
10380 #define _(a) found_something += a;
10381   foreach_ip4_proto_field;
10382 #undef _
10383
10384   if (found_something == 0)
10385     return 0;
10386
10387   vec_validate (mask, sizeof (*ip) - 1);
10388
10389   ip = (ip4_header_t *) mask;
10390
10391 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10392   foreach_ip4_proto_field;
10393 #undef _
10394
10395   ip->ip_version_and_header_length = 0;
10396
10397   if (version)
10398     ip->ip_version_and_header_length |= 0xF0;
10399
10400   if (hdr_length)
10401     ip->ip_version_and_header_length |= 0x0F;
10402
10403   *maskp = mask;
10404   return 1;
10405 }
10406
10407 #define foreach_ip6_proto_field                 \
10408 _(src_address)                                  \
10409 _(dst_address)                                  \
10410 _(payload_length)                               \
10411 _(hop_limit)                                    \
10412 _(protocol)
10413
10414 uword
10415 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10416 {
10417   u8 **maskp = va_arg (*args, u8 **);
10418   u8 *mask = 0;
10419   u8 found_something = 0;
10420   ip6_header_t *ip;
10421   u32 ip_version_traffic_class_and_flow_label;
10422
10423 #define _(a) u8 a=0;
10424   foreach_ip6_proto_field;
10425 #undef _
10426   u8 version = 0;
10427   u8 traffic_class = 0;
10428   u8 flow_label = 0;
10429
10430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10431     {
10432       if (unformat (input, "version"))
10433         version = 1;
10434       else if (unformat (input, "traffic-class"))
10435         traffic_class = 1;
10436       else if (unformat (input, "flow-label"))
10437         flow_label = 1;
10438       else if (unformat (input, "src"))
10439         src_address = 1;
10440       else if (unformat (input, "dst"))
10441         dst_address = 1;
10442       else if (unformat (input, "proto"))
10443         protocol = 1;
10444
10445 #define _(a) else if (unformat (input, #a)) a=1;
10446       foreach_ip6_proto_field
10447 #undef _
10448         else
10449         break;
10450     }
10451
10452 #define _(a) found_something += a;
10453   foreach_ip6_proto_field;
10454 #undef _
10455
10456   if (found_something == 0)
10457     return 0;
10458
10459   vec_validate (mask, sizeof (*ip) - 1);
10460
10461   ip = (ip6_header_t *) mask;
10462
10463 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10464   foreach_ip6_proto_field;
10465 #undef _
10466
10467   ip_version_traffic_class_and_flow_label = 0;
10468
10469   if (version)
10470     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10471
10472   if (traffic_class)
10473     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10474
10475   if (flow_label)
10476     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10477
10478   ip->ip_version_traffic_class_and_flow_label =
10479     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10480
10481   *maskp = mask;
10482   return 1;
10483 }
10484
10485 uword
10486 unformat_l3_mask (unformat_input_t * input, va_list * args)
10487 {
10488   u8 **maskp = va_arg (*args, u8 **);
10489
10490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10491     {
10492       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10493         return 1;
10494       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10495         return 1;
10496       else
10497         break;
10498     }
10499   return 0;
10500 }
10501
10502 uword
10503 unformat_l2_mask (unformat_input_t * input, va_list * args)
10504 {
10505   u8 **maskp = va_arg (*args, u8 **);
10506   u8 *mask = 0;
10507   u8 src = 0;
10508   u8 dst = 0;
10509   u8 proto = 0;
10510   u8 tag1 = 0;
10511   u8 tag2 = 0;
10512   u8 ignore_tag1 = 0;
10513   u8 ignore_tag2 = 0;
10514   u8 cos1 = 0;
10515   u8 cos2 = 0;
10516   u8 dot1q = 0;
10517   u8 dot1ad = 0;
10518   int len = 14;
10519
10520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10521     {
10522       if (unformat (input, "src"))
10523         src = 1;
10524       else if (unformat (input, "dst"))
10525         dst = 1;
10526       else if (unformat (input, "proto"))
10527         proto = 1;
10528       else if (unformat (input, "tag1"))
10529         tag1 = 1;
10530       else if (unformat (input, "tag2"))
10531         tag2 = 1;
10532       else if (unformat (input, "ignore-tag1"))
10533         ignore_tag1 = 1;
10534       else if (unformat (input, "ignore-tag2"))
10535         ignore_tag2 = 1;
10536       else if (unformat (input, "cos1"))
10537         cos1 = 1;
10538       else if (unformat (input, "cos2"))
10539         cos2 = 1;
10540       else if (unformat (input, "dot1q"))
10541         dot1q = 1;
10542       else if (unformat (input, "dot1ad"))
10543         dot1ad = 1;
10544       else
10545         break;
10546     }
10547   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10548        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10549     return 0;
10550
10551   if (tag1 || ignore_tag1 || cos1 || dot1q)
10552     len = 18;
10553   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10554     len = 22;
10555
10556   vec_validate (mask, len - 1);
10557
10558   if (dst)
10559     clib_memset (mask, 0xff, 6);
10560
10561   if (src)
10562     clib_memset (mask + 6, 0xff, 6);
10563
10564   if (tag2 || dot1ad)
10565     {
10566       /* inner vlan tag */
10567       if (tag2)
10568         {
10569           mask[19] = 0xff;
10570           mask[18] = 0x0f;
10571         }
10572       if (cos2)
10573         mask[18] |= 0xe0;
10574       if (proto)
10575         mask[21] = mask[20] = 0xff;
10576       if (tag1)
10577         {
10578           mask[15] = 0xff;
10579           mask[14] = 0x0f;
10580         }
10581       if (cos1)
10582         mask[14] |= 0xe0;
10583       *maskp = mask;
10584       return 1;
10585     }
10586   if (tag1 | dot1q)
10587     {
10588       if (tag1)
10589         {
10590           mask[15] = 0xff;
10591           mask[14] = 0x0f;
10592         }
10593       if (cos1)
10594         mask[14] |= 0xe0;
10595       if (proto)
10596         mask[16] = mask[17] = 0xff;
10597
10598       *maskp = mask;
10599       return 1;
10600     }
10601   if (cos2)
10602     mask[18] |= 0xe0;
10603   if (cos1)
10604     mask[14] |= 0xe0;
10605   if (proto)
10606     mask[12] = mask[13] = 0xff;
10607
10608   *maskp = mask;
10609   return 1;
10610 }
10611
10612 uword
10613 unformat_classify_mask (unformat_input_t * input, va_list * args)
10614 {
10615   u8 **maskp = va_arg (*args, u8 **);
10616   u32 *skipp = va_arg (*args, u32 *);
10617   u32 *matchp = va_arg (*args, u32 *);
10618   u32 match;
10619   u8 *mask = 0;
10620   u8 *l2 = 0;
10621   u8 *l3 = 0;
10622   u8 *l4 = 0;
10623   int i;
10624
10625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10626     {
10627       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10628         ;
10629       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10630         ;
10631       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10632         ;
10633       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10634         ;
10635       else
10636         break;
10637     }
10638
10639   if (l4 && !l3)
10640     {
10641       vec_free (mask);
10642       vec_free (l2);
10643       vec_free (l4);
10644       return 0;
10645     }
10646
10647   if (mask || l2 || l3 || l4)
10648     {
10649       if (l2 || l3 || l4)
10650         {
10651           /* "With a free Ethernet header in every package" */
10652           if (l2 == 0)
10653             vec_validate (l2, 13);
10654           mask = l2;
10655           if (vec_len (l3))
10656             {
10657               vec_append (mask, l3);
10658               vec_free (l3);
10659             }
10660           if (vec_len (l4))
10661             {
10662               vec_append (mask, l4);
10663               vec_free (l4);
10664             }
10665         }
10666
10667       /* Scan forward looking for the first significant mask octet */
10668       for (i = 0; i < vec_len (mask); i++)
10669         if (mask[i])
10670           break;
10671
10672       /* compute (skip, match) params */
10673       *skipp = i / sizeof (u32x4);
10674       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10675
10676       /* Pad mask to an even multiple of the vector size */
10677       while (vec_len (mask) % sizeof (u32x4))
10678         vec_add1 (mask, 0);
10679
10680       match = vec_len (mask) / sizeof (u32x4);
10681
10682       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10683         {
10684           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10685           if (*tmp || *(tmp + 1))
10686             break;
10687           match--;
10688         }
10689       if (match == 0)
10690         clib_warning ("BUG: match 0");
10691
10692       _vec_len (mask) = match * sizeof (u32x4);
10693
10694       *matchp = match;
10695       *maskp = mask;
10696
10697       return 1;
10698     }
10699
10700   return 0;
10701 }
10702 #endif /* VPP_API_TEST_BUILTIN */
10703
10704 #define foreach_l2_next                         \
10705 _(drop, DROP)                                   \
10706 _(ethernet, ETHERNET_INPUT)                     \
10707 _(ip4, IP4_INPUT)                               \
10708 _(ip6, IP6_INPUT)
10709
10710 uword
10711 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10712 {
10713   u32 *miss_next_indexp = va_arg (*args, u32 *);
10714   u32 next_index = 0;
10715   u32 tmp;
10716
10717 #define _(n,N) \
10718   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10719   foreach_l2_next;
10720 #undef _
10721
10722   if (unformat (input, "%d", &tmp))
10723     {
10724       next_index = tmp;
10725       goto out;
10726     }
10727
10728   return 0;
10729
10730 out:
10731   *miss_next_indexp = next_index;
10732   return 1;
10733 }
10734
10735 #define foreach_ip_next                         \
10736 _(drop, DROP)                                   \
10737 _(local, LOCAL)                                 \
10738 _(rewrite, REWRITE)
10739
10740 uword
10741 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10742 {
10743   u32 *miss_next_indexp = va_arg (*args, u32 *);
10744   u32 next_index = 0;
10745   u32 tmp;
10746
10747 #define _(n,N) \
10748   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10749   foreach_ip_next;
10750 #undef _
10751
10752   if (unformat (input, "%d", &tmp))
10753     {
10754       next_index = tmp;
10755       goto out;
10756     }
10757
10758   return 0;
10759
10760 out:
10761   *miss_next_indexp = next_index;
10762   return 1;
10763 }
10764
10765 #define foreach_acl_next                        \
10766 _(deny, DENY)
10767
10768 uword
10769 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10770 {
10771   u32 *miss_next_indexp = va_arg (*args, u32 *);
10772   u32 next_index = 0;
10773   u32 tmp;
10774
10775 #define _(n,N) \
10776   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10777   foreach_acl_next;
10778 #undef _
10779
10780   if (unformat (input, "permit"))
10781     {
10782       next_index = ~0;
10783       goto out;
10784     }
10785   else if (unformat (input, "%d", &tmp))
10786     {
10787       next_index = tmp;
10788       goto out;
10789     }
10790
10791   return 0;
10792
10793 out:
10794   *miss_next_indexp = next_index;
10795   return 1;
10796 }
10797
10798 uword
10799 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10800 {
10801   u32 *r = va_arg (*args, u32 *);
10802
10803   if (unformat (input, "conform-color"))
10804     *r = POLICE_CONFORM;
10805   else if (unformat (input, "exceed-color"))
10806     *r = POLICE_EXCEED;
10807   else
10808     return 0;
10809
10810   return 1;
10811 }
10812
10813 static int
10814 api_classify_add_del_table (vat_main_t * vam)
10815 {
10816   unformat_input_t *i = vam->input;
10817   vl_api_classify_add_del_table_t *mp;
10818
10819   u32 nbuckets = 2;
10820   u32 skip = ~0;
10821   u32 match = ~0;
10822   int is_add = 1;
10823   int del_chain = 0;
10824   u32 table_index = ~0;
10825   u32 next_table_index = ~0;
10826   u32 miss_next_index = ~0;
10827   u32 memory_size = 32 << 20;
10828   u8 *mask = 0;
10829   u32 current_data_flag = 0;
10830   int current_data_offset = 0;
10831   int ret;
10832
10833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10834     {
10835       if (unformat (i, "del"))
10836         is_add = 0;
10837       else if (unformat (i, "del-chain"))
10838         {
10839           is_add = 0;
10840           del_chain = 1;
10841         }
10842       else if (unformat (i, "buckets %d", &nbuckets))
10843         ;
10844       else if (unformat (i, "memory_size %d", &memory_size))
10845         ;
10846       else if (unformat (i, "skip %d", &skip))
10847         ;
10848       else if (unformat (i, "match %d", &match))
10849         ;
10850       else if (unformat (i, "table %d", &table_index))
10851         ;
10852       else if (unformat (i, "mask %U", unformat_classify_mask,
10853                          &mask, &skip, &match))
10854         ;
10855       else if (unformat (i, "next-table %d", &next_table_index))
10856         ;
10857       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10858                          &miss_next_index))
10859         ;
10860       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10861                          &miss_next_index))
10862         ;
10863       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10864                          &miss_next_index))
10865         ;
10866       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10867         ;
10868       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10869         ;
10870       else
10871         break;
10872     }
10873
10874   if (is_add && mask == 0)
10875     {
10876       errmsg ("Mask required");
10877       return -99;
10878     }
10879
10880   if (is_add && skip == ~0)
10881     {
10882       errmsg ("skip count required");
10883       return -99;
10884     }
10885
10886   if (is_add && match == ~0)
10887     {
10888       errmsg ("match count required");
10889       return -99;
10890     }
10891
10892   if (!is_add && table_index == ~0)
10893     {
10894       errmsg ("table index required for delete");
10895       return -99;
10896     }
10897
10898   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10899
10900   mp->is_add = is_add;
10901   mp->del_chain = del_chain;
10902   mp->table_index = ntohl (table_index);
10903   mp->nbuckets = ntohl (nbuckets);
10904   mp->memory_size = ntohl (memory_size);
10905   mp->skip_n_vectors = ntohl (skip);
10906   mp->match_n_vectors = ntohl (match);
10907   mp->next_table_index = ntohl (next_table_index);
10908   mp->miss_next_index = ntohl (miss_next_index);
10909   mp->current_data_flag = ntohl (current_data_flag);
10910   mp->current_data_offset = ntohl (current_data_offset);
10911   mp->mask_len = ntohl (vec_len (mask));
10912   clib_memcpy (mp->mask, mask, vec_len (mask));
10913
10914   vec_free (mask);
10915
10916   S (mp);
10917   W (ret);
10918   return ret;
10919 }
10920
10921 #if VPP_API_TEST_BUILTIN == 0
10922 uword
10923 unformat_l4_match (unformat_input_t * input, va_list * args)
10924 {
10925   u8 **matchp = va_arg (*args, u8 **);
10926
10927   u8 *proto_header = 0;
10928   int src_port = 0;
10929   int dst_port = 0;
10930
10931   tcpudp_header_t h;
10932
10933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10934     {
10935       if (unformat (input, "src_port %d", &src_port))
10936         ;
10937       else if (unformat (input, "dst_port %d", &dst_port))
10938         ;
10939       else
10940         return 0;
10941     }
10942
10943   h.src_port = clib_host_to_net_u16 (src_port);
10944   h.dst_port = clib_host_to_net_u16 (dst_port);
10945   vec_validate (proto_header, sizeof (h) - 1);
10946   memcpy (proto_header, &h, sizeof (h));
10947
10948   *matchp = proto_header;
10949
10950   return 1;
10951 }
10952
10953 uword
10954 unformat_ip4_match (unformat_input_t * input, va_list * args)
10955 {
10956   u8 **matchp = va_arg (*args, u8 **);
10957   u8 *match = 0;
10958   ip4_header_t *ip;
10959   int version = 0;
10960   u32 version_val;
10961   int hdr_length = 0;
10962   u32 hdr_length_val;
10963   int src = 0, dst = 0;
10964   ip4_address_t src_val, dst_val;
10965   int proto = 0;
10966   u32 proto_val;
10967   int tos = 0;
10968   u32 tos_val;
10969   int length = 0;
10970   u32 length_val;
10971   int fragment_id = 0;
10972   u32 fragment_id_val;
10973   int ttl = 0;
10974   int ttl_val;
10975   int checksum = 0;
10976   u32 checksum_val;
10977
10978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10979     {
10980       if (unformat (input, "version %d", &version_val))
10981         version = 1;
10982       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10983         hdr_length = 1;
10984       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10985         src = 1;
10986       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10987         dst = 1;
10988       else if (unformat (input, "proto %d", &proto_val))
10989         proto = 1;
10990       else if (unformat (input, "tos %d", &tos_val))
10991         tos = 1;
10992       else if (unformat (input, "length %d", &length_val))
10993         length = 1;
10994       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10995         fragment_id = 1;
10996       else if (unformat (input, "ttl %d", &ttl_val))
10997         ttl = 1;
10998       else if (unformat (input, "checksum %d", &checksum_val))
10999         checksum = 1;
11000       else
11001         break;
11002     }
11003
11004   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11005       + ttl + checksum == 0)
11006     return 0;
11007
11008   /*
11009    * Aligned because we use the real comparison functions
11010    */
11011   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11012
11013   ip = (ip4_header_t *) match;
11014
11015   /* These are realistically matched in practice */
11016   if (src)
11017     ip->src_address.as_u32 = src_val.as_u32;
11018
11019   if (dst)
11020     ip->dst_address.as_u32 = dst_val.as_u32;
11021
11022   if (proto)
11023     ip->protocol = proto_val;
11024
11025
11026   /* These are not, but they're included for completeness */
11027   if (version)
11028     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11029
11030   if (hdr_length)
11031     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11032
11033   if (tos)
11034     ip->tos = tos_val;
11035
11036   if (length)
11037     ip->length = clib_host_to_net_u16 (length_val);
11038
11039   if (ttl)
11040     ip->ttl = ttl_val;
11041
11042   if (checksum)
11043     ip->checksum = clib_host_to_net_u16 (checksum_val);
11044
11045   *matchp = match;
11046   return 1;
11047 }
11048
11049 uword
11050 unformat_ip6_match (unformat_input_t * input, va_list * args)
11051 {
11052   u8 **matchp = va_arg (*args, u8 **);
11053   u8 *match = 0;
11054   ip6_header_t *ip;
11055   int version = 0;
11056   u32 version_val;
11057   u8 traffic_class = 0;
11058   u32 traffic_class_val = 0;
11059   u8 flow_label = 0;
11060   u8 flow_label_val;
11061   int src = 0, dst = 0;
11062   ip6_address_t src_val, dst_val;
11063   int proto = 0;
11064   u32 proto_val;
11065   int payload_length = 0;
11066   u32 payload_length_val;
11067   int hop_limit = 0;
11068   int hop_limit_val;
11069   u32 ip_version_traffic_class_and_flow_label;
11070
11071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11072     {
11073       if (unformat (input, "version %d", &version_val))
11074         version = 1;
11075       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11076         traffic_class = 1;
11077       else if (unformat (input, "flow_label %d", &flow_label_val))
11078         flow_label = 1;
11079       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11080         src = 1;
11081       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11082         dst = 1;
11083       else if (unformat (input, "proto %d", &proto_val))
11084         proto = 1;
11085       else if (unformat (input, "payload_length %d", &payload_length_val))
11086         payload_length = 1;
11087       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11088         hop_limit = 1;
11089       else
11090         break;
11091     }
11092
11093   if (version + traffic_class + flow_label + src + dst + proto +
11094       payload_length + hop_limit == 0)
11095     return 0;
11096
11097   /*
11098    * Aligned because we use the real comparison functions
11099    */
11100   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11101
11102   ip = (ip6_header_t *) match;
11103
11104   if (src)
11105     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11106
11107   if (dst)
11108     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11109
11110   if (proto)
11111     ip->protocol = proto_val;
11112
11113   ip_version_traffic_class_and_flow_label = 0;
11114
11115   if (version)
11116     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11117
11118   if (traffic_class)
11119     ip_version_traffic_class_and_flow_label |=
11120       (traffic_class_val & 0xFF) << 20;
11121
11122   if (flow_label)
11123     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11124
11125   ip->ip_version_traffic_class_and_flow_label =
11126     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11127
11128   if (payload_length)
11129     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11130
11131   if (hop_limit)
11132     ip->hop_limit = hop_limit_val;
11133
11134   *matchp = match;
11135   return 1;
11136 }
11137
11138 uword
11139 unformat_l3_match (unformat_input_t * input, va_list * args)
11140 {
11141   u8 **matchp = va_arg (*args, u8 **);
11142
11143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11144     {
11145       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11146         return 1;
11147       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11148         return 1;
11149       else
11150         break;
11151     }
11152   return 0;
11153 }
11154
11155 uword
11156 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11157 {
11158   u8 *tagp = va_arg (*args, u8 *);
11159   u32 tag;
11160
11161   if (unformat (input, "%d", &tag))
11162     {
11163       tagp[0] = (tag >> 8) & 0x0F;
11164       tagp[1] = tag & 0xFF;
11165       return 1;
11166     }
11167
11168   return 0;
11169 }
11170
11171 uword
11172 unformat_l2_match (unformat_input_t * input, va_list * args)
11173 {
11174   u8 **matchp = va_arg (*args, u8 **);
11175   u8 *match = 0;
11176   u8 src = 0;
11177   u8 src_val[6];
11178   u8 dst = 0;
11179   u8 dst_val[6];
11180   u8 proto = 0;
11181   u16 proto_val;
11182   u8 tag1 = 0;
11183   u8 tag1_val[2];
11184   u8 tag2 = 0;
11185   u8 tag2_val[2];
11186   int len = 14;
11187   u8 ignore_tag1 = 0;
11188   u8 ignore_tag2 = 0;
11189   u8 cos1 = 0;
11190   u8 cos2 = 0;
11191   u32 cos1_val = 0;
11192   u32 cos2_val = 0;
11193
11194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11195     {
11196       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11197         src = 1;
11198       else
11199         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11200         dst = 1;
11201       else if (unformat (input, "proto %U",
11202                          unformat_ethernet_type_host_byte_order, &proto_val))
11203         proto = 1;
11204       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11205         tag1 = 1;
11206       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11207         tag2 = 1;
11208       else if (unformat (input, "ignore-tag1"))
11209         ignore_tag1 = 1;
11210       else if (unformat (input, "ignore-tag2"))
11211         ignore_tag2 = 1;
11212       else if (unformat (input, "cos1 %d", &cos1_val))
11213         cos1 = 1;
11214       else if (unformat (input, "cos2 %d", &cos2_val))
11215         cos2 = 1;
11216       else
11217         break;
11218     }
11219   if ((src + dst + proto + tag1 + tag2 +
11220        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11221     return 0;
11222
11223   if (tag1 || ignore_tag1 || cos1)
11224     len = 18;
11225   if (tag2 || ignore_tag2 || cos2)
11226     len = 22;
11227
11228   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11229
11230   if (dst)
11231     clib_memcpy (match, dst_val, 6);
11232
11233   if (src)
11234     clib_memcpy (match + 6, src_val, 6);
11235
11236   if (tag2)
11237     {
11238       /* inner vlan tag */
11239       match[19] = tag2_val[1];
11240       match[18] = tag2_val[0];
11241       if (cos2)
11242         match[18] |= (cos2_val & 0x7) << 5;
11243       if (proto)
11244         {
11245           match[21] = proto_val & 0xff;
11246           match[20] = proto_val >> 8;
11247         }
11248       if (tag1)
11249         {
11250           match[15] = tag1_val[1];
11251           match[14] = tag1_val[0];
11252         }
11253       if (cos1)
11254         match[14] |= (cos1_val & 0x7) << 5;
11255       *matchp = match;
11256       return 1;
11257     }
11258   if (tag1)
11259     {
11260       match[15] = tag1_val[1];
11261       match[14] = tag1_val[0];
11262       if (proto)
11263         {
11264           match[17] = proto_val & 0xff;
11265           match[16] = proto_val >> 8;
11266         }
11267       if (cos1)
11268         match[14] |= (cos1_val & 0x7) << 5;
11269
11270       *matchp = match;
11271       return 1;
11272     }
11273   if (cos2)
11274     match[18] |= (cos2_val & 0x7) << 5;
11275   if (cos1)
11276     match[14] |= (cos1_val & 0x7) << 5;
11277   if (proto)
11278     {
11279       match[13] = proto_val & 0xff;
11280       match[12] = proto_val >> 8;
11281     }
11282
11283   *matchp = match;
11284   return 1;
11285 }
11286
11287 uword
11288 unformat_qos_source (unformat_input_t * input, va_list * args)
11289 {
11290   int *qs = va_arg (*args, int *);
11291
11292   if (unformat (input, "ip"))
11293     *qs = QOS_SOURCE_IP;
11294   else if (unformat (input, "mpls"))
11295     *qs = QOS_SOURCE_MPLS;
11296   else if (unformat (input, "ext"))
11297     *qs = QOS_SOURCE_EXT;
11298   else if (unformat (input, "vlan"))
11299     *qs = QOS_SOURCE_VLAN;
11300   else
11301     return 0;
11302
11303   return 1;
11304 }
11305 #endif
11306
11307 uword
11308 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11309 {
11310   u8 **matchp = va_arg (*args, u8 **);
11311   u32 skip_n_vectors = va_arg (*args, u32);
11312   u32 match_n_vectors = va_arg (*args, u32);
11313
11314   u8 *match = 0;
11315   u8 *l2 = 0;
11316   u8 *l3 = 0;
11317   u8 *l4 = 0;
11318
11319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11320     {
11321       if (unformat (input, "hex %U", unformat_hex_string, &match))
11322         ;
11323       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11324         ;
11325       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11326         ;
11327       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11328         ;
11329       else
11330         break;
11331     }
11332
11333   if (l4 && !l3)
11334     {
11335       vec_free (match);
11336       vec_free (l2);
11337       vec_free (l4);
11338       return 0;
11339     }
11340
11341   if (match || l2 || l3 || l4)
11342     {
11343       if (l2 || l3 || l4)
11344         {
11345           /* "Win a free Ethernet header in every packet" */
11346           if (l2 == 0)
11347             vec_validate_aligned (l2, 13, sizeof (u32x4));
11348           match = l2;
11349           if (vec_len (l3))
11350             {
11351               vec_append_aligned (match, l3, sizeof (u32x4));
11352               vec_free (l3);
11353             }
11354           if (vec_len (l4))
11355             {
11356               vec_append_aligned (match, l4, sizeof (u32x4));
11357               vec_free (l4);
11358             }
11359         }
11360
11361       /* Make sure the vector is big enough even if key is all 0's */
11362       vec_validate_aligned
11363         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11364          sizeof (u32x4));
11365
11366       /* Set size, include skipped vectors */
11367       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11368
11369       *matchp = match;
11370
11371       return 1;
11372     }
11373
11374   return 0;
11375 }
11376
11377 static int
11378 api_classify_add_del_session (vat_main_t * vam)
11379 {
11380   unformat_input_t *i = vam->input;
11381   vl_api_classify_add_del_session_t *mp;
11382   int is_add = 1;
11383   u32 table_index = ~0;
11384   u32 hit_next_index = ~0;
11385   u32 opaque_index = ~0;
11386   u8 *match = 0;
11387   i32 advance = 0;
11388   u32 skip_n_vectors = 0;
11389   u32 match_n_vectors = 0;
11390   u32 action = 0;
11391   u32 metadata = 0;
11392   int ret;
11393
11394   /*
11395    * Warning: you have to supply skip_n and match_n
11396    * because the API client cant simply look at the classify
11397    * table object.
11398    */
11399
11400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11401     {
11402       if (unformat (i, "del"))
11403         is_add = 0;
11404       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11405                          &hit_next_index))
11406         ;
11407       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11408                          &hit_next_index))
11409         ;
11410       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11411                          &hit_next_index))
11412         ;
11413       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11414         ;
11415       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11416         ;
11417       else if (unformat (i, "opaque-index %d", &opaque_index))
11418         ;
11419       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11420         ;
11421       else if (unformat (i, "match_n %d", &match_n_vectors))
11422         ;
11423       else if (unformat (i, "match %U", api_unformat_classify_match,
11424                          &match, skip_n_vectors, match_n_vectors))
11425         ;
11426       else if (unformat (i, "advance %d", &advance))
11427         ;
11428       else if (unformat (i, "table-index %d", &table_index))
11429         ;
11430       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11431         action = 1;
11432       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11433         action = 2;
11434       else if (unformat (i, "action %d", &action))
11435         ;
11436       else if (unformat (i, "metadata %d", &metadata))
11437         ;
11438       else
11439         break;
11440     }
11441
11442   if (table_index == ~0)
11443     {
11444       errmsg ("Table index required");
11445       return -99;
11446     }
11447
11448   if (is_add && match == 0)
11449     {
11450       errmsg ("Match value required");
11451       return -99;
11452     }
11453
11454   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11455
11456   mp->is_add = is_add;
11457   mp->table_index = ntohl (table_index);
11458   mp->hit_next_index = ntohl (hit_next_index);
11459   mp->opaque_index = ntohl (opaque_index);
11460   mp->advance = ntohl (advance);
11461   mp->action = action;
11462   mp->metadata = ntohl (metadata);
11463   mp->match_len = ntohl (vec_len (match));
11464   clib_memcpy (mp->match, match, vec_len (match));
11465   vec_free (match);
11466
11467   S (mp);
11468   W (ret);
11469   return ret;
11470 }
11471
11472 static int
11473 api_classify_set_interface_ip_table (vat_main_t * vam)
11474 {
11475   unformat_input_t *i = vam->input;
11476   vl_api_classify_set_interface_ip_table_t *mp;
11477   u32 sw_if_index;
11478   int sw_if_index_set;
11479   u32 table_index = ~0;
11480   u8 is_ipv6 = 0;
11481   int ret;
11482
11483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11486         sw_if_index_set = 1;
11487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11488         sw_if_index_set = 1;
11489       else if (unformat (i, "table %d", &table_index))
11490         ;
11491       else
11492         {
11493           clib_warning ("parse error '%U'", format_unformat_error, i);
11494           return -99;
11495         }
11496     }
11497
11498   if (sw_if_index_set == 0)
11499     {
11500       errmsg ("missing interface name or sw_if_index");
11501       return -99;
11502     }
11503
11504
11505   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11506
11507   mp->sw_if_index = ntohl (sw_if_index);
11508   mp->table_index = ntohl (table_index);
11509   mp->is_ipv6 = is_ipv6;
11510
11511   S (mp);
11512   W (ret);
11513   return ret;
11514 }
11515
11516 static int
11517 api_classify_set_interface_l2_tables (vat_main_t * vam)
11518 {
11519   unformat_input_t *i = vam->input;
11520   vl_api_classify_set_interface_l2_tables_t *mp;
11521   u32 sw_if_index;
11522   int sw_if_index_set;
11523   u32 ip4_table_index = ~0;
11524   u32 ip6_table_index = ~0;
11525   u32 other_table_index = ~0;
11526   u32 is_input = 1;
11527   int ret;
11528
11529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11530     {
11531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11532         sw_if_index_set = 1;
11533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11534         sw_if_index_set = 1;
11535       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11536         ;
11537       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11538         ;
11539       else if (unformat (i, "other-table %d", &other_table_index))
11540         ;
11541       else if (unformat (i, "is-input %d", &is_input))
11542         ;
11543       else
11544         {
11545           clib_warning ("parse error '%U'", format_unformat_error, i);
11546           return -99;
11547         }
11548     }
11549
11550   if (sw_if_index_set == 0)
11551     {
11552       errmsg ("missing interface name or sw_if_index");
11553       return -99;
11554     }
11555
11556
11557   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11558
11559   mp->sw_if_index = ntohl (sw_if_index);
11560   mp->ip4_table_index = ntohl (ip4_table_index);
11561   mp->ip6_table_index = ntohl (ip6_table_index);
11562   mp->other_table_index = ntohl (other_table_index);
11563   mp->is_input = (u8) is_input;
11564
11565   S (mp);
11566   W (ret);
11567   return ret;
11568 }
11569
11570 static int
11571 api_set_ipfix_exporter (vat_main_t * vam)
11572 {
11573   unformat_input_t *i = vam->input;
11574   vl_api_set_ipfix_exporter_t *mp;
11575   ip4_address_t collector_address;
11576   u8 collector_address_set = 0;
11577   u32 collector_port = ~0;
11578   ip4_address_t src_address;
11579   u8 src_address_set = 0;
11580   u32 vrf_id = ~0;
11581   u32 path_mtu = ~0;
11582   u32 template_interval = ~0;
11583   u8 udp_checksum = 0;
11584   int ret;
11585
11586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11587     {
11588       if (unformat (i, "collector_address %U", unformat_ip4_address,
11589                     &collector_address))
11590         collector_address_set = 1;
11591       else if (unformat (i, "collector_port %d", &collector_port))
11592         ;
11593       else if (unformat (i, "src_address %U", unformat_ip4_address,
11594                          &src_address))
11595         src_address_set = 1;
11596       else if (unformat (i, "vrf_id %d", &vrf_id))
11597         ;
11598       else if (unformat (i, "path_mtu %d", &path_mtu))
11599         ;
11600       else if (unformat (i, "template_interval %d", &template_interval))
11601         ;
11602       else if (unformat (i, "udp_checksum"))
11603         udp_checksum = 1;
11604       else
11605         break;
11606     }
11607
11608   if (collector_address_set == 0)
11609     {
11610       errmsg ("collector_address required");
11611       return -99;
11612     }
11613
11614   if (src_address_set == 0)
11615     {
11616       errmsg ("src_address required");
11617       return -99;
11618     }
11619
11620   M (SET_IPFIX_EXPORTER, mp);
11621
11622   memcpy (mp->collector_address, collector_address.data,
11623           sizeof (collector_address.data));
11624   mp->collector_port = htons ((u16) collector_port);
11625   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11626   mp->vrf_id = htonl (vrf_id);
11627   mp->path_mtu = htonl (path_mtu);
11628   mp->template_interval = htonl (template_interval);
11629   mp->udp_checksum = udp_checksum;
11630
11631   S (mp);
11632   W (ret);
11633   return ret;
11634 }
11635
11636 static int
11637 api_set_ipfix_classify_stream (vat_main_t * vam)
11638 {
11639   unformat_input_t *i = vam->input;
11640   vl_api_set_ipfix_classify_stream_t *mp;
11641   u32 domain_id = 0;
11642   u32 src_port = UDP_DST_PORT_ipfix;
11643   int ret;
11644
11645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11646     {
11647       if (unformat (i, "domain %d", &domain_id))
11648         ;
11649       else if (unformat (i, "src_port %d", &src_port))
11650         ;
11651       else
11652         {
11653           errmsg ("unknown input `%U'", format_unformat_error, i);
11654           return -99;
11655         }
11656     }
11657
11658   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11659
11660   mp->domain_id = htonl (domain_id);
11661   mp->src_port = htons ((u16) src_port);
11662
11663   S (mp);
11664   W (ret);
11665   return ret;
11666 }
11667
11668 static int
11669 api_ipfix_classify_table_add_del (vat_main_t * vam)
11670 {
11671   unformat_input_t *i = vam->input;
11672   vl_api_ipfix_classify_table_add_del_t *mp;
11673   int is_add = -1;
11674   u32 classify_table_index = ~0;
11675   u8 ip_version = 0;
11676   u8 transport_protocol = 255;
11677   int ret;
11678
11679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11680     {
11681       if (unformat (i, "add"))
11682         is_add = 1;
11683       else if (unformat (i, "del"))
11684         is_add = 0;
11685       else if (unformat (i, "table %d", &classify_table_index))
11686         ;
11687       else if (unformat (i, "ip4"))
11688         ip_version = 4;
11689       else if (unformat (i, "ip6"))
11690         ip_version = 6;
11691       else if (unformat (i, "tcp"))
11692         transport_protocol = 6;
11693       else if (unformat (i, "udp"))
11694         transport_protocol = 17;
11695       else
11696         {
11697           errmsg ("unknown input `%U'", format_unformat_error, i);
11698           return -99;
11699         }
11700     }
11701
11702   if (is_add == -1)
11703     {
11704       errmsg ("expecting: add|del");
11705       return -99;
11706     }
11707   if (classify_table_index == ~0)
11708     {
11709       errmsg ("classifier table not specified");
11710       return -99;
11711     }
11712   if (ip_version == 0)
11713     {
11714       errmsg ("IP version not specified");
11715       return -99;
11716     }
11717
11718   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11719
11720   mp->is_add = is_add;
11721   mp->table_id = htonl (classify_table_index);
11722   mp->ip_version = ip_version;
11723   mp->transport_protocol = transport_protocol;
11724
11725   S (mp);
11726   W (ret);
11727   return ret;
11728 }
11729
11730 static int
11731 api_get_node_index (vat_main_t * vam)
11732 {
11733   unformat_input_t *i = vam->input;
11734   vl_api_get_node_index_t *mp;
11735   u8 *name = 0;
11736   int ret;
11737
11738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11739     {
11740       if (unformat (i, "node %s", &name))
11741         ;
11742       else
11743         break;
11744     }
11745   if (name == 0)
11746     {
11747       errmsg ("node name required");
11748       return -99;
11749     }
11750   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11751     {
11752       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11753       return -99;
11754     }
11755
11756   M (GET_NODE_INDEX, mp);
11757   clib_memcpy (mp->node_name, name, vec_len (name));
11758   vec_free (name);
11759
11760   S (mp);
11761   W (ret);
11762   return ret;
11763 }
11764
11765 static int
11766 api_get_next_index (vat_main_t * vam)
11767 {
11768   unformat_input_t *i = vam->input;
11769   vl_api_get_next_index_t *mp;
11770   u8 *node_name = 0, *next_node_name = 0;
11771   int ret;
11772
11773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11774     {
11775       if (unformat (i, "node-name %s", &node_name))
11776         ;
11777       else if (unformat (i, "next-node-name %s", &next_node_name))
11778         break;
11779     }
11780
11781   if (node_name == 0)
11782     {
11783       errmsg ("node name required");
11784       return -99;
11785     }
11786   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11787     {
11788       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11789       return -99;
11790     }
11791
11792   if (next_node_name == 0)
11793     {
11794       errmsg ("next node name required");
11795       return -99;
11796     }
11797   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11798     {
11799       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11800       return -99;
11801     }
11802
11803   M (GET_NEXT_INDEX, mp);
11804   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11805   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11806   vec_free (node_name);
11807   vec_free (next_node_name);
11808
11809   S (mp);
11810   W (ret);
11811   return ret;
11812 }
11813
11814 static int
11815 api_add_node_next (vat_main_t * vam)
11816 {
11817   unformat_input_t *i = vam->input;
11818   vl_api_add_node_next_t *mp;
11819   u8 *name = 0;
11820   u8 *next = 0;
11821   int ret;
11822
11823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11824     {
11825       if (unformat (i, "node %s", &name))
11826         ;
11827       else if (unformat (i, "next %s", &next))
11828         ;
11829       else
11830         break;
11831     }
11832   if (name == 0)
11833     {
11834       errmsg ("node name required");
11835       return -99;
11836     }
11837   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11838     {
11839       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11840       return -99;
11841     }
11842   if (next == 0)
11843     {
11844       errmsg ("next node required");
11845       return -99;
11846     }
11847   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11848     {
11849       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11850       return -99;
11851     }
11852
11853   M (ADD_NODE_NEXT, mp);
11854   clib_memcpy (mp->node_name, name, vec_len (name));
11855   clib_memcpy (mp->next_name, next, vec_len (next));
11856   vec_free (name);
11857   vec_free (next);
11858
11859   S (mp);
11860   W (ret);
11861   return ret;
11862 }
11863
11864 static int
11865 api_l2tpv3_create_tunnel (vat_main_t * vam)
11866 {
11867   unformat_input_t *i = vam->input;
11868   ip6_address_t client_address, our_address;
11869   int client_address_set = 0;
11870   int our_address_set = 0;
11871   u32 local_session_id = 0;
11872   u32 remote_session_id = 0;
11873   u64 local_cookie = 0;
11874   u64 remote_cookie = 0;
11875   u8 l2_sublayer_present = 0;
11876   vl_api_l2tpv3_create_tunnel_t *mp;
11877   int ret;
11878
11879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11880     {
11881       if (unformat (i, "client_address %U", unformat_ip6_address,
11882                     &client_address))
11883         client_address_set = 1;
11884       else if (unformat (i, "our_address %U", unformat_ip6_address,
11885                          &our_address))
11886         our_address_set = 1;
11887       else if (unformat (i, "local_session_id %d", &local_session_id))
11888         ;
11889       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11890         ;
11891       else if (unformat (i, "local_cookie %lld", &local_cookie))
11892         ;
11893       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11894         ;
11895       else if (unformat (i, "l2-sublayer-present"))
11896         l2_sublayer_present = 1;
11897       else
11898         break;
11899     }
11900
11901   if (client_address_set == 0)
11902     {
11903       errmsg ("client_address required");
11904       return -99;
11905     }
11906
11907   if (our_address_set == 0)
11908     {
11909       errmsg ("our_address required");
11910       return -99;
11911     }
11912
11913   M (L2TPV3_CREATE_TUNNEL, mp);
11914
11915   clib_memcpy (mp->client_address, client_address.as_u8,
11916                sizeof (mp->client_address));
11917
11918   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11919
11920   mp->local_session_id = ntohl (local_session_id);
11921   mp->remote_session_id = ntohl (remote_session_id);
11922   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11923   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11924   mp->l2_sublayer_present = l2_sublayer_present;
11925   mp->is_ipv6 = 1;
11926
11927   S (mp);
11928   W (ret);
11929   return ret;
11930 }
11931
11932 static int
11933 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11934 {
11935   unformat_input_t *i = vam->input;
11936   u32 sw_if_index;
11937   u8 sw_if_index_set = 0;
11938   u64 new_local_cookie = 0;
11939   u64 new_remote_cookie = 0;
11940   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11941   int ret;
11942
11943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11944     {
11945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11946         sw_if_index_set = 1;
11947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11948         sw_if_index_set = 1;
11949       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11950         ;
11951       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11952         ;
11953       else
11954         break;
11955     }
11956
11957   if (sw_if_index_set == 0)
11958     {
11959       errmsg ("missing interface name or sw_if_index");
11960       return -99;
11961     }
11962
11963   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11964
11965   mp->sw_if_index = ntohl (sw_if_index);
11966   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11967   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11968
11969   S (mp);
11970   W (ret);
11971   return ret;
11972 }
11973
11974 static int
11975 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11976 {
11977   unformat_input_t *i = vam->input;
11978   vl_api_l2tpv3_interface_enable_disable_t *mp;
11979   u32 sw_if_index;
11980   u8 sw_if_index_set = 0;
11981   u8 enable_disable = 1;
11982   int ret;
11983
11984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11985     {
11986       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11987         sw_if_index_set = 1;
11988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11989         sw_if_index_set = 1;
11990       else if (unformat (i, "enable"))
11991         enable_disable = 1;
11992       else if (unformat (i, "disable"))
11993         enable_disable = 0;
11994       else
11995         break;
11996     }
11997
11998   if (sw_if_index_set == 0)
11999     {
12000       errmsg ("missing interface name or sw_if_index");
12001       return -99;
12002     }
12003
12004   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12005
12006   mp->sw_if_index = ntohl (sw_if_index);
12007   mp->enable_disable = enable_disable;
12008
12009   S (mp);
12010   W (ret);
12011   return ret;
12012 }
12013
12014 static int
12015 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12016 {
12017   unformat_input_t *i = vam->input;
12018   vl_api_l2tpv3_set_lookup_key_t *mp;
12019   u8 key = ~0;
12020   int ret;
12021
12022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12023     {
12024       if (unformat (i, "lookup_v6_src"))
12025         key = L2T_LOOKUP_SRC_ADDRESS;
12026       else if (unformat (i, "lookup_v6_dst"))
12027         key = L2T_LOOKUP_DST_ADDRESS;
12028       else if (unformat (i, "lookup_session_id"))
12029         key = L2T_LOOKUP_SESSION_ID;
12030       else
12031         break;
12032     }
12033
12034   if (key == (u8) ~ 0)
12035     {
12036       errmsg ("l2tp session lookup key unset");
12037       return -99;
12038     }
12039
12040   M (L2TPV3_SET_LOOKUP_KEY, mp);
12041
12042   mp->key = key;
12043
12044   S (mp);
12045   W (ret);
12046   return ret;
12047 }
12048
12049 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12050   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12051 {
12052   vat_main_t *vam = &vat_main;
12053
12054   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12055          format_ip6_address, mp->our_address,
12056          format_ip6_address, mp->client_address,
12057          clib_net_to_host_u32 (mp->sw_if_index));
12058
12059   print (vam->ofp,
12060          "   local cookies %016llx %016llx remote cookie %016llx",
12061          clib_net_to_host_u64 (mp->local_cookie[0]),
12062          clib_net_to_host_u64 (mp->local_cookie[1]),
12063          clib_net_to_host_u64 (mp->remote_cookie));
12064
12065   print (vam->ofp, "   local session-id %d remote session-id %d",
12066          clib_net_to_host_u32 (mp->local_session_id),
12067          clib_net_to_host_u32 (mp->remote_session_id));
12068
12069   print (vam->ofp, "   l2 specific sublayer %s\n",
12070          mp->l2_sublayer_present ? "preset" : "absent");
12071
12072 }
12073
12074 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12075   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12076 {
12077   vat_main_t *vam = &vat_main;
12078   vat_json_node_t *node = NULL;
12079   struct in6_addr addr;
12080
12081   if (VAT_JSON_ARRAY != vam->json_tree.type)
12082     {
12083       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12084       vat_json_init_array (&vam->json_tree);
12085     }
12086   node = vat_json_array_add (&vam->json_tree);
12087
12088   vat_json_init_object (node);
12089
12090   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12091   vat_json_object_add_ip6 (node, "our_address", addr);
12092   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12093   vat_json_object_add_ip6 (node, "client_address", addr);
12094
12095   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12096   vat_json_init_array (lc);
12097   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12098   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12099   vat_json_object_add_uint (node, "remote_cookie",
12100                             clib_net_to_host_u64 (mp->remote_cookie));
12101
12102   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12103   vat_json_object_add_uint (node, "local_session_id",
12104                             clib_net_to_host_u32 (mp->local_session_id));
12105   vat_json_object_add_uint (node, "remote_session_id",
12106                             clib_net_to_host_u32 (mp->remote_session_id));
12107   vat_json_object_add_string_copy (node, "l2_sublayer",
12108                                    mp->l2_sublayer_present ? (u8 *) "present"
12109                                    : (u8 *) "absent");
12110 }
12111
12112 static int
12113 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12114 {
12115   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12116   vl_api_control_ping_t *mp_ping;
12117   int ret;
12118
12119   /* Get list of l2tpv3-tunnel interfaces */
12120   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12121   S (mp);
12122
12123   /* Use a control ping for synchronization */
12124   MPING (CONTROL_PING, mp_ping);
12125   S (mp_ping);
12126
12127   W (ret);
12128   return ret;
12129 }
12130
12131
12132 static void vl_api_sw_interface_tap_v2_details_t_handler
12133   (vl_api_sw_interface_tap_v2_details_t * mp)
12134 {
12135   vat_main_t *vam = &vat_main;
12136
12137   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12138                     mp->host_ip4_prefix_len);
12139   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12140                     mp->host_ip6_prefix_len);
12141
12142   print (vam->ofp,
12143          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12144          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12145          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12146          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12147          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12148
12149   vec_free (ip4);
12150   vec_free (ip6);
12151 }
12152
12153 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12154   (vl_api_sw_interface_tap_v2_details_t * mp)
12155 {
12156   vat_main_t *vam = &vat_main;
12157   vat_json_node_t *node = NULL;
12158
12159   if (VAT_JSON_ARRAY != vam->json_tree.type)
12160     {
12161       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12162       vat_json_init_array (&vam->json_tree);
12163     }
12164   node = vat_json_array_add (&vam->json_tree);
12165
12166   vat_json_init_object (node);
12167   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12168   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12169   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12170   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12171   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12172   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12173   vat_json_object_add_string_copy (node, "host_mac_addr",
12174                                    format (0, "%U", format_ethernet_address,
12175                                            &mp->host_mac_addr));
12176   vat_json_object_add_string_copy (node, "host_namespace",
12177                                    mp->host_namespace);
12178   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12179   vat_json_object_add_string_copy (node, "host_ip4_addr",
12180                                    format (0, "%U/%d", format_ip4_address,
12181                                            mp->host_ip4_addr,
12182                                            mp->host_ip4_prefix_len));
12183   vat_json_object_add_string_copy (node, "host_ip6_addr",
12184                                    format (0, "%U/%d", format_ip6_address,
12185                                            mp->host_ip6_addr,
12186                                            mp->host_ip6_prefix_len));
12187
12188 }
12189
12190 static int
12191 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12192 {
12193   vl_api_sw_interface_tap_v2_dump_t *mp;
12194   vl_api_control_ping_t *mp_ping;
12195   int ret;
12196
12197   print (vam->ofp,
12198          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12199          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12200          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12201          "host_ip6_addr");
12202
12203   /* Get list of tap interfaces */
12204   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12205   S (mp);
12206
12207   /* Use a control ping for synchronization */
12208   MPING (CONTROL_PING, mp_ping);
12209   S (mp_ping);
12210
12211   W (ret);
12212   return ret;
12213 }
12214
12215 static void vl_api_sw_interface_virtio_pci_details_t_handler
12216   (vl_api_sw_interface_virtio_pci_details_t * mp)
12217 {
12218   vat_main_t *vam = &vat_main;
12219
12220   typedef union
12221   {
12222     struct
12223     {
12224       u16 domain;
12225       u8 bus;
12226       u8 slot:5;
12227       u8 function:3;
12228     };
12229     u32 as_u32;
12230   } pci_addr_t;
12231   pci_addr_t addr;
12232   addr.as_u32 = ntohl (mp->pci_addr);
12233   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12234                          addr.slot, addr.function);
12235
12236   print (vam->ofp,
12237          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12238          pci_addr, ntohl (mp->sw_if_index),
12239          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12240          format_ethernet_address, mp->mac_addr,
12241          clib_net_to_host_u64 (mp->features));
12242   vec_free (pci_addr);
12243 }
12244
12245 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12246   (vl_api_sw_interface_virtio_pci_details_t * mp)
12247 {
12248   vat_main_t *vam = &vat_main;
12249   vat_json_node_t *node = NULL;
12250
12251   if (VAT_JSON_ARRAY != vam->json_tree.type)
12252     {
12253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12254       vat_json_init_array (&vam->json_tree);
12255     }
12256   node = vat_json_array_add (&vam->json_tree);
12257
12258   vat_json_init_object (node);
12259   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12260   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12261   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12262   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12263   vat_json_object_add_uint (node, "features",
12264                             clib_net_to_host_u64 (mp->features));
12265   vat_json_object_add_string_copy (node, "mac_addr",
12266                                    format (0, "%U", format_ethernet_address,
12267                                            &mp->mac_addr));
12268 }
12269
12270 static int
12271 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12272 {
12273   vl_api_sw_interface_virtio_pci_dump_t *mp;
12274   vl_api_control_ping_t *mp_ping;
12275   int ret;
12276
12277   print (vam->ofp,
12278          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12279          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12280          "mac_addr", "features");
12281
12282   /* Get list of tap interfaces */
12283   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12284   S (mp);
12285
12286   /* Use a control ping for synchronization */
12287   MPING (CONTROL_PING, mp_ping);
12288   S (mp_ping);
12289
12290   W (ret);
12291   return ret;
12292 }
12293
12294 static int
12295 api_vxlan_offload_rx (vat_main_t * vam)
12296 {
12297   unformat_input_t *line_input = vam->input;
12298   vl_api_vxlan_offload_rx_t *mp;
12299   u32 hw_if_index = ~0, rx_if_index = ~0;
12300   u8 is_add = 1;
12301   int ret;
12302
12303   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12304     {
12305       if (unformat (line_input, "del"))
12306         is_add = 0;
12307       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12308                          &hw_if_index))
12309         ;
12310       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12311         ;
12312       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12313                          &rx_if_index))
12314         ;
12315       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12316         ;
12317       else
12318         {
12319           errmsg ("parse error '%U'", format_unformat_error, line_input);
12320           return -99;
12321         }
12322     }
12323
12324   if (hw_if_index == ~0)
12325     {
12326       errmsg ("no hw interface");
12327       return -99;
12328     }
12329
12330   if (rx_if_index == ~0)
12331     {
12332       errmsg ("no rx tunnel");
12333       return -99;
12334     }
12335
12336   M (VXLAN_OFFLOAD_RX, mp);
12337
12338   mp->hw_if_index = ntohl (hw_if_index);
12339   mp->sw_if_index = ntohl (rx_if_index);
12340   mp->enable = is_add;
12341
12342   S (mp);
12343   W (ret);
12344   return ret;
12345 }
12346
12347 static uword unformat_vxlan_decap_next
12348   (unformat_input_t * input, va_list * args)
12349 {
12350   u32 *result = va_arg (*args, u32 *);
12351   u32 tmp;
12352
12353   if (unformat (input, "l2"))
12354     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12355   else if (unformat (input, "%d", &tmp))
12356     *result = tmp;
12357   else
12358     return 0;
12359   return 1;
12360 }
12361
12362 static int
12363 api_vxlan_add_del_tunnel (vat_main_t * vam)
12364 {
12365   unformat_input_t *line_input = vam->input;
12366   vl_api_vxlan_add_del_tunnel_t *mp;
12367   ip46_address_t src, dst;
12368   u8 is_add = 1;
12369   u8 ipv4_set = 0, ipv6_set = 0;
12370   u8 src_set = 0;
12371   u8 dst_set = 0;
12372   u8 grp_set = 0;
12373   u32 instance = ~0;
12374   u32 mcast_sw_if_index = ~0;
12375   u32 encap_vrf_id = 0;
12376   u32 decap_next_index = ~0;
12377   u32 vni = 0;
12378   int ret;
12379
12380   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12381   clib_memset (&src, 0, sizeof src);
12382   clib_memset (&dst, 0, sizeof dst);
12383
12384   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12385     {
12386       if (unformat (line_input, "del"))
12387         is_add = 0;
12388       else if (unformat (line_input, "instance %d", &instance))
12389         ;
12390       else
12391         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12392         {
12393           ipv4_set = 1;
12394           src_set = 1;
12395         }
12396       else
12397         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12398         {
12399           ipv4_set = 1;
12400           dst_set = 1;
12401         }
12402       else
12403         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12404         {
12405           ipv6_set = 1;
12406           src_set = 1;
12407         }
12408       else
12409         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12410         {
12411           ipv6_set = 1;
12412           dst_set = 1;
12413         }
12414       else if (unformat (line_input, "group %U %U",
12415                          unformat_ip4_address, &dst.ip4,
12416                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12417         {
12418           grp_set = dst_set = 1;
12419           ipv4_set = 1;
12420         }
12421       else if (unformat (line_input, "group %U",
12422                          unformat_ip4_address, &dst.ip4))
12423         {
12424           grp_set = dst_set = 1;
12425           ipv4_set = 1;
12426         }
12427       else if (unformat (line_input, "group %U %U",
12428                          unformat_ip6_address, &dst.ip6,
12429                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12430         {
12431           grp_set = dst_set = 1;
12432           ipv6_set = 1;
12433         }
12434       else if (unformat (line_input, "group %U",
12435                          unformat_ip6_address, &dst.ip6))
12436         {
12437           grp_set = dst_set = 1;
12438           ipv6_set = 1;
12439         }
12440       else
12441         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12442         ;
12443       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12444         ;
12445       else if (unformat (line_input, "decap-next %U",
12446                          unformat_vxlan_decap_next, &decap_next_index))
12447         ;
12448       else if (unformat (line_input, "vni %d", &vni))
12449         ;
12450       else
12451         {
12452           errmsg ("parse error '%U'", format_unformat_error, line_input);
12453           return -99;
12454         }
12455     }
12456
12457   if (src_set == 0)
12458     {
12459       errmsg ("tunnel src address not specified");
12460       return -99;
12461     }
12462   if (dst_set == 0)
12463     {
12464       errmsg ("tunnel dst address not specified");
12465       return -99;
12466     }
12467
12468   if (grp_set && !ip46_address_is_multicast (&dst))
12469     {
12470       errmsg ("tunnel group address not multicast");
12471       return -99;
12472     }
12473   if (grp_set && mcast_sw_if_index == ~0)
12474     {
12475       errmsg ("tunnel nonexistent multicast device");
12476       return -99;
12477     }
12478   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12479     {
12480       errmsg ("tunnel dst address must be unicast");
12481       return -99;
12482     }
12483
12484
12485   if (ipv4_set && ipv6_set)
12486     {
12487       errmsg ("both IPv4 and IPv6 addresses specified");
12488       return -99;
12489     }
12490
12491   if ((vni == 0) || (vni >> 24))
12492     {
12493       errmsg ("vni not specified or out of range");
12494       return -99;
12495     }
12496
12497   M (VXLAN_ADD_DEL_TUNNEL, mp);
12498
12499   if (ipv6_set)
12500     {
12501       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12502       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12503     }
12504   else
12505     {
12506       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12507       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12508     }
12509
12510   mp->instance = htonl (instance);
12511   mp->encap_vrf_id = ntohl (encap_vrf_id);
12512   mp->decap_next_index = ntohl (decap_next_index);
12513   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12514   mp->vni = ntohl (vni);
12515   mp->is_add = is_add;
12516   mp->is_ipv6 = ipv6_set;
12517
12518   S (mp);
12519   W (ret);
12520   return ret;
12521 }
12522
12523 static void vl_api_vxlan_tunnel_details_t_handler
12524   (vl_api_vxlan_tunnel_details_t * mp)
12525 {
12526   vat_main_t *vam = &vat_main;
12527   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12528   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12529
12530   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12531          ntohl (mp->sw_if_index),
12532          ntohl (mp->instance),
12533          format_ip46_address, &src, IP46_TYPE_ANY,
12534          format_ip46_address, &dst, IP46_TYPE_ANY,
12535          ntohl (mp->encap_vrf_id),
12536          ntohl (mp->decap_next_index), ntohl (mp->vni),
12537          ntohl (mp->mcast_sw_if_index));
12538 }
12539
12540 static void vl_api_vxlan_tunnel_details_t_handler_json
12541   (vl_api_vxlan_tunnel_details_t * mp)
12542 {
12543   vat_main_t *vam = &vat_main;
12544   vat_json_node_t *node = NULL;
12545
12546   if (VAT_JSON_ARRAY != vam->json_tree.type)
12547     {
12548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12549       vat_json_init_array (&vam->json_tree);
12550     }
12551   node = vat_json_array_add (&vam->json_tree);
12552
12553   vat_json_init_object (node);
12554   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12555
12556   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12557
12558   if (mp->is_ipv6)
12559     {
12560       struct in6_addr ip6;
12561
12562       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12563       vat_json_object_add_ip6 (node, "src_address", ip6);
12564       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12565       vat_json_object_add_ip6 (node, "dst_address", ip6);
12566     }
12567   else
12568     {
12569       struct in_addr ip4;
12570
12571       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12572       vat_json_object_add_ip4 (node, "src_address", ip4);
12573       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12574       vat_json_object_add_ip4 (node, "dst_address", ip4);
12575     }
12576   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12577   vat_json_object_add_uint (node, "decap_next_index",
12578                             ntohl (mp->decap_next_index));
12579   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12580   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12581   vat_json_object_add_uint (node, "mcast_sw_if_index",
12582                             ntohl (mp->mcast_sw_if_index));
12583 }
12584
12585 static int
12586 api_vxlan_tunnel_dump (vat_main_t * vam)
12587 {
12588   unformat_input_t *i = vam->input;
12589   vl_api_vxlan_tunnel_dump_t *mp;
12590   vl_api_control_ping_t *mp_ping;
12591   u32 sw_if_index;
12592   u8 sw_if_index_set = 0;
12593   int ret;
12594
12595   /* Parse args required to build the message */
12596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12597     {
12598       if (unformat (i, "sw_if_index %d", &sw_if_index))
12599         sw_if_index_set = 1;
12600       else
12601         break;
12602     }
12603
12604   if (sw_if_index_set == 0)
12605     {
12606       sw_if_index = ~0;
12607     }
12608
12609   if (!vam->json_output)
12610     {
12611       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12612              "sw_if_index", "instance", "src_address", "dst_address",
12613              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12614     }
12615
12616   /* Get list of vxlan-tunnel interfaces */
12617   M (VXLAN_TUNNEL_DUMP, mp);
12618
12619   mp->sw_if_index = htonl (sw_if_index);
12620
12621   S (mp);
12622
12623   /* Use a control ping for synchronization */
12624   MPING (CONTROL_PING, mp_ping);
12625   S (mp_ping);
12626
12627   W (ret);
12628   return ret;
12629 }
12630
12631 static uword unformat_geneve_decap_next
12632   (unformat_input_t * input, va_list * args)
12633 {
12634   u32 *result = va_arg (*args, u32 *);
12635   u32 tmp;
12636
12637   if (unformat (input, "l2"))
12638     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12639   else if (unformat (input, "%d", &tmp))
12640     *result = tmp;
12641   else
12642     return 0;
12643   return 1;
12644 }
12645
12646 static int
12647 api_geneve_add_del_tunnel (vat_main_t * vam)
12648 {
12649   unformat_input_t *line_input = vam->input;
12650   vl_api_geneve_add_del_tunnel_t *mp;
12651   ip46_address_t src, dst;
12652   u8 is_add = 1;
12653   u8 ipv4_set = 0, ipv6_set = 0;
12654   u8 src_set = 0;
12655   u8 dst_set = 0;
12656   u8 grp_set = 0;
12657   u32 mcast_sw_if_index = ~0;
12658   u32 encap_vrf_id = 0;
12659   u32 decap_next_index = ~0;
12660   u32 vni = 0;
12661   int ret;
12662
12663   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12664   clib_memset (&src, 0, sizeof src);
12665   clib_memset (&dst, 0, sizeof dst);
12666
12667   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12668     {
12669       if (unformat (line_input, "del"))
12670         is_add = 0;
12671       else
12672         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12673         {
12674           ipv4_set = 1;
12675           src_set = 1;
12676         }
12677       else
12678         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12679         {
12680           ipv4_set = 1;
12681           dst_set = 1;
12682         }
12683       else
12684         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12685         {
12686           ipv6_set = 1;
12687           src_set = 1;
12688         }
12689       else
12690         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12691         {
12692           ipv6_set = 1;
12693           dst_set = 1;
12694         }
12695       else if (unformat (line_input, "group %U %U",
12696                          unformat_ip4_address, &dst.ip4,
12697                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12698         {
12699           grp_set = dst_set = 1;
12700           ipv4_set = 1;
12701         }
12702       else if (unformat (line_input, "group %U",
12703                          unformat_ip4_address, &dst.ip4))
12704         {
12705           grp_set = dst_set = 1;
12706           ipv4_set = 1;
12707         }
12708       else if (unformat (line_input, "group %U %U",
12709                          unformat_ip6_address, &dst.ip6,
12710                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12711         {
12712           grp_set = dst_set = 1;
12713           ipv6_set = 1;
12714         }
12715       else if (unformat (line_input, "group %U",
12716                          unformat_ip6_address, &dst.ip6))
12717         {
12718           grp_set = dst_set = 1;
12719           ipv6_set = 1;
12720         }
12721       else
12722         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12723         ;
12724       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12725         ;
12726       else if (unformat (line_input, "decap-next %U",
12727                          unformat_geneve_decap_next, &decap_next_index))
12728         ;
12729       else if (unformat (line_input, "vni %d", &vni))
12730         ;
12731       else
12732         {
12733           errmsg ("parse error '%U'", format_unformat_error, line_input);
12734           return -99;
12735         }
12736     }
12737
12738   if (src_set == 0)
12739     {
12740       errmsg ("tunnel src address not specified");
12741       return -99;
12742     }
12743   if (dst_set == 0)
12744     {
12745       errmsg ("tunnel dst address not specified");
12746       return -99;
12747     }
12748
12749   if (grp_set && !ip46_address_is_multicast (&dst))
12750     {
12751       errmsg ("tunnel group address not multicast");
12752       return -99;
12753     }
12754   if (grp_set && mcast_sw_if_index == ~0)
12755     {
12756       errmsg ("tunnel nonexistent multicast device");
12757       return -99;
12758     }
12759   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12760     {
12761       errmsg ("tunnel dst address must be unicast");
12762       return -99;
12763     }
12764
12765
12766   if (ipv4_set && ipv6_set)
12767     {
12768       errmsg ("both IPv4 and IPv6 addresses specified");
12769       return -99;
12770     }
12771
12772   if ((vni == 0) || (vni >> 24))
12773     {
12774       errmsg ("vni not specified or out of range");
12775       return -99;
12776     }
12777
12778   M (GENEVE_ADD_DEL_TUNNEL, mp);
12779
12780   if (ipv6_set)
12781     {
12782       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12783       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12784     }
12785   else
12786     {
12787       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12788       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12789     }
12790   mp->encap_vrf_id = ntohl (encap_vrf_id);
12791   mp->decap_next_index = ntohl (decap_next_index);
12792   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12793   mp->vni = ntohl (vni);
12794   mp->is_add = is_add;
12795   mp->is_ipv6 = ipv6_set;
12796
12797   S (mp);
12798   W (ret);
12799   return ret;
12800 }
12801
12802 static void vl_api_geneve_tunnel_details_t_handler
12803   (vl_api_geneve_tunnel_details_t * mp)
12804 {
12805   vat_main_t *vam = &vat_main;
12806   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12807   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12808
12809   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12810          ntohl (mp->sw_if_index),
12811          format_ip46_address, &src, IP46_TYPE_ANY,
12812          format_ip46_address, &dst, IP46_TYPE_ANY,
12813          ntohl (mp->encap_vrf_id),
12814          ntohl (mp->decap_next_index), ntohl (mp->vni),
12815          ntohl (mp->mcast_sw_if_index));
12816 }
12817
12818 static void vl_api_geneve_tunnel_details_t_handler_json
12819   (vl_api_geneve_tunnel_details_t * mp)
12820 {
12821   vat_main_t *vam = &vat_main;
12822   vat_json_node_t *node = NULL;
12823
12824   if (VAT_JSON_ARRAY != vam->json_tree.type)
12825     {
12826       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12827       vat_json_init_array (&vam->json_tree);
12828     }
12829   node = vat_json_array_add (&vam->json_tree);
12830
12831   vat_json_init_object (node);
12832   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12833   if (mp->is_ipv6)
12834     {
12835       struct in6_addr ip6;
12836
12837       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12838       vat_json_object_add_ip6 (node, "src_address", ip6);
12839       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12840       vat_json_object_add_ip6 (node, "dst_address", ip6);
12841     }
12842   else
12843     {
12844       struct in_addr ip4;
12845
12846       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12847       vat_json_object_add_ip4 (node, "src_address", ip4);
12848       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12849       vat_json_object_add_ip4 (node, "dst_address", ip4);
12850     }
12851   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12852   vat_json_object_add_uint (node, "decap_next_index",
12853                             ntohl (mp->decap_next_index));
12854   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12855   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12856   vat_json_object_add_uint (node, "mcast_sw_if_index",
12857                             ntohl (mp->mcast_sw_if_index));
12858 }
12859
12860 static int
12861 api_geneve_tunnel_dump (vat_main_t * vam)
12862 {
12863   unformat_input_t *i = vam->input;
12864   vl_api_geneve_tunnel_dump_t *mp;
12865   vl_api_control_ping_t *mp_ping;
12866   u32 sw_if_index;
12867   u8 sw_if_index_set = 0;
12868   int ret;
12869
12870   /* Parse args required to build the message */
12871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12872     {
12873       if (unformat (i, "sw_if_index %d", &sw_if_index))
12874         sw_if_index_set = 1;
12875       else
12876         break;
12877     }
12878
12879   if (sw_if_index_set == 0)
12880     {
12881       sw_if_index = ~0;
12882     }
12883
12884   if (!vam->json_output)
12885     {
12886       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12887              "sw_if_index", "local_address", "remote_address",
12888              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12889     }
12890
12891   /* Get list of geneve-tunnel interfaces */
12892   M (GENEVE_TUNNEL_DUMP, mp);
12893
12894   mp->sw_if_index = htonl (sw_if_index);
12895
12896   S (mp);
12897
12898   /* Use a control ping for synchronization */
12899   M (CONTROL_PING, mp_ping);
12900   S (mp_ping);
12901
12902   W (ret);
12903   return ret;
12904 }
12905
12906 static int
12907 api_gre_tunnel_add_del (vat_main_t * vam)
12908 {
12909   unformat_input_t *line_input = vam->input;
12910   vl_api_address_t src = { }, dst =
12911   {
12912   };
12913   vl_api_gre_tunnel_add_del_t *mp;
12914   vl_api_gre_tunnel_type_t t_type;
12915   u8 is_add = 1;
12916   u8 src_set = 0;
12917   u8 dst_set = 0;
12918   u32 outer_fib_id = 0;
12919   u32 session_id = 0;
12920   u32 instance = ~0;
12921   int ret;
12922
12923   t_type = GRE_API_TUNNEL_TYPE_L3;
12924
12925   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12926     {
12927       if (unformat (line_input, "del"))
12928         is_add = 0;
12929       else if (unformat (line_input, "instance %d", &instance))
12930         ;
12931       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12932         {
12933           src_set = 1;
12934         }
12935       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12936         {
12937           dst_set = 1;
12938         }
12939       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12940         ;
12941       else if (unformat (line_input, "teb"))
12942         t_type = GRE_API_TUNNEL_TYPE_TEB;
12943       else if (unformat (line_input, "erspan %d", &session_id))
12944         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12945       else
12946         {
12947           errmsg ("parse error '%U'", format_unformat_error, line_input);
12948           return -99;
12949         }
12950     }
12951
12952   if (src_set == 0)
12953     {
12954       errmsg ("tunnel src address not specified");
12955       return -99;
12956     }
12957   if (dst_set == 0)
12958     {
12959       errmsg ("tunnel dst address not specified");
12960       return -99;
12961     }
12962
12963   M (GRE_TUNNEL_ADD_DEL, mp);
12964
12965   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12966   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12967
12968   mp->tunnel.instance = htonl (instance);
12969   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12970   mp->is_add = is_add;
12971   mp->tunnel.session_id = htons ((u16) session_id);
12972   mp->tunnel.type = htonl (t_type);
12973
12974   S (mp);
12975   W (ret);
12976   return ret;
12977 }
12978
12979 static void vl_api_gre_tunnel_details_t_handler
12980   (vl_api_gre_tunnel_details_t * mp)
12981 {
12982   vat_main_t *vam = &vat_main;
12983
12984   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12985          ntohl (mp->tunnel.sw_if_index),
12986          ntohl (mp->tunnel.instance),
12987          format_vl_api_address, &mp->tunnel.src,
12988          format_vl_api_address, &mp->tunnel.dst,
12989          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12990          ntohl (mp->tunnel.session_id));
12991 }
12992
12993 static void vl_api_gre_tunnel_details_t_handler_json
12994   (vl_api_gre_tunnel_details_t * mp)
12995 {
12996   vat_main_t *vam = &vat_main;
12997   vat_json_node_t *node = NULL;
12998
12999   if (VAT_JSON_ARRAY != vam->json_tree.type)
13000     {
13001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13002       vat_json_init_array (&vam->json_tree);
13003     }
13004   node = vat_json_array_add (&vam->json_tree);
13005
13006   vat_json_init_object (node);
13007   vat_json_object_add_uint (node, "sw_if_index",
13008                             ntohl (mp->tunnel.sw_if_index));
13009   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13010
13011   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13012   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13013   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13014   vat_json_object_add_uint (node, "outer_fib_id",
13015                             ntohl (mp->tunnel.outer_fib_id));
13016   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13017 }
13018
13019 static int
13020 api_gre_tunnel_dump (vat_main_t * vam)
13021 {
13022   unformat_input_t *i = vam->input;
13023   vl_api_gre_tunnel_dump_t *mp;
13024   vl_api_control_ping_t *mp_ping;
13025   u32 sw_if_index;
13026   u8 sw_if_index_set = 0;
13027   int ret;
13028
13029   /* Parse args required to build the message */
13030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13031     {
13032       if (unformat (i, "sw_if_index %d", &sw_if_index))
13033         sw_if_index_set = 1;
13034       else
13035         break;
13036     }
13037
13038   if (sw_if_index_set == 0)
13039     {
13040       sw_if_index = ~0;
13041     }
13042
13043   if (!vam->json_output)
13044     {
13045       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13046              "sw_if_index", "instance", "src_address", "dst_address",
13047              "tunnel_type", "outer_fib_id", "session_id");
13048     }
13049
13050   /* Get list of gre-tunnel interfaces */
13051   M (GRE_TUNNEL_DUMP, mp);
13052
13053   mp->sw_if_index = htonl (sw_if_index);
13054
13055   S (mp);
13056
13057   /* Use a control ping for synchronization */
13058   MPING (CONTROL_PING, mp_ping);
13059   S (mp_ping);
13060
13061   W (ret);
13062   return ret;
13063 }
13064
13065 static int
13066 api_l2_fib_clear_table (vat_main_t * vam)
13067 {
13068 //  unformat_input_t * i = vam->input;
13069   vl_api_l2_fib_clear_table_t *mp;
13070   int ret;
13071
13072   M (L2_FIB_CLEAR_TABLE, mp);
13073
13074   S (mp);
13075   W (ret);
13076   return ret;
13077 }
13078
13079 static int
13080 api_l2_interface_efp_filter (vat_main_t * vam)
13081 {
13082   unformat_input_t *i = vam->input;
13083   vl_api_l2_interface_efp_filter_t *mp;
13084   u32 sw_if_index;
13085   u8 enable = 1;
13086   u8 sw_if_index_set = 0;
13087   int ret;
13088
13089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13090     {
13091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13092         sw_if_index_set = 1;
13093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13094         sw_if_index_set = 1;
13095       else if (unformat (i, "enable"))
13096         enable = 1;
13097       else if (unformat (i, "disable"))
13098         enable = 0;
13099       else
13100         {
13101           clib_warning ("parse error '%U'", format_unformat_error, i);
13102           return -99;
13103         }
13104     }
13105
13106   if (sw_if_index_set == 0)
13107     {
13108       errmsg ("missing sw_if_index");
13109       return -99;
13110     }
13111
13112   M (L2_INTERFACE_EFP_FILTER, mp);
13113
13114   mp->sw_if_index = ntohl (sw_if_index);
13115   mp->enable_disable = enable;
13116
13117   S (mp);
13118   W (ret);
13119   return ret;
13120 }
13121
13122 #define foreach_vtr_op                          \
13123 _("disable",  L2_VTR_DISABLED)                  \
13124 _("push-1",  L2_VTR_PUSH_1)                     \
13125 _("push-2",  L2_VTR_PUSH_2)                     \
13126 _("pop-1",  L2_VTR_POP_1)                       \
13127 _("pop-2",  L2_VTR_POP_2)                       \
13128 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13129 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13130 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13131 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13132
13133 static int
13134 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13135 {
13136   unformat_input_t *i = vam->input;
13137   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13138   u32 sw_if_index;
13139   u8 sw_if_index_set = 0;
13140   u8 vtr_op_set = 0;
13141   u32 vtr_op = 0;
13142   u32 push_dot1q = 1;
13143   u32 tag1 = ~0;
13144   u32 tag2 = ~0;
13145   int ret;
13146
13147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13148     {
13149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13150         sw_if_index_set = 1;
13151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13152         sw_if_index_set = 1;
13153       else if (unformat (i, "vtr_op %d", &vtr_op))
13154         vtr_op_set = 1;
13155 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13156       foreach_vtr_op
13157 #undef _
13158         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13159         ;
13160       else if (unformat (i, "tag1 %d", &tag1))
13161         ;
13162       else if (unformat (i, "tag2 %d", &tag2))
13163         ;
13164       else
13165         {
13166           clib_warning ("parse error '%U'", format_unformat_error, i);
13167           return -99;
13168         }
13169     }
13170
13171   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13172     {
13173       errmsg ("missing vtr operation or sw_if_index");
13174       return -99;
13175     }
13176
13177   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13178   mp->sw_if_index = ntohl (sw_if_index);
13179   mp->vtr_op = ntohl (vtr_op);
13180   mp->push_dot1q = ntohl (push_dot1q);
13181   mp->tag1 = ntohl (tag1);
13182   mp->tag2 = ntohl (tag2);
13183
13184   S (mp);
13185   W (ret);
13186   return ret;
13187 }
13188
13189 static int
13190 api_create_vhost_user_if (vat_main_t * vam)
13191 {
13192   unformat_input_t *i = vam->input;
13193   vl_api_create_vhost_user_if_t *mp;
13194   u8 *file_name;
13195   u8 is_server = 0;
13196   u8 file_name_set = 0;
13197   u32 custom_dev_instance = ~0;
13198   u8 hwaddr[6];
13199   u8 use_custom_mac = 0;
13200   u8 disable_mrg_rxbuf = 0;
13201   u8 disable_indirect_desc = 0;
13202   u8 *tag = 0;
13203   u8 enable_gso = 0;
13204   int ret;
13205
13206   /* Shut up coverity */
13207   clib_memset (hwaddr, 0, sizeof (hwaddr));
13208
13209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13210     {
13211       if (unformat (i, "socket %s", &file_name))
13212         {
13213           file_name_set = 1;
13214         }
13215       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13216         ;
13217       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13218         use_custom_mac = 1;
13219       else if (unformat (i, "server"))
13220         is_server = 1;
13221       else if (unformat (i, "disable_mrg_rxbuf"))
13222         disable_mrg_rxbuf = 1;
13223       else if (unformat (i, "disable_indirect_desc"))
13224         disable_indirect_desc = 1;
13225       else if (unformat (i, "gso"))
13226         enable_gso = 1;
13227       else if (unformat (i, "tag %s", &tag))
13228         ;
13229       else
13230         break;
13231     }
13232
13233   if (file_name_set == 0)
13234     {
13235       errmsg ("missing socket file name");
13236       return -99;
13237     }
13238
13239   if (vec_len (file_name) > 255)
13240     {
13241       errmsg ("socket file name too long");
13242       return -99;
13243     }
13244   vec_add1 (file_name, 0);
13245
13246   M (CREATE_VHOST_USER_IF, mp);
13247
13248   mp->is_server = is_server;
13249   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13250   mp->disable_indirect_desc = disable_indirect_desc;
13251   mp->enable_gso = enable_gso;
13252   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13253   vec_free (file_name);
13254   if (custom_dev_instance != ~0)
13255     {
13256       mp->renumber = 1;
13257       mp->custom_dev_instance = ntohl (custom_dev_instance);
13258     }
13259
13260   mp->use_custom_mac = use_custom_mac;
13261   clib_memcpy (mp->mac_address, hwaddr, 6);
13262   if (tag)
13263     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13264   vec_free (tag);
13265
13266   S (mp);
13267   W (ret);
13268   return ret;
13269 }
13270
13271 static int
13272 api_modify_vhost_user_if (vat_main_t * vam)
13273 {
13274   unformat_input_t *i = vam->input;
13275   vl_api_modify_vhost_user_if_t *mp;
13276   u8 *file_name;
13277   u8 is_server = 0;
13278   u8 file_name_set = 0;
13279   u32 custom_dev_instance = ~0;
13280   u8 sw_if_index_set = 0;
13281   u32 sw_if_index = (u32) ~ 0;
13282   u8 enable_gso = 0;
13283   int ret;
13284
13285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13286     {
13287       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13288         sw_if_index_set = 1;
13289       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13290         sw_if_index_set = 1;
13291       else if (unformat (i, "socket %s", &file_name))
13292         {
13293           file_name_set = 1;
13294         }
13295       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13296         ;
13297       else if (unformat (i, "server"))
13298         is_server = 1;
13299       else if (unformat (i, "gso"))
13300         enable_gso = 1;
13301       else
13302         break;
13303     }
13304
13305   if (sw_if_index_set == 0)
13306     {
13307       errmsg ("missing sw_if_index or interface name");
13308       return -99;
13309     }
13310
13311   if (file_name_set == 0)
13312     {
13313       errmsg ("missing socket file name");
13314       return -99;
13315     }
13316
13317   if (vec_len (file_name) > 255)
13318     {
13319       errmsg ("socket file name too long");
13320       return -99;
13321     }
13322   vec_add1 (file_name, 0);
13323
13324   M (MODIFY_VHOST_USER_IF, mp);
13325
13326   mp->sw_if_index = ntohl (sw_if_index);
13327   mp->is_server = is_server;
13328   mp->enable_gso = enable_gso;
13329   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13330   vec_free (file_name);
13331   if (custom_dev_instance != ~0)
13332     {
13333       mp->renumber = 1;
13334       mp->custom_dev_instance = ntohl (custom_dev_instance);
13335     }
13336
13337   S (mp);
13338   W (ret);
13339   return ret;
13340 }
13341
13342 static int
13343 api_delete_vhost_user_if (vat_main_t * vam)
13344 {
13345   unformat_input_t *i = vam->input;
13346   vl_api_delete_vhost_user_if_t *mp;
13347   u32 sw_if_index = ~0;
13348   u8 sw_if_index_set = 0;
13349   int ret;
13350
13351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13352     {
13353       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13354         sw_if_index_set = 1;
13355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13356         sw_if_index_set = 1;
13357       else
13358         break;
13359     }
13360
13361   if (sw_if_index_set == 0)
13362     {
13363       errmsg ("missing sw_if_index or interface name");
13364       return -99;
13365     }
13366
13367
13368   M (DELETE_VHOST_USER_IF, mp);
13369
13370   mp->sw_if_index = ntohl (sw_if_index);
13371
13372   S (mp);
13373   W (ret);
13374   return ret;
13375 }
13376
13377 static void vl_api_sw_interface_vhost_user_details_t_handler
13378   (vl_api_sw_interface_vhost_user_details_t * mp)
13379 {
13380   vat_main_t *vam = &vat_main;
13381
13382   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13383          (char *) mp->interface_name,
13384          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13385          clib_net_to_host_u64 (mp->features), mp->is_server,
13386          ntohl (mp->num_regions), (char *) mp->sock_filename);
13387   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13388 }
13389
13390 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13391   (vl_api_sw_interface_vhost_user_details_t * mp)
13392 {
13393   vat_main_t *vam = &vat_main;
13394   vat_json_node_t *node = NULL;
13395
13396   if (VAT_JSON_ARRAY != vam->json_tree.type)
13397     {
13398       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13399       vat_json_init_array (&vam->json_tree);
13400     }
13401   node = vat_json_array_add (&vam->json_tree);
13402
13403   vat_json_init_object (node);
13404   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13405   vat_json_object_add_string_copy (node, "interface_name",
13406                                    mp->interface_name);
13407   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13408                             ntohl (mp->virtio_net_hdr_sz));
13409   vat_json_object_add_uint (node, "features",
13410                             clib_net_to_host_u64 (mp->features));
13411   vat_json_object_add_uint (node, "is_server", mp->is_server);
13412   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13413   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13414   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13415 }
13416
13417 static int
13418 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13419 {
13420   vl_api_sw_interface_vhost_user_dump_t *mp;
13421   vl_api_control_ping_t *mp_ping;
13422   int ret;
13423   print (vam->ofp,
13424          "Interface name            idx hdr_sz features server regions filename");
13425
13426   /* Get list of vhost-user interfaces */
13427   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13428   S (mp);
13429
13430   /* Use a control ping for synchronization */
13431   MPING (CONTROL_PING, mp_ping);
13432   S (mp_ping);
13433
13434   W (ret);
13435   return ret;
13436 }
13437
13438 static int
13439 api_show_version (vat_main_t * vam)
13440 {
13441   vl_api_show_version_t *mp;
13442   int ret;
13443
13444   M (SHOW_VERSION, mp);
13445
13446   S (mp);
13447   W (ret);
13448   return ret;
13449 }
13450
13451
13452 static int
13453 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13454 {
13455   unformat_input_t *line_input = vam->input;
13456   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13457   ip4_address_t local4, remote4;
13458   ip6_address_t local6, remote6;
13459   u8 is_add = 1;
13460   u8 ipv4_set = 0, ipv6_set = 0;
13461   u8 local_set = 0;
13462   u8 remote_set = 0;
13463   u8 grp_set = 0;
13464   u32 mcast_sw_if_index = ~0;
13465   u32 encap_vrf_id = 0;
13466   u32 decap_vrf_id = 0;
13467   u8 protocol = ~0;
13468   u32 vni;
13469   u8 vni_set = 0;
13470   int ret;
13471
13472   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13473   clib_memset (&local4, 0, sizeof local4);
13474   clib_memset (&remote4, 0, sizeof remote4);
13475   clib_memset (&local6, 0, sizeof local6);
13476   clib_memset (&remote6, 0, sizeof remote6);
13477
13478   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13479     {
13480       if (unformat (line_input, "del"))
13481         is_add = 0;
13482       else if (unformat (line_input, "local %U",
13483                          unformat_ip4_address, &local4))
13484         {
13485           local_set = 1;
13486           ipv4_set = 1;
13487         }
13488       else if (unformat (line_input, "remote %U",
13489                          unformat_ip4_address, &remote4))
13490         {
13491           remote_set = 1;
13492           ipv4_set = 1;
13493         }
13494       else if (unformat (line_input, "local %U",
13495                          unformat_ip6_address, &local6))
13496         {
13497           local_set = 1;
13498           ipv6_set = 1;
13499         }
13500       else if (unformat (line_input, "remote %U",
13501                          unformat_ip6_address, &remote6))
13502         {
13503           remote_set = 1;
13504           ipv6_set = 1;
13505         }
13506       else if (unformat (line_input, "group %U %U",
13507                          unformat_ip4_address, &remote4,
13508                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13509         {
13510           grp_set = remote_set = 1;
13511           ipv4_set = 1;
13512         }
13513       else if (unformat (line_input, "group %U",
13514                          unformat_ip4_address, &remote4))
13515         {
13516           grp_set = remote_set = 1;
13517           ipv4_set = 1;
13518         }
13519       else if (unformat (line_input, "group %U %U",
13520                          unformat_ip6_address, &remote6,
13521                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13522         {
13523           grp_set = remote_set = 1;
13524           ipv6_set = 1;
13525         }
13526       else if (unformat (line_input, "group %U",
13527                          unformat_ip6_address, &remote6))
13528         {
13529           grp_set = remote_set = 1;
13530           ipv6_set = 1;
13531         }
13532       else
13533         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13534         ;
13535       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13536         ;
13537       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13538         ;
13539       else if (unformat (line_input, "vni %d", &vni))
13540         vni_set = 1;
13541       else if (unformat (line_input, "next-ip4"))
13542         protocol = 1;
13543       else if (unformat (line_input, "next-ip6"))
13544         protocol = 2;
13545       else if (unformat (line_input, "next-ethernet"))
13546         protocol = 3;
13547       else if (unformat (line_input, "next-nsh"))
13548         protocol = 4;
13549       else
13550         {
13551           errmsg ("parse error '%U'", format_unformat_error, line_input);
13552           return -99;
13553         }
13554     }
13555
13556   if (local_set == 0)
13557     {
13558       errmsg ("tunnel local address not specified");
13559       return -99;
13560     }
13561   if (remote_set == 0)
13562     {
13563       errmsg ("tunnel remote address not specified");
13564       return -99;
13565     }
13566   if (grp_set && mcast_sw_if_index == ~0)
13567     {
13568       errmsg ("tunnel nonexistent multicast device");
13569       return -99;
13570     }
13571   if (ipv4_set && ipv6_set)
13572     {
13573       errmsg ("both IPv4 and IPv6 addresses specified");
13574       return -99;
13575     }
13576
13577   if (vni_set == 0)
13578     {
13579       errmsg ("vni not specified");
13580       return -99;
13581     }
13582
13583   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13584
13585
13586   if (ipv6_set)
13587     {
13588       clib_memcpy (&mp->local, &local6, sizeof (local6));
13589       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13590     }
13591   else
13592     {
13593       clib_memcpy (&mp->local, &local4, sizeof (local4));
13594       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13595     }
13596
13597   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13598   mp->encap_vrf_id = ntohl (encap_vrf_id);
13599   mp->decap_vrf_id = ntohl (decap_vrf_id);
13600   mp->protocol = protocol;
13601   mp->vni = ntohl (vni);
13602   mp->is_add = is_add;
13603   mp->is_ipv6 = ipv6_set;
13604
13605   S (mp);
13606   W (ret);
13607   return ret;
13608 }
13609
13610 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13611   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13612 {
13613   vat_main_t *vam = &vat_main;
13614   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13615   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13616
13617   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13618          ntohl (mp->sw_if_index),
13619          format_ip46_address, &local, IP46_TYPE_ANY,
13620          format_ip46_address, &remote, IP46_TYPE_ANY,
13621          ntohl (mp->vni), mp->protocol,
13622          ntohl (mp->mcast_sw_if_index),
13623          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13624 }
13625
13626
13627 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13628   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13629 {
13630   vat_main_t *vam = &vat_main;
13631   vat_json_node_t *node = NULL;
13632   struct in_addr ip4;
13633   struct in6_addr ip6;
13634
13635   if (VAT_JSON_ARRAY != vam->json_tree.type)
13636     {
13637       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13638       vat_json_init_array (&vam->json_tree);
13639     }
13640   node = vat_json_array_add (&vam->json_tree);
13641
13642   vat_json_init_object (node);
13643   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13644   if (mp->is_ipv6)
13645     {
13646       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13647       vat_json_object_add_ip6 (node, "local", ip6);
13648       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13649       vat_json_object_add_ip6 (node, "remote", ip6);
13650     }
13651   else
13652     {
13653       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13654       vat_json_object_add_ip4 (node, "local", ip4);
13655       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13656       vat_json_object_add_ip4 (node, "remote", ip4);
13657     }
13658   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13659   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13660   vat_json_object_add_uint (node, "mcast_sw_if_index",
13661                             ntohl (mp->mcast_sw_if_index));
13662   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13663   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13664   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13665 }
13666
13667 static int
13668 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13669 {
13670   unformat_input_t *i = vam->input;
13671   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13672   vl_api_control_ping_t *mp_ping;
13673   u32 sw_if_index;
13674   u8 sw_if_index_set = 0;
13675   int ret;
13676
13677   /* Parse args required to build the message */
13678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13679     {
13680       if (unformat (i, "sw_if_index %d", &sw_if_index))
13681         sw_if_index_set = 1;
13682       else
13683         break;
13684     }
13685
13686   if (sw_if_index_set == 0)
13687     {
13688       sw_if_index = ~0;
13689     }
13690
13691   if (!vam->json_output)
13692     {
13693       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13694              "sw_if_index", "local", "remote", "vni",
13695              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13696     }
13697
13698   /* Get list of vxlan-tunnel interfaces */
13699   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13700
13701   mp->sw_if_index = htonl (sw_if_index);
13702
13703   S (mp);
13704
13705   /* Use a control ping for synchronization */
13706   MPING (CONTROL_PING, mp_ping);
13707   S (mp_ping);
13708
13709   W (ret);
13710   return ret;
13711 }
13712
13713 static void vl_api_l2_fib_table_details_t_handler
13714   (vl_api_l2_fib_table_details_t * mp)
13715 {
13716   vat_main_t *vam = &vat_main;
13717
13718   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13719          "       %d       %d     %d",
13720          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13721          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13722          mp->bvi_mac);
13723 }
13724
13725 static void vl_api_l2_fib_table_details_t_handler_json
13726   (vl_api_l2_fib_table_details_t * mp)
13727 {
13728   vat_main_t *vam = &vat_main;
13729   vat_json_node_t *node = NULL;
13730
13731   if (VAT_JSON_ARRAY != vam->json_tree.type)
13732     {
13733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13734       vat_json_init_array (&vam->json_tree);
13735     }
13736   node = vat_json_array_add (&vam->json_tree);
13737
13738   vat_json_init_object (node);
13739   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13740   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13741   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13742   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13743   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13744   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13745 }
13746
13747 static int
13748 api_l2_fib_table_dump (vat_main_t * vam)
13749 {
13750   unformat_input_t *i = vam->input;
13751   vl_api_l2_fib_table_dump_t *mp;
13752   vl_api_control_ping_t *mp_ping;
13753   u32 bd_id;
13754   u8 bd_id_set = 0;
13755   int ret;
13756
13757   /* Parse args required to build the message */
13758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13759     {
13760       if (unformat (i, "bd_id %d", &bd_id))
13761         bd_id_set = 1;
13762       else
13763         break;
13764     }
13765
13766   if (bd_id_set == 0)
13767     {
13768       errmsg ("missing bridge domain");
13769       return -99;
13770     }
13771
13772   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13773
13774   /* Get list of l2 fib entries */
13775   M (L2_FIB_TABLE_DUMP, mp);
13776
13777   mp->bd_id = ntohl (bd_id);
13778   S (mp);
13779
13780   /* Use a control ping for synchronization */
13781   MPING (CONTROL_PING, mp_ping);
13782   S (mp_ping);
13783
13784   W (ret);
13785   return ret;
13786 }
13787
13788
13789 static int
13790 api_interface_name_renumber (vat_main_t * vam)
13791 {
13792   unformat_input_t *line_input = vam->input;
13793   vl_api_interface_name_renumber_t *mp;
13794   u32 sw_if_index = ~0;
13795   u32 new_show_dev_instance = ~0;
13796   int ret;
13797
13798   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13799     {
13800       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13801                     &sw_if_index))
13802         ;
13803       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13804         ;
13805       else if (unformat (line_input, "new_show_dev_instance %d",
13806                          &new_show_dev_instance))
13807         ;
13808       else
13809         break;
13810     }
13811
13812   if (sw_if_index == ~0)
13813     {
13814       errmsg ("missing interface name or sw_if_index");
13815       return -99;
13816     }
13817
13818   if (new_show_dev_instance == ~0)
13819     {
13820       errmsg ("missing new_show_dev_instance");
13821       return -99;
13822     }
13823
13824   M (INTERFACE_NAME_RENUMBER, mp);
13825
13826   mp->sw_if_index = ntohl (sw_if_index);
13827   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13828
13829   S (mp);
13830   W (ret);
13831   return ret;
13832 }
13833
13834 static int
13835 api_ip_probe_neighbor (vat_main_t * vam)
13836 {
13837   unformat_input_t *i = vam->input;
13838   vl_api_ip_probe_neighbor_t *mp;
13839   vl_api_address_t dst_adr = { };
13840   u8 int_set = 0;
13841   u8 adr_set = 0;
13842   u32 sw_if_index;
13843   int ret;
13844
13845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13846     {
13847       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13848         int_set = 1;
13849       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13850         int_set = 1;
13851       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13852         adr_set = 1;
13853       else
13854         break;
13855     }
13856
13857   if (int_set == 0)
13858     {
13859       errmsg ("missing interface");
13860       return -99;
13861     }
13862
13863   if (adr_set == 0)
13864     {
13865       errmsg ("missing addresses");
13866       return -99;
13867     }
13868
13869   M (IP_PROBE_NEIGHBOR, mp);
13870
13871   mp->sw_if_index = ntohl (sw_if_index);
13872   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13873
13874   S (mp);
13875   W (ret);
13876   return ret;
13877 }
13878
13879 static int
13880 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13881 {
13882   unformat_input_t *i = vam->input;
13883   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13884   u8 mode = IP_SCAN_V46_NEIGHBORS;
13885   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13886   int ret;
13887
13888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13889     {
13890       if (unformat (i, "ip4"))
13891         mode = IP_SCAN_V4_NEIGHBORS;
13892       else if (unformat (i, "ip6"))
13893         mode = IP_SCAN_V6_NEIGHBORS;
13894       if (unformat (i, "both"))
13895         mode = IP_SCAN_V46_NEIGHBORS;
13896       else if (unformat (i, "disable"))
13897         mode = IP_SCAN_DISABLED;
13898       else if (unformat (i, "interval %d", &interval))
13899         ;
13900       else if (unformat (i, "max-time %d", &time))
13901         ;
13902       else if (unformat (i, "max-update %d", &update))
13903         ;
13904       else if (unformat (i, "delay %d", &delay))
13905         ;
13906       else if (unformat (i, "stale %d", &stale))
13907         ;
13908       else
13909         break;
13910     }
13911
13912   if (interval > 255)
13913     {
13914       errmsg ("interval cannot exceed 255 minutes.");
13915       return -99;
13916     }
13917   if (time > 255)
13918     {
13919       errmsg ("max-time cannot exceed 255 usec.");
13920       return -99;
13921     }
13922   if (update > 255)
13923     {
13924       errmsg ("max-update cannot exceed 255.");
13925       return -99;
13926     }
13927   if (delay > 255)
13928     {
13929       errmsg ("delay cannot exceed 255 msec.");
13930       return -99;
13931     }
13932   if (stale > 255)
13933     {
13934       errmsg ("stale cannot exceed 255 minutes.");
13935       return -99;
13936     }
13937
13938   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13939   mp->mode = mode;
13940   mp->scan_interval = interval;
13941   mp->max_proc_time = time;
13942   mp->max_update = update;
13943   mp->scan_int_delay = delay;
13944   mp->stale_threshold = stale;
13945
13946   S (mp);
13947   W (ret);
13948   return ret;
13949 }
13950
13951 static int
13952 api_want_ip4_arp_events (vat_main_t * vam)
13953 {
13954   unformat_input_t *line_input = vam->input;
13955   vl_api_want_ip4_arp_events_t *mp;
13956   ip4_address_t address;
13957   int address_set = 0;
13958   u32 enable_disable = 1;
13959   int ret;
13960
13961   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13962     {
13963       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13964         address_set = 1;
13965       else if (unformat (line_input, "del"))
13966         enable_disable = 0;
13967       else
13968         break;
13969     }
13970
13971   if (address_set == 0)
13972     {
13973       errmsg ("missing addresses");
13974       return -99;
13975     }
13976
13977   M (WANT_IP4_ARP_EVENTS, mp);
13978   mp->enable_disable = enable_disable;
13979   mp->pid = htonl (getpid ());
13980   clib_memcpy (mp->ip, &address, sizeof (address));
13981
13982   S (mp);
13983   W (ret);
13984   return ret;
13985 }
13986
13987 static int
13988 api_want_ip6_nd_events (vat_main_t * vam)
13989 {
13990   unformat_input_t *line_input = vam->input;
13991   vl_api_want_ip6_nd_events_t *mp;
13992   vl_api_ip6_address_t address;
13993   int address_set = 0;
13994   u32 enable_disable = 1;
13995   int ret;
13996
13997   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13998     {
13999       if (unformat
14000           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14001         address_set = 1;
14002       else if (unformat (line_input, "del"))
14003         enable_disable = 0;
14004       else
14005         break;
14006     }
14007
14008   if (address_set == 0)
14009     {
14010       errmsg ("missing addresses");
14011       return -99;
14012     }
14013
14014   M (WANT_IP6_ND_EVENTS, mp);
14015   mp->enable_disable = enable_disable;
14016   mp->pid = htonl (getpid ());
14017   clib_memcpy (&mp->ip, &address, sizeof (address));
14018
14019   S (mp);
14020   W (ret);
14021   return ret;
14022 }
14023
14024 static int
14025 api_want_l2_macs_events (vat_main_t * vam)
14026 {
14027   unformat_input_t *line_input = vam->input;
14028   vl_api_want_l2_macs_events_t *mp;
14029   u8 enable_disable = 1;
14030   u32 scan_delay = 0;
14031   u32 max_macs_in_event = 0;
14032   u32 learn_limit = 0;
14033   int ret;
14034
14035   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14036     {
14037       if (unformat (line_input, "learn-limit %d", &learn_limit))
14038         ;
14039       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14040         ;
14041       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14042         ;
14043       else if (unformat (line_input, "disable"))
14044         enable_disable = 0;
14045       else
14046         break;
14047     }
14048
14049   M (WANT_L2_MACS_EVENTS, mp);
14050   mp->enable_disable = enable_disable;
14051   mp->pid = htonl (getpid ());
14052   mp->learn_limit = htonl (learn_limit);
14053   mp->scan_delay = (u8) scan_delay;
14054   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14055   S (mp);
14056   W (ret);
14057   return ret;
14058 }
14059
14060 static int
14061 api_input_acl_set_interface (vat_main_t * vam)
14062 {
14063   unformat_input_t *i = vam->input;
14064   vl_api_input_acl_set_interface_t *mp;
14065   u32 sw_if_index;
14066   int sw_if_index_set;
14067   u32 ip4_table_index = ~0;
14068   u32 ip6_table_index = ~0;
14069   u32 l2_table_index = ~0;
14070   u8 is_add = 1;
14071   int ret;
14072
14073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14074     {
14075       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14076         sw_if_index_set = 1;
14077       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14078         sw_if_index_set = 1;
14079       else if (unformat (i, "del"))
14080         is_add = 0;
14081       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14082         ;
14083       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14084         ;
14085       else if (unformat (i, "l2-table %d", &l2_table_index))
14086         ;
14087       else
14088         {
14089           clib_warning ("parse error '%U'", format_unformat_error, i);
14090           return -99;
14091         }
14092     }
14093
14094   if (sw_if_index_set == 0)
14095     {
14096       errmsg ("missing interface name or sw_if_index");
14097       return -99;
14098     }
14099
14100   M (INPUT_ACL_SET_INTERFACE, mp);
14101
14102   mp->sw_if_index = ntohl (sw_if_index);
14103   mp->ip4_table_index = ntohl (ip4_table_index);
14104   mp->ip6_table_index = ntohl (ip6_table_index);
14105   mp->l2_table_index = ntohl (l2_table_index);
14106   mp->is_add = is_add;
14107
14108   S (mp);
14109   W (ret);
14110   return ret;
14111 }
14112
14113 static int
14114 api_output_acl_set_interface (vat_main_t * vam)
14115 {
14116   unformat_input_t *i = vam->input;
14117   vl_api_output_acl_set_interface_t *mp;
14118   u32 sw_if_index;
14119   int sw_if_index_set;
14120   u32 ip4_table_index = ~0;
14121   u32 ip6_table_index = ~0;
14122   u32 l2_table_index = ~0;
14123   u8 is_add = 1;
14124   int ret;
14125
14126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14127     {
14128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14129         sw_if_index_set = 1;
14130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14131         sw_if_index_set = 1;
14132       else if (unformat (i, "del"))
14133         is_add = 0;
14134       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14135         ;
14136       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14137         ;
14138       else if (unformat (i, "l2-table %d", &l2_table_index))
14139         ;
14140       else
14141         {
14142           clib_warning ("parse error '%U'", format_unformat_error, i);
14143           return -99;
14144         }
14145     }
14146
14147   if (sw_if_index_set == 0)
14148     {
14149       errmsg ("missing interface name or sw_if_index");
14150       return -99;
14151     }
14152
14153   M (OUTPUT_ACL_SET_INTERFACE, mp);
14154
14155   mp->sw_if_index = ntohl (sw_if_index);
14156   mp->ip4_table_index = ntohl (ip4_table_index);
14157   mp->ip6_table_index = ntohl (ip6_table_index);
14158   mp->l2_table_index = ntohl (l2_table_index);
14159   mp->is_add = is_add;
14160
14161   S (mp);
14162   W (ret);
14163   return ret;
14164 }
14165
14166 static int
14167 api_ip_address_dump (vat_main_t * vam)
14168 {
14169   unformat_input_t *i = vam->input;
14170   vl_api_ip_address_dump_t *mp;
14171   vl_api_control_ping_t *mp_ping;
14172   u32 sw_if_index = ~0;
14173   u8 sw_if_index_set = 0;
14174   u8 ipv4_set = 0;
14175   u8 ipv6_set = 0;
14176   int ret;
14177
14178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14179     {
14180       if (unformat (i, "sw_if_index %d", &sw_if_index))
14181         sw_if_index_set = 1;
14182       else
14183         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14184         sw_if_index_set = 1;
14185       else if (unformat (i, "ipv4"))
14186         ipv4_set = 1;
14187       else if (unformat (i, "ipv6"))
14188         ipv6_set = 1;
14189       else
14190         break;
14191     }
14192
14193   if (ipv4_set && ipv6_set)
14194     {
14195       errmsg ("ipv4 and ipv6 flags cannot be both set");
14196       return -99;
14197     }
14198
14199   if ((!ipv4_set) && (!ipv6_set))
14200     {
14201       errmsg ("no ipv4 nor ipv6 flag set");
14202       return -99;
14203     }
14204
14205   if (sw_if_index_set == 0)
14206     {
14207       errmsg ("missing interface name or sw_if_index");
14208       return -99;
14209     }
14210
14211   vam->current_sw_if_index = sw_if_index;
14212   vam->is_ipv6 = ipv6_set;
14213
14214   M (IP_ADDRESS_DUMP, mp);
14215   mp->sw_if_index = ntohl (sw_if_index);
14216   mp->is_ipv6 = ipv6_set;
14217   S (mp);
14218
14219   /* Use a control ping for synchronization */
14220   MPING (CONTROL_PING, mp_ping);
14221   S (mp_ping);
14222
14223   W (ret);
14224   return ret;
14225 }
14226
14227 static int
14228 api_ip_dump (vat_main_t * vam)
14229 {
14230   vl_api_ip_dump_t *mp;
14231   vl_api_control_ping_t *mp_ping;
14232   unformat_input_t *in = vam->input;
14233   int ipv4_set = 0;
14234   int ipv6_set = 0;
14235   int is_ipv6;
14236   int i;
14237   int ret;
14238
14239   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14240     {
14241       if (unformat (in, "ipv4"))
14242         ipv4_set = 1;
14243       else if (unformat (in, "ipv6"))
14244         ipv6_set = 1;
14245       else
14246         break;
14247     }
14248
14249   if (ipv4_set && ipv6_set)
14250     {
14251       errmsg ("ipv4 and ipv6 flags cannot be both set");
14252       return -99;
14253     }
14254
14255   if ((!ipv4_set) && (!ipv6_set))
14256     {
14257       errmsg ("no ipv4 nor ipv6 flag set");
14258       return -99;
14259     }
14260
14261   is_ipv6 = ipv6_set;
14262   vam->is_ipv6 = is_ipv6;
14263
14264   /* free old data */
14265   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14266     {
14267       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14268     }
14269   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14270
14271   M (IP_DUMP, mp);
14272   mp->is_ipv6 = ipv6_set;
14273   S (mp);
14274
14275   /* Use a control ping for synchronization */
14276   MPING (CONTROL_PING, mp_ping);
14277   S (mp_ping);
14278
14279   W (ret);
14280   return ret;
14281 }
14282
14283 static int
14284 api_ipsec_spd_add_del (vat_main_t * vam)
14285 {
14286   unformat_input_t *i = vam->input;
14287   vl_api_ipsec_spd_add_del_t *mp;
14288   u32 spd_id = ~0;
14289   u8 is_add = 1;
14290   int ret;
14291
14292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14293     {
14294       if (unformat (i, "spd_id %d", &spd_id))
14295         ;
14296       else if (unformat (i, "del"))
14297         is_add = 0;
14298       else
14299         {
14300           clib_warning ("parse error '%U'", format_unformat_error, i);
14301           return -99;
14302         }
14303     }
14304   if (spd_id == ~0)
14305     {
14306       errmsg ("spd_id must be set");
14307       return -99;
14308     }
14309
14310   M (IPSEC_SPD_ADD_DEL, mp);
14311
14312   mp->spd_id = ntohl (spd_id);
14313   mp->is_add = is_add;
14314
14315   S (mp);
14316   W (ret);
14317   return ret;
14318 }
14319
14320 static int
14321 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14322 {
14323   unformat_input_t *i = vam->input;
14324   vl_api_ipsec_interface_add_del_spd_t *mp;
14325   u32 sw_if_index;
14326   u8 sw_if_index_set = 0;
14327   u32 spd_id = (u32) ~ 0;
14328   u8 is_add = 1;
14329   int ret;
14330
14331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14332     {
14333       if (unformat (i, "del"))
14334         is_add = 0;
14335       else if (unformat (i, "spd_id %d", &spd_id))
14336         ;
14337       else
14338         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14339         sw_if_index_set = 1;
14340       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14341         sw_if_index_set = 1;
14342       else
14343         {
14344           clib_warning ("parse error '%U'", format_unformat_error, i);
14345           return -99;
14346         }
14347
14348     }
14349
14350   if (spd_id == (u32) ~ 0)
14351     {
14352       errmsg ("spd_id must be set");
14353       return -99;
14354     }
14355
14356   if (sw_if_index_set == 0)
14357     {
14358       errmsg ("missing interface name or sw_if_index");
14359       return -99;
14360     }
14361
14362   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14363
14364   mp->spd_id = ntohl (spd_id);
14365   mp->sw_if_index = ntohl (sw_if_index);
14366   mp->is_add = is_add;
14367
14368   S (mp);
14369   W (ret);
14370   return ret;
14371 }
14372
14373 static int
14374 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14375 {
14376   unformat_input_t *i = vam->input;
14377   vl_api_ipsec_spd_entry_add_del_t *mp;
14378   u8 is_add = 1, is_outbound = 0;
14379   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14380   i32 priority = 0;
14381   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14382   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14383   vl_api_address_t laddr_start = { }, laddr_stop =
14384   {
14385   }, raddr_start =
14386   {
14387   }, raddr_stop =
14388   {
14389   };
14390   int ret;
14391
14392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14393     {
14394       if (unformat (i, "del"))
14395         is_add = 0;
14396       if (unformat (i, "outbound"))
14397         is_outbound = 1;
14398       if (unformat (i, "inbound"))
14399         is_outbound = 0;
14400       else if (unformat (i, "spd_id %d", &spd_id))
14401         ;
14402       else if (unformat (i, "sa_id %d", &sa_id))
14403         ;
14404       else if (unformat (i, "priority %d", &priority))
14405         ;
14406       else if (unformat (i, "protocol %d", &protocol))
14407         ;
14408       else if (unformat (i, "lport_start %d", &lport_start))
14409         ;
14410       else if (unformat (i, "lport_stop %d", &lport_stop))
14411         ;
14412       else if (unformat (i, "rport_start %d", &rport_start))
14413         ;
14414       else if (unformat (i, "rport_stop %d", &rport_stop))
14415         ;
14416       else if (unformat (i, "laddr_start %U",
14417                          unformat_vl_api_address, &laddr_start))
14418         ;
14419       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14420                          &laddr_stop))
14421         ;
14422       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14423                          &raddr_start))
14424         ;
14425       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14426                          &raddr_stop))
14427         ;
14428       else
14429         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14430         {
14431           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14432             {
14433               clib_warning ("unsupported action: 'resolve'");
14434               return -99;
14435             }
14436         }
14437       else
14438         {
14439           clib_warning ("parse error '%U'", format_unformat_error, i);
14440           return -99;
14441         }
14442
14443     }
14444
14445   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14446
14447   mp->is_add = is_add;
14448
14449   mp->entry.spd_id = ntohl (spd_id);
14450   mp->entry.priority = ntohl (priority);
14451   mp->entry.is_outbound = is_outbound;
14452
14453   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14454                sizeof (vl_api_address_t));
14455   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14456                sizeof (vl_api_address_t));
14457   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14458                sizeof (vl_api_address_t));
14459   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14460                sizeof (vl_api_address_t));
14461
14462   mp->entry.protocol = (u8) protocol;
14463   mp->entry.local_port_start = ntohs ((u16) lport_start);
14464   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14465   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14466   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14467   mp->entry.policy = (u8) policy;
14468   mp->entry.sa_id = ntohl (sa_id);
14469
14470   S (mp);
14471   W (ret);
14472   return ret;
14473 }
14474
14475 static int
14476 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14477 {
14478   unformat_input_t *i = vam->input;
14479   vl_api_ipsec_sad_entry_add_del_t *mp;
14480   u32 sad_id = 0, spi = 0;
14481   u8 *ck = 0, *ik = 0;
14482   u8 is_add = 1;
14483
14484   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14485   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14486   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14487   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14488   vl_api_address_t tun_src, tun_dst;
14489   int ret;
14490
14491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14492     {
14493       if (unformat (i, "del"))
14494         is_add = 0;
14495       else if (unformat (i, "sad_id %d", &sad_id))
14496         ;
14497       else if (unformat (i, "spi %d", &spi))
14498         ;
14499       else if (unformat (i, "esp"))
14500         protocol = IPSEC_API_PROTO_ESP;
14501       else
14502         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14503         {
14504           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14505           if (ADDRESS_IP6 == tun_src.af)
14506             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14507         }
14508       else
14509         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14510         {
14511           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14512           if (ADDRESS_IP6 == tun_src.af)
14513             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14514         }
14515       else
14516         if (unformat (i, "crypto_alg %U",
14517                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14518         ;
14519       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14520         ;
14521       else if (unformat (i, "integ_alg %U",
14522                          unformat_ipsec_api_integ_alg, &integ_alg))
14523         ;
14524       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14525         ;
14526       else
14527         {
14528           clib_warning ("parse error '%U'", format_unformat_error, i);
14529           return -99;
14530         }
14531
14532     }
14533
14534   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14535
14536   mp->is_add = is_add;
14537   mp->entry.sad_id = ntohl (sad_id);
14538   mp->entry.protocol = protocol;
14539   mp->entry.spi = ntohl (spi);
14540   mp->entry.flags = flags;
14541
14542   mp->entry.crypto_algorithm = crypto_alg;
14543   mp->entry.integrity_algorithm = integ_alg;
14544   mp->entry.crypto_key.length = vec_len (ck);
14545   mp->entry.integrity_key.length = vec_len (ik);
14546
14547   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14548     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14549
14550   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14551     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14552
14553   if (ck)
14554     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14555   if (ik)
14556     clib_memcpy (mp->entry.integrity_key.data, ik,
14557                  mp->entry.integrity_key.length);
14558
14559   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14560     {
14561       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14562                    sizeof (mp->entry.tunnel_src));
14563       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14564                    sizeof (mp->entry.tunnel_dst));
14565     }
14566
14567   S (mp);
14568   W (ret);
14569   return ret;
14570 }
14571
14572 static int
14573 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14574 {
14575   unformat_input_t *i = vam->input;
14576   vl_api_ipsec_tunnel_if_add_del_t *mp;
14577   u32 local_spi = 0, remote_spi = 0;
14578   u32 crypto_alg = 0, integ_alg = 0;
14579   u8 *lck = NULL, *rck = NULL;
14580   u8 *lik = NULL, *rik = NULL;
14581   vl_api_address_t local_ip = { 0 };
14582   vl_api_address_t remote_ip = { 0 };
14583   f64 before = 0;
14584   u8 is_add = 1;
14585   u8 esn = 0;
14586   u8 anti_replay = 0;
14587   u8 renumber = 0;
14588   u32 instance = ~0;
14589   u32 count = 1, jj;
14590   int ret = -1;
14591
14592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14593     {
14594       if (unformat (i, "del"))
14595         is_add = 0;
14596       else if (unformat (i, "esn"))
14597         esn = 1;
14598       else if (unformat (i, "anti-replay"))
14599         anti_replay = 1;
14600       else if (unformat (i, "count %d", &count))
14601         ;
14602       else if (unformat (i, "local_spi %d", &local_spi))
14603         ;
14604       else if (unformat (i, "remote_spi %d", &remote_spi))
14605         ;
14606       else
14607         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14608         ;
14609       else
14610         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14611         ;
14612       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14613         ;
14614       else
14615         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14616         ;
14617       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14618         ;
14619       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14620         ;
14621       else
14622         if (unformat
14623             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14624         {
14625           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14626             {
14627               errmsg ("unsupported crypto-alg: '%U'\n",
14628                       format_ipsec_crypto_alg, crypto_alg);
14629               return -99;
14630             }
14631         }
14632       else
14633         if (unformat
14634             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14635         {
14636           if (integ_alg >= IPSEC_INTEG_N_ALG)
14637             {
14638               errmsg ("unsupported integ-alg: '%U'\n",
14639                       format_ipsec_integ_alg, integ_alg);
14640               return -99;
14641             }
14642         }
14643       else if (unformat (i, "instance %u", &instance))
14644         renumber = 1;
14645       else
14646         {
14647           errmsg ("parse error '%U'\n", format_unformat_error, i);
14648           return -99;
14649         }
14650     }
14651
14652   if (count > 1)
14653     {
14654       /* Turn on async mode */
14655       vam->async_mode = 1;
14656       vam->async_errors = 0;
14657       before = vat_time_now (vam);
14658     }
14659
14660   for (jj = 0; jj < count; jj++)
14661     {
14662       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14663
14664       mp->is_add = is_add;
14665       mp->esn = esn;
14666       mp->anti_replay = anti_replay;
14667
14668       if (jj > 0)
14669         increment_address (&remote_ip);
14670
14671       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14672       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14673
14674       mp->local_spi = htonl (local_spi + jj);
14675       mp->remote_spi = htonl (remote_spi + jj);
14676       mp->crypto_alg = (u8) crypto_alg;
14677
14678       mp->local_crypto_key_len = 0;
14679       if (lck)
14680         {
14681           mp->local_crypto_key_len = vec_len (lck);
14682           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14683             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14684           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14685         }
14686
14687       mp->remote_crypto_key_len = 0;
14688       if (rck)
14689         {
14690           mp->remote_crypto_key_len = vec_len (rck);
14691           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14692             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14693           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14694         }
14695
14696       mp->integ_alg = (u8) integ_alg;
14697
14698       mp->local_integ_key_len = 0;
14699       if (lik)
14700         {
14701           mp->local_integ_key_len = vec_len (lik);
14702           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14703             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14704           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14705         }
14706
14707       mp->remote_integ_key_len = 0;
14708       if (rik)
14709         {
14710           mp->remote_integ_key_len = vec_len (rik);
14711           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14712             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14713           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14714         }
14715
14716       if (renumber)
14717         {
14718           mp->renumber = renumber;
14719           mp->show_instance = ntohl (instance);
14720         }
14721       S (mp);
14722     }
14723
14724   /* When testing multiple add/del ops, use a control-ping to sync */
14725   if (count > 1)
14726     {
14727       vl_api_control_ping_t *mp_ping;
14728       f64 after;
14729       f64 timeout;
14730
14731       /* Shut off async mode */
14732       vam->async_mode = 0;
14733
14734       MPING (CONTROL_PING, mp_ping);
14735       S (mp_ping);
14736
14737       timeout = vat_time_now (vam) + 1.0;
14738       while (vat_time_now (vam) < timeout)
14739         if (vam->result_ready == 1)
14740           goto out;
14741       vam->retval = -99;
14742
14743     out:
14744       if (vam->retval == -99)
14745         errmsg ("timeout");
14746
14747       if (vam->async_errors > 0)
14748         {
14749           errmsg ("%d asynchronous errors", vam->async_errors);
14750           vam->retval = -98;
14751         }
14752       vam->async_errors = 0;
14753       after = vat_time_now (vam);
14754
14755       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14756       if (jj > 0)
14757         count = jj;
14758
14759       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14760              count, after - before, count / (after - before));
14761     }
14762   else
14763     {
14764       /* Wait for a reply... */
14765       W (ret);
14766       return ret;
14767     }
14768
14769   return ret;
14770 }
14771
14772 static void
14773 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14774 {
14775   vat_main_t *vam = &vat_main;
14776
14777   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14778          "crypto_key %U integ_alg %u integ_key %U flags %x "
14779          "tunnel_src_addr %U tunnel_dst_addr %U "
14780          "salt %u seq_outbound %lu last_seq_inbound %lu "
14781          "replay_window %lu\n",
14782          ntohl (mp->entry.sad_id),
14783          ntohl (mp->sw_if_index),
14784          ntohl (mp->entry.spi),
14785          ntohl (mp->entry.protocol),
14786          ntohl (mp->entry.crypto_algorithm),
14787          format_hex_bytes, mp->entry.crypto_key.data,
14788          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14789          format_hex_bytes, mp->entry.integrity_key.data,
14790          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14791          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14792          &mp->entry.tunnel_dst, ntohl (mp->salt),
14793          clib_net_to_host_u64 (mp->seq_outbound),
14794          clib_net_to_host_u64 (mp->last_seq_inbound),
14795          clib_net_to_host_u64 (mp->replay_window));
14796 }
14797
14798 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14799 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14800
14801 static void vl_api_ipsec_sa_details_t_handler_json
14802   (vl_api_ipsec_sa_details_t * mp)
14803 {
14804   vat_main_t *vam = &vat_main;
14805   vat_json_node_t *node = NULL;
14806   vl_api_ipsec_sad_flags_t flags;
14807
14808   if (VAT_JSON_ARRAY != vam->json_tree.type)
14809     {
14810       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14811       vat_json_init_array (&vam->json_tree);
14812     }
14813   node = vat_json_array_add (&vam->json_tree);
14814
14815   vat_json_init_object (node);
14816   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14817   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14818   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14819   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14820   vat_json_object_add_uint (node, "crypto_alg",
14821                             ntohl (mp->entry.crypto_algorithm));
14822   vat_json_object_add_uint (node, "integ_alg",
14823                             ntohl (mp->entry.integrity_algorithm));
14824   flags = ntohl (mp->entry.flags);
14825   vat_json_object_add_uint (node, "use_esn",
14826                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14827   vat_json_object_add_uint (node, "use_anti_replay",
14828                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14829   vat_json_object_add_uint (node, "is_tunnel",
14830                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14831   vat_json_object_add_uint (node, "is_tunnel_ip6",
14832                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14833   vat_json_object_add_uint (node, "udp_encap",
14834                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14835   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14836                              mp->entry.crypto_key.length);
14837   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14838                              mp->entry.integrity_key.length);
14839   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14840   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14841   vat_json_object_add_uint (node, "replay_window",
14842                             clib_net_to_host_u64 (mp->replay_window));
14843 }
14844
14845 static int
14846 api_ipsec_sa_dump (vat_main_t * vam)
14847 {
14848   unformat_input_t *i = vam->input;
14849   vl_api_ipsec_sa_dump_t *mp;
14850   vl_api_control_ping_t *mp_ping;
14851   u32 sa_id = ~0;
14852   int ret;
14853
14854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14855     {
14856       if (unformat (i, "sa_id %d", &sa_id))
14857         ;
14858       else
14859         {
14860           clib_warning ("parse error '%U'", format_unformat_error, i);
14861           return -99;
14862         }
14863     }
14864
14865   M (IPSEC_SA_DUMP, mp);
14866
14867   mp->sa_id = ntohl (sa_id);
14868
14869   S (mp);
14870
14871   /* Use a control ping for synchronization */
14872   M (CONTROL_PING, mp_ping);
14873   S (mp_ping);
14874
14875   W (ret);
14876   return ret;
14877 }
14878
14879 static int
14880 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14881 {
14882   unformat_input_t *i = vam->input;
14883   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14884   u32 sw_if_index = ~0;
14885   u32 sa_id = ~0;
14886   u8 is_outbound = (u8) ~ 0;
14887   int ret;
14888
14889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14890     {
14891       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14892         ;
14893       else if (unformat (i, "sa_id %d", &sa_id))
14894         ;
14895       else if (unformat (i, "outbound"))
14896         is_outbound = 1;
14897       else if (unformat (i, "inbound"))
14898         is_outbound = 0;
14899       else
14900         {
14901           clib_warning ("parse error '%U'", format_unformat_error, i);
14902           return -99;
14903         }
14904     }
14905
14906   if (sw_if_index == ~0)
14907     {
14908       errmsg ("interface must be specified");
14909       return -99;
14910     }
14911
14912   if (sa_id == ~0)
14913     {
14914       errmsg ("SA ID must be specified");
14915       return -99;
14916     }
14917
14918   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14919
14920   mp->sw_if_index = htonl (sw_if_index);
14921   mp->sa_id = htonl (sa_id);
14922   mp->is_outbound = is_outbound;
14923
14924   S (mp);
14925   W (ret);
14926
14927   return ret;
14928 }
14929
14930 static int
14931 api_get_first_msg_id (vat_main_t * vam)
14932 {
14933   vl_api_get_first_msg_id_t *mp;
14934   unformat_input_t *i = vam->input;
14935   u8 *name;
14936   u8 name_set = 0;
14937   int ret;
14938
14939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14940     {
14941       if (unformat (i, "client %s", &name))
14942         name_set = 1;
14943       else
14944         break;
14945     }
14946
14947   if (name_set == 0)
14948     {
14949       errmsg ("missing client name");
14950       return -99;
14951     }
14952   vec_add1 (name, 0);
14953
14954   if (vec_len (name) > 63)
14955     {
14956       errmsg ("client name too long");
14957       return -99;
14958     }
14959
14960   M (GET_FIRST_MSG_ID, mp);
14961   clib_memcpy (mp->name, name, vec_len (name));
14962   S (mp);
14963   W (ret);
14964   return ret;
14965 }
14966
14967 static int
14968 api_cop_interface_enable_disable (vat_main_t * vam)
14969 {
14970   unformat_input_t *line_input = vam->input;
14971   vl_api_cop_interface_enable_disable_t *mp;
14972   u32 sw_if_index = ~0;
14973   u8 enable_disable = 1;
14974   int ret;
14975
14976   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14977     {
14978       if (unformat (line_input, "disable"))
14979         enable_disable = 0;
14980       if (unformat (line_input, "enable"))
14981         enable_disable = 1;
14982       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14983                          vam, &sw_if_index))
14984         ;
14985       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14986         ;
14987       else
14988         break;
14989     }
14990
14991   if (sw_if_index == ~0)
14992     {
14993       errmsg ("missing interface name or sw_if_index");
14994       return -99;
14995     }
14996
14997   /* Construct the API message */
14998   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14999   mp->sw_if_index = ntohl (sw_if_index);
15000   mp->enable_disable = enable_disable;
15001
15002   /* send it... */
15003   S (mp);
15004   /* Wait for the reply */
15005   W (ret);
15006   return ret;
15007 }
15008
15009 static int
15010 api_cop_whitelist_enable_disable (vat_main_t * vam)
15011 {
15012   unformat_input_t *line_input = vam->input;
15013   vl_api_cop_whitelist_enable_disable_t *mp;
15014   u32 sw_if_index = ~0;
15015   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15016   u32 fib_id = 0;
15017   int ret;
15018
15019   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15020     {
15021       if (unformat (line_input, "ip4"))
15022         ip4 = 1;
15023       else if (unformat (line_input, "ip6"))
15024         ip6 = 1;
15025       else if (unformat (line_input, "default"))
15026         default_cop = 1;
15027       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15028                          vam, &sw_if_index))
15029         ;
15030       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15031         ;
15032       else if (unformat (line_input, "fib-id %d", &fib_id))
15033         ;
15034       else
15035         break;
15036     }
15037
15038   if (sw_if_index == ~0)
15039     {
15040       errmsg ("missing interface name or sw_if_index");
15041       return -99;
15042     }
15043
15044   /* Construct the API message */
15045   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15046   mp->sw_if_index = ntohl (sw_if_index);
15047   mp->fib_id = ntohl (fib_id);
15048   mp->ip4 = ip4;
15049   mp->ip6 = ip6;
15050   mp->default_cop = default_cop;
15051
15052   /* send it... */
15053   S (mp);
15054   /* Wait for the reply */
15055   W (ret);
15056   return ret;
15057 }
15058
15059 static int
15060 api_get_node_graph (vat_main_t * vam)
15061 {
15062   vl_api_get_node_graph_t *mp;
15063   int ret;
15064
15065   M (GET_NODE_GRAPH, mp);
15066
15067   /* send it... */
15068   S (mp);
15069   /* Wait for the reply */
15070   W (ret);
15071   return ret;
15072 }
15073
15074 /* *INDENT-OFF* */
15075 /** Used for parsing LISP eids */
15076 typedef CLIB_PACKED(struct{
15077   u8 addr[16];   /**< eid address */
15078   u32 len;       /**< prefix length if IP */
15079   u8 type;      /**< type of eid */
15080 }) lisp_eid_vat_t;
15081 /* *INDENT-ON* */
15082
15083 static uword
15084 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15085 {
15086   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15087
15088   clib_memset (a, 0, sizeof (a[0]));
15089
15090   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15091     {
15092       a->type = 0;              /* ipv4 type */
15093     }
15094   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15095     {
15096       a->type = 1;              /* ipv6 type */
15097     }
15098   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15099     {
15100       a->type = 2;              /* mac type */
15101     }
15102   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15103     {
15104       a->type = 3;              /* NSH type */
15105       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15106       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15107     }
15108   else
15109     {
15110       return 0;
15111     }
15112
15113   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15114     {
15115       return 0;
15116     }
15117
15118   return 1;
15119 }
15120
15121 static int
15122 lisp_eid_size_vat (u8 type)
15123 {
15124   switch (type)
15125     {
15126     case 0:
15127       return 4;
15128     case 1:
15129       return 16;
15130     case 2:
15131       return 6;
15132     case 3:
15133       return 5;
15134     }
15135   return 0;
15136 }
15137
15138 static void
15139 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15140 {
15141   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15142 }
15143
15144 static int
15145 api_one_add_del_locator_set (vat_main_t * vam)
15146 {
15147   unformat_input_t *input = vam->input;
15148   vl_api_one_add_del_locator_set_t *mp;
15149   u8 is_add = 1;
15150   u8 *locator_set_name = NULL;
15151   u8 locator_set_name_set = 0;
15152   vl_api_local_locator_t locator, *locators = 0;
15153   u32 sw_if_index, priority, weight;
15154   u32 data_len = 0;
15155
15156   int ret;
15157   /* Parse args required to build the message */
15158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15159     {
15160       if (unformat (input, "del"))
15161         {
15162           is_add = 0;
15163         }
15164       else if (unformat (input, "locator-set %s", &locator_set_name))
15165         {
15166           locator_set_name_set = 1;
15167         }
15168       else if (unformat (input, "sw_if_index %u p %u w %u",
15169                          &sw_if_index, &priority, &weight))
15170         {
15171           locator.sw_if_index = htonl (sw_if_index);
15172           locator.priority = priority;
15173           locator.weight = weight;
15174           vec_add1 (locators, locator);
15175         }
15176       else
15177         if (unformat
15178             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15179              &sw_if_index, &priority, &weight))
15180         {
15181           locator.sw_if_index = htonl (sw_if_index);
15182           locator.priority = priority;
15183           locator.weight = weight;
15184           vec_add1 (locators, locator);
15185         }
15186       else
15187         break;
15188     }
15189
15190   if (locator_set_name_set == 0)
15191     {
15192       errmsg ("missing locator-set name");
15193       vec_free (locators);
15194       return -99;
15195     }
15196
15197   if (vec_len (locator_set_name) > 64)
15198     {
15199       errmsg ("locator-set name too long");
15200       vec_free (locator_set_name);
15201       vec_free (locators);
15202       return -99;
15203     }
15204   vec_add1 (locator_set_name, 0);
15205
15206   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15207
15208   /* Construct the API message */
15209   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15210
15211   mp->is_add = is_add;
15212   clib_memcpy (mp->locator_set_name, locator_set_name,
15213                vec_len (locator_set_name));
15214   vec_free (locator_set_name);
15215
15216   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15217   if (locators)
15218     clib_memcpy (mp->locators, locators, data_len);
15219   vec_free (locators);
15220
15221   /* send it... */
15222   S (mp);
15223
15224   /* Wait for a reply... */
15225   W (ret);
15226   return ret;
15227 }
15228
15229 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15230
15231 static int
15232 api_one_add_del_locator (vat_main_t * vam)
15233 {
15234   unformat_input_t *input = vam->input;
15235   vl_api_one_add_del_locator_t *mp;
15236   u32 tmp_if_index = ~0;
15237   u32 sw_if_index = ~0;
15238   u8 sw_if_index_set = 0;
15239   u8 sw_if_index_if_name_set = 0;
15240   u32 priority = ~0;
15241   u8 priority_set = 0;
15242   u32 weight = ~0;
15243   u8 weight_set = 0;
15244   u8 is_add = 1;
15245   u8 *locator_set_name = NULL;
15246   u8 locator_set_name_set = 0;
15247   int ret;
15248
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, "iface %U", api_unformat_sw_if_index, vam,
15261                          &tmp_if_index))
15262         {
15263           sw_if_index_if_name_set = 1;
15264           sw_if_index = tmp_if_index;
15265         }
15266       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15267         {
15268           sw_if_index_set = 1;
15269           sw_if_index = tmp_if_index;
15270         }
15271       else if (unformat (input, "p %d", &priority))
15272         {
15273           priority_set = 1;
15274         }
15275       else if (unformat (input, "w %d", &weight))
15276         {
15277           weight_set = 1;
15278         }
15279       else
15280         break;
15281     }
15282
15283   if (locator_set_name_set == 0)
15284     {
15285       errmsg ("missing locator-set name");
15286       return -99;
15287     }
15288
15289   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15290     {
15291       errmsg ("missing sw_if_index");
15292       vec_free (locator_set_name);
15293       return -99;
15294     }
15295
15296   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15297     {
15298       errmsg ("cannot use both params interface name and sw_if_index");
15299       vec_free (locator_set_name);
15300       return -99;
15301     }
15302
15303   if (priority_set == 0)
15304     {
15305       errmsg ("missing locator-set priority");
15306       vec_free (locator_set_name);
15307       return -99;
15308     }
15309
15310   if (weight_set == 0)
15311     {
15312       errmsg ("missing locator-set weight");
15313       vec_free (locator_set_name);
15314       return -99;
15315     }
15316
15317   if (vec_len (locator_set_name) > 64)
15318     {
15319       errmsg ("locator-set name too long");
15320       vec_free (locator_set_name);
15321       return -99;
15322     }
15323   vec_add1 (locator_set_name, 0);
15324
15325   /* Construct the API message */
15326   M (ONE_ADD_DEL_LOCATOR, mp);
15327
15328   mp->is_add = is_add;
15329   mp->sw_if_index = ntohl (sw_if_index);
15330   mp->priority = priority;
15331   mp->weight = weight;
15332   clib_memcpy (mp->locator_set_name, locator_set_name,
15333                vec_len (locator_set_name));
15334   vec_free (locator_set_name);
15335
15336   /* send it... */
15337   S (mp);
15338
15339   /* Wait for a reply... */
15340   W (ret);
15341   return ret;
15342 }
15343
15344 #define api_lisp_add_del_locator api_one_add_del_locator
15345
15346 uword
15347 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15348 {
15349   u32 *key_id = va_arg (*args, u32 *);
15350   u8 *s = 0;
15351
15352   if (unformat (input, "%s", &s))
15353     {
15354       if (!strcmp ((char *) s, "sha1"))
15355         key_id[0] = HMAC_SHA_1_96;
15356       else if (!strcmp ((char *) s, "sha256"))
15357         key_id[0] = HMAC_SHA_256_128;
15358       else
15359         {
15360           clib_warning ("invalid key_id: '%s'", s);
15361           key_id[0] = HMAC_NO_KEY;
15362         }
15363     }
15364   else
15365     return 0;
15366
15367   vec_free (s);
15368   return 1;
15369 }
15370
15371 static int
15372 api_one_add_del_local_eid (vat_main_t * vam)
15373 {
15374   unformat_input_t *input = vam->input;
15375   vl_api_one_add_del_local_eid_t *mp;
15376   u8 is_add = 1;
15377   u8 eid_set = 0;
15378   lisp_eid_vat_t _eid, *eid = &_eid;
15379   u8 *locator_set_name = 0;
15380   u8 locator_set_name_set = 0;
15381   u32 vni = 0;
15382   u16 key_id = 0;
15383   u8 *key = 0;
15384   int ret;
15385
15386   /* Parse args required to build the message */
15387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15388     {
15389       if (unformat (input, "del"))
15390         {
15391           is_add = 0;
15392         }
15393       else if (unformat (input, "vni %d", &vni))
15394         {
15395           ;
15396         }
15397       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15398         {
15399           eid_set = 1;
15400         }
15401       else if (unformat (input, "locator-set %s", &locator_set_name))
15402         {
15403           locator_set_name_set = 1;
15404         }
15405       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15406         ;
15407       else if (unformat (input, "secret-key %_%v%_", &key))
15408         ;
15409       else
15410         break;
15411     }
15412
15413   if (locator_set_name_set == 0)
15414     {
15415       errmsg ("missing locator-set name");
15416       return -99;
15417     }
15418
15419   if (0 == eid_set)
15420     {
15421       errmsg ("EID address not set!");
15422       vec_free (locator_set_name);
15423       return -99;
15424     }
15425
15426   if (key && (0 == key_id))
15427     {
15428       errmsg ("invalid key_id!");
15429       return -99;
15430     }
15431
15432   if (vec_len (key) > 64)
15433     {
15434       errmsg ("key too long");
15435       vec_free (key);
15436       return -99;
15437     }
15438
15439   if (vec_len (locator_set_name) > 64)
15440     {
15441       errmsg ("locator-set name too long");
15442       vec_free (locator_set_name);
15443       return -99;
15444     }
15445   vec_add1 (locator_set_name, 0);
15446
15447   /* Construct the API message */
15448   M (ONE_ADD_DEL_LOCAL_EID, mp);
15449
15450   mp->is_add = is_add;
15451   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15452   mp->eid_type = eid->type;
15453   mp->prefix_len = eid->len;
15454   mp->vni = clib_host_to_net_u32 (vni);
15455   mp->key_id = clib_host_to_net_u16 (key_id);
15456   clib_memcpy (mp->locator_set_name, locator_set_name,
15457                vec_len (locator_set_name));
15458   clib_memcpy (mp->key, key, vec_len (key));
15459
15460   vec_free (locator_set_name);
15461   vec_free (key);
15462
15463   /* send it... */
15464   S (mp);
15465
15466   /* Wait for a reply... */
15467   W (ret);
15468   return ret;
15469 }
15470
15471 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15472
15473 static int
15474 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15475 {
15476   u32 dp_table = 0, vni = 0;;
15477   unformat_input_t *input = vam->input;
15478   vl_api_gpe_add_del_fwd_entry_t *mp;
15479   u8 is_add = 1;
15480   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15481   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15482   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15483   u32 action = ~0, w;
15484   ip4_address_t rmt_rloc4, lcl_rloc4;
15485   ip6_address_t rmt_rloc6, lcl_rloc6;
15486   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15487   int ret;
15488
15489   clib_memset (&rloc, 0, sizeof (rloc));
15490
15491   /* Parse args required to build the message */
15492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15493     {
15494       if (unformat (input, "del"))
15495         is_add = 0;
15496       else if (unformat (input, "add"))
15497         is_add = 1;
15498       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15499         {
15500           rmt_eid_set = 1;
15501         }
15502       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15503         {
15504           lcl_eid_set = 1;
15505         }
15506       else if (unformat (input, "vrf %d", &dp_table))
15507         ;
15508       else if (unformat (input, "bd %d", &dp_table))
15509         ;
15510       else if (unformat (input, "vni %d", &vni))
15511         ;
15512       else if (unformat (input, "w %d", &w))
15513         {
15514           if (!curr_rloc)
15515             {
15516               errmsg ("No RLOC configured for setting priority/weight!");
15517               return -99;
15518             }
15519           curr_rloc->weight = w;
15520         }
15521       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15522                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15523         {
15524           rloc.is_ip4 = 1;
15525
15526           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15527           rloc.weight = 0;
15528           vec_add1 (lcl_locs, rloc);
15529
15530           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15531           vec_add1 (rmt_locs, rloc);
15532           /* weight saved in rmt loc */
15533           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15534         }
15535       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15536                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15537         {
15538           rloc.is_ip4 = 0;
15539           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15540           rloc.weight = 0;
15541           vec_add1 (lcl_locs, rloc);
15542
15543           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15544           vec_add1 (rmt_locs, rloc);
15545           /* weight saved in rmt loc */
15546           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15547         }
15548       else if (unformat (input, "action %d", &action))
15549         {
15550           ;
15551         }
15552       else
15553         {
15554           clib_warning ("parse error '%U'", format_unformat_error, input);
15555           return -99;
15556         }
15557     }
15558
15559   if (!rmt_eid_set)
15560     {
15561       errmsg ("remote eid addresses not set");
15562       return -99;
15563     }
15564
15565   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15566     {
15567       errmsg ("eid types don't match");
15568       return -99;
15569     }
15570
15571   if (0 == rmt_locs && (u32) ~ 0 == action)
15572     {
15573       errmsg ("action not set for negative mapping");
15574       return -99;
15575     }
15576
15577   /* Construct the API message */
15578   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15579       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15580
15581   mp->is_add = is_add;
15582   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15583   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15584   mp->eid_type = rmt_eid->type;
15585   mp->dp_table = clib_host_to_net_u32 (dp_table);
15586   mp->vni = clib_host_to_net_u32 (vni);
15587   mp->rmt_len = rmt_eid->len;
15588   mp->lcl_len = lcl_eid->len;
15589   mp->action = action;
15590
15591   if (0 != rmt_locs && 0 != lcl_locs)
15592     {
15593       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15594       clib_memcpy (mp->locs, lcl_locs,
15595                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15596
15597       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15598       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15599                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15600     }
15601   vec_free (lcl_locs);
15602   vec_free (rmt_locs);
15603
15604   /* send it... */
15605   S (mp);
15606
15607   /* Wait for a reply... */
15608   W (ret);
15609   return ret;
15610 }
15611
15612 static int
15613 api_one_add_del_map_server (vat_main_t * vam)
15614 {
15615   unformat_input_t *input = vam->input;
15616   vl_api_one_add_del_map_server_t *mp;
15617   u8 is_add = 1;
15618   u8 ipv4_set = 0;
15619   u8 ipv6_set = 0;
15620   ip4_address_t ipv4;
15621   ip6_address_t ipv6;
15622   int ret;
15623
15624   /* Parse args required to build the message */
15625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15626     {
15627       if (unformat (input, "del"))
15628         {
15629           is_add = 0;
15630         }
15631       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15632         {
15633           ipv4_set = 1;
15634         }
15635       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15636         {
15637           ipv6_set = 1;
15638         }
15639       else
15640         break;
15641     }
15642
15643   if (ipv4_set && ipv6_set)
15644     {
15645       errmsg ("both eid v4 and v6 addresses set");
15646       return -99;
15647     }
15648
15649   if (!ipv4_set && !ipv6_set)
15650     {
15651       errmsg ("eid addresses not set");
15652       return -99;
15653     }
15654
15655   /* Construct the API message */
15656   M (ONE_ADD_DEL_MAP_SERVER, mp);
15657
15658   mp->is_add = is_add;
15659   if (ipv6_set)
15660     {
15661       mp->is_ipv6 = 1;
15662       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15663     }
15664   else
15665     {
15666       mp->is_ipv6 = 0;
15667       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15668     }
15669
15670   /* send it... */
15671   S (mp);
15672
15673   /* Wait for a reply... */
15674   W (ret);
15675   return ret;
15676 }
15677
15678 #define api_lisp_add_del_map_server api_one_add_del_map_server
15679
15680 static int
15681 api_one_add_del_map_resolver (vat_main_t * vam)
15682 {
15683   unformat_input_t *input = vam->input;
15684   vl_api_one_add_del_map_resolver_t *mp;
15685   u8 is_add = 1;
15686   u8 ipv4_set = 0;
15687   u8 ipv6_set = 0;
15688   ip4_address_t ipv4;
15689   ip6_address_t ipv6;
15690   int ret;
15691
15692   /* Parse args required to build the message */
15693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15694     {
15695       if (unformat (input, "del"))
15696         {
15697           is_add = 0;
15698         }
15699       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15700         {
15701           ipv4_set = 1;
15702         }
15703       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15704         {
15705           ipv6_set = 1;
15706         }
15707       else
15708         break;
15709     }
15710
15711   if (ipv4_set && ipv6_set)
15712     {
15713       errmsg ("both eid v4 and v6 addresses set");
15714       return -99;
15715     }
15716
15717   if (!ipv4_set && !ipv6_set)
15718     {
15719       errmsg ("eid addresses not set");
15720       return -99;
15721     }
15722
15723   /* Construct the API message */
15724   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15725
15726   mp->is_add = is_add;
15727   if (ipv6_set)
15728     {
15729       mp->is_ipv6 = 1;
15730       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15731     }
15732   else
15733     {
15734       mp->is_ipv6 = 0;
15735       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15736     }
15737
15738   /* send it... */
15739   S (mp);
15740
15741   /* Wait for a reply... */
15742   W (ret);
15743   return ret;
15744 }
15745
15746 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15747
15748 static int
15749 api_lisp_gpe_enable_disable (vat_main_t * vam)
15750 {
15751   unformat_input_t *input = vam->input;
15752   vl_api_gpe_enable_disable_t *mp;
15753   u8 is_set = 0;
15754   u8 is_en = 1;
15755   int ret;
15756
15757   /* Parse args required to build the message */
15758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15759     {
15760       if (unformat (input, "enable"))
15761         {
15762           is_set = 1;
15763           is_en = 1;
15764         }
15765       else if (unformat (input, "disable"))
15766         {
15767           is_set = 1;
15768           is_en = 0;
15769         }
15770       else
15771         break;
15772     }
15773
15774   if (is_set == 0)
15775     {
15776       errmsg ("Value not set");
15777       return -99;
15778     }
15779
15780   /* Construct the API message */
15781   M (GPE_ENABLE_DISABLE, mp);
15782
15783   mp->is_en = is_en;
15784
15785   /* send it... */
15786   S (mp);
15787
15788   /* Wait for a reply... */
15789   W (ret);
15790   return ret;
15791 }
15792
15793 static int
15794 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15795 {
15796   unformat_input_t *input = vam->input;
15797   vl_api_one_rloc_probe_enable_disable_t *mp;
15798   u8 is_set = 0;
15799   u8 is_en = 0;
15800   int ret;
15801
15802   /* Parse args required to build the message */
15803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15804     {
15805       if (unformat (input, "enable"))
15806         {
15807           is_set = 1;
15808           is_en = 1;
15809         }
15810       else if (unformat (input, "disable"))
15811         is_set = 1;
15812       else
15813         break;
15814     }
15815
15816   if (!is_set)
15817     {
15818       errmsg ("Value not set");
15819       return -99;
15820     }
15821
15822   /* Construct the API message */
15823   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15824
15825   mp->is_enabled = is_en;
15826
15827   /* send it... */
15828   S (mp);
15829
15830   /* Wait for a reply... */
15831   W (ret);
15832   return ret;
15833 }
15834
15835 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15836
15837 static int
15838 api_one_map_register_enable_disable (vat_main_t * vam)
15839 {
15840   unformat_input_t *input = vam->input;
15841   vl_api_one_map_register_enable_disable_t *mp;
15842   u8 is_set = 0;
15843   u8 is_en = 0;
15844   int ret;
15845
15846   /* Parse args required to build the message */
15847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15848     {
15849       if (unformat (input, "enable"))
15850         {
15851           is_set = 1;
15852           is_en = 1;
15853         }
15854       else if (unformat (input, "disable"))
15855         is_set = 1;
15856       else
15857         break;
15858     }
15859
15860   if (!is_set)
15861     {
15862       errmsg ("Value not set");
15863       return -99;
15864     }
15865
15866   /* Construct the API message */
15867   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15868
15869   mp->is_enabled = is_en;
15870
15871   /* send it... */
15872   S (mp);
15873
15874   /* Wait for a reply... */
15875   W (ret);
15876   return ret;
15877 }
15878
15879 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15880
15881 static int
15882 api_one_enable_disable (vat_main_t * vam)
15883 {
15884   unformat_input_t *input = vam->input;
15885   vl_api_one_enable_disable_t *mp;
15886   u8 is_set = 0;
15887   u8 is_en = 0;
15888   int ret;
15889
15890   /* Parse args required to build the message */
15891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15892     {
15893       if (unformat (input, "enable"))
15894         {
15895           is_set = 1;
15896           is_en = 1;
15897         }
15898       else if (unformat (input, "disable"))
15899         {
15900           is_set = 1;
15901         }
15902       else
15903         break;
15904     }
15905
15906   if (!is_set)
15907     {
15908       errmsg ("Value not set");
15909       return -99;
15910     }
15911
15912   /* Construct the API message */
15913   M (ONE_ENABLE_DISABLE, mp);
15914
15915   mp->is_en = is_en;
15916
15917   /* send it... */
15918   S (mp);
15919
15920   /* Wait for a reply... */
15921   W (ret);
15922   return ret;
15923 }
15924
15925 #define api_lisp_enable_disable api_one_enable_disable
15926
15927 static int
15928 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15929 {
15930   unformat_input_t *input = vam->input;
15931   vl_api_one_enable_disable_xtr_mode_t *mp;
15932   u8 is_set = 0;
15933   u8 is_en = 0;
15934   int ret;
15935
15936   /* Parse args required to build the message */
15937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15938     {
15939       if (unformat (input, "enable"))
15940         {
15941           is_set = 1;
15942           is_en = 1;
15943         }
15944       else if (unformat (input, "disable"))
15945         {
15946           is_set = 1;
15947         }
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_ENABLE_DISABLE_XTR_MODE, mp);
15960
15961   mp->is_en = is_en;
15962
15963   /* send it... */
15964   S (mp);
15965
15966   /* Wait for a reply... */
15967   W (ret);
15968   return ret;
15969 }
15970
15971 static int
15972 api_one_show_xtr_mode (vat_main_t * vam)
15973 {
15974   vl_api_one_show_xtr_mode_t *mp;
15975   int ret;
15976
15977   /* Construct the API message */
15978   M (ONE_SHOW_XTR_MODE, mp);
15979
15980   /* send it... */
15981   S (mp);
15982
15983   /* Wait for a reply... */
15984   W (ret);
15985   return ret;
15986 }
15987
15988 static int
15989 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15990 {
15991   unformat_input_t *input = vam->input;
15992   vl_api_one_enable_disable_pitr_mode_t *mp;
15993   u8 is_set = 0;
15994   u8 is_en = 0;
15995   int ret;
15996
15997   /* Parse args required to build the message */
15998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15999     {
16000       if (unformat (input, "enable"))
16001         {
16002           is_set = 1;
16003           is_en = 1;
16004         }
16005       else if (unformat (input, "disable"))
16006         {
16007           is_set = 1;
16008         }
16009       else
16010         break;
16011     }
16012
16013   if (!is_set)
16014     {
16015       errmsg ("Value not set");
16016       return -99;
16017     }
16018
16019   /* Construct the API message */
16020   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16021
16022   mp->is_en = is_en;
16023
16024   /* send it... */
16025   S (mp);
16026
16027   /* Wait for a reply... */
16028   W (ret);
16029   return ret;
16030 }
16031
16032 static int
16033 api_one_show_pitr_mode (vat_main_t * vam)
16034 {
16035   vl_api_one_show_pitr_mode_t *mp;
16036   int ret;
16037
16038   /* Construct the API message */
16039   M (ONE_SHOW_PITR_MODE, mp);
16040
16041   /* send it... */
16042   S (mp);
16043
16044   /* Wait for a reply... */
16045   W (ret);
16046   return ret;
16047 }
16048
16049 static int
16050 api_one_enable_disable_petr_mode (vat_main_t * vam)
16051 {
16052   unformat_input_t *input = vam->input;
16053   vl_api_one_enable_disable_petr_mode_t *mp;
16054   u8 is_set = 0;
16055   u8 is_en = 0;
16056   int ret;
16057
16058   /* Parse args required to build the message */
16059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16060     {
16061       if (unformat (input, "enable"))
16062         {
16063           is_set = 1;
16064           is_en = 1;
16065         }
16066       else if (unformat (input, "disable"))
16067         {
16068           is_set = 1;
16069         }
16070       else
16071         break;
16072     }
16073
16074   if (!is_set)
16075     {
16076       errmsg ("Value not set");
16077       return -99;
16078     }
16079
16080   /* Construct the API message */
16081   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16082
16083   mp->is_en = is_en;
16084
16085   /* send it... */
16086   S (mp);
16087
16088   /* Wait for a reply... */
16089   W (ret);
16090   return ret;
16091 }
16092
16093 static int
16094 api_one_show_petr_mode (vat_main_t * vam)
16095 {
16096   vl_api_one_show_petr_mode_t *mp;
16097   int ret;
16098
16099   /* Construct the API message */
16100   M (ONE_SHOW_PETR_MODE, mp);
16101
16102   /* send it... */
16103   S (mp);
16104
16105   /* Wait for a reply... */
16106   W (ret);
16107   return ret;
16108 }
16109
16110 static int
16111 api_show_one_map_register_state (vat_main_t * vam)
16112 {
16113   vl_api_show_one_map_register_state_t *mp;
16114   int ret;
16115
16116   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16117
16118   /* send */
16119   S (mp);
16120
16121   /* wait for reply */
16122   W (ret);
16123   return ret;
16124 }
16125
16126 #define api_show_lisp_map_register_state api_show_one_map_register_state
16127
16128 static int
16129 api_show_one_rloc_probe_state (vat_main_t * vam)
16130 {
16131   vl_api_show_one_rloc_probe_state_t *mp;
16132   int ret;
16133
16134   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16135
16136   /* send */
16137   S (mp);
16138
16139   /* wait for reply */
16140   W (ret);
16141   return ret;
16142 }
16143
16144 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16145
16146 static int
16147 api_one_add_del_ndp_entry (vat_main_t * vam)
16148 {
16149   vl_api_one_add_del_ndp_entry_t *mp;
16150   unformat_input_t *input = vam->input;
16151   u8 is_add = 1;
16152   u8 mac_set = 0;
16153   u8 bd_set = 0;
16154   u8 ip_set = 0;
16155   u8 mac[6] = { 0, };
16156   u8 ip6[16] = { 0, };
16157   u32 bd = ~0;
16158   int ret;
16159
16160   /* Parse args required to build the message */
16161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16162     {
16163       if (unformat (input, "del"))
16164         is_add = 0;
16165       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16166         mac_set = 1;
16167       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16168         ip_set = 1;
16169       else if (unformat (input, "bd %d", &bd))
16170         bd_set = 1;
16171       else
16172         {
16173           errmsg ("parse error '%U'", format_unformat_error, input);
16174           return -99;
16175         }
16176     }
16177
16178   if (!bd_set || !ip_set || (!mac_set && is_add))
16179     {
16180       errmsg ("Missing BD, IP or MAC!");
16181       return -99;
16182     }
16183
16184   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16185   mp->is_add = is_add;
16186   clib_memcpy (mp->mac, mac, 6);
16187   mp->bd = clib_host_to_net_u32 (bd);
16188   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16189
16190   /* send */
16191   S (mp);
16192
16193   /* wait for reply */
16194   W (ret);
16195   return ret;
16196 }
16197
16198 static int
16199 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16200 {
16201   vl_api_one_add_del_l2_arp_entry_t *mp;
16202   unformat_input_t *input = vam->input;
16203   u8 is_add = 1;
16204   u8 mac_set = 0;
16205   u8 bd_set = 0;
16206   u8 ip_set = 0;
16207   u8 mac[6] = { 0, };
16208   u32 ip4 = 0, bd = ~0;
16209   int ret;
16210
16211   /* Parse args required to build the message */
16212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16213     {
16214       if (unformat (input, "del"))
16215         is_add = 0;
16216       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16217         mac_set = 1;
16218       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16219         ip_set = 1;
16220       else if (unformat (input, "bd %d", &bd))
16221         bd_set = 1;
16222       else
16223         {
16224           errmsg ("parse error '%U'", format_unformat_error, input);
16225           return -99;
16226         }
16227     }
16228
16229   if (!bd_set || !ip_set || (!mac_set && is_add))
16230     {
16231       errmsg ("Missing BD, IP or MAC!");
16232       return -99;
16233     }
16234
16235   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16236   mp->is_add = is_add;
16237   clib_memcpy (mp->mac, mac, 6);
16238   mp->bd = clib_host_to_net_u32 (bd);
16239   mp->ip4 = ip4;
16240
16241   /* send */
16242   S (mp);
16243
16244   /* wait for reply */
16245   W (ret);
16246   return ret;
16247 }
16248
16249 static int
16250 api_one_ndp_bd_get (vat_main_t * vam)
16251 {
16252   vl_api_one_ndp_bd_get_t *mp;
16253   int ret;
16254
16255   M (ONE_NDP_BD_GET, mp);
16256
16257   /* send */
16258   S (mp);
16259
16260   /* wait for reply */
16261   W (ret);
16262   return ret;
16263 }
16264
16265 static int
16266 api_one_ndp_entries_get (vat_main_t * vam)
16267 {
16268   vl_api_one_ndp_entries_get_t *mp;
16269   unformat_input_t *input = vam->input;
16270   u8 bd_set = 0;
16271   u32 bd = ~0;
16272   int ret;
16273
16274   /* Parse args required to build the message */
16275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16276     {
16277       if (unformat (input, "bd %d", &bd))
16278         bd_set = 1;
16279       else
16280         {
16281           errmsg ("parse error '%U'", format_unformat_error, input);
16282           return -99;
16283         }
16284     }
16285
16286   if (!bd_set)
16287     {
16288       errmsg ("Expected bridge domain!");
16289       return -99;
16290     }
16291
16292   M (ONE_NDP_ENTRIES_GET, mp);
16293   mp->bd = clib_host_to_net_u32 (bd);
16294
16295   /* send */
16296   S (mp);
16297
16298   /* wait for reply */
16299   W (ret);
16300   return ret;
16301 }
16302
16303 static int
16304 api_one_l2_arp_bd_get (vat_main_t * vam)
16305 {
16306   vl_api_one_l2_arp_bd_get_t *mp;
16307   int ret;
16308
16309   M (ONE_L2_ARP_BD_GET, mp);
16310
16311   /* send */
16312   S (mp);
16313
16314   /* wait for reply */
16315   W (ret);
16316   return ret;
16317 }
16318
16319 static int
16320 api_one_l2_arp_entries_get (vat_main_t * vam)
16321 {
16322   vl_api_one_l2_arp_entries_get_t *mp;
16323   unformat_input_t *input = vam->input;
16324   u8 bd_set = 0;
16325   u32 bd = ~0;
16326   int ret;
16327
16328   /* Parse args required to build the message */
16329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16330     {
16331       if (unformat (input, "bd %d", &bd))
16332         bd_set = 1;
16333       else
16334         {
16335           errmsg ("parse error '%U'", format_unformat_error, input);
16336           return -99;
16337         }
16338     }
16339
16340   if (!bd_set)
16341     {
16342       errmsg ("Expected bridge domain!");
16343       return -99;
16344     }
16345
16346   M (ONE_L2_ARP_ENTRIES_GET, mp);
16347   mp->bd = clib_host_to_net_u32 (bd);
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_stats_enable_disable (vat_main_t * vam)
16359 {
16360   vl_api_one_stats_enable_disable_t *mp;
16361   unformat_input_t *input = vam->input;
16362   u8 is_set = 0;
16363   u8 is_en = 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, "enable"))
16370         {
16371           is_set = 1;
16372           is_en = 1;
16373         }
16374       else if (unformat (input, "disable"))
16375         {
16376           is_set = 1;
16377         }
16378       else
16379         break;
16380     }
16381
16382   if (!is_set)
16383     {
16384       errmsg ("Value not set");
16385       return -99;
16386     }
16387
16388   M (ONE_STATS_ENABLE_DISABLE, mp);
16389   mp->is_en = is_en;
16390
16391   /* send */
16392   S (mp);
16393
16394   /* wait for reply */
16395   W (ret);
16396   return ret;
16397 }
16398
16399 static int
16400 api_show_one_stats_enable_disable (vat_main_t * vam)
16401 {
16402   vl_api_show_one_stats_enable_disable_t *mp;
16403   int ret;
16404
16405   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16406
16407   /* send */
16408   S (mp);
16409
16410   /* wait for reply */
16411   W (ret);
16412   return ret;
16413 }
16414
16415 static int
16416 api_show_one_map_request_mode (vat_main_t * vam)
16417 {
16418   vl_api_show_one_map_request_mode_t *mp;
16419   int ret;
16420
16421   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16422
16423   /* send */
16424   S (mp);
16425
16426   /* wait for reply */
16427   W (ret);
16428   return ret;
16429 }
16430
16431 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16432
16433 static int
16434 api_one_map_request_mode (vat_main_t * vam)
16435 {
16436   unformat_input_t *input = vam->input;
16437   vl_api_one_map_request_mode_t *mp;
16438   u8 mode = 0;
16439   int ret;
16440
16441   /* Parse args required to build the message */
16442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16443     {
16444       if (unformat (input, "dst-only"))
16445         mode = 0;
16446       else if (unformat (input, "src-dst"))
16447         mode = 1;
16448       else
16449         {
16450           errmsg ("parse error '%U'", format_unformat_error, input);
16451           return -99;
16452         }
16453     }
16454
16455   M (ONE_MAP_REQUEST_MODE, mp);
16456
16457   mp->mode = mode;
16458
16459   /* send */
16460   S (mp);
16461
16462   /* wait for reply */
16463   W (ret);
16464   return ret;
16465 }
16466
16467 #define api_lisp_map_request_mode api_one_map_request_mode
16468
16469 /**
16470  * Enable/disable ONE proxy ITR.
16471  *
16472  * @param vam vpp API test context
16473  * @return return code
16474  */
16475 static int
16476 api_one_pitr_set_locator_set (vat_main_t * vam)
16477 {
16478   u8 ls_name_set = 0;
16479   unformat_input_t *input = vam->input;
16480   vl_api_one_pitr_set_locator_set_t *mp;
16481   u8 is_add = 1;
16482   u8 *ls_name = 0;
16483   int ret;
16484
16485   /* Parse args required to build the message */
16486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16487     {
16488       if (unformat (input, "del"))
16489         is_add = 0;
16490       else if (unformat (input, "locator-set %s", &ls_name))
16491         ls_name_set = 1;
16492       else
16493         {
16494           errmsg ("parse error '%U'", format_unformat_error, input);
16495           return -99;
16496         }
16497     }
16498
16499   if (!ls_name_set)
16500     {
16501       errmsg ("locator-set name not set!");
16502       return -99;
16503     }
16504
16505   M (ONE_PITR_SET_LOCATOR_SET, mp);
16506
16507   mp->is_add = is_add;
16508   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16509   vec_free (ls_name);
16510
16511   /* send */
16512   S (mp);
16513
16514   /* wait for reply */
16515   W (ret);
16516   return ret;
16517 }
16518
16519 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16520
16521 static int
16522 api_one_nsh_set_locator_set (vat_main_t * vam)
16523 {
16524   u8 ls_name_set = 0;
16525   unformat_input_t *input = vam->input;
16526   vl_api_one_nsh_set_locator_set_t *mp;
16527   u8 is_add = 1;
16528   u8 *ls_name = 0;
16529   int ret;
16530
16531   /* Parse args required to build the message */
16532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16533     {
16534       if (unformat (input, "del"))
16535         is_add = 0;
16536       else if (unformat (input, "ls %s", &ls_name))
16537         ls_name_set = 1;
16538       else
16539         {
16540           errmsg ("parse error '%U'", format_unformat_error, input);
16541           return -99;
16542         }
16543     }
16544
16545   if (!ls_name_set && is_add)
16546     {
16547       errmsg ("locator-set name not set!");
16548       return -99;
16549     }
16550
16551   M (ONE_NSH_SET_LOCATOR_SET, mp);
16552
16553   mp->is_add = is_add;
16554   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16555   vec_free (ls_name);
16556
16557   /* send */
16558   S (mp);
16559
16560   /* wait for reply */
16561   W (ret);
16562   return ret;
16563 }
16564
16565 static int
16566 api_show_one_pitr (vat_main_t * vam)
16567 {
16568   vl_api_show_one_pitr_t *mp;
16569   int ret;
16570
16571   if (!vam->json_output)
16572     {
16573       print (vam->ofp, "%=20s", "lisp status:");
16574     }
16575
16576   M (SHOW_ONE_PITR, mp);
16577   /* send it... */
16578   S (mp);
16579
16580   /* Wait for a reply... */
16581   W (ret);
16582   return ret;
16583 }
16584
16585 #define api_show_lisp_pitr api_show_one_pitr
16586
16587 static int
16588 api_one_use_petr (vat_main_t * vam)
16589 {
16590   unformat_input_t *input = vam->input;
16591   vl_api_one_use_petr_t *mp;
16592   u8 is_add = 0;
16593   ip_address_t ip;
16594   int ret;
16595
16596   clib_memset (&ip, 0, sizeof (ip));
16597
16598   /* Parse args required to build the message */
16599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16600     {
16601       if (unformat (input, "disable"))
16602         is_add = 0;
16603       else
16604         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16605         {
16606           is_add = 1;
16607           ip_addr_version (&ip) = IP4;
16608         }
16609       else
16610         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16611         {
16612           is_add = 1;
16613           ip_addr_version (&ip) = IP6;
16614         }
16615       else
16616         {
16617           errmsg ("parse error '%U'", format_unformat_error, input);
16618           return -99;
16619         }
16620     }
16621
16622   M (ONE_USE_PETR, mp);
16623
16624   mp->is_add = is_add;
16625   if (is_add)
16626     {
16627       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16628       if (mp->is_ip4)
16629         clib_memcpy (mp->address, &ip, 4);
16630       else
16631         clib_memcpy (mp->address, &ip, 16);
16632     }
16633
16634   /* send */
16635   S (mp);
16636
16637   /* wait for reply */
16638   W (ret);
16639   return ret;
16640 }
16641
16642 #define api_lisp_use_petr api_one_use_petr
16643
16644 static int
16645 api_show_one_nsh_mapping (vat_main_t * vam)
16646 {
16647   vl_api_show_one_use_petr_t *mp;
16648   int ret;
16649
16650   if (!vam->json_output)
16651     {
16652       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16653     }
16654
16655   M (SHOW_ONE_NSH_MAPPING, mp);
16656   /* send it... */
16657   S (mp);
16658
16659   /* Wait for a reply... */
16660   W (ret);
16661   return ret;
16662 }
16663
16664 static int
16665 api_show_one_use_petr (vat_main_t * vam)
16666 {
16667   vl_api_show_one_use_petr_t *mp;
16668   int ret;
16669
16670   if (!vam->json_output)
16671     {
16672       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16673     }
16674
16675   M (SHOW_ONE_USE_PETR, mp);
16676   /* send it... */
16677   S (mp);
16678
16679   /* Wait for a reply... */
16680   W (ret);
16681   return ret;
16682 }
16683
16684 #define api_show_lisp_use_petr api_show_one_use_petr
16685
16686 /**
16687  * Add/delete mapping between vni and vrf
16688  */
16689 static int
16690 api_one_eid_table_add_del_map (vat_main_t * vam)
16691 {
16692   unformat_input_t *input = vam->input;
16693   vl_api_one_eid_table_add_del_map_t *mp;
16694   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16695   u32 vni, vrf, bd_index;
16696   int ret;
16697
16698   /* Parse args required to build the message */
16699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16700     {
16701       if (unformat (input, "del"))
16702         is_add = 0;
16703       else if (unformat (input, "vrf %d", &vrf))
16704         vrf_set = 1;
16705       else if (unformat (input, "bd_index %d", &bd_index))
16706         bd_index_set = 1;
16707       else if (unformat (input, "vni %d", &vni))
16708         vni_set = 1;
16709       else
16710         break;
16711     }
16712
16713   if (!vni_set || (!vrf_set && !bd_index_set))
16714     {
16715       errmsg ("missing arguments!");
16716       return -99;
16717     }
16718
16719   if (vrf_set && bd_index_set)
16720     {
16721       errmsg ("error: both vrf and bd entered!");
16722       return -99;
16723     }
16724
16725   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16726
16727   mp->is_add = is_add;
16728   mp->vni = htonl (vni);
16729   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16730   mp->is_l2 = bd_index_set;
16731
16732   /* send */
16733   S (mp);
16734
16735   /* wait for reply */
16736   W (ret);
16737   return ret;
16738 }
16739
16740 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16741
16742 uword
16743 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16744 {
16745   u32 *action = va_arg (*args, u32 *);
16746   u8 *s = 0;
16747
16748   if (unformat (input, "%s", &s))
16749     {
16750       if (!strcmp ((char *) s, "no-action"))
16751         action[0] = 0;
16752       else if (!strcmp ((char *) s, "natively-forward"))
16753         action[0] = 1;
16754       else if (!strcmp ((char *) s, "send-map-request"))
16755         action[0] = 2;
16756       else if (!strcmp ((char *) s, "drop"))
16757         action[0] = 3;
16758       else
16759         {
16760           clib_warning ("invalid action: '%s'", s);
16761           action[0] = 3;
16762         }
16763     }
16764   else
16765     return 0;
16766
16767   vec_free (s);
16768   return 1;
16769 }
16770
16771 /**
16772  * Add/del remote mapping to/from ONE control plane
16773  *
16774  * @param vam vpp API test context
16775  * @return return code
16776  */
16777 static int
16778 api_one_add_del_remote_mapping (vat_main_t * vam)
16779 {
16780   unformat_input_t *input = vam->input;
16781   vl_api_one_add_del_remote_mapping_t *mp;
16782   u32 vni = 0;
16783   lisp_eid_vat_t _eid, *eid = &_eid;
16784   lisp_eid_vat_t _seid, *seid = &_seid;
16785   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16786   u32 action = ~0, p, w, data_len;
16787   ip4_address_t rloc4;
16788   ip6_address_t rloc6;
16789   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16790   int ret;
16791
16792   clib_memset (&rloc, 0, sizeof (rloc));
16793
16794   /* Parse args required to build the message */
16795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16796     {
16797       if (unformat (input, "del-all"))
16798         {
16799           del_all = 1;
16800         }
16801       else if (unformat (input, "del"))
16802         {
16803           is_add = 0;
16804         }
16805       else if (unformat (input, "add"))
16806         {
16807           is_add = 1;
16808         }
16809       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16810         {
16811           eid_set = 1;
16812         }
16813       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16814         {
16815           seid_set = 1;
16816         }
16817       else if (unformat (input, "vni %d", &vni))
16818         {
16819           ;
16820         }
16821       else if (unformat (input, "p %d w %d", &p, &w))
16822         {
16823           if (!curr_rloc)
16824             {
16825               errmsg ("No RLOC configured for setting priority/weight!");
16826               return -99;
16827             }
16828           curr_rloc->priority = p;
16829           curr_rloc->weight = w;
16830         }
16831       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16832         {
16833           rloc.is_ip4 = 1;
16834           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16835           vec_add1 (rlocs, rloc);
16836           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16837         }
16838       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16839         {
16840           rloc.is_ip4 = 0;
16841           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16842           vec_add1 (rlocs, rloc);
16843           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16844         }
16845       else if (unformat (input, "action %U",
16846                          unformat_negative_mapping_action, &action))
16847         {
16848           ;
16849         }
16850       else
16851         {
16852           clib_warning ("parse error '%U'", format_unformat_error, input);
16853           return -99;
16854         }
16855     }
16856
16857   if (0 == eid_set)
16858     {
16859       errmsg ("missing params!");
16860       return -99;
16861     }
16862
16863   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16864     {
16865       errmsg ("no action set for negative map-reply!");
16866       return -99;
16867     }
16868
16869   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16870
16871   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16872   mp->is_add = is_add;
16873   mp->vni = htonl (vni);
16874   mp->action = (u8) action;
16875   mp->is_src_dst = seid_set;
16876   mp->eid_len = eid->len;
16877   mp->seid_len = seid->len;
16878   mp->del_all = del_all;
16879   mp->eid_type = eid->type;
16880   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16881   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16882
16883   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16884   clib_memcpy (mp->rlocs, rlocs, data_len);
16885   vec_free (rlocs);
16886
16887   /* send it... */
16888   S (mp);
16889
16890   /* Wait for a reply... */
16891   W (ret);
16892   return ret;
16893 }
16894
16895 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16896
16897 /**
16898  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16899  * forwarding entries in data-plane accordingly.
16900  *
16901  * @param vam vpp API test context
16902  * @return return code
16903  */
16904 static int
16905 api_one_add_del_adjacency (vat_main_t * vam)
16906 {
16907   unformat_input_t *input = vam->input;
16908   vl_api_one_add_del_adjacency_t *mp;
16909   u32 vni = 0;
16910   ip4_address_t leid4, reid4;
16911   ip6_address_t leid6, reid6;
16912   u8 reid_mac[6] = { 0 };
16913   u8 leid_mac[6] = { 0 };
16914   u8 reid_type, leid_type;
16915   u32 leid_len = 0, reid_len = 0, len;
16916   u8 is_add = 1;
16917   int ret;
16918
16919   leid_type = reid_type = (u8) ~ 0;
16920
16921   /* Parse args required to build the message */
16922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16923     {
16924       if (unformat (input, "del"))
16925         {
16926           is_add = 0;
16927         }
16928       else if (unformat (input, "add"))
16929         {
16930           is_add = 1;
16931         }
16932       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16933                          &reid4, &len))
16934         {
16935           reid_type = 0;        /* ipv4 */
16936           reid_len = len;
16937         }
16938       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16939                          &reid6, &len))
16940         {
16941           reid_type = 1;        /* ipv6 */
16942           reid_len = len;
16943         }
16944       else if (unformat (input, "reid %U", unformat_ethernet_address,
16945                          reid_mac))
16946         {
16947           reid_type = 2;        /* mac */
16948         }
16949       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16950                          &leid4, &len))
16951         {
16952           leid_type = 0;        /* ipv4 */
16953           leid_len = len;
16954         }
16955       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16956                          &leid6, &len))
16957         {
16958           leid_type = 1;        /* ipv6 */
16959           leid_len = len;
16960         }
16961       else if (unformat (input, "leid %U", unformat_ethernet_address,
16962                          leid_mac))
16963         {
16964           leid_type = 2;        /* mac */
16965         }
16966       else if (unformat (input, "vni %d", &vni))
16967         {
16968           ;
16969         }
16970       else
16971         {
16972           errmsg ("parse error '%U'", format_unformat_error, input);
16973           return -99;
16974         }
16975     }
16976
16977   if ((u8) ~ 0 == reid_type)
16978     {
16979       errmsg ("missing params!");
16980       return -99;
16981     }
16982
16983   if (leid_type != reid_type)
16984     {
16985       errmsg ("remote and local EIDs are of different types!");
16986       return -99;
16987     }
16988
16989   M (ONE_ADD_DEL_ADJACENCY, mp);
16990   mp->is_add = is_add;
16991   mp->vni = htonl (vni);
16992   mp->leid_len = leid_len;
16993   mp->reid_len = reid_len;
16994   mp->eid_type = reid_type;
16995
16996   switch (mp->eid_type)
16997     {
16998     case 0:
16999       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17000       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17001       break;
17002     case 1:
17003       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17004       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17005       break;
17006     case 2:
17007       clib_memcpy (mp->leid, leid_mac, 6);
17008       clib_memcpy (mp->reid, reid_mac, 6);
17009       break;
17010     default:
17011       errmsg ("unknown EID type %d!", mp->eid_type);
17012       return 0;
17013     }
17014
17015   /* send it... */
17016   S (mp);
17017
17018   /* Wait for a reply... */
17019   W (ret);
17020   return ret;
17021 }
17022
17023 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17024
17025 uword
17026 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17027 {
17028   u32 *mode = va_arg (*args, u32 *);
17029
17030   if (unformat (input, "lisp"))
17031     *mode = 0;
17032   else if (unformat (input, "vxlan"))
17033     *mode = 1;
17034   else
17035     return 0;
17036
17037   return 1;
17038 }
17039
17040 static int
17041 api_gpe_get_encap_mode (vat_main_t * vam)
17042 {
17043   vl_api_gpe_get_encap_mode_t *mp;
17044   int ret;
17045
17046   /* Construct the API message */
17047   M (GPE_GET_ENCAP_MODE, mp);
17048
17049   /* send it... */
17050   S (mp);
17051
17052   /* Wait for a reply... */
17053   W (ret);
17054   return ret;
17055 }
17056
17057 static int
17058 api_gpe_set_encap_mode (vat_main_t * vam)
17059 {
17060   unformat_input_t *input = vam->input;
17061   vl_api_gpe_set_encap_mode_t *mp;
17062   int ret;
17063   u32 mode = 0;
17064
17065   /* Parse args required to build the message */
17066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17067     {
17068       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17069         ;
17070       else
17071         break;
17072     }
17073
17074   /* Construct the API message */
17075   M (GPE_SET_ENCAP_MODE, mp);
17076
17077   mp->mode = mode;
17078
17079   /* send it... */
17080   S (mp);
17081
17082   /* Wait for a reply... */
17083   W (ret);
17084   return ret;
17085 }
17086
17087 static int
17088 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17089 {
17090   unformat_input_t *input = vam->input;
17091   vl_api_gpe_add_del_iface_t *mp;
17092   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17093   u32 dp_table = 0, vni = 0;
17094   int ret;
17095
17096   /* Parse args required to build the message */
17097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17098     {
17099       if (unformat (input, "up"))
17100         {
17101           action_set = 1;
17102           is_add = 1;
17103         }
17104       else if (unformat (input, "down"))
17105         {
17106           action_set = 1;
17107           is_add = 0;
17108         }
17109       else if (unformat (input, "table_id %d", &dp_table))
17110         {
17111           dp_table_set = 1;
17112         }
17113       else if (unformat (input, "bd_id %d", &dp_table))
17114         {
17115           dp_table_set = 1;
17116           is_l2 = 1;
17117         }
17118       else if (unformat (input, "vni %d", &vni))
17119         {
17120           vni_set = 1;
17121         }
17122       else
17123         break;
17124     }
17125
17126   if (action_set == 0)
17127     {
17128       errmsg ("Action not set");
17129       return -99;
17130     }
17131   if (dp_table_set == 0 || vni_set == 0)
17132     {
17133       errmsg ("vni and dp_table must be set");
17134       return -99;
17135     }
17136
17137   /* Construct the API message */
17138   M (GPE_ADD_DEL_IFACE, mp);
17139
17140   mp->is_add = is_add;
17141   mp->dp_table = clib_host_to_net_u32 (dp_table);
17142   mp->is_l2 = is_l2;
17143   mp->vni = clib_host_to_net_u32 (vni);
17144
17145   /* send it... */
17146   S (mp);
17147
17148   /* Wait for a reply... */
17149   W (ret);
17150   return ret;
17151 }
17152
17153 static int
17154 api_one_map_register_fallback_threshold (vat_main_t * vam)
17155 {
17156   unformat_input_t *input = vam->input;
17157   vl_api_one_map_register_fallback_threshold_t *mp;
17158   u32 value = 0;
17159   u8 is_set = 0;
17160   int ret;
17161
17162   /* Parse args required to build the message */
17163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17164     {
17165       if (unformat (input, "%u", &value))
17166         is_set = 1;
17167       else
17168         {
17169           clib_warning ("parse error '%U'", format_unformat_error, input);
17170           return -99;
17171         }
17172     }
17173
17174   if (!is_set)
17175     {
17176       errmsg ("fallback threshold value is missing!");
17177       return -99;
17178     }
17179
17180   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17181   mp->value = clib_host_to_net_u32 (value);
17182
17183   /* send it... */
17184   S (mp);
17185
17186   /* Wait for a reply... */
17187   W (ret);
17188   return ret;
17189 }
17190
17191 static int
17192 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17193 {
17194   vl_api_show_one_map_register_fallback_threshold_t *mp;
17195   int ret;
17196
17197   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17198
17199   /* send it... */
17200   S (mp);
17201
17202   /* Wait for a reply... */
17203   W (ret);
17204   return ret;
17205 }
17206
17207 uword
17208 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17209 {
17210   u32 *proto = va_arg (*args, u32 *);
17211
17212   if (unformat (input, "udp"))
17213     *proto = 1;
17214   else if (unformat (input, "api"))
17215     *proto = 2;
17216   else
17217     return 0;
17218
17219   return 1;
17220 }
17221
17222 static int
17223 api_one_set_transport_protocol (vat_main_t * vam)
17224 {
17225   unformat_input_t *input = vam->input;
17226   vl_api_one_set_transport_protocol_t *mp;
17227   u8 is_set = 0;
17228   u32 protocol = 0;
17229   int ret;
17230
17231   /* Parse args required to build the message */
17232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17233     {
17234       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17235         is_set = 1;
17236       else
17237         {
17238           clib_warning ("parse error '%U'", format_unformat_error, input);
17239           return -99;
17240         }
17241     }
17242
17243   if (!is_set)
17244     {
17245       errmsg ("Transport protocol missing!");
17246       return -99;
17247     }
17248
17249   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17250   mp->protocol = (u8) protocol;
17251
17252   /* send it... */
17253   S (mp);
17254
17255   /* Wait for a reply... */
17256   W (ret);
17257   return ret;
17258 }
17259
17260 static int
17261 api_one_get_transport_protocol (vat_main_t * vam)
17262 {
17263   vl_api_one_get_transport_protocol_t *mp;
17264   int ret;
17265
17266   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17267
17268   /* send it... */
17269   S (mp);
17270
17271   /* Wait for a reply... */
17272   W (ret);
17273   return ret;
17274 }
17275
17276 static int
17277 api_one_map_register_set_ttl (vat_main_t * vam)
17278 {
17279   unformat_input_t *input = vam->input;
17280   vl_api_one_map_register_set_ttl_t *mp;
17281   u32 ttl = 0;
17282   u8 is_set = 0;
17283   int ret;
17284
17285   /* Parse args required to build the message */
17286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17287     {
17288       if (unformat (input, "%u", &ttl))
17289         is_set = 1;
17290       else
17291         {
17292           clib_warning ("parse error '%U'", format_unformat_error, input);
17293           return -99;
17294         }
17295     }
17296
17297   if (!is_set)
17298     {
17299       errmsg ("TTL value missing!");
17300       return -99;
17301     }
17302
17303   M (ONE_MAP_REGISTER_SET_TTL, mp);
17304   mp->ttl = clib_host_to_net_u32 (ttl);
17305
17306   /* send it... */
17307   S (mp);
17308
17309   /* Wait for a reply... */
17310   W (ret);
17311   return ret;
17312 }
17313
17314 static int
17315 api_show_one_map_register_ttl (vat_main_t * vam)
17316 {
17317   vl_api_show_one_map_register_ttl_t *mp;
17318   int ret;
17319
17320   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17321
17322   /* send it... */
17323   S (mp);
17324
17325   /* Wait for a reply... */
17326   W (ret);
17327   return ret;
17328 }
17329
17330 /**
17331  * Add/del map request itr rlocs from ONE control plane and updates
17332  *
17333  * @param vam vpp API test context
17334  * @return return code
17335  */
17336 static int
17337 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17338 {
17339   unformat_input_t *input = vam->input;
17340   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17341   u8 *locator_set_name = 0;
17342   u8 locator_set_name_set = 0;
17343   u8 is_add = 1;
17344   int ret;
17345
17346   /* Parse args required to build the message */
17347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17348     {
17349       if (unformat (input, "del"))
17350         {
17351           is_add = 0;
17352         }
17353       else if (unformat (input, "%_%v%_", &locator_set_name))
17354         {
17355           locator_set_name_set = 1;
17356         }
17357       else
17358         {
17359           clib_warning ("parse error '%U'", format_unformat_error, input);
17360           return -99;
17361         }
17362     }
17363
17364   if (is_add && !locator_set_name_set)
17365     {
17366       errmsg ("itr-rloc is not set!");
17367       return -99;
17368     }
17369
17370   if (is_add && vec_len (locator_set_name) > 64)
17371     {
17372       errmsg ("itr-rloc locator-set name too long");
17373       vec_free (locator_set_name);
17374       return -99;
17375     }
17376
17377   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17378   mp->is_add = is_add;
17379   if (is_add)
17380     {
17381       clib_memcpy (mp->locator_set_name, locator_set_name,
17382                    vec_len (locator_set_name));
17383     }
17384   else
17385     {
17386       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17387     }
17388   vec_free (locator_set_name);
17389
17390   /* send it... */
17391   S (mp);
17392
17393   /* Wait for a reply... */
17394   W (ret);
17395   return ret;
17396 }
17397
17398 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17399
17400 static int
17401 api_one_locator_dump (vat_main_t * vam)
17402 {
17403   unformat_input_t *input = vam->input;
17404   vl_api_one_locator_dump_t *mp;
17405   vl_api_control_ping_t *mp_ping;
17406   u8 is_index_set = 0, is_name_set = 0;
17407   u8 *ls_name = 0;
17408   u32 ls_index = ~0;
17409   int ret;
17410
17411   /* Parse args required to build the message */
17412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17413     {
17414       if (unformat (input, "ls_name %_%v%_", &ls_name))
17415         {
17416           is_name_set = 1;
17417         }
17418       else if (unformat (input, "ls_index %d", &ls_index))
17419         {
17420           is_index_set = 1;
17421         }
17422       else
17423         {
17424           errmsg ("parse error '%U'", format_unformat_error, input);
17425           return -99;
17426         }
17427     }
17428
17429   if (!is_index_set && !is_name_set)
17430     {
17431       errmsg ("error: expected one of index or name!");
17432       return -99;
17433     }
17434
17435   if (is_index_set && is_name_set)
17436     {
17437       errmsg ("error: only one param expected!");
17438       return -99;
17439     }
17440
17441   if (vec_len (ls_name) > 62)
17442     {
17443       errmsg ("error: locator set name too long!");
17444       return -99;
17445     }
17446
17447   if (!vam->json_output)
17448     {
17449       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17450     }
17451
17452   M (ONE_LOCATOR_DUMP, mp);
17453   mp->is_index_set = is_index_set;
17454
17455   if (is_index_set)
17456     mp->ls_index = clib_host_to_net_u32 (ls_index);
17457   else
17458     {
17459       vec_add1 (ls_name, 0);
17460       strncpy ((char *) mp->ls_name, (char *) ls_name,
17461                sizeof (mp->ls_name) - 1);
17462     }
17463
17464   /* send it... */
17465   S (mp);
17466
17467   /* Use a control ping for synchronization */
17468   MPING (CONTROL_PING, mp_ping);
17469   S (mp_ping);
17470
17471   /* Wait for a reply... */
17472   W (ret);
17473   return ret;
17474 }
17475
17476 #define api_lisp_locator_dump api_one_locator_dump
17477
17478 static int
17479 api_one_locator_set_dump (vat_main_t * vam)
17480 {
17481   vl_api_one_locator_set_dump_t *mp;
17482   vl_api_control_ping_t *mp_ping;
17483   unformat_input_t *input = vam->input;
17484   u8 filter = 0;
17485   int ret;
17486
17487   /* Parse args required to build the message */
17488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17489     {
17490       if (unformat (input, "local"))
17491         {
17492           filter = 1;
17493         }
17494       else if (unformat (input, "remote"))
17495         {
17496           filter = 2;
17497         }
17498       else
17499         {
17500           errmsg ("parse error '%U'", format_unformat_error, input);
17501           return -99;
17502         }
17503     }
17504
17505   if (!vam->json_output)
17506     {
17507       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17508     }
17509
17510   M (ONE_LOCATOR_SET_DUMP, mp);
17511
17512   mp->filter = filter;
17513
17514   /* send it... */
17515   S (mp);
17516
17517   /* Use a control ping for synchronization */
17518   MPING (CONTROL_PING, mp_ping);
17519   S (mp_ping);
17520
17521   /* Wait for a reply... */
17522   W (ret);
17523   return ret;
17524 }
17525
17526 #define api_lisp_locator_set_dump api_one_locator_set_dump
17527
17528 static int
17529 api_one_eid_table_map_dump (vat_main_t * vam)
17530 {
17531   u8 is_l2 = 0;
17532   u8 mode_set = 0;
17533   unformat_input_t *input = vam->input;
17534   vl_api_one_eid_table_map_dump_t *mp;
17535   vl_api_control_ping_t *mp_ping;
17536   int ret;
17537
17538   /* Parse args required to build the message */
17539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17540     {
17541       if (unformat (input, "l2"))
17542         {
17543           is_l2 = 1;
17544           mode_set = 1;
17545         }
17546       else if (unformat (input, "l3"))
17547         {
17548           is_l2 = 0;
17549           mode_set = 1;
17550         }
17551       else
17552         {
17553           errmsg ("parse error '%U'", format_unformat_error, input);
17554           return -99;
17555         }
17556     }
17557
17558   if (!mode_set)
17559     {
17560       errmsg ("expected one of 'l2' or 'l3' parameter!");
17561       return -99;
17562     }
17563
17564   if (!vam->json_output)
17565     {
17566       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17567     }
17568
17569   M (ONE_EID_TABLE_MAP_DUMP, mp);
17570   mp->is_l2 = is_l2;
17571
17572   /* send it... */
17573   S (mp);
17574
17575   /* Use a control ping for synchronization */
17576   MPING (CONTROL_PING, mp_ping);
17577   S (mp_ping);
17578
17579   /* Wait for a reply... */
17580   W (ret);
17581   return ret;
17582 }
17583
17584 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17585
17586 static int
17587 api_one_eid_table_vni_dump (vat_main_t * vam)
17588 {
17589   vl_api_one_eid_table_vni_dump_t *mp;
17590   vl_api_control_ping_t *mp_ping;
17591   int ret;
17592
17593   if (!vam->json_output)
17594     {
17595       print (vam->ofp, "VNI");
17596     }
17597
17598   M (ONE_EID_TABLE_VNI_DUMP, mp);
17599
17600   /* send it... */
17601   S (mp);
17602
17603   /* Use a control ping for synchronization */
17604   MPING (CONTROL_PING, mp_ping);
17605   S (mp_ping);
17606
17607   /* Wait for a reply... */
17608   W (ret);
17609   return ret;
17610 }
17611
17612 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17613
17614 static int
17615 api_one_eid_table_dump (vat_main_t * vam)
17616 {
17617   unformat_input_t *i = vam->input;
17618   vl_api_one_eid_table_dump_t *mp;
17619   vl_api_control_ping_t *mp_ping;
17620   struct in_addr ip4;
17621   struct in6_addr ip6;
17622   u8 mac[6];
17623   u8 eid_type = ~0, eid_set = 0;
17624   u32 prefix_length = ~0, t, vni = 0;
17625   u8 filter = 0;
17626   int ret;
17627   lisp_nsh_api_t nsh;
17628
17629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17630     {
17631       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17632         {
17633           eid_set = 1;
17634           eid_type = 0;
17635           prefix_length = t;
17636         }
17637       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17638         {
17639           eid_set = 1;
17640           eid_type = 1;
17641           prefix_length = t;
17642         }
17643       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17644         {
17645           eid_set = 1;
17646           eid_type = 2;
17647         }
17648       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17649         {
17650           eid_set = 1;
17651           eid_type = 3;
17652         }
17653       else if (unformat (i, "vni %d", &t))
17654         {
17655           vni = t;
17656         }
17657       else if (unformat (i, "local"))
17658         {
17659           filter = 1;
17660         }
17661       else if (unformat (i, "remote"))
17662         {
17663           filter = 2;
17664         }
17665       else
17666         {
17667           errmsg ("parse error '%U'", format_unformat_error, i);
17668           return -99;
17669         }
17670     }
17671
17672   if (!vam->json_output)
17673     {
17674       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17675              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17676     }
17677
17678   M (ONE_EID_TABLE_DUMP, mp);
17679
17680   mp->filter = filter;
17681   if (eid_set)
17682     {
17683       mp->eid_set = 1;
17684       mp->vni = htonl (vni);
17685       mp->eid_type = eid_type;
17686       switch (eid_type)
17687         {
17688         case 0:
17689           mp->prefix_length = prefix_length;
17690           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17691           break;
17692         case 1:
17693           mp->prefix_length = prefix_length;
17694           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17695           break;
17696         case 2:
17697           clib_memcpy (mp->eid, mac, sizeof (mac));
17698           break;
17699         case 3:
17700           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17701           break;
17702         default:
17703           errmsg ("unknown EID type %d!", eid_type);
17704           return -99;
17705         }
17706     }
17707
17708   /* send it... */
17709   S (mp);
17710
17711   /* Use a control ping for synchronization */
17712   MPING (CONTROL_PING, mp_ping);
17713   S (mp_ping);
17714
17715   /* Wait for a reply... */
17716   W (ret);
17717   return ret;
17718 }
17719
17720 #define api_lisp_eid_table_dump api_one_eid_table_dump
17721
17722 static int
17723 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17724 {
17725   unformat_input_t *i = vam->input;
17726   vl_api_gpe_fwd_entries_get_t *mp;
17727   u8 vni_set = 0;
17728   u32 vni = ~0;
17729   int ret;
17730
17731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17732     {
17733       if (unformat (i, "vni %d", &vni))
17734         {
17735           vni_set = 1;
17736         }
17737       else
17738         {
17739           errmsg ("parse error '%U'", format_unformat_error, i);
17740           return -99;
17741         }
17742     }
17743
17744   if (!vni_set)
17745     {
17746       errmsg ("vni not set!");
17747       return -99;
17748     }
17749
17750   if (!vam->json_output)
17751     {
17752       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17753              "leid", "reid");
17754     }
17755
17756   M (GPE_FWD_ENTRIES_GET, mp);
17757   mp->vni = clib_host_to_net_u32 (vni);
17758
17759   /* send it... */
17760   S (mp);
17761
17762   /* Wait for a reply... */
17763   W (ret);
17764   return ret;
17765 }
17766
17767 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17768 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17769 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17770 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17771 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17772 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17773 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17774 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17775
17776 static int
17777 api_one_adjacencies_get (vat_main_t * vam)
17778 {
17779   unformat_input_t *i = vam->input;
17780   vl_api_one_adjacencies_get_t *mp;
17781   u8 vni_set = 0;
17782   u32 vni = ~0;
17783   int ret;
17784
17785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17786     {
17787       if (unformat (i, "vni %d", &vni))
17788         {
17789           vni_set = 1;
17790         }
17791       else
17792         {
17793           errmsg ("parse error '%U'", format_unformat_error, i);
17794           return -99;
17795         }
17796     }
17797
17798   if (!vni_set)
17799     {
17800       errmsg ("vni not set!");
17801       return -99;
17802     }
17803
17804   if (!vam->json_output)
17805     {
17806       print (vam->ofp, "%s %40s", "leid", "reid");
17807     }
17808
17809   M (ONE_ADJACENCIES_GET, mp);
17810   mp->vni = clib_host_to_net_u32 (vni);
17811
17812   /* send it... */
17813   S (mp);
17814
17815   /* Wait for a reply... */
17816   W (ret);
17817   return ret;
17818 }
17819
17820 #define api_lisp_adjacencies_get api_one_adjacencies_get
17821
17822 static int
17823 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17824 {
17825   unformat_input_t *i = vam->input;
17826   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17827   int ret;
17828   u8 ip_family_set = 0, is_ip4 = 1;
17829
17830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17831     {
17832       if (unformat (i, "ip4"))
17833         {
17834           ip_family_set = 1;
17835           is_ip4 = 1;
17836         }
17837       else if (unformat (i, "ip6"))
17838         {
17839           ip_family_set = 1;
17840           is_ip4 = 0;
17841         }
17842       else
17843         {
17844           errmsg ("parse error '%U'", format_unformat_error, i);
17845           return -99;
17846         }
17847     }
17848
17849   if (!ip_family_set)
17850     {
17851       errmsg ("ip family not set!");
17852       return -99;
17853     }
17854
17855   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17856   mp->is_ip4 = is_ip4;
17857
17858   /* send it... */
17859   S (mp);
17860
17861   /* Wait for a reply... */
17862   W (ret);
17863   return ret;
17864 }
17865
17866 static int
17867 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17868 {
17869   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17870   int ret;
17871
17872   if (!vam->json_output)
17873     {
17874       print (vam->ofp, "VNIs");
17875     }
17876
17877   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17878
17879   /* send it... */
17880   S (mp);
17881
17882   /* Wait for a reply... */
17883   W (ret);
17884   return ret;
17885 }
17886
17887 static int
17888 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17889 {
17890   unformat_input_t *i = vam->input;
17891   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17892   int ret = 0;
17893   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17894   struct in_addr ip4;
17895   struct in6_addr ip6;
17896   u32 table_id = 0, nh_sw_if_index = ~0;
17897
17898   clib_memset (&ip4, 0, sizeof (ip4));
17899   clib_memset (&ip6, 0, sizeof (ip6));
17900
17901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17902     {
17903       if (unformat (i, "del"))
17904         is_add = 0;
17905       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17906                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17907         {
17908           ip_set = 1;
17909           is_ip4 = 1;
17910         }
17911       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17912                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17913         {
17914           ip_set = 1;
17915           is_ip4 = 0;
17916         }
17917       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17918         {
17919           ip_set = 1;
17920           is_ip4 = 1;
17921           nh_sw_if_index = ~0;
17922         }
17923       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17924         {
17925           ip_set = 1;
17926           is_ip4 = 0;
17927           nh_sw_if_index = ~0;
17928         }
17929       else if (unformat (i, "table %d", &table_id))
17930         ;
17931       else
17932         {
17933           errmsg ("parse error '%U'", format_unformat_error, i);
17934           return -99;
17935         }
17936     }
17937
17938   if (!ip_set)
17939     {
17940       errmsg ("nh addr not set!");
17941       return -99;
17942     }
17943
17944   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17945   mp->is_add = is_add;
17946   mp->table_id = clib_host_to_net_u32 (table_id);
17947   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17948   mp->is_ip4 = is_ip4;
17949   if (is_ip4)
17950     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17951   else
17952     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17953
17954   /* send it... */
17955   S (mp);
17956
17957   /* Wait for a reply... */
17958   W (ret);
17959   return ret;
17960 }
17961
17962 static int
17963 api_one_map_server_dump (vat_main_t * vam)
17964 {
17965   vl_api_one_map_server_dump_t *mp;
17966   vl_api_control_ping_t *mp_ping;
17967   int ret;
17968
17969   if (!vam->json_output)
17970     {
17971       print (vam->ofp, "%=20s", "Map server");
17972     }
17973
17974   M (ONE_MAP_SERVER_DUMP, mp);
17975   /* send it... */
17976   S (mp);
17977
17978   /* Use a control ping for synchronization */
17979   MPING (CONTROL_PING, mp_ping);
17980   S (mp_ping);
17981
17982   /* Wait for a reply... */
17983   W (ret);
17984   return ret;
17985 }
17986
17987 #define api_lisp_map_server_dump api_one_map_server_dump
17988
17989 static int
17990 api_one_map_resolver_dump (vat_main_t * vam)
17991 {
17992   vl_api_one_map_resolver_dump_t *mp;
17993   vl_api_control_ping_t *mp_ping;
17994   int ret;
17995
17996   if (!vam->json_output)
17997     {
17998       print (vam->ofp, "%=20s", "Map resolver");
17999     }
18000
18001   M (ONE_MAP_RESOLVER_DUMP, mp);
18002   /* send it... */
18003   S (mp);
18004
18005   /* Use a control ping for synchronization */
18006   MPING (CONTROL_PING, mp_ping);
18007   S (mp_ping);
18008
18009   /* Wait for a reply... */
18010   W (ret);
18011   return ret;
18012 }
18013
18014 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18015
18016 static int
18017 api_one_stats_flush (vat_main_t * vam)
18018 {
18019   vl_api_one_stats_flush_t *mp;
18020   int ret = 0;
18021
18022   M (ONE_STATS_FLUSH, mp);
18023   S (mp);
18024   W (ret);
18025   return ret;
18026 }
18027
18028 static int
18029 api_one_stats_dump (vat_main_t * vam)
18030 {
18031   vl_api_one_stats_dump_t *mp;
18032   vl_api_control_ping_t *mp_ping;
18033   int ret;
18034
18035   M (ONE_STATS_DUMP, mp);
18036   /* send it... */
18037   S (mp);
18038
18039   /* Use a control ping for synchronization */
18040   MPING (CONTROL_PING, mp_ping);
18041   S (mp_ping);
18042
18043   /* Wait for a reply... */
18044   W (ret);
18045   return ret;
18046 }
18047
18048 static int
18049 api_show_one_status (vat_main_t * vam)
18050 {
18051   vl_api_show_one_status_t *mp;
18052   int ret;
18053
18054   if (!vam->json_output)
18055     {
18056       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18057     }
18058
18059   M (SHOW_ONE_STATUS, mp);
18060   /* send it... */
18061   S (mp);
18062   /* Wait for a reply... */
18063   W (ret);
18064   return ret;
18065 }
18066
18067 #define api_show_lisp_status api_show_one_status
18068
18069 static int
18070 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18071 {
18072   vl_api_gpe_fwd_entry_path_dump_t *mp;
18073   vl_api_control_ping_t *mp_ping;
18074   unformat_input_t *i = vam->input;
18075   u32 fwd_entry_index = ~0;
18076   int ret;
18077
18078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18079     {
18080       if (unformat (i, "index %d", &fwd_entry_index))
18081         ;
18082       else
18083         break;
18084     }
18085
18086   if (~0 == fwd_entry_index)
18087     {
18088       errmsg ("no index specified!");
18089       return -99;
18090     }
18091
18092   if (!vam->json_output)
18093     {
18094       print (vam->ofp, "first line");
18095     }
18096
18097   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18098
18099   /* send it... */
18100   S (mp);
18101   /* Use a control ping for synchronization */
18102   MPING (CONTROL_PING, mp_ping);
18103   S (mp_ping);
18104
18105   /* Wait for a reply... */
18106   W (ret);
18107   return ret;
18108 }
18109
18110 static int
18111 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18112 {
18113   vl_api_one_get_map_request_itr_rlocs_t *mp;
18114   int ret;
18115
18116   if (!vam->json_output)
18117     {
18118       print (vam->ofp, "%=20s", "itr-rlocs:");
18119     }
18120
18121   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18122   /* send it... */
18123   S (mp);
18124   /* Wait for a reply... */
18125   W (ret);
18126   return ret;
18127 }
18128
18129 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18130
18131 static int
18132 api_af_packet_create (vat_main_t * vam)
18133 {
18134   unformat_input_t *i = vam->input;
18135   vl_api_af_packet_create_t *mp;
18136   u8 *host_if_name = 0;
18137   u8 hw_addr[6];
18138   u8 random_hw_addr = 1;
18139   int ret;
18140
18141   clib_memset (hw_addr, 0, sizeof (hw_addr));
18142
18143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18144     {
18145       if (unformat (i, "name %s", &host_if_name))
18146         vec_add1 (host_if_name, 0);
18147       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18148         random_hw_addr = 0;
18149       else
18150         break;
18151     }
18152
18153   if (!vec_len (host_if_name))
18154     {
18155       errmsg ("host-interface name must be specified");
18156       return -99;
18157     }
18158
18159   if (vec_len (host_if_name) > 64)
18160     {
18161       errmsg ("host-interface name too long");
18162       return -99;
18163     }
18164
18165   M (AF_PACKET_CREATE, mp);
18166
18167   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18168   clib_memcpy (mp->hw_addr, hw_addr, 6);
18169   mp->use_random_hw_addr = random_hw_addr;
18170   vec_free (host_if_name);
18171
18172   S (mp);
18173
18174   /* *INDENT-OFF* */
18175   W2 (ret,
18176       ({
18177         if (ret == 0)
18178           fprintf (vam->ofp ? vam->ofp : stderr,
18179                    " new sw_if_index = %d\n", vam->sw_if_index);
18180       }));
18181   /* *INDENT-ON* */
18182   return ret;
18183 }
18184
18185 static int
18186 api_af_packet_delete (vat_main_t * vam)
18187 {
18188   unformat_input_t *i = vam->input;
18189   vl_api_af_packet_delete_t *mp;
18190   u8 *host_if_name = 0;
18191   int ret;
18192
18193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18194     {
18195       if (unformat (i, "name %s", &host_if_name))
18196         vec_add1 (host_if_name, 0);
18197       else
18198         break;
18199     }
18200
18201   if (!vec_len (host_if_name))
18202     {
18203       errmsg ("host-interface name must be specified");
18204       return -99;
18205     }
18206
18207   if (vec_len (host_if_name) > 64)
18208     {
18209       errmsg ("host-interface name too long");
18210       return -99;
18211     }
18212
18213   M (AF_PACKET_DELETE, mp);
18214
18215   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18216   vec_free (host_if_name);
18217
18218   S (mp);
18219   W (ret);
18220   return ret;
18221 }
18222
18223 static void vl_api_af_packet_details_t_handler
18224   (vl_api_af_packet_details_t * mp)
18225 {
18226   vat_main_t *vam = &vat_main;
18227
18228   print (vam->ofp, "%-16s %d",
18229          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18230 }
18231
18232 static void vl_api_af_packet_details_t_handler_json
18233   (vl_api_af_packet_details_t * mp)
18234 {
18235   vat_main_t *vam = &vat_main;
18236   vat_json_node_t *node = NULL;
18237
18238   if (VAT_JSON_ARRAY != vam->json_tree.type)
18239     {
18240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18241       vat_json_init_array (&vam->json_tree);
18242     }
18243   node = vat_json_array_add (&vam->json_tree);
18244
18245   vat_json_init_object (node);
18246   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18247   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18248 }
18249
18250 static int
18251 api_af_packet_dump (vat_main_t * vam)
18252 {
18253   vl_api_af_packet_dump_t *mp;
18254   vl_api_control_ping_t *mp_ping;
18255   int ret;
18256
18257   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18258   /* Get list of tap interfaces */
18259   M (AF_PACKET_DUMP, mp);
18260   S (mp);
18261
18262   /* Use a control ping for synchronization */
18263   MPING (CONTROL_PING, mp_ping);
18264   S (mp_ping);
18265
18266   W (ret);
18267   return ret;
18268 }
18269
18270 static int
18271 api_policer_add_del (vat_main_t * vam)
18272 {
18273   unformat_input_t *i = vam->input;
18274   vl_api_policer_add_del_t *mp;
18275   u8 is_add = 1;
18276   u8 *name = 0;
18277   u32 cir = 0;
18278   u32 eir = 0;
18279   u64 cb = 0;
18280   u64 eb = 0;
18281   u8 rate_type = 0;
18282   u8 round_type = 0;
18283   u8 type = 0;
18284   u8 color_aware = 0;
18285   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18286   int ret;
18287
18288   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18289   conform_action.dscp = 0;
18290   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18291   exceed_action.dscp = 0;
18292   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18293   violate_action.dscp = 0;
18294
18295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18296     {
18297       if (unformat (i, "del"))
18298         is_add = 0;
18299       else if (unformat (i, "name %s", &name))
18300         vec_add1 (name, 0);
18301       else if (unformat (i, "cir %u", &cir))
18302         ;
18303       else if (unformat (i, "eir %u", &eir))
18304         ;
18305       else if (unformat (i, "cb %u", &cb))
18306         ;
18307       else if (unformat (i, "eb %u", &eb))
18308         ;
18309       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18310                          &rate_type))
18311         ;
18312       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18313                          &round_type))
18314         ;
18315       else if (unformat (i, "type %U", unformat_policer_type, &type))
18316         ;
18317       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18318                          &conform_action))
18319         ;
18320       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18321                          &exceed_action))
18322         ;
18323       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18324                          &violate_action))
18325         ;
18326       else if (unformat (i, "color-aware"))
18327         color_aware = 1;
18328       else
18329         break;
18330     }
18331
18332   if (!vec_len (name))
18333     {
18334       errmsg ("policer name must be specified");
18335       return -99;
18336     }
18337
18338   if (vec_len (name) > 64)
18339     {
18340       errmsg ("policer name too long");
18341       return -99;
18342     }
18343
18344   M (POLICER_ADD_DEL, mp);
18345
18346   clib_memcpy (mp->name, name, vec_len (name));
18347   vec_free (name);
18348   mp->is_add = is_add;
18349   mp->cir = ntohl (cir);
18350   mp->eir = ntohl (eir);
18351   mp->cb = clib_net_to_host_u64 (cb);
18352   mp->eb = clib_net_to_host_u64 (eb);
18353   mp->rate_type = rate_type;
18354   mp->round_type = round_type;
18355   mp->type = type;
18356   mp->conform_action_type = conform_action.action_type;
18357   mp->conform_dscp = conform_action.dscp;
18358   mp->exceed_action_type = exceed_action.action_type;
18359   mp->exceed_dscp = exceed_action.dscp;
18360   mp->violate_action_type = violate_action.action_type;
18361   mp->violate_dscp = violate_action.dscp;
18362   mp->color_aware = color_aware;
18363
18364   S (mp);
18365   W (ret);
18366   return ret;
18367 }
18368
18369 static int
18370 api_policer_dump (vat_main_t * vam)
18371 {
18372   unformat_input_t *i = vam->input;
18373   vl_api_policer_dump_t *mp;
18374   vl_api_control_ping_t *mp_ping;
18375   u8 *match_name = 0;
18376   u8 match_name_valid = 0;
18377   int ret;
18378
18379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18380     {
18381       if (unformat (i, "name %s", &match_name))
18382         {
18383           vec_add1 (match_name, 0);
18384           match_name_valid = 1;
18385         }
18386       else
18387         break;
18388     }
18389
18390   M (POLICER_DUMP, mp);
18391   mp->match_name_valid = match_name_valid;
18392   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18393   vec_free (match_name);
18394   /* send it... */
18395   S (mp);
18396
18397   /* Use a control ping for synchronization */
18398   MPING (CONTROL_PING, mp_ping);
18399   S (mp_ping);
18400
18401   /* Wait for a reply... */
18402   W (ret);
18403   return ret;
18404 }
18405
18406 static int
18407 api_policer_classify_set_interface (vat_main_t * vam)
18408 {
18409   unformat_input_t *i = vam->input;
18410   vl_api_policer_classify_set_interface_t *mp;
18411   u32 sw_if_index;
18412   int sw_if_index_set;
18413   u32 ip4_table_index = ~0;
18414   u32 ip6_table_index = ~0;
18415   u32 l2_table_index = ~0;
18416   u8 is_add = 1;
18417   int ret;
18418
18419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18420     {
18421       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18422         sw_if_index_set = 1;
18423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18424         sw_if_index_set = 1;
18425       else if (unformat (i, "del"))
18426         is_add = 0;
18427       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18428         ;
18429       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18430         ;
18431       else if (unformat (i, "l2-table %d", &l2_table_index))
18432         ;
18433       else
18434         {
18435           clib_warning ("parse error '%U'", format_unformat_error, i);
18436           return -99;
18437         }
18438     }
18439
18440   if (sw_if_index_set == 0)
18441     {
18442       errmsg ("missing interface name or sw_if_index");
18443       return -99;
18444     }
18445
18446   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18447
18448   mp->sw_if_index = ntohl (sw_if_index);
18449   mp->ip4_table_index = ntohl (ip4_table_index);
18450   mp->ip6_table_index = ntohl (ip6_table_index);
18451   mp->l2_table_index = ntohl (l2_table_index);
18452   mp->is_add = is_add;
18453
18454   S (mp);
18455   W (ret);
18456   return ret;
18457 }
18458
18459 static int
18460 api_policer_classify_dump (vat_main_t * vam)
18461 {
18462   unformat_input_t *i = vam->input;
18463   vl_api_policer_classify_dump_t *mp;
18464   vl_api_control_ping_t *mp_ping;
18465   u8 type = POLICER_CLASSIFY_N_TABLES;
18466   int ret;
18467
18468   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18469     ;
18470   else
18471     {
18472       errmsg ("classify table type must be specified");
18473       return -99;
18474     }
18475
18476   if (!vam->json_output)
18477     {
18478       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18479     }
18480
18481   M (POLICER_CLASSIFY_DUMP, mp);
18482   mp->type = type;
18483   /* send it... */
18484   S (mp);
18485
18486   /* Use a control ping for synchronization */
18487   MPING (CONTROL_PING, mp_ping);
18488   S (mp_ping);
18489
18490   /* Wait for a reply... */
18491   W (ret);
18492   return ret;
18493 }
18494
18495 static int
18496 api_netmap_create (vat_main_t * vam)
18497 {
18498   unformat_input_t *i = vam->input;
18499   vl_api_netmap_create_t *mp;
18500   u8 *if_name = 0;
18501   u8 hw_addr[6];
18502   u8 random_hw_addr = 1;
18503   u8 is_pipe = 0;
18504   u8 is_master = 0;
18505   int ret;
18506
18507   clib_memset (hw_addr, 0, sizeof (hw_addr));
18508
18509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18510     {
18511       if (unformat (i, "name %s", &if_name))
18512         vec_add1 (if_name, 0);
18513       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18514         random_hw_addr = 0;
18515       else if (unformat (i, "pipe"))
18516         is_pipe = 1;
18517       else if (unformat (i, "master"))
18518         is_master = 1;
18519       else if (unformat (i, "slave"))
18520         is_master = 0;
18521       else
18522         break;
18523     }
18524
18525   if (!vec_len (if_name))
18526     {
18527       errmsg ("interface name must be specified");
18528       return -99;
18529     }
18530
18531   if (vec_len (if_name) > 64)
18532     {
18533       errmsg ("interface name too long");
18534       return -99;
18535     }
18536
18537   M (NETMAP_CREATE, mp);
18538
18539   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18540   clib_memcpy (mp->hw_addr, hw_addr, 6);
18541   mp->use_random_hw_addr = random_hw_addr;
18542   mp->is_pipe = is_pipe;
18543   mp->is_master = is_master;
18544   vec_free (if_name);
18545
18546   S (mp);
18547   W (ret);
18548   return ret;
18549 }
18550
18551 static int
18552 api_netmap_delete (vat_main_t * vam)
18553 {
18554   unformat_input_t *i = vam->input;
18555   vl_api_netmap_delete_t *mp;
18556   u8 *if_name = 0;
18557   int ret;
18558
18559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18560     {
18561       if (unformat (i, "name %s", &if_name))
18562         vec_add1 (if_name, 0);
18563       else
18564         break;
18565     }
18566
18567   if (!vec_len (if_name))
18568     {
18569       errmsg ("interface name must be specified");
18570       return -99;
18571     }
18572
18573   if (vec_len (if_name) > 64)
18574     {
18575       errmsg ("interface name too long");
18576       return -99;
18577     }
18578
18579   M (NETMAP_DELETE, mp);
18580
18581   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18582   vec_free (if_name);
18583
18584   S (mp);
18585   W (ret);
18586   return ret;
18587 }
18588
18589 static u8 *
18590 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18591 {
18592   vl_api_fib_path_nh_proto_t proto =
18593     va_arg (*args, vl_api_fib_path_nh_proto_t);
18594
18595   switch (proto)
18596     {
18597     case FIB_API_PATH_NH_PROTO_IP4:
18598       s = format (s, "ip4");
18599       break;
18600     case FIB_API_PATH_NH_PROTO_IP6:
18601       s = format (s, "ip6");
18602       break;
18603     case FIB_API_PATH_NH_PROTO_MPLS:
18604       s = format (s, "mpls");
18605       break;
18606     case FIB_API_PATH_NH_PROTO_BIER:
18607       s = format (s, "bier");
18608       break;
18609     case FIB_API_PATH_NH_PROTO_ETHERNET:
18610       s = format (s, "ethernet");
18611       break;
18612     }
18613
18614   return (s);
18615 }
18616
18617 static u8 *
18618 format_vl_api_ip_address_union (u8 * s, va_list * args)
18619 {
18620   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18621   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18622
18623   switch (af)
18624     {
18625     case ADDRESS_IP4:
18626       s = format (s, "%U", format_ip4_address, u->ip4);
18627       break;
18628     case ADDRESS_IP6:
18629       s = format (s, "%U", format_ip6_address, u->ip6);
18630       break;
18631     }
18632   return (s);
18633 }
18634
18635 static u8 *
18636 format_vl_api_fib_path_type (u8 * s, va_list * args)
18637 {
18638   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18639
18640   switch (t)
18641     {
18642     case FIB_API_PATH_TYPE_NORMAL:
18643       s = format (s, "normal");
18644       break;
18645     case FIB_API_PATH_TYPE_LOCAL:
18646       s = format (s, "local");
18647       break;
18648     case FIB_API_PATH_TYPE_DROP:
18649       s = format (s, "drop");
18650       break;
18651     case FIB_API_PATH_TYPE_UDP_ENCAP:
18652       s = format (s, "udp-encap");
18653       break;
18654     case FIB_API_PATH_TYPE_BIER_IMP:
18655       s = format (s, "bier-imp");
18656       break;
18657     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18658       s = format (s, "unreach");
18659       break;
18660     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18661       s = format (s, "prohibit");
18662       break;
18663     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18664       s = format (s, "src-lookup");
18665       break;
18666     case FIB_API_PATH_TYPE_DVR:
18667       s = format (s, "dvr");
18668       break;
18669     case FIB_API_PATH_TYPE_INTERFACE_RX:
18670       s = format (s, "interface-rx");
18671       break;
18672     case FIB_API_PATH_TYPE_CLASSIFY:
18673       s = format (s, "classify");
18674       break;
18675     }
18676
18677   return (s);
18678 }
18679
18680 static void
18681 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18682 {
18683   print (vam->ofp,
18684          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18685          ntohl (fp->weight), ntohl (fp->sw_if_index),
18686          format_vl_api_fib_path_type, fp->type,
18687          format_fib_api_path_nh_proto, fp->proto,
18688          format_vl_api_ip_address_union, &fp->nh.address);
18689 }
18690
18691 static void
18692 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18693                                  vl_api_fib_path_t * fp)
18694 {
18695   struct in_addr ip4;
18696   struct in6_addr ip6;
18697
18698   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18699   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18700   vat_json_object_add_uint (node, "type", fp->type);
18701   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18702   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18703     {
18704       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18705       vat_json_object_add_ip4 (node, "next_hop", ip4);
18706     }
18707   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18708     {
18709       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18710       vat_json_object_add_ip6 (node, "next_hop", ip6);
18711     }
18712 }
18713
18714 static void
18715 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18716 {
18717   vat_main_t *vam = &vat_main;
18718   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18719   vl_api_fib_path_t *fp;
18720   i32 i;
18721
18722   print (vam->ofp, "sw_if_index %d via:",
18723          ntohl (mp->mt_tunnel.mt_sw_if_index));
18724   fp = mp->mt_tunnel.mt_paths;
18725   for (i = 0; i < count; i++)
18726     {
18727       vl_api_fib_path_print (vam, fp);
18728       fp++;
18729     }
18730
18731   print (vam->ofp, "");
18732 }
18733
18734 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18735 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18736
18737 static void
18738 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18739 {
18740   vat_main_t *vam = &vat_main;
18741   vat_json_node_t *node = NULL;
18742   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18743   vl_api_fib_path_t *fp;
18744   i32 i;
18745
18746   if (VAT_JSON_ARRAY != vam->json_tree.type)
18747     {
18748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18749       vat_json_init_array (&vam->json_tree);
18750     }
18751   node = vat_json_array_add (&vam->json_tree);
18752
18753   vat_json_init_object (node);
18754   vat_json_object_add_uint (node, "sw_if_index",
18755                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18756
18757   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18758
18759   fp = mp->mt_tunnel.mt_paths;
18760   for (i = 0; i < count; i++)
18761     {
18762       vl_api_mpls_fib_path_json_print (node, fp);
18763       fp++;
18764     }
18765 }
18766
18767 static int
18768 api_mpls_tunnel_dump (vat_main_t * vam)
18769 {
18770   vl_api_mpls_tunnel_dump_t *mp;
18771   vl_api_control_ping_t *mp_ping;
18772   int ret;
18773
18774   M (MPLS_TUNNEL_DUMP, mp);
18775
18776   S (mp);
18777
18778   /* Use a control ping for synchronization */
18779   MPING (CONTROL_PING, mp_ping);
18780   S (mp_ping);
18781
18782   W (ret);
18783   return ret;
18784 }
18785
18786 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18787 #define vl_api_mpls_table_details_t_print vl_noop_handler
18788
18789
18790 static void
18791 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18792 {
18793   vat_main_t *vam = &vat_main;
18794
18795   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18796 }
18797
18798 static void vl_api_mpls_table_details_t_handler_json
18799   (vl_api_mpls_table_details_t * mp)
18800 {
18801   vat_main_t *vam = &vat_main;
18802   vat_json_node_t *node = NULL;
18803
18804   if (VAT_JSON_ARRAY != vam->json_tree.type)
18805     {
18806       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18807       vat_json_init_array (&vam->json_tree);
18808     }
18809   node = vat_json_array_add (&vam->json_tree);
18810
18811   vat_json_init_object (node);
18812   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18813 }
18814
18815 static int
18816 api_mpls_table_dump (vat_main_t * vam)
18817 {
18818   vl_api_mpls_table_dump_t *mp;
18819   vl_api_control_ping_t *mp_ping;
18820   int ret;
18821
18822   M (MPLS_TABLE_DUMP, mp);
18823   S (mp);
18824
18825   /* Use a control ping for synchronization */
18826   MPING (CONTROL_PING, mp_ping);
18827   S (mp_ping);
18828
18829   W (ret);
18830   return ret;
18831 }
18832
18833 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18834 #define vl_api_mpls_route_details_t_print vl_noop_handler
18835
18836 static void
18837 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18838 {
18839   vat_main_t *vam = &vat_main;
18840   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18841   vl_api_fib_path_t *fp;
18842   int i;
18843
18844   print (vam->ofp,
18845          "table-id %d, label %u, ess_bit %u",
18846          ntohl (mp->mr_route.mr_table_id),
18847          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18848   fp = mp->mr_route.mr_paths;
18849   for (i = 0; i < count; i++)
18850     {
18851       vl_api_fib_path_print (vam, fp);
18852       fp++;
18853     }
18854 }
18855
18856 static void vl_api_mpls_route_details_t_handler_json
18857   (vl_api_mpls_route_details_t * mp)
18858 {
18859   vat_main_t *vam = &vat_main;
18860   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18861   vat_json_node_t *node = NULL;
18862   vl_api_fib_path_t *fp;
18863   int i;
18864
18865   if (VAT_JSON_ARRAY != vam->json_tree.type)
18866     {
18867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18868       vat_json_init_array (&vam->json_tree);
18869     }
18870   node = vat_json_array_add (&vam->json_tree);
18871
18872   vat_json_init_object (node);
18873   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18874   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18875   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18876   vat_json_object_add_uint (node, "path_count", count);
18877   fp = mp->mr_route.mr_paths;
18878   for (i = 0; i < count; i++)
18879     {
18880       vl_api_mpls_fib_path_json_print (node, fp);
18881       fp++;
18882     }
18883 }
18884
18885 static int
18886 api_mpls_route_dump (vat_main_t * vam)
18887 {
18888   unformat_input_t *input = vam->input;
18889   vl_api_mpls_route_dump_t *mp;
18890   vl_api_control_ping_t *mp_ping;
18891   u32 table_id;
18892   int ret;
18893
18894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18895     {
18896       if (unformat (input, "table_id %d", &table_id))
18897         ;
18898       else
18899         break;
18900     }
18901   if (table_id == ~0)
18902     {
18903       errmsg ("missing table id");
18904       return -99;
18905     }
18906
18907   M (MPLS_ROUTE_DUMP, mp);
18908
18909   mp->table.mt_table_id = ntohl (table_id);
18910   S (mp);
18911
18912   /* Use a control ping for synchronization */
18913   MPING (CONTROL_PING, mp_ping);
18914   S (mp_ping);
18915
18916   W (ret);
18917   return ret;
18918 }
18919
18920 #define vl_api_ip_table_details_t_endian vl_noop_handler
18921 #define vl_api_ip_table_details_t_print vl_noop_handler
18922
18923 static void
18924 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18925 {
18926   vat_main_t *vam = &vat_main;
18927
18928   print (vam->ofp,
18929          "%s; table-id %d, prefix %U/%d",
18930          mp->table.name, ntohl (mp->table.table_id));
18931 }
18932
18933
18934 static void vl_api_ip_table_details_t_handler_json
18935   (vl_api_ip_table_details_t * mp)
18936 {
18937   vat_main_t *vam = &vat_main;
18938   vat_json_node_t *node = NULL;
18939
18940   if (VAT_JSON_ARRAY != vam->json_tree.type)
18941     {
18942       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18943       vat_json_init_array (&vam->json_tree);
18944     }
18945   node = vat_json_array_add (&vam->json_tree);
18946
18947   vat_json_init_object (node);
18948   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18949 }
18950
18951 static int
18952 api_ip_table_dump (vat_main_t * vam)
18953 {
18954   vl_api_ip_table_dump_t *mp;
18955   vl_api_control_ping_t *mp_ping;
18956   int ret;
18957
18958   M (IP_TABLE_DUMP, mp);
18959   S (mp);
18960
18961   /* Use a control ping for synchronization */
18962   MPING (CONTROL_PING, mp_ping);
18963   S (mp_ping);
18964
18965   W (ret);
18966   return ret;
18967 }
18968
18969 static int
18970 api_ip_mtable_dump (vat_main_t * vam)
18971 {
18972   vl_api_ip_mtable_dump_t *mp;
18973   vl_api_control_ping_t *mp_ping;
18974   int ret;
18975
18976   M (IP_MTABLE_DUMP, mp);
18977   S (mp);
18978
18979   /* Use a control ping for synchronization */
18980   MPING (CONTROL_PING, mp_ping);
18981   S (mp_ping);
18982
18983   W (ret);
18984   return ret;
18985 }
18986
18987 static int
18988 api_ip_mroute_dump (vat_main_t * vam)
18989 {
18990   unformat_input_t *input = vam->input;
18991   vl_api_control_ping_t *mp_ping;
18992   vl_api_ip_mroute_dump_t *mp;
18993   int ret, is_ip6;
18994   u32 table_id;
18995
18996   is_ip6 = 0;
18997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18998     {
18999       if (unformat (input, "table_id %d", &table_id))
19000         ;
19001       else if (unformat (input, "ip6"))
19002         is_ip6 = 1;
19003       else if (unformat (input, "ip4"))
19004         is_ip6 = 0;
19005       else
19006         break;
19007     }
19008   if (table_id == ~0)
19009     {
19010       errmsg ("missing table id");
19011       return -99;
19012     }
19013
19014   M (IP_MROUTE_DUMP, mp);
19015   mp->table.table_id = table_id;
19016   mp->table.is_ip6 = is_ip6;
19017   S (mp);
19018
19019   /* Use a control ping for synchronization */
19020   MPING (CONTROL_PING, mp_ping);
19021   S (mp_ping);
19022
19023   W (ret);
19024   return ret;
19025 }
19026
19027 static void vl_api_ip_neighbor_details_t_handler
19028   (vl_api_ip_neighbor_details_t * mp)
19029 {
19030   vat_main_t *vam = &vat_main;
19031
19032   print (vam->ofp, "%c %U %U",
19033          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19034          format_vl_api_mac_address, &mp->neighbor.mac_address,
19035          format_vl_api_address, &mp->neighbor.ip_address);
19036 }
19037
19038 static void vl_api_ip_neighbor_details_t_handler_json
19039   (vl_api_ip_neighbor_details_t * mp)
19040 {
19041
19042   vat_main_t *vam = &vat_main;
19043   vat_json_node_t *node;
19044
19045   if (VAT_JSON_ARRAY != vam->json_tree.type)
19046     {
19047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19048       vat_json_init_array (&vam->json_tree);
19049     }
19050   node = vat_json_array_add (&vam->json_tree);
19051
19052   vat_json_init_object (node);
19053   vat_json_object_add_string_copy
19054     (node, "flag",
19055      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19056       (u8 *) "static" : (u8 *) "dynamic"));
19057
19058   vat_json_object_add_string_copy (node, "link_layer",
19059                                    format (0, "%U", format_vl_api_mac_address,
19060                                            &mp->neighbor.mac_address));
19061   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19062 }
19063
19064 static int
19065 api_ip_neighbor_dump (vat_main_t * vam)
19066 {
19067   unformat_input_t *i = vam->input;
19068   vl_api_ip_neighbor_dump_t *mp;
19069   vl_api_control_ping_t *mp_ping;
19070   u8 is_ipv6 = 0;
19071   u32 sw_if_index = ~0;
19072   int ret;
19073
19074   /* Parse args required to build the message */
19075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19076     {
19077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19078         ;
19079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19080         ;
19081       else if (unformat (i, "ip6"))
19082         is_ipv6 = 1;
19083       else
19084         break;
19085     }
19086
19087   if (sw_if_index == ~0)
19088     {
19089       errmsg ("missing interface name or sw_if_index");
19090       return -99;
19091     }
19092
19093   M (IP_NEIGHBOR_DUMP, mp);
19094   mp->is_ipv6 = (u8) is_ipv6;
19095   mp->sw_if_index = ntohl (sw_if_index);
19096   S (mp);
19097
19098   /* Use a control ping for synchronization */
19099   MPING (CONTROL_PING, mp_ping);
19100   S (mp_ping);
19101
19102   W (ret);
19103   return ret;
19104 }
19105
19106 #define vl_api_ip_route_details_t_endian vl_noop_handler
19107 #define vl_api_ip_route_details_t_print vl_noop_handler
19108
19109 static void
19110 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19111 {
19112   vat_main_t *vam = &vat_main;
19113   u8 count = mp->route.n_paths;
19114   vl_api_fib_path_t *fp;
19115   int i;
19116
19117   print (vam->ofp,
19118          "table-id %d, prefix %U/%d",
19119          ntohl (mp->route.table_id),
19120          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19121   for (i = 0; i < count; i++)
19122     {
19123       fp = &mp->route.paths[i];
19124
19125       vl_api_fib_path_print (vam, fp);
19126       fp++;
19127     }
19128 }
19129
19130 static void vl_api_ip_route_details_t_handler_json
19131   (vl_api_ip_route_details_t * mp)
19132 {
19133   vat_main_t *vam = &vat_main;
19134   u8 count = mp->route.n_paths;
19135   vat_json_node_t *node = NULL;
19136   struct in_addr ip4;
19137   struct in6_addr ip6;
19138   vl_api_fib_path_t *fp;
19139   int i;
19140
19141   if (VAT_JSON_ARRAY != vam->json_tree.type)
19142     {
19143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19144       vat_json_init_array (&vam->json_tree);
19145     }
19146   node = vat_json_array_add (&vam->json_tree);
19147
19148   vat_json_init_object (node);
19149   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19150   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19151     {
19152       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19153       vat_json_object_add_ip6 (node, "prefix", ip6);
19154     }
19155   else
19156     {
19157       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19158       vat_json_object_add_ip4 (node, "prefix", ip4);
19159     }
19160   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19161   vat_json_object_add_uint (node, "path_count", count);
19162   for (i = 0; i < count; i++)
19163     {
19164       fp = &mp->route.paths[i];
19165       vl_api_mpls_fib_path_json_print (node, fp);
19166     }
19167 }
19168
19169 static int
19170 api_ip_route_dump (vat_main_t * vam)
19171 {
19172   unformat_input_t *input = vam->input;
19173   vl_api_ip_route_dump_t *mp;
19174   vl_api_control_ping_t *mp_ping;
19175   u32 table_id;
19176   u8 is_ip6;
19177   int ret;
19178
19179   is_ip6 = 0;
19180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19181     {
19182       if (unformat (input, "table_id %d", &table_id))
19183         ;
19184       else if (unformat (input, "ip6"))
19185         is_ip6 = 1;
19186       else if (unformat (input, "ip4"))
19187         is_ip6 = 0;
19188       else
19189         break;
19190     }
19191   if (table_id == ~0)
19192     {
19193       errmsg ("missing table id");
19194       return -99;
19195     }
19196
19197   M (IP_ROUTE_DUMP, mp);
19198
19199   mp->table.table_id = table_id;
19200   mp->table.is_ip6 = is_ip6;
19201
19202   S (mp);
19203
19204   /* Use a control ping for synchronization */
19205   MPING (CONTROL_PING, mp_ping);
19206   S (mp_ping);
19207
19208   W (ret);
19209   return ret;
19210 }
19211
19212 int
19213 api_classify_table_ids (vat_main_t * vam)
19214 {
19215   vl_api_classify_table_ids_t *mp;
19216   int ret;
19217
19218   /* Construct the API message */
19219   M (CLASSIFY_TABLE_IDS, mp);
19220   mp->context = 0;
19221
19222   S (mp);
19223   W (ret);
19224   return ret;
19225 }
19226
19227 int
19228 api_classify_table_by_interface (vat_main_t * vam)
19229 {
19230   unformat_input_t *input = vam->input;
19231   vl_api_classify_table_by_interface_t *mp;
19232
19233   u32 sw_if_index = ~0;
19234   int ret;
19235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19236     {
19237       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19238         ;
19239       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19240         ;
19241       else
19242         break;
19243     }
19244   if (sw_if_index == ~0)
19245     {
19246       errmsg ("missing interface name or sw_if_index");
19247       return -99;
19248     }
19249
19250   /* Construct the API message */
19251   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19252   mp->context = 0;
19253   mp->sw_if_index = ntohl (sw_if_index);
19254
19255   S (mp);
19256   W (ret);
19257   return ret;
19258 }
19259
19260 int
19261 api_classify_table_info (vat_main_t * vam)
19262 {
19263   unformat_input_t *input = vam->input;
19264   vl_api_classify_table_info_t *mp;
19265
19266   u32 table_id = ~0;
19267   int ret;
19268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19269     {
19270       if (unformat (input, "table_id %d", &table_id))
19271         ;
19272       else
19273         break;
19274     }
19275   if (table_id == ~0)
19276     {
19277       errmsg ("missing table id");
19278       return -99;
19279     }
19280
19281   /* Construct the API message */
19282   M (CLASSIFY_TABLE_INFO, mp);
19283   mp->context = 0;
19284   mp->table_id = ntohl (table_id);
19285
19286   S (mp);
19287   W (ret);
19288   return ret;
19289 }
19290
19291 int
19292 api_classify_session_dump (vat_main_t * vam)
19293 {
19294   unformat_input_t *input = vam->input;
19295   vl_api_classify_session_dump_t *mp;
19296   vl_api_control_ping_t *mp_ping;
19297
19298   u32 table_id = ~0;
19299   int ret;
19300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19301     {
19302       if (unformat (input, "table_id %d", &table_id))
19303         ;
19304       else
19305         break;
19306     }
19307   if (table_id == ~0)
19308     {
19309       errmsg ("missing table id");
19310       return -99;
19311     }
19312
19313   /* Construct the API message */
19314   M (CLASSIFY_SESSION_DUMP, mp);
19315   mp->context = 0;
19316   mp->table_id = ntohl (table_id);
19317   S (mp);
19318
19319   /* Use a control ping for synchronization */
19320   MPING (CONTROL_PING, mp_ping);
19321   S (mp_ping);
19322
19323   W (ret);
19324   return ret;
19325 }
19326
19327 static void
19328 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19329 {
19330   vat_main_t *vam = &vat_main;
19331
19332   print (vam->ofp, "collector_address %U, collector_port %d, "
19333          "src_address %U, vrf_id %d, path_mtu %u, "
19334          "template_interval %u, udp_checksum %d",
19335          format_ip4_address, mp->collector_address,
19336          ntohs (mp->collector_port),
19337          format_ip4_address, mp->src_address,
19338          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19339          ntohl (mp->template_interval), mp->udp_checksum);
19340
19341   vam->retval = 0;
19342   vam->result_ready = 1;
19343 }
19344
19345 static void
19346   vl_api_ipfix_exporter_details_t_handler_json
19347   (vl_api_ipfix_exporter_details_t * mp)
19348 {
19349   vat_main_t *vam = &vat_main;
19350   vat_json_node_t node;
19351   struct in_addr collector_address;
19352   struct in_addr src_address;
19353
19354   vat_json_init_object (&node);
19355   clib_memcpy (&collector_address, &mp->collector_address,
19356                sizeof (collector_address));
19357   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19358   vat_json_object_add_uint (&node, "collector_port",
19359                             ntohs (mp->collector_port));
19360   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19361   vat_json_object_add_ip4 (&node, "src_address", src_address);
19362   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19363   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19364   vat_json_object_add_uint (&node, "template_interval",
19365                             ntohl (mp->template_interval));
19366   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19367
19368   vat_json_print (vam->ofp, &node);
19369   vat_json_free (&node);
19370   vam->retval = 0;
19371   vam->result_ready = 1;
19372 }
19373
19374 int
19375 api_ipfix_exporter_dump (vat_main_t * vam)
19376 {
19377   vl_api_ipfix_exporter_dump_t *mp;
19378   int ret;
19379
19380   /* Construct the API message */
19381   M (IPFIX_EXPORTER_DUMP, mp);
19382   mp->context = 0;
19383
19384   S (mp);
19385   W (ret);
19386   return ret;
19387 }
19388
19389 static int
19390 api_ipfix_classify_stream_dump (vat_main_t * vam)
19391 {
19392   vl_api_ipfix_classify_stream_dump_t *mp;
19393   int ret;
19394
19395   /* Construct the API message */
19396   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19397   mp->context = 0;
19398
19399   S (mp);
19400   W (ret);
19401   return ret;
19402   /* NOTREACHED */
19403   return 0;
19404 }
19405
19406 static void
19407   vl_api_ipfix_classify_stream_details_t_handler
19408   (vl_api_ipfix_classify_stream_details_t * mp)
19409 {
19410   vat_main_t *vam = &vat_main;
19411   print (vam->ofp, "domain_id %d, src_port %d",
19412          ntohl (mp->domain_id), ntohs (mp->src_port));
19413   vam->retval = 0;
19414   vam->result_ready = 1;
19415 }
19416
19417 static void
19418   vl_api_ipfix_classify_stream_details_t_handler_json
19419   (vl_api_ipfix_classify_stream_details_t * mp)
19420 {
19421   vat_main_t *vam = &vat_main;
19422   vat_json_node_t node;
19423
19424   vat_json_init_object (&node);
19425   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19426   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19427
19428   vat_json_print (vam->ofp, &node);
19429   vat_json_free (&node);
19430   vam->retval = 0;
19431   vam->result_ready = 1;
19432 }
19433
19434 static int
19435 api_ipfix_classify_table_dump (vat_main_t * vam)
19436 {
19437   vl_api_ipfix_classify_table_dump_t *mp;
19438   vl_api_control_ping_t *mp_ping;
19439   int ret;
19440
19441   if (!vam->json_output)
19442     {
19443       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19444              "transport_protocol");
19445     }
19446
19447   /* Construct the API message */
19448   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19449
19450   /* send it... */
19451   S (mp);
19452
19453   /* Use a control ping for synchronization */
19454   MPING (CONTROL_PING, mp_ping);
19455   S (mp_ping);
19456
19457   W (ret);
19458   return ret;
19459 }
19460
19461 static void
19462   vl_api_ipfix_classify_table_details_t_handler
19463   (vl_api_ipfix_classify_table_details_t * mp)
19464 {
19465   vat_main_t *vam = &vat_main;
19466   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19467          mp->transport_protocol);
19468 }
19469
19470 static void
19471   vl_api_ipfix_classify_table_details_t_handler_json
19472   (vl_api_ipfix_classify_table_details_t * mp)
19473 {
19474   vat_json_node_t *node = NULL;
19475   vat_main_t *vam = &vat_main;
19476
19477   if (VAT_JSON_ARRAY != vam->json_tree.type)
19478     {
19479       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19480       vat_json_init_array (&vam->json_tree);
19481     }
19482
19483   node = vat_json_array_add (&vam->json_tree);
19484   vat_json_init_object (node);
19485
19486   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19487   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19488   vat_json_object_add_uint (node, "transport_protocol",
19489                             mp->transport_protocol);
19490 }
19491
19492 static int
19493 api_sw_interface_span_enable_disable (vat_main_t * vam)
19494 {
19495   unformat_input_t *i = vam->input;
19496   vl_api_sw_interface_span_enable_disable_t *mp;
19497   u32 src_sw_if_index = ~0;
19498   u32 dst_sw_if_index = ~0;
19499   u8 state = 3;
19500   int ret;
19501   u8 is_l2 = 0;
19502
19503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19504     {
19505       if (unformat
19506           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19507         ;
19508       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19509         ;
19510       else
19511         if (unformat
19512             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19513         ;
19514       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19515         ;
19516       else if (unformat (i, "disable"))
19517         state = 0;
19518       else if (unformat (i, "rx"))
19519         state = 1;
19520       else if (unformat (i, "tx"))
19521         state = 2;
19522       else if (unformat (i, "both"))
19523         state = 3;
19524       else if (unformat (i, "l2"))
19525         is_l2 = 1;
19526       else
19527         break;
19528     }
19529
19530   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19531
19532   mp->sw_if_index_from = htonl (src_sw_if_index);
19533   mp->sw_if_index_to = htonl (dst_sw_if_index);
19534   mp->state = state;
19535   mp->is_l2 = is_l2;
19536
19537   S (mp);
19538   W (ret);
19539   return ret;
19540 }
19541
19542 static void
19543 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19544                                             * mp)
19545 {
19546   vat_main_t *vam = &vat_main;
19547   u8 *sw_if_from_name = 0;
19548   u8 *sw_if_to_name = 0;
19549   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19550   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19551   char *states[] = { "none", "rx", "tx", "both" };
19552   hash_pair_t *p;
19553
19554   /* *INDENT-OFF* */
19555   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19556   ({
19557     if ((u32) p->value[0] == sw_if_index_from)
19558       {
19559         sw_if_from_name = (u8 *)(p->key);
19560         if (sw_if_to_name)
19561           break;
19562       }
19563     if ((u32) p->value[0] == sw_if_index_to)
19564       {
19565         sw_if_to_name = (u8 *)(p->key);
19566         if (sw_if_from_name)
19567           break;
19568       }
19569   }));
19570   /* *INDENT-ON* */
19571   print (vam->ofp, "%20s => %20s (%s) %s",
19572          sw_if_from_name, sw_if_to_name, states[mp->state],
19573          mp->is_l2 ? "l2" : "device");
19574 }
19575
19576 static void
19577   vl_api_sw_interface_span_details_t_handler_json
19578   (vl_api_sw_interface_span_details_t * mp)
19579 {
19580   vat_main_t *vam = &vat_main;
19581   vat_json_node_t *node = NULL;
19582   u8 *sw_if_from_name = 0;
19583   u8 *sw_if_to_name = 0;
19584   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19585   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19586   hash_pair_t *p;
19587
19588   /* *INDENT-OFF* */
19589   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19590   ({
19591     if ((u32) p->value[0] == sw_if_index_from)
19592       {
19593         sw_if_from_name = (u8 *)(p->key);
19594         if (sw_if_to_name)
19595           break;
19596       }
19597     if ((u32) p->value[0] == sw_if_index_to)
19598       {
19599         sw_if_to_name = (u8 *)(p->key);
19600         if (sw_if_from_name)
19601           break;
19602       }
19603   }));
19604   /* *INDENT-ON* */
19605
19606   if (VAT_JSON_ARRAY != vam->json_tree.type)
19607     {
19608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19609       vat_json_init_array (&vam->json_tree);
19610     }
19611   node = vat_json_array_add (&vam->json_tree);
19612
19613   vat_json_init_object (node);
19614   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19615   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19616   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19617   if (0 != sw_if_to_name)
19618     {
19619       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19620     }
19621   vat_json_object_add_uint (node, "state", mp->state);
19622   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19623 }
19624
19625 static int
19626 api_sw_interface_span_dump (vat_main_t * vam)
19627 {
19628   unformat_input_t *input = vam->input;
19629   vl_api_sw_interface_span_dump_t *mp;
19630   vl_api_control_ping_t *mp_ping;
19631   u8 is_l2 = 0;
19632   int ret;
19633
19634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19635     {
19636       if (unformat (input, "l2"))
19637         is_l2 = 1;
19638       else
19639         break;
19640     }
19641
19642   M (SW_INTERFACE_SPAN_DUMP, mp);
19643   mp->is_l2 = is_l2;
19644   S (mp);
19645
19646   /* Use a control ping for synchronization */
19647   MPING (CONTROL_PING, mp_ping);
19648   S (mp_ping);
19649
19650   W (ret);
19651   return ret;
19652 }
19653
19654 int
19655 api_pg_create_interface (vat_main_t * vam)
19656 {
19657   unformat_input_t *input = vam->input;
19658   vl_api_pg_create_interface_t *mp;
19659
19660   u32 if_id = ~0, gso_size = 0;
19661   u8 gso_enabled = 0;
19662   int ret;
19663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19664     {
19665       if (unformat (input, "if_id %d", &if_id))
19666         ;
19667       else if (unformat (input, "gso-enabled"))
19668         {
19669           gso_enabled = 1;
19670           if (unformat (input, "gso-size %u", &gso_size))
19671             ;
19672           else
19673             {
19674               errmsg ("missing gso-size");
19675               return -99;
19676             }
19677         }
19678       else
19679         break;
19680     }
19681   if (if_id == ~0)
19682     {
19683       errmsg ("missing pg interface index");
19684       return -99;
19685     }
19686
19687   /* Construct the API message */
19688   M (PG_CREATE_INTERFACE, mp);
19689   mp->context = 0;
19690   mp->interface_id = ntohl (if_id);
19691   mp->gso_enabled = gso_enabled;
19692
19693   S (mp);
19694   W (ret);
19695   return ret;
19696 }
19697
19698 int
19699 api_pg_capture (vat_main_t * vam)
19700 {
19701   unformat_input_t *input = vam->input;
19702   vl_api_pg_capture_t *mp;
19703
19704   u32 if_id = ~0;
19705   u8 enable = 1;
19706   u32 count = 1;
19707   u8 pcap_file_set = 0;
19708   u8 *pcap_file = 0;
19709   int ret;
19710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19711     {
19712       if (unformat (input, "if_id %d", &if_id))
19713         ;
19714       else if (unformat (input, "pcap %s", &pcap_file))
19715         pcap_file_set = 1;
19716       else if (unformat (input, "count %d", &count))
19717         ;
19718       else if (unformat (input, "disable"))
19719         enable = 0;
19720       else
19721         break;
19722     }
19723   if (if_id == ~0)
19724     {
19725       errmsg ("missing pg interface index");
19726       return -99;
19727     }
19728   if (pcap_file_set > 0)
19729     {
19730       if (vec_len (pcap_file) > 255)
19731         {
19732           errmsg ("pcap file name is too long");
19733           return -99;
19734         }
19735     }
19736
19737   u32 name_len = vec_len (pcap_file);
19738   /* Construct the API message */
19739   M (PG_CAPTURE, mp);
19740   mp->context = 0;
19741   mp->interface_id = ntohl (if_id);
19742   mp->is_enabled = enable;
19743   mp->count = ntohl (count);
19744   mp->pcap_name_length = ntohl (name_len);
19745   if (pcap_file_set != 0)
19746     {
19747       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19748     }
19749   vec_free (pcap_file);
19750
19751   S (mp);
19752   W (ret);
19753   return ret;
19754 }
19755
19756 int
19757 api_pg_enable_disable (vat_main_t * vam)
19758 {
19759   unformat_input_t *input = vam->input;
19760   vl_api_pg_enable_disable_t *mp;
19761
19762   u8 enable = 1;
19763   u8 stream_name_set = 0;
19764   u8 *stream_name = 0;
19765   int ret;
19766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19767     {
19768       if (unformat (input, "stream %s", &stream_name))
19769         stream_name_set = 1;
19770       else if (unformat (input, "disable"))
19771         enable = 0;
19772       else
19773         break;
19774     }
19775
19776   if (stream_name_set > 0)
19777     {
19778       if (vec_len (stream_name) > 255)
19779         {
19780           errmsg ("stream name too long");
19781           return -99;
19782         }
19783     }
19784
19785   u32 name_len = vec_len (stream_name);
19786   /* Construct the API message */
19787   M (PG_ENABLE_DISABLE, mp);
19788   mp->context = 0;
19789   mp->is_enabled = enable;
19790   if (stream_name_set != 0)
19791     {
19792       mp->stream_name_length = ntohl (name_len);
19793       clib_memcpy (mp->stream_name, stream_name, name_len);
19794     }
19795   vec_free (stream_name);
19796
19797   S (mp);
19798   W (ret);
19799   return ret;
19800 }
19801
19802 int
19803 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19804 {
19805   unformat_input_t *input = vam->input;
19806   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19807
19808   u16 *low_ports = 0;
19809   u16 *high_ports = 0;
19810   u16 this_low;
19811   u16 this_hi;
19812   vl_api_prefix_t prefix;
19813   u32 tmp, tmp2;
19814   u8 prefix_set = 0;
19815   u32 vrf_id = ~0;
19816   u8 is_add = 1;
19817   int ret;
19818
19819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19820     {
19821       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19822         prefix_set = 1;
19823       else if (unformat (input, "vrf %d", &vrf_id))
19824         ;
19825       else if (unformat (input, "del"))
19826         is_add = 0;
19827       else if (unformat (input, "port %d", &tmp))
19828         {
19829           if (tmp == 0 || tmp > 65535)
19830             {
19831               errmsg ("port %d out of range", tmp);
19832               return -99;
19833             }
19834           this_low = tmp;
19835           this_hi = this_low + 1;
19836           vec_add1 (low_ports, this_low);
19837           vec_add1 (high_ports, this_hi);
19838         }
19839       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19840         {
19841           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19842             {
19843               errmsg ("incorrect range parameters");
19844               return -99;
19845             }
19846           this_low = tmp;
19847           /* Note: in debug CLI +1 is added to high before
19848              passing to real fn that does "the work"
19849              (ip_source_and_port_range_check_add_del).
19850              This fn is a wrapper around the binary API fn a
19851              control plane will call, which expects this increment
19852              to have occurred. Hence letting the binary API control
19853              plane fn do the increment for consistency between VAT
19854              and other control planes.
19855            */
19856           this_hi = tmp2;
19857           vec_add1 (low_ports, this_low);
19858           vec_add1 (high_ports, this_hi);
19859         }
19860       else
19861         break;
19862     }
19863
19864   if (prefix_set == 0)
19865     {
19866       errmsg ("<address>/<mask> not specified");
19867       return -99;
19868     }
19869
19870   if (vrf_id == ~0)
19871     {
19872       errmsg ("VRF ID required, not specified");
19873       return -99;
19874     }
19875
19876   if (vrf_id == 0)
19877     {
19878       errmsg
19879         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19880       return -99;
19881     }
19882
19883   if (vec_len (low_ports) == 0)
19884     {
19885       errmsg ("At least one port or port range required");
19886       return -99;
19887     }
19888
19889   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19890
19891   mp->is_add = is_add;
19892
19893   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19894
19895   mp->number_of_ranges = vec_len (low_ports);
19896
19897   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19898   vec_free (low_ports);
19899
19900   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19901   vec_free (high_ports);
19902
19903   mp->vrf_id = ntohl (vrf_id);
19904
19905   S (mp);
19906   W (ret);
19907   return ret;
19908 }
19909
19910 int
19911 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19912 {
19913   unformat_input_t *input = vam->input;
19914   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19915   u32 sw_if_index = ~0;
19916   int vrf_set = 0;
19917   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19918   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19919   u8 is_add = 1;
19920   int ret;
19921
19922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19923     {
19924       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19925         ;
19926       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19927         ;
19928       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19929         vrf_set = 1;
19930       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19931         vrf_set = 1;
19932       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19933         vrf_set = 1;
19934       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19935         vrf_set = 1;
19936       else if (unformat (input, "del"))
19937         is_add = 0;
19938       else
19939         break;
19940     }
19941
19942   if (sw_if_index == ~0)
19943     {
19944       errmsg ("Interface required but not specified");
19945       return -99;
19946     }
19947
19948   if (vrf_set == 0)
19949     {
19950       errmsg ("VRF ID required but not specified");
19951       return -99;
19952     }
19953
19954   if (tcp_out_vrf_id == 0
19955       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19956     {
19957       errmsg
19958         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19959       return -99;
19960     }
19961
19962   /* Construct the API message */
19963   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19964
19965   mp->sw_if_index = ntohl (sw_if_index);
19966   mp->is_add = is_add;
19967   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19968   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19969   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19970   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19971
19972   /* send it... */
19973   S (mp);
19974
19975   /* Wait for a reply... */
19976   W (ret);
19977   return ret;
19978 }
19979
19980 static int
19981 api_set_punt (vat_main_t * vam)
19982 {
19983   unformat_input_t *i = vam->input;
19984   vl_api_address_family_t af;
19985   vl_api_set_punt_t *mp;
19986   u32 protocol = ~0;
19987   u32 port = ~0;
19988   int is_add = 1;
19989   int ret;
19990
19991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19992     {
19993       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19994         ;
19995       else if (unformat (i, "protocol %d", &protocol))
19996         ;
19997       else if (unformat (i, "port %d", &port))
19998         ;
19999       else if (unformat (i, "del"))
20000         is_add = 0;
20001       else
20002         {
20003           clib_warning ("parse error '%U'", format_unformat_error, i);
20004           return -99;
20005         }
20006     }
20007
20008   M (SET_PUNT, mp);
20009
20010   mp->is_add = (u8) is_add;
20011   mp->punt.type = PUNT_API_TYPE_L4;
20012   mp->punt.punt.l4.af = af;
20013   mp->punt.punt.l4.protocol = (u8) protocol;
20014   mp->punt.punt.l4.port = htons ((u16) port);
20015
20016   S (mp);
20017   W (ret);
20018   return ret;
20019 }
20020
20021 static int
20022 api_delete_subif (vat_main_t * vam)
20023 {
20024   unformat_input_t *i = vam->input;
20025   vl_api_delete_subif_t *mp;
20026   u32 sw_if_index = ~0;
20027   int ret;
20028
20029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20030     {
20031       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20032         ;
20033       if (unformat (i, "sw_if_index %d", &sw_if_index))
20034         ;
20035       else
20036         break;
20037     }
20038
20039   if (sw_if_index == ~0)
20040     {
20041       errmsg ("missing sw_if_index");
20042       return -99;
20043     }
20044
20045   /* Construct the API message */
20046   M (DELETE_SUBIF, mp);
20047   mp->sw_if_index = ntohl (sw_if_index);
20048
20049   S (mp);
20050   W (ret);
20051   return ret;
20052 }
20053
20054 #define foreach_pbb_vtr_op      \
20055 _("disable",  L2_VTR_DISABLED)  \
20056 _("pop",  L2_VTR_POP_2)         \
20057 _("push",  L2_VTR_PUSH_2)
20058
20059 static int
20060 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20061 {
20062   unformat_input_t *i = vam->input;
20063   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20064   u32 sw_if_index = ~0, vtr_op = ~0;
20065   u16 outer_tag = ~0;
20066   u8 dmac[6], smac[6];
20067   u8 dmac_set = 0, smac_set = 0;
20068   u16 vlanid = 0;
20069   u32 sid = ~0;
20070   u32 tmp;
20071   int ret;
20072
20073   /* Shut up coverity */
20074   clib_memset (dmac, 0, sizeof (dmac));
20075   clib_memset (smac, 0, sizeof (smac));
20076
20077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20078     {
20079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20080         ;
20081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20082         ;
20083       else if (unformat (i, "vtr_op %d", &vtr_op))
20084         ;
20085 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20086       foreach_pbb_vtr_op
20087 #undef _
20088         else if (unformat (i, "translate_pbb_stag"))
20089         {
20090           if (unformat (i, "%d", &tmp))
20091             {
20092               vtr_op = L2_VTR_TRANSLATE_2_1;
20093               outer_tag = tmp;
20094             }
20095           else
20096             {
20097               errmsg
20098                 ("translate_pbb_stag operation requires outer tag definition");
20099               return -99;
20100             }
20101         }
20102       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20103         dmac_set++;
20104       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20105         smac_set++;
20106       else if (unformat (i, "sid %d", &sid))
20107         ;
20108       else if (unformat (i, "vlanid %d", &tmp))
20109         vlanid = tmp;
20110       else
20111         {
20112           clib_warning ("parse error '%U'", format_unformat_error, i);
20113           return -99;
20114         }
20115     }
20116
20117   if ((sw_if_index == ~0) || (vtr_op == ~0))
20118     {
20119       errmsg ("missing sw_if_index or vtr operation");
20120       return -99;
20121     }
20122   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20123       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20124     {
20125       errmsg
20126         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20127       return -99;
20128     }
20129
20130   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20131   mp->sw_if_index = ntohl (sw_if_index);
20132   mp->vtr_op = ntohl (vtr_op);
20133   mp->outer_tag = ntohs (outer_tag);
20134   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20135   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20136   mp->b_vlanid = ntohs (vlanid);
20137   mp->i_sid = ntohl (sid);
20138
20139   S (mp);
20140   W (ret);
20141   return ret;
20142 }
20143
20144 static int
20145 api_flow_classify_set_interface (vat_main_t * vam)
20146 {
20147   unformat_input_t *i = vam->input;
20148   vl_api_flow_classify_set_interface_t *mp;
20149   u32 sw_if_index;
20150   int sw_if_index_set;
20151   u32 ip4_table_index = ~0;
20152   u32 ip6_table_index = ~0;
20153   u8 is_add = 1;
20154   int ret;
20155
20156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20157     {
20158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20159         sw_if_index_set = 1;
20160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20161         sw_if_index_set = 1;
20162       else if (unformat (i, "del"))
20163         is_add = 0;
20164       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20165         ;
20166       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20167         ;
20168       else
20169         {
20170           clib_warning ("parse error '%U'", format_unformat_error, i);
20171           return -99;
20172         }
20173     }
20174
20175   if (sw_if_index_set == 0)
20176     {
20177       errmsg ("missing interface name or sw_if_index");
20178       return -99;
20179     }
20180
20181   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20182
20183   mp->sw_if_index = ntohl (sw_if_index);
20184   mp->ip4_table_index = ntohl (ip4_table_index);
20185   mp->ip6_table_index = ntohl (ip6_table_index);
20186   mp->is_add = is_add;
20187
20188   S (mp);
20189   W (ret);
20190   return ret;
20191 }
20192
20193 static int
20194 api_flow_classify_dump (vat_main_t * vam)
20195 {
20196   unformat_input_t *i = vam->input;
20197   vl_api_flow_classify_dump_t *mp;
20198   vl_api_control_ping_t *mp_ping;
20199   u8 type = FLOW_CLASSIFY_N_TABLES;
20200   int ret;
20201
20202   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20203     ;
20204   else
20205     {
20206       errmsg ("classify table type must be specified");
20207       return -99;
20208     }
20209
20210   if (!vam->json_output)
20211     {
20212       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20213     }
20214
20215   M (FLOW_CLASSIFY_DUMP, mp);
20216   mp->type = type;
20217   /* send it... */
20218   S (mp);
20219
20220   /* Use a control ping for synchronization */
20221   MPING (CONTROL_PING, mp_ping);
20222   S (mp_ping);
20223
20224   /* Wait for a reply... */
20225   W (ret);
20226   return ret;
20227 }
20228
20229 static int
20230 api_feature_enable_disable (vat_main_t * vam)
20231 {
20232   unformat_input_t *i = vam->input;
20233   vl_api_feature_enable_disable_t *mp;
20234   u8 *arc_name = 0;
20235   u8 *feature_name = 0;
20236   u32 sw_if_index = ~0;
20237   u8 enable = 1;
20238   int ret;
20239
20240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20241     {
20242       if (unformat (i, "arc_name %s", &arc_name))
20243         ;
20244       else if (unformat (i, "feature_name %s", &feature_name))
20245         ;
20246       else
20247         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20248         ;
20249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20250         ;
20251       else if (unformat (i, "disable"))
20252         enable = 0;
20253       else
20254         break;
20255     }
20256
20257   if (arc_name == 0)
20258     {
20259       errmsg ("missing arc name");
20260       return -99;
20261     }
20262   if (vec_len (arc_name) > 63)
20263     {
20264       errmsg ("arc name too long");
20265     }
20266
20267   if (feature_name == 0)
20268     {
20269       errmsg ("missing feature name");
20270       return -99;
20271     }
20272   if (vec_len (feature_name) > 63)
20273     {
20274       errmsg ("feature name too long");
20275     }
20276
20277   if (sw_if_index == ~0)
20278     {
20279       errmsg ("missing interface name or sw_if_index");
20280       return -99;
20281     }
20282
20283   /* Construct the API message */
20284   M (FEATURE_ENABLE_DISABLE, mp);
20285   mp->sw_if_index = ntohl (sw_if_index);
20286   mp->enable = enable;
20287   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20288   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20289   vec_free (arc_name);
20290   vec_free (feature_name);
20291
20292   S (mp);
20293   W (ret);
20294   return ret;
20295 }
20296
20297 static int
20298 api_sw_interface_tag_add_del (vat_main_t * vam)
20299 {
20300   unformat_input_t *i = vam->input;
20301   vl_api_sw_interface_tag_add_del_t *mp;
20302   u32 sw_if_index = ~0;
20303   u8 *tag = 0;
20304   u8 enable = 1;
20305   int ret;
20306
20307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20308     {
20309       if (unformat (i, "tag %s", &tag))
20310         ;
20311       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20312         ;
20313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20314         ;
20315       else if (unformat (i, "del"))
20316         enable = 0;
20317       else
20318         break;
20319     }
20320
20321   if (sw_if_index == ~0)
20322     {
20323       errmsg ("missing interface name or sw_if_index");
20324       return -99;
20325     }
20326
20327   if (enable && (tag == 0))
20328     {
20329       errmsg ("no tag specified");
20330       return -99;
20331     }
20332
20333   /* Construct the API message */
20334   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20335   mp->sw_if_index = ntohl (sw_if_index);
20336   mp->is_add = enable;
20337   if (enable)
20338     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20339   vec_free (tag);
20340
20341   S (mp);
20342   W (ret);
20343   return ret;
20344 }
20345
20346 static void vl_api_l2_xconnect_details_t_handler
20347   (vl_api_l2_xconnect_details_t * mp)
20348 {
20349   vat_main_t *vam = &vat_main;
20350
20351   print (vam->ofp, "%15d%15d",
20352          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20353 }
20354
20355 static void vl_api_l2_xconnect_details_t_handler_json
20356   (vl_api_l2_xconnect_details_t * mp)
20357 {
20358   vat_main_t *vam = &vat_main;
20359   vat_json_node_t *node = NULL;
20360
20361   if (VAT_JSON_ARRAY != vam->json_tree.type)
20362     {
20363       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20364       vat_json_init_array (&vam->json_tree);
20365     }
20366   node = vat_json_array_add (&vam->json_tree);
20367
20368   vat_json_init_object (node);
20369   vat_json_object_add_uint (node, "rx_sw_if_index",
20370                             ntohl (mp->rx_sw_if_index));
20371   vat_json_object_add_uint (node, "tx_sw_if_index",
20372                             ntohl (mp->tx_sw_if_index));
20373 }
20374
20375 static int
20376 api_l2_xconnect_dump (vat_main_t * vam)
20377 {
20378   vl_api_l2_xconnect_dump_t *mp;
20379   vl_api_control_ping_t *mp_ping;
20380   int ret;
20381
20382   if (!vam->json_output)
20383     {
20384       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20385     }
20386
20387   M (L2_XCONNECT_DUMP, mp);
20388
20389   S (mp);
20390
20391   /* Use a control ping for synchronization */
20392   MPING (CONTROL_PING, mp_ping);
20393   S (mp_ping);
20394
20395   W (ret);
20396   return ret;
20397 }
20398
20399 static int
20400 api_hw_interface_set_mtu (vat_main_t * vam)
20401 {
20402   unformat_input_t *i = vam->input;
20403   vl_api_hw_interface_set_mtu_t *mp;
20404   u32 sw_if_index = ~0;
20405   u32 mtu = 0;
20406   int ret;
20407
20408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20409     {
20410       if (unformat (i, "mtu %d", &mtu))
20411         ;
20412       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20413         ;
20414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20415         ;
20416       else
20417         break;
20418     }
20419
20420   if (sw_if_index == ~0)
20421     {
20422       errmsg ("missing interface name or sw_if_index");
20423       return -99;
20424     }
20425
20426   if (mtu == 0)
20427     {
20428       errmsg ("no mtu specified");
20429       return -99;
20430     }
20431
20432   /* Construct the API message */
20433   M (HW_INTERFACE_SET_MTU, mp);
20434   mp->sw_if_index = ntohl (sw_if_index);
20435   mp->mtu = ntohs ((u16) mtu);
20436
20437   S (mp);
20438   W (ret);
20439   return ret;
20440 }
20441
20442 static int
20443 api_p2p_ethernet_add (vat_main_t * vam)
20444 {
20445   unformat_input_t *i = vam->input;
20446   vl_api_p2p_ethernet_add_t *mp;
20447   u32 parent_if_index = ~0;
20448   u32 sub_id = ~0;
20449   u8 remote_mac[6];
20450   u8 mac_set = 0;
20451   int ret;
20452
20453   clib_memset (remote_mac, 0, sizeof (remote_mac));
20454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20455     {
20456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20457         ;
20458       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20459         ;
20460       else
20461         if (unformat
20462             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20463         mac_set++;
20464       else if (unformat (i, "sub_id %d", &sub_id))
20465         ;
20466       else
20467         {
20468           clib_warning ("parse error '%U'", format_unformat_error, i);
20469           return -99;
20470         }
20471     }
20472
20473   if (parent_if_index == ~0)
20474     {
20475       errmsg ("missing interface name or sw_if_index");
20476       return -99;
20477     }
20478   if (mac_set == 0)
20479     {
20480       errmsg ("missing remote mac address");
20481       return -99;
20482     }
20483   if (sub_id == ~0)
20484     {
20485       errmsg ("missing sub-interface id");
20486       return -99;
20487     }
20488
20489   M (P2P_ETHERNET_ADD, mp);
20490   mp->parent_if_index = ntohl (parent_if_index);
20491   mp->subif_id = ntohl (sub_id);
20492   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20493
20494   S (mp);
20495   W (ret);
20496   return ret;
20497 }
20498
20499 static int
20500 api_p2p_ethernet_del (vat_main_t * vam)
20501 {
20502   unformat_input_t *i = vam->input;
20503   vl_api_p2p_ethernet_del_t *mp;
20504   u32 parent_if_index = ~0;
20505   u8 remote_mac[6];
20506   u8 mac_set = 0;
20507   int ret;
20508
20509   clib_memset (remote_mac, 0, sizeof (remote_mac));
20510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20511     {
20512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20513         ;
20514       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20515         ;
20516       else
20517         if (unformat
20518             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20519         mac_set++;
20520       else
20521         {
20522           clib_warning ("parse error '%U'", format_unformat_error, i);
20523           return -99;
20524         }
20525     }
20526
20527   if (parent_if_index == ~0)
20528     {
20529       errmsg ("missing interface name or sw_if_index");
20530       return -99;
20531     }
20532   if (mac_set == 0)
20533     {
20534       errmsg ("missing remote mac address");
20535       return -99;
20536     }
20537
20538   M (P2P_ETHERNET_DEL, mp);
20539   mp->parent_if_index = ntohl (parent_if_index);
20540   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20541
20542   S (mp);
20543   W (ret);
20544   return ret;
20545 }
20546
20547 static int
20548 api_lldp_config (vat_main_t * vam)
20549 {
20550   unformat_input_t *i = vam->input;
20551   vl_api_lldp_config_t *mp;
20552   int tx_hold = 0;
20553   int tx_interval = 0;
20554   u8 *sys_name = NULL;
20555   int ret;
20556
20557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20558     {
20559       if (unformat (i, "system-name %s", &sys_name))
20560         ;
20561       else if (unformat (i, "tx-hold %d", &tx_hold))
20562         ;
20563       else if (unformat (i, "tx-interval %d", &tx_interval))
20564         ;
20565       else
20566         {
20567           clib_warning ("parse error '%U'", format_unformat_error, i);
20568           return -99;
20569         }
20570     }
20571
20572   vec_add1 (sys_name, 0);
20573
20574   M (LLDP_CONFIG, mp);
20575   mp->tx_hold = htonl (tx_hold);
20576   mp->tx_interval = htonl (tx_interval);
20577   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20578   vec_free (sys_name);
20579
20580   S (mp);
20581   W (ret);
20582   return ret;
20583 }
20584
20585 static int
20586 api_sw_interface_set_lldp (vat_main_t * vam)
20587 {
20588   unformat_input_t *i = vam->input;
20589   vl_api_sw_interface_set_lldp_t *mp;
20590   u32 sw_if_index = ~0;
20591   u32 enable = 1;
20592   u8 *port_desc = NULL, *mgmt_oid = NULL;
20593   ip4_address_t ip4_addr;
20594   ip6_address_t ip6_addr;
20595   int ret;
20596
20597   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20598   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20599
20600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20601     {
20602       if (unformat (i, "disable"))
20603         enable = 0;
20604       else
20605         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20606         ;
20607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20608         ;
20609       else if (unformat (i, "port-desc %s", &port_desc))
20610         ;
20611       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20612         ;
20613       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20614         ;
20615       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20616         ;
20617       else
20618         break;
20619     }
20620
20621   if (sw_if_index == ~0)
20622     {
20623       errmsg ("missing interface name or sw_if_index");
20624       return -99;
20625     }
20626
20627   /* Construct the API message */
20628   vec_add1 (port_desc, 0);
20629   vec_add1 (mgmt_oid, 0);
20630   M (SW_INTERFACE_SET_LLDP, mp);
20631   mp->sw_if_index = ntohl (sw_if_index);
20632   mp->enable = enable;
20633   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20634   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20635   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20636   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20637   vec_free (port_desc);
20638   vec_free (mgmt_oid);
20639
20640   S (mp);
20641   W (ret);
20642   return ret;
20643 }
20644
20645 static int
20646 api_tcp_configure_src_addresses (vat_main_t * vam)
20647 {
20648   vl_api_tcp_configure_src_addresses_t *mp;
20649   unformat_input_t *i = vam->input;
20650   ip4_address_t v4first, v4last;
20651   ip6_address_t v6first, v6last;
20652   u8 range_set = 0;
20653   u32 vrf_id = 0;
20654   int ret;
20655
20656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20657     {
20658       if (unformat (i, "%U - %U",
20659                     unformat_ip4_address, &v4first,
20660                     unformat_ip4_address, &v4last))
20661         {
20662           if (range_set)
20663             {
20664               errmsg ("one range per message (range already set)");
20665               return -99;
20666             }
20667           range_set = 1;
20668         }
20669       else if (unformat (i, "%U - %U",
20670                          unformat_ip6_address, &v6first,
20671                          unformat_ip6_address, &v6last))
20672         {
20673           if (range_set)
20674             {
20675               errmsg ("one range per message (range already set)");
20676               return -99;
20677             }
20678           range_set = 2;
20679         }
20680       else if (unformat (i, "vrf %d", &vrf_id))
20681         ;
20682       else
20683         break;
20684     }
20685
20686   if (range_set == 0)
20687     {
20688       errmsg ("address range not set");
20689       return -99;
20690     }
20691
20692   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20693   mp->vrf_id = ntohl (vrf_id);
20694   /* ipv6? */
20695   if (range_set == 2)
20696     {
20697       mp->is_ipv6 = 1;
20698       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20699       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20700     }
20701   else
20702     {
20703       mp->is_ipv6 = 0;
20704       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20705       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20706     }
20707   S (mp);
20708   W (ret);
20709   return ret;
20710 }
20711
20712 static void vl_api_app_namespace_add_del_reply_t_handler
20713   (vl_api_app_namespace_add_del_reply_t * mp)
20714 {
20715   vat_main_t *vam = &vat_main;
20716   i32 retval = ntohl (mp->retval);
20717   if (vam->async_mode)
20718     {
20719       vam->async_errors += (retval < 0);
20720     }
20721   else
20722     {
20723       vam->retval = retval;
20724       if (retval == 0)
20725         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20726       vam->result_ready = 1;
20727     }
20728 }
20729
20730 static void vl_api_app_namespace_add_del_reply_t_handler_json
20731   (vl_api_app_namespace_add_del_reply_t * mp)
20732 {
20733   vat_main_t *vam = &vat_main;
20734   vat_json_node_t node;
20735
20736   vat_json_init_object (&node);
20737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20738   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20739
20740   vat_json_print (vam->ofp, &node);
20741   vat_json_free (&node);
20742
20743   vam->retval = ntohl (mp->retval);
20744   vam->result_ready = 1;
20745 }
20746
20747 static int
20748 api_app_namespace_add_del (vat_main_t * vam)
20749 {
20750   vl_api_app_namespace_add_del_t *mp;
20751   unformat_input_t *i = vam->input;
20752   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20753   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20754   u64 secret;
20755   int ret;
20756
20757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20758     {
20759       if (unformat (i, "id %_%v%_", &ns_id))
20760         ;
20761       else if (unformat (i, "secret %lu", &secret))
20762         secret_set = 1;
20763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20764         sw_if_index_set = 1;
20765       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20766         ;
20767       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20768         ;
20769       else
20770         break;
20771     }
20772   if (!ns_id || !secret_set || !sw_if_index_set)
20773     {
20774       errmsg ("namespace id, secret and sw_if_index must be set");
20775       return -99;
20776     }
20777   if (vec_len (ns_id) > 64)
20778     {
20779       errmsg ("namespace id too long");
20780       return -99;
20781     }
20782   M (APP_NAMESPACE_ADD_DEL, mp);
20783
20784   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20785   mp->namespace_id_len = vec_len (ns_id);
20786   mp->secret = clib_host_to_net_u64 (secret);
20787   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20788   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20789   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20790   vec_free (ns_id);
20791   S (mp);
20792   W (ret);
20793   return ret;
20794 }
20795
20796 static int
20797 api_sock_init_shm (vat_main_t * vam)
20798 {
20799 #if VPP_API_TEST_BUILTIN == 0
20800   unformat_input_t *i = vam->input;
20801   vl_api_shm_elem_config_t *config = 0;
20802   u64 size = 64 << 20;
20803   int rv;
20804
20805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20806     {
20807       if (unformat (i, "size %U", unformat_memory_size, &size))
20808         ;
20809       else
20810         break;
20811     }
20812
20813   /*
20814    * Canned custom ring allocator config.
20815    * Should probably parse all of this
20816    */
20817   vec_validate (config, 6);
20818   config[0].type = VL_API_VLIB_RING;
20819   config[0].size = 256;
20820   config[0].count = 32;
20821
20822   config[1].type = VL_API_VLIB_RING;
20823   config[1].size = 1024;
20824   config[1].count = 16;
20825
20826   config[2].type = VL_API_VLIB_RING;
20827   config[2].size = 4096;
20828   config[2].count = 2;
20829
20830   config[3].type = VL_API_CLIENT_RING;
20831   config[3].size = 256;
20832   config[3].count = 32;
20833
20834   config[4].type = VL_API_CLIENT_RING;
20835   config[4].size = 1024;
20836   config[4].count = 16;
20837
20838   config[5].type = VL_API_CLIENT_RING;
20839   config[5].size = 4096;
20840   config[5].count = 2;
20841
20842   config[6].type = VL_API_QUEUE;
20843   config[6].count = 128;
20844   config[6].size = sizeof (uword);
20845
20846   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20847   if (!rv)
20848     vam->client_index_invalid = 1;
20849   return rv;
20850 #else
20851   return -99;
20852 #endif
20853 }
20854
20855 static void
20856 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20857 {
20858   vat_main_t *vam = &vat_main;
20859
20860   if (mp->is_ip4)
20861     {
20862       print (vam->ofp,
20863              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20864              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20865              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20866              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20867              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20868              clib_net_to_host_u32 (mp->action_index), mp->tag);
20869     }
20870   else
20871     {
20872       print (vam->ofp,
20873              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20874              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20875              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20876              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20877              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20878              clib_net_to_host_u32 (mp->action_index), mp->tag);
20879     }
20880 }
20881
20882 static void
20883 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20884                                              mp)
20885 {
20886   vat_main_t *vam = &vat_main;
20887   vat_json_node_t *node = NULL;
20888   struct in6_addr ip6;
20889   struct in_addr ip4;
20890
20891   if (VAT_JSON_ARRAY != vam->json_tree.type)
20892     {
20893       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20894       vat_json_init_array (&vam->json_tree);
20895     }
20896   node = vat_json_array_add (&vam->json_tree);
20897   vat_json_init_object (node);
20898
20899   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20900   vat_json_object_add_uint (node, "appns_index",
20901                             clib_net_to_host_u32 (mp->appns_index));
20902   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20903   vat_json_object_add_uint (node, "scope", mp->scope);
20904   vat_json_object_add_uint (node, "action_index",
20905                             clib_net_to_host_u32 (mp->action_index));
20906   vat_json_object_add_uint (node, "lcl_port",
20907                             clib_net_to_host_u16 (mp->lcl_port));
20908   vat_json_object_add_uint (node, "rmt_port",
20909                             clib_net_to_host_u16 (mp->rmt_port));
20910   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20911   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20912   vat_json_object_add_string_copy (node, "tag", mp->tag);
20913   if (mp->is_ip4)
20914     {
20915       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20916       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20917       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20918       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20919     }
20920   else
20921     {
20922       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20923       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20924       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20925       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20926     }
20927 }
20928
20929 static int
20930 api_session_rule_add_del (vat_main_t * vam)
20931 {
20932   vl_api_session_rule_add_del_t *mp;
20933   unformat_input_t *i = vam->input;
20934   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20935   u32 appns_index = 0, scope = 0;
20936   ip4_address_t lcl_ip4, rmt_ip4;
20937   ip6_address_t lcl_ip6, rmt_ip6;
20938   u8 is_ip4 = 1, conn_set = 0;
20939   u8 is_add = 1, *tag = 0;
20940   int ret;
20941
20942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20943     {
20944       if (unformat (i, "del"))
20945         is_add = 0;
20946       else if (unformat (i, "add"))
20947         ;
20948       else if (unformat (i, "proto tcp"))
20949         proto = 0;
20950       else if (unformat (i, "proto udp"))
20951         proto = 1;
20952       else if (unformat (i, "appns %d", &appns_index))
20953         ;
20954       else if (unformat (i, "scope %d", &scope))
20955         ;
20956       else if (unformat (i, "tag %_%v%_", &tag))
20957         ;
20958       else
20959         if (unformat
20960             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20961              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20962              &rmt_port))
20963         {
20964           is_ip4 = 1;
20965           conn_set = 1;
20966         }
20967       else
20968         if (unformat
20969             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20970              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20971              &rmt_port))
20972         {
20973           is_ip4 = 0;
20974           conn_set = 1;
20975         }
20976       else if (unformat (i, "action %d", &action))
20977         ;
20978       else
20979         break;
20980     }
20981   if (proto == ~0 || !conn_set || action == ~0)
20982     {
20983       errmsg ("transport proto, connection and action must be set");
20984       return -99;
20985     }
20986
20987   if (scope > 3)
20988     {
20989       errmsg ("scope should be 0-3");
20990       return -99;
20991     }
20992
20993   M (SESSION_RULE_ADD_DEL, mp);
20994
20995   mp->is_ip4 = is_ip4;
20996   mp->transport_proto = proto;
20997   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20998   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20999   mp->lcl_plen = lcl_plen;
21000   mp->rmt_plen = rmt_plen;
21001   mp->action_index = clib_host_to_net_u32 (action);
21002   mp->appns_index = clib_host_to_net_u32 (appns_index);
21003   mp->scope = scope;
21004   mp->is_add = is_add;
21005   if (is_ip4)
21006     {
21007       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21008       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21009     }
21010   else
21011     {
21012       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21013       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21014     }
21015   if (tag)
21016     {
21017       clib_memcpy (mp->tag, tag, vec_len (tag));
21018       vec_free (tag);
21019     }
21020
21021   S (mp);
21022   W (ret);
21023   return ret;
21024 }
21025
21026 static int
21027 api_session_rules_dump (vat_main_t * vam)
21028 {
21029   vl_api_session_rules_dump_t *mp;
21030   vl_api_control_ping_t *mp_ping;
21031   int ret;
21032
21033   if (!vam->json_output)
21034     {
21035       print (vam->ofp, "%=20s", "Session Rules");
21036     }
21037
21038   M (SESSION_RULES_DUMP, mp);
21039   /* send it... */
21040   S (mp);
21041
21042   /* Use a control ping for synchronization */
21043   MPING (CONTROL_PING, mp_ping);
21044   S (mp_ping);
21045
21046   /* Wait for a reply... */
21047   W (ret);
21048   return ret;
21049 }
21050
21051 static int
21052 api_ip_container_proxy_add_del (vat_main_t * vam)
21053 {
21054   vl_api_ip_container_proxy_add_del_t *mp;
21055   unformat_input_t *i = vam->input;
21056   u32 sw_if_index = ~0;
21057   vl_api_prefix_t pfx = { };
21058   u8 is_add = 1;
21059   int ret;
21060
21061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21062     {
21063       if (unformat (i, "del"))
21064         is_add = 0;
21065       else if (unformat (i, "add"))
21066         ;
21067       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21068         ;
21069       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21070         ;
21071       else
21072         break;
21073     }
21074   if (sw_if_index == ~0 || pfx.len == 0)
21075     {
21076       errmsg ("address and sw_if_index must be set");
21077       return -99;
21078     }
21079
21080   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21081
21082   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21083   mp->is_add = is_add;
21084   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21085
21086   S (mp);
21087   W (ret);
21088   return ret;
21089 }
21090
21091 static int
21092 api_qos_record_enable_disable (vat_main_t * vam)
21093 {
21094   unformat_input_t *i = vam->input;
21095   vl_api_qos_record_enable_disable_t *mp;
21096   u32 sw_if_index, qs = 0xff;
21097   u8 sw_if_index_set = 0;
21098   u8 enable = 1;
21099   int ret;
21100
21101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21102     {
21103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21104         sw_if_index_set = 1;
21105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21106         sw_if_index_set = 1;
21107       else if (unformat (i, "%U", unformat_qos_source, &qs))
21108         ;
21109       else if (unformat (i, "disable"))
21110         enable = 0;
21111       else
21112         {
21113           clib_warning ("parse error '%U'", format_unformat_error, i);
21114           return -99;
21115         }
21116     }
21117
21118   if (sw_if_index_set == 0)
21119     {
21120       errmsg ("missing interface name or sw_if_index");
21121       return -99;
21122     }
21123   if (qs == 0xff)
21124     {
21125       errmsg ("input location must be specified");
21126       return -99;
21127     }
21128
21129   M (QOS_RECORD_ENABLE_DISABLE, mp);
21130
21131   mp->record.sw_if_index = ntohl (sw_if_index);
21132   mp->record.input_source = qs;
21133   mp->enable = enable;
21134
21135   S (mp);
21136   W (ret);
21137   return ret;
21138 }
21139
21140
21141 static int
21142 q_or_quit (vat_main_t * vam)
21143 {
21144 #if VPP_API_TEST_BUILTIN == 0
21145   longjmp (vam->jump_buf, 1);
21146 #endif
21147   return 0;                     /* not so much */
21148 }
21149
21150 static int
21151 q (vat_main_t * vam)
21152 {
21153   return q_or_quit (vam);
21154 }
21155
21156 static int
21157 quit (vat_main_t * vam)
21158 {
21159   return q_or_quit (vam);
21160 }
21161
21162 static int
21163 comment (vat_main_t * vam)
21164 {
21165   return 0;
21166 }
21167
21168 static int
21169 elog_save (vat_main_t * vam)
21170 {
21171 #if VPP_API_TEST_BUILTIN == 0
21172   elog_main_t *em = &vam->elog_main;
21173   unformat_input_t *i = vam->input;
21174   char *file, *chroot_file;
21175   clib_error_t *error;
21176
21177   if (!unformat (i, "%s", &file))
21178     {
21179       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21180       return 0;
21181     }
21182
21183   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21184   if (strstr (file, "..") || index (file, '/'))
21185     {
21186       errmsg ("illegal characters in filename '%s'", file);
21187       return 0;
21188     }
21189
21190   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21191
21192   vec_free (file);
21193
21194   errmsg ("Saving %wd of %wd events to %s",
21195           elog_n_events_in_buffer (em),
21196           elog_buffer_capacity (em), chroot_file);
21197
21198   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21199   vec_free (chroot_file);
21200
21201   if (error)
21202     clib_error_report (error);
21203 #else
21204   errmsg ("Use the vpp event loger...");
21205 #endif
21206
21207   return 0;
21208 }
21209
21210 static int
21211 elog_setup (vat_main_t * vam)
21212 {
21213 #if VPP_API_TEST_BUILTIN == 0
21214   elog_main_t *em = &vam->elog_main;
21215   unformat_input_t *i = vam->input;
21216   u32 nevents = 128 << 10;
21217
21218   (void) unformat (i, "nevents %d", &nevents);
21219
21220   elog_init (em, nevents);
21221   vl_api_set_elog_main (em);
21222   vl_api_set_elog_trace_api_messages (1);
21223   errmsg ("Event logger initialized with %u events", nevents);
21224 #else
21225   errmsg ("Use the vpp event loger...");
21226 #endif
21227   return 0;
21228 }
21229
21230 static int
21231 elog_enable (vat_main_t * vam)
21232 {
21233 #if VPP_API_TEST_BUILTIN == 0
21234   elog_main_t *em = &vam->elog_main;
21235
21236   elog_enable_disable (em, 1 /* enable */ );
21237   vl_api_set_elog_trace_api_messages (1);
21238   errmsg ("Event logger enabled...");
21239 #else
21240   errmsg ("Use the vpp event loger...");
21241 #endif
21242   return 0;
21243 }
21244
21245 static int
21246 elog_disable (vat_main_t * vam)
21247 {
21248 #if VPP_API_TEST_BUILTIN == 0
21249   elog_main_t *em = &vam->elog_main;
21250
21251   elog_enable_disable (em, 0 /* enable */ );
21252   vl_api_set_elog_trace_api_messages (1);
21253   errmsg ("Event logger disabled...");
21254 #else
21255   errmsg ("Use the vpp event loger...");
21256 #endif
21257   return 0;
21258 }
21259
21260 static int
21261 statseg (vat_main_t * vam)
21262 {
21263   ssvm_private_t *ssvmp = &vam->stat_segment;
21264   ssvm_shared_header_t *shared_header = ssvmp->sh;
21265   vlib_counter_t **counters;
21266   u64 thread0_index1_packets;
21267   u64 thread0_index1_bytes;
21268   f64 vector_rate, input_rate;
21269   uword *p;
21270
21271   uword *counter_vector_by_name;
21272   if (vam->stat_segment_lockp == 0)
21273     {
21274       errmsg ("Stat segment not mapped...");
21275       return -99;
21276     }
21277
21278   /* look up "/if/rx for sw_if_index 1 as a test */
21279
21280   clib_spinlock_lock (vam->stat_segment_lockp);
21281
21282   counter_vector_by_name = (uword *) shared_header->opaque[1];
21283
21284   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21285   if (p == 0)
21286     {
21287       clib_spinlock_unlock (vam->stat_segment_lockp);
21288       errmsg ("/if/tx not found?");
21289       return -99;
21290     }
21291
21292   /* Fish per-thread vector of combined counters from shared memory */
21293   counters = (vlib_counter_t **) p[0];
21294
21295   if (vec_len (counters[0]) < 2)
21296     {
21297       clib_spinlock_unlock (vam->stat_segment_lockp);
21298       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21299       return -99;
21300     }
21301
21302   /* Read thread 0 sw_if_index 1 counter */
21303   thread0_index1_packets = counters[0][1].packets;
21304   thread0_index1_bytes = counters[0][1].bytes;
21305
21306   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21307   if (p == 0)
21308     {
21309       clib_spinlock_unlock (vam->stat_segment_lockp);
21310       errmsg ("vector_rate not found?");
21311       return -99;
21312     }
21313
21314   vector_rate = *(f64 *) (p[0]);
21315   p = hash_get_mem (counter_vector_by_name, "input_rate");
21316   if (p == 0)
21317     {
21318       clib_spinlock_unlock (vam->stat_segment_lockp);
21319       errmsg ("input_rate not found?");
21320       return -99;
21321     }
21322   input_rate = *(f64 *) (p[0]);
21323
21324   clib_spinlock_unlock (vam->stat_segment_lockp);
21325
21326   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21327          vector_rate, input_rate);
21328   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21329          thread0_index1_packets, thread0_index1_bytes);
21330
21331   return 0;
21332 }
21333
21334 static int
21335 cmd_cmp (void *a1, void *a2)
21336 {
21337   u8 **c1 = a1;
21338   u8 **c2 = a2;
21339
21340   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21341 }
21342
21343 static int
21344 help (vat_main_t * vam)
21345 {
21346   u8 **cmds = 0;
21347   u8 *name = 0;
21348   hash_pair_t *p;
21349   unformat_input_t *i = vam->input;
21350   int j;
21351
21352   if (unformat (i, "%s", &name))
21353     {
21354       uword *hs;
21355
21356       vec_add1 (name, 0);
21357
21358       hs = hash_get_mem (vam->help_by_name, name);
21359       if (hs)
21360         print (vam->ofp, "usage: %s %s", name, hs[0]);
21361       else
21362         print (vam->ofp, "No such msg / command '%s'", name);
21363       vec_free (name);
21364       return 0;
21365     }
21366
21367   print (vam->ofp, "Help is available for the following:");
21368
21369     /* *INDENT-OFF* */
21370     hash_foreach_pair (p, vam->function_by_name,
21371     ({
21372       vec_add1 (cmds, (u8 *)(p->key));
21373     }));
21374     /* *INDENT-ON* */
21375
21376   vec_sort_with_function (cmds, cmd_cmp);
21377
21378   for (j = 0; j < vec_len (cmds); j++)
21379     print (vam->ofp, "%s", cmds[j]);
21380
21381   vec_free (cmds);
21382   return 0;
21383 }
21384
21385 static int
21386 set (vat_main_t * vam)
21387 {
21388   u8 *name = 0, *value = 0;
21389   unformat_input_t *i = vam->input;
21390
21391   if (unformat (i, "%s", &name))
21392     {
21393       /* The input buffer is a vector, not a string. */
21394       value = vec_dup (i->buffer);
21395       vec_delete (value, i->index, 0);
21396       /* Almost certainly has a trailing newline */
21397       if (value[vec_len (value) - 1] == '\n')
21398         value[vec_len (value) - 1] = 0;
21399       /* Make sure it's a proper string, one way or the other */
21400       vec_add1 (value, 0);
21401       (void) clib_macro_set_value (&vam->macro_main,
21402                                    (char *) name, (char *) value);
21403     }
21404   else
21405     errmsg ("usage: set <name> <value>");
21406
21407   vec_free (name);
21408   vec_free (value);
21409   return 0;
21410 }
21411
21412 static int
21413 unset (vat_main_t * vam)
21414 {
21415   u8 *name = 0;
21416
21417   if (unformat (vam->input, "%s", &name))
21418     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21419       errmsg ("unset: %s wasn't set", name);
21420   vec_free (name);
21421   return 0;
21422 }
21423
21424 typedef struct
21425 {
21426   u8 *name;
21427   u8 *value;
21428 } macro_sort_t;
21429
21430
21431 static int
21432 macro_sort_cmp (void *a1, void *a2)
21433 {
21434   macro_sort_t *s1 = a1;
21435   macro_sort_t *s2 = a2;
21436
21437   return strcmp ((char *) (s1->name), (char *) (s2->name));
21438 }
21439
21440 static int
21441 dump_macro_table (vat_main_t * vam)
21442 {
21443   macro_sort_t *sort_me = 0, *sm;
21444   int i;
21445   hash_pair_t *p;
21446
21447     /* *INDENT-OFF* */
21448     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21449     ({
21450       vec_add2 (sort_me, sm, 1);
21451       sm->name = (u8 *)(p->key);
21452       sm->value = (u8 *) (p->value[0]);
21453     }));
21454     /* *INDENT-ON* */
21455
21456   vec_sort_with_function (sort_me, macro_sort_cmp);
21457
21458   if (vec_len (sort_me))
21459     print (vam->ofp, "%-15s%s", "Name", "Value");
21460   else
21461     print (vam->ofp, "The macro table is empty...");
21462
21463   for (i = 0; i < vec_len (sort_me); i++)
21464     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21465   return 0;
21466 }
21467
21468 static int
21469 dump_node_table (vat_main_t * vam)
21470 {
21471   int i, j;
21472   vlib_node_t *node, *next_node;
21473
21474   if (vec_len (vam->graph_nodes) == 0)
21475     {
21476       print (vam->ofp, "Node table empty, issue get_node_graph...");
21477       return 0;
21478     }
21479
21480   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21481     {
21482       node = vam->graph_nodes[0][i];
21483       print (vam->ofp, "[%d] %s", i, node->name);
21484       for (j = 0; j < vec_len (node->next_nodes); j++)
21485         {
21486           if (node->next_nodes[j] != ~0)
21487             {
21488               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21489               print (vam->ofp, "  [%d] %s", j, next_node->name);
21490             }
21491         }
21492     }
21493   return 0;
21494 }
21495
21496 static int
21497 value_sort_cmp (void *a1, void *a2)
21498 {
21499   name_sort_t *n1 = a1;
21500   name_sort_t *n2 = a2;
21501
21502   if (n1->value < n2->value)
21503     return -1;
21504   if (n1->value > n2->value)
21505     return 1;
21506   return 0;
21507 }
21508
21509
21510 static int
21511 dump_msg_api_table (vat_main_t * vam)
21512 {
21513   api_main_t *am = &api_main;
21514   name_sort_t *nses = 0, *ns;
21515   hash_pair_t *hp;
21516   int i;
21517
21518   /* *INDENT-OFF* */
21519   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21520   ({
21521     vec_add2 (nses, ns, 1);
21522     ns->name = (u8 *)(hp->key);
21523     ns->value = (u32) hp->value[0];
21524   }));
21525   /* *INDENT-ON* */
21526
21527   vec_sort_with_function (nses, value_sort_cmp);
21528
21529   for (i = 0; i < vec_len (nses); i++)
21530     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21531   vec_free (nses);
21532   return 0;
21533 }
21534
21535 static int
21536 get_msg_id (vat_main_t * vam)
21537 {
21538   u8 *name_and_crc;
21539   u32 message_index;
21540
21541   if (unformat (vam->input, "%s", &name_and_crc))
21542     {
21543       message_index = vl_msg_api_get_msg_index (name_and_crc);
21544       if (message_index == ~0)
21545         {
21546           print (vam->ofp, " '%s' not found", name_and_crc);
21547           return 0;
21548         }
21549       print (vam->ofp, " '%s' has message index %d",
21550              name_and_crc, message_index);
21551       return 0;
21552     }
21553   errmsg ("name_and_crc required...");
21554   return 0;
21555 }
21556
21557 static int
21558 search_node_table (vat_main_t * vam)
21559 {
21560   unformat_input_t *line_input = vam->input;
21561   u8 *node_to_find;
21562   int j;
21563   vlib_node_t *node, *next_node;
21564   uword *p;
21565
21566   if (vam->graph_node_index_by_name == 0)
21567     {
21568       print (vam->ofp, "Node table empty, issue get_node_graph...");
21569       return 0;
21570     }
21571
21572   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21573     {
21574       if (unformat (line_input, "%s", &node_to_find))
21575         {
21576           vec_add1 (node_to_find, 0);
21577           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21578           if (p == 0)
21579             {
21580               print (vam->ofp, "%s not found...", node_to_find);
21581               goto out;
21582             }
21583           node = vam->graph_nodes[0][p[0]];
21584           print (vam->ofp, "[%d] %s", p[0], node->name);
21585           for (j = 0; j < vec_len (node->next_nodes); j++)
21586             {
21587               if (node->next_nodes[j] != ~0)
21588                 {
21589                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21590                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21591                 }
21592             }
21593         }
21594
21595       else
21596         {
21597           clib_warning ("parse error '%U'", format_unformat_error,
21598                         line_input);
21599           return -99;
21600         }
21601
21602     out:
21603       vec_free (node_to_find);
21604
21605     }
21606
21607   return 0;
21608 }
21609
21610
21611 static int
21612 script (vat_main_t * vam)
21613 {
21614 #if (VPP_API_TEST_BUILTIN==0)
21615   u8 *s = 0;
21616   char *save_current_file;
21617   unformat_input_t save_input;
21618   jmp_buf save_jump_buf;
21619   u32 save_line_number;
21620
21621   FILE *new_fp, *save_ifp;
21622
21623   if (unformat (vam->input, "%s", &s))
21624     {
21625       new_fp = fopen ((char *) s, "r");
21626       if (new_fp == 0)
21627         {
21628           errmsg ("Couldn't open script file %s", s);
21629           vec_free (s);
21630           return -99;
21631         }
21632     }
21633   else
21634     {
21635       errmsg ("Missing script name");
21636       return -99;
21637     }
21638
21639   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21640   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21641   save_ifp = vam->ifp;
21642   save_line_number = vam->input_line_number;
21643   save_current_file = (char *) vam->current_file;
21644
21645   vam->input_line_number = 0;
21646   vam->ifp = new_fp;
21647   vam->current_file = s;
21648   do_one_file (vam);
21649
21650   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21651   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21652   vam->ifp = save_ifp;
21653   vam->input_line_number = save_line_number;
21654   vam->current_file = (u8 *) save_current_file;
21655   vec_free (s);
21656
21657   return 0;
21658 #else
21659   clib_warning ("use the exec command...");
21660   return -99;
21661 #endif
21662 }
21663
21664 static int
21665 echo (vat_main_t * vam)
21666 {
21667   print (vam->ofp, "%v", vam->input->buffer);
21668   return 0;
21669 }
21670
21671 /* List of API message constructors, CLI names map to api_xxx */
21672 #define foreach_vpe_api_msg                                             \
21673 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21674 _(sw_interface_dump,"")                                                 \
21675 _(sw_interface_set_flags,                                               \
21676   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21677 _(sw_interface_add_del_address,                                         \
21678   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21679 _(sw_interface_set_rx_mode,                                             \
21680   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21681 _(sw_interface_set_rx_placement,                                        \
21682   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21683 _(sw_interface_rx_placement_dump,                                       \
21684   "[<intfc> | sw_if_index <id>]")                                         \
21685 _(sw_interface_set_table,                                               \
21686   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21687 _(sw_interface_set_mpls_enable,                                         \
21688   "<intfc> | sw_if_index [disable | dis]")                              \
21689 _(sw_interface_set_vpath,                                               \
21690   "<intfc> | sw_if_index <id> enable | disable")                        \
21691 _(sw_interface_set_vxlan_bypass,                                        \
21692   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21693 _(sw_interface_set_geneve_bypass,                                       \
21694   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21695 _(sw_interface_set_l2_xconnect,                                         \
21696   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21697   "enable | disable")                                                   \
21698 _(sw_interface_set_l2_bridge,                                           \
21699   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21700   "[shg <split-horizon-group>] [bvi]\n"                                 \
21701   "enable | disable")                                                   \
21702 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21703 _(bridge_domain_add_del,                                                \
21704   "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") \
21705 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21706 _(l2fib_add_del,                                                        \
21707   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21708 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21709 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21710 _(l2_flags,                                                             \
21711   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21712 _(bridge_flags,                                                         \
21713   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21714 _(tap_create_v2,                                                        \
21715   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21716 _(tap_delete_v2,                                                        \
21717   "<vpp-if-name> | sw_if_index <id>")                                   \
21718 _(sw_interface_tap_v2_dump, "")                                         \
21719 _(virtio_pci_create,                                                    \
21720   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21721 _(virtio_pci_delete,                                                    \
21722   "<vpp-if-name> | sw_if_index <id>")                                   \
21723 _(sw_interface_virtio_pci_dump, "")                                     \
21724 _(bond_create,                                                          \
21725   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21726   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21727   "[id <if-id>]")                                                       \
21728 _(bond_delete,                                                          \
21729   "<vpp-if-name> | sw_if_index <id>")                                   \
21730 _(bond_enslave,                                                         \
21731   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21732 _(bond_detach_slave,                                                    \
21733   "sw_if_index <n>")                                                    \
21734 _(sw_interface_bond_dump, "")                                           \
21735 _(sw_interface_slave_dump,                                              \
21736   "<vpp-if-name> | sw_if_index <id>")                                   \
21737 _(ip_table_add_del,                                                     \
21738   "table <n> [ipv6] [add | del]\n")                                     \
21739 _(ip_route_add_del,                                                     \
21740   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21741   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21742   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21743   "[multipath] [count <n>] [del]")                                      \
21744 _(ip_mroute_add_del,                                                    \
21745   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21746   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21747 _(mpls_table_add_del,                                                   \
21748   "table <n> [add | del]\n")                                            \
21749 _(mpls_route_add_del,                                                   \
21750   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21751   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21752   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21753   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21754   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21755   "[count <n>] [del]")                                                  \
21756 _(mpls_ip_bind_unbind,                                                  \
21757   "<label> <addr/len>")                                                 \
21758 _(mpls_tunnel_add_del,                                                  \
21759   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21760   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21761   "[l2-only]  [out-label <n>]")                                         \
21762 _(sr_mpls_policy_add,                                                   \
21763   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21764 _(sr_mpls_policy_del,                                                   \
21765   "bsid <id>")                                                          \
21766 _(bier_table_add_del,                                                   \
21767   "<label> <sub-domain> <set> <bsl> [del]")                             \
21768 _(bier_route_add_del,                                                   \
21769   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21770   "[<intfc> | sw_if_index <id>]"                                        \
21771   "[weight <n>] [del] [multipath]")                                     \
21772 _(proxy_arp_add_del,                                                    \
21773   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21774 _(proxy_arp_intfc_enable_disable,                                       \
21775   "<intfc> | sw_if_index <id> enable | disable")                        \
21776 _(sw_interface_set_unnumbered,                                          \
21777   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21778 _(ip_neighbor_add_del,                                                  \
21779   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21780   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21781 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21782 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21783   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21784   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21785   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21786 _(reset_fib, "vrf <n> [ipv6]")                                          \
21787 _(dhcp_proxy_config,                                                    \
21788   "svr <v46-address> src <v46-address>\n"                               \
21789    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21790 _(dhcp_proxy_set_vss,                                                   \
21791   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21792 _(dhcp_proxy_dump, "ip6")                                               \
21793 _(dhcp_client_config,                                                   \
21794   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21795 _(set_ip_flow_hash,                                                     \
21796   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21797 _(sw_interface_ip6_enable_disable,                                      \
21798   "<intfc> | sw_if_index <id> enable | disable")                        \
21799 _(ip6nd_proxy_add_del,                                                  \
21800   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21801 _(ip6nd_proxy_dump, "")                                                 \
21802 _(sw_interface_ip6nd_ra_prefix,                                         \
21803   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21804   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21805   "[nolink] [isno]")                                                    \
21806 _(sw_interface_ip6nd_ra_config,                                         \
21807   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21808   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21809   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21810 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21811 _(l2_patch_add_del,                                                     \
21812   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21813   "enable | disable")                                                   \
21814 _(sr_localsid_add_del,                                                  \
21815   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21816   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21817 _(classify_add_del_table,                                               \
21818   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21819   " [del] [del-chain] mask <mask-value>\n"                              \
21820   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21821   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21822 _(classify_add_del_session,                                             \
21823   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21824   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21825   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21826   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21827 _(classify_set_interface_ip_table,                                      \
21828   "<intfc> | sw_if_index <nn> table <nn>")                              \
21829 _(classify_set_interface_l2_tables,                                     \
21830   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21831   "  [other-table <nn>]")                                               \
21832 _(get_node_index, "node <node-name")                                    \
21833 _(add_node_next, "node <node-name> next <next-node-name>")              \
21834 _(l2tpv3_create_tunnel,                                                 \
21835   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21836   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21837   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21838 _(l2tpv3_set_tunnel_cookies,                                            \
21839   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21840   "[new_remote_cookie <nn>]\n")                                         \
21841 _(l2tpv3_interface_enable_disable,                                      \
21842   "<intfc> | sw_if_index <nn> enable | disable")                        \
21843 _(l2tpv3_set_lookup_key,                                                \
21844   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21845 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21846 _(vxlan_offload_rx,                                                     \
21847   "hw { <interface name> | hw_if_index <nn>} "                          \
21848   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21849 _(vxlan_add_del_tunnel,                                                 \
21850   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21851   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21852   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21853 _(geneve_add_del_tunnel,                                                \
21854   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21855   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21856   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21857 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21858 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21859 _(gre_tunnel_add_del,                                                   \
21860   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21861   "[teb | erspan <session-id>] [del]")                                  \
21862 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21863 _(l2_fib_clear_table, "")                                               \
21864 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21865 _(l2_interface_vlan_tag_rewrite,                                        \
21866   "<intfc> | sw_if_index <nn> \n"                                       \
21867   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21868   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21869 _(create_vhost_user_if,                                                 \
21870         "socket <filename> [server] [renumber <dev_instance>] "         \
21871         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21872         "[mac <mac_address>]")                                          \
21873 _(modify_vhost_user_if,                                                 \
21874         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21875         "[server] [renumber <dev_instance>] [gso]")                     \
21876 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21877 _(sw_interface_vhost_user_dump, "")                                     \
21878 _(show_version, "")                                                     \
21879 _(show_threads, "")                                                     \
21880 _(vxlan_gpe_add_del_tunnel,                                             \
21881   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21882   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21883   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21884   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21885 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21886 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21887 _(interface_name_renumber,                                              \
21888   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21889 _(input_acl_set_interface,                                              \
21890   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21891   "  [l2-table <nn>] [del]")                                            \
21892 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21893 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21894   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21895 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21896 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21897 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21898 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21899 _(ip_dump, "ipv4 | ipv6")                                               \
21900 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21901 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21902   "  spid_id <n> ")                                                     \
21903 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21904   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21905   "  integ_alg <alg> integ_key <hex>")                                  \
21906 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21907   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21908   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21909   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21910 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21911   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21912   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21913   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21914   "  [instance <n>]")     \
21915 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21916 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21917 _(delete_loopback,"sw_if_index <nn>")                                   \
21918 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21919 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21920 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21921 _(want_interface_events,  "enable|disable")                             \
21922 _(get_first_msg_id, "client <name>")                                    \
21923 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21924 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21925   "fib-id <nn> [ip4][ip6][default]")                                    \
21926 _(get_node_graph, " ")                                                  \
21927 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21928 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21929 _(ioam_disable, "")                                                     \
21930 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21931                             " sw_if_index <sw_if_index> p <priority> "  \
21932                             "w <weight>] [del]")                        \
21933 _(one_add_del_locator, "locator-set <locator_name> "                    \
21934                         "iface <intf> | sw_if_index <sw_if_index> "     \
21935                         "p <priority> w <weight> [del]")                \
21936 _(one_add_del_local_eid,"vni <vni> eid "                                \
21937                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21938                          "locator-set <locator_name> [del]"             \
21939                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21940 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21941 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21942 _(one_enable_disable, "enable|disable")                                 \
21943 _(one_map_register_enable_disable, "enable|disable")                    \
21944 _(one_map_register_fallback_threshold, "<value>")                       \
21945 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21946 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21947                                "[seid <seid>] "                         \
21948                                "rloc <locator> p <prio> "               \
21949                                "w <weight> [rloc <loc> ... ] "          \
21950                                "action <action> [del-all]")             \
21951 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21952                           "<local-eid>")                                \
21953 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21954 _(one_use_petr, "ip-address> | disable")                                \
21955 _(one_map_request_mode, "src-dst|dst-only")                             \
21956 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21957 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21958 _(one_locator_set_dump, "[local | remote]")                             \
21959 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21960 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21961                        "[local] | [remote]")                            \
21962 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21963 _(one_ndp_bd_get, "")                                                   \
21964 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21965 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21966 _(one_l2_arp_bd_get, "")                                                \
21967 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21968 _(one_stats_enable_disable, "enable|disable")                           \
21969 _(show_one_stats_enable_disable, "")                                    \
21970 _(one_eid_table_vni_dump, "")                                           \
21971 _(one_eid_table_map_dump, "l2|l3")                                      \
21972 _(one_map_resolver_dump, "")                                            \
21973 _(one_map_server_dump, "")                                              \
21974 _(one_adjacencies_get, "vni <vni>")                                     \
21975 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21976 _(show_one_rloc_probe_state, "")                                        \
21977 _(show_one_map_register_state, "")                                      \
21978 _(show_one_status, "")                                                  \
21979 _(one_stats_dump, "")                                                   \
21980 _(one_stats_flush, "")                                                  \
21981 _(one_get_map_request_itr_rlocs, "")                                    \
21982 _(one_map_register_set_ttl, "<ttl>")                                    \
21983 _(one_set_transport_protocol, "udp|api")                                \
21984 _(one_get_transport_protocol, "")                                       \
21985 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21986 _(one_show_xtr_mode, "")                                                \
21987 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21988 _(one_show_pitr_mode, "")                                               \
21989 _(one_enable_disable_petr_mode, "enable|disable")                       \
21990 _(one_show_petr_mode, "")                                               \
21991 _(show_one_nsh_mapping, "")                                             \
21992 _(show_one_pitr, "")                                                    \
21993 _(show_one_use_petr, "")                                                \
21994 _(show_one_map_request_mode, "")                                        \
21995 _(show_one_map_register_ttl, "")                                        \
21996 _(show_one_map_register_fallback_threshold, "")                         \
21997 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21998                             " sw_if_index <sw_if_index> p <priority> "  \
21999                             "w <weight>] [del]")                        \
22000 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22001                         "iface <intf> | sw_if_index <sw_if_index> "     \
22002                         "p <priority> w <weight> [del]")                \
22003 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22004                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22005                          "locator-set <locator_name> [del]"             \
22006                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22007 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22008 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22009 _(lisp_enable_disable, "enable|disable")                                \
22010 _(lisp_map_register_enable_disable, "enable|disable")                   \
22011 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22012 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22013                                "[seid <seid>] "                         \
22014                                "rloc <locator> p <prio> "               \
22015                                "w <weight> [rloc <loc> ... ] "          \
22016                                "action <action> [del-all]")             \
22017 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22018                           "<local-eid>")                                \
22019 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22020 _(lisp_use_petr, "<ip-address> | disable")                              \
22021 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22022 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22023 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22024 _(lisp_locator_set_dump, "[local | remote]")                            \
22025 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22026 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22027                        "[local] | [remote]")                            \
22028 _(lisp_eid_table_vni_dump, "")                                          \
22029 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22030 _(lisp_map_resolver_dump, "")                                           \
22031 _(lisp_map_server_dump, "")                                             \
22032 _(lisp_adjacencies_get, "vni <vni>")                                    \
22033 _(gpe_fwd_entry_vnis_get, "")                                           \
22034 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22035 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22036                                 "[table <table-id>]")                   \
22037 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22038 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22039 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22040 _(gpe_get_encap_mode, "")                                               \
22041 _(lisp_gpe_add_del_iface, "up|down")                                    \
22042 _(lisp_gpe_enable_disable, "enable|disable")                            \
22043 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22044   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22045 _(show_lisp_rloc_probe_state, "")                                       \
22046 _(show_lisp_map_register_state, "")                                     \
22047 _(show_lisp_status, "")                                                 \
22048 _(lisp_get_map_request_itr_rlocs, "")                                   \
22049 _(show_lisp_pitr, "")                                                   \
22050 _(show_lisp_use_petr, "")                                               \
22051 _(show_lisp_map_request_mode, "")                                       \
22052 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22053 _(af_packet_delete, "name <host interface name>")                       \
22054 _(af_packet_dump, "")                                                   \
22055 _(policer_add_del, "name <policer name> <params> [del]")                \
22056 _(policer_dump, "[name <policer name>]")                                \
22057 _(policer_classify_set_interface,                                       \
22058   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22059   "  [l2-table <nn>] [del]")                                            \
22060 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22061 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22062     "[master|slave]")                                                   \
22063 _(netmap_delete, "name <interface name>")                               \
22064 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22065 _(mpls_table_dump, "")                                                  \
22066 _(mpls_route_dump, "table-id <ID>")                                     \
22067 _(classify_table_ids, "")                                               \
22068 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22069 _(classify_table_info, "table_id <nn>")                                 \
22070 _(classify_session_dump, "table_id <nn>")                               \
22071 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22072     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22073     "[template_interval <nn>] [udp_checksum]")                          \
22074 _(ipfix_exporter_dump, "")                                              \
22075 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22076 _(ipfix_classify_stream_dump, "")                                       \
22077 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22078 _(ipfix_classify_table_dump, "")                                        \
22079 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22080 _(sw_interface_span_dump, "[l2]")                                           \
22081 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22082 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22083 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22084 _(pg_enable_disable, "[stream <id>] disable")                           \
22085 _(ip_source_and_port_range_check_add_del,                               \
22086   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22087 _(ip_source_and_port_range_check_interface_add_del,                     \
22088   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22089   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22090 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22091 _(l2_interface_pbb_tag_rewrite,                                         \
22092   "<intfc> | sw_if_index <nn> \n"                                       \
22093   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22094   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22095 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22096 _(flow_classify_set_interface,                                          \
22097   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22098 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22099 _(ip_table_dump, "")                                                    \
22100 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22101 _(ip_mtable_dump, "")                                                   \
22102 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22103 _(feature_enable_disable, "arc_name <arc_name> "                        \
22104   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22105 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22106 "[disable]")                                                            \
22107 _(l2_xconnect_dump, "")                                                 \
22108 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22109 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22110 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22111 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22112 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22113 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22114 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22115   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22116 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22117 _(sock_init_shm, "size <nnn>")                                          \
22118 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22119 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22120   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22121 _(session_rules_dump, "")                                               \
22122 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22123 _(output_acl_set_interface,                                             \
22124   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22125   "  [l2-table <nn>] [del]")                                            \
22126 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22127
22128 /* List of command functions, CLI names map directly to functions */
22129 #define foreach_cli_function                                    \
22130 _(comment, "usage: comment <ignore-rest-of-line>")              \
22131 _(dump_interface_table, "usage: dump_interface_table")          \
22132 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22133 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22134 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22135 _(dump_macro_table, "usage: dump_macro_table ")                 \
22136 _(dump_node_table, "usage: dump_node_table")                    \
22137 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22138 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22139 _(elog_disable, "usage: elog_disable")                          \
22140 _(elog_enable, "usage: elog_enable")                            \
22141 _(elog_save, "usage: elog_save <filename>")                     \
22142 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22143 _(echo, "usage: echo <message>")                                \
22144 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22145 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22146 _(help, "usage: help")                                          \
22147 _(q, "usage: quit")                                             \
22148 _(quit, "usage: quit")                                          \
22149 _(search_node_table, "usage: search_node_table <name>...")      \
22150 _(set, "usage: set <variable-name> <value>")                    \
22151 _(script, "usage: script <file-name>")                          \
22152 _(statseg, "usage: statseg")                                    \
22153 _(unset, "usage: unset <variable-name>")
22154
22155 #define _(N,n)                                  \
22156     static void vl_api_##n##_t_handler_uni      \
22157     (vl_api_##n##_t * mp)                       \
22158     {                                           \
22159         vat_main_t * vam = &vat_main;           \
22160         if (vam->json_output) {                 \
22161             vl_api_##n##_t_handler_json(mp);    \
22162         } else {                                \
22163             vl_api_##n##_t_handler(mp);         \
22164         }                                       \
22165     }
22166 foreach_vpe_api_reply_msg;
22167 #if VPP_API_TEST_BUILTIN == 0
22168 foreach_standalone_reply_msg;
22169 #endif
22170 #undef _
22171
22172 void
22173 vat_api_hookup (vat_main_t * vam)
22174 {
22175 #define _(N,n)                                                  \
22176     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22177                            vl_api_##n##_t_handler_uni,          \
22178                            vl_noop_handler,                     \
22179                            vl_api_##n##_t_endian,               \
22180                            vl_api_##n##_t_print,                \
22181                            sizeof(vl_api_##n##_t), 1);
22182   foreach_vpe_api_reply_msg;
22183 #if VPP_API_TEST_BUILTIN == 0
22184   foreach_standalone_reply_msg;
22185 #endif
22186 #undef _
22187
22188 #if (VPP_API_TEST_BUILTIN==0)
22189   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22190
22191   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22192
22193   vam->function_by_name = hash_create_string (0, sizeof (uword));
22194
22195   vam->help_by_name = hash_create_string (0, sizeof (uword));
22196 #endif
22197
22198   /* API messages we can send */
22199 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22200   foreach_vpe_api_msg;
22201 #undef _
22202
22203   /* Help strings */
22204 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22205   foreach_vpe_api_msg;
22206 #undef _
22207
22208   /* CLI functions */
22209 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22210   foreach_cli_function;
22211 #undef _
22212
22213   /* Help strings */
22214 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22215   foreach_cli_function;
22216 #undef _
22217 }
22218
22219 #if VPP_API_TEST_BUILTIN
22220 static clib_error_t *
22221 vat_api_hookup_shim (vlib_main_t * vm)
22222 {
22223   vat_api_hookup (&vat_main);
22224   return 0;
22225 }
22226
22227 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22228 #endif
22229
22230 /*
22231  * fd.io coding-style-patch-verification: ON
22232  *
22233  * Local Variables:
22234  * eval: (c-set-style "gnu")
22235  * End:
22236  */