dns: make the dns name resolver a plugin
[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",
978                   vl_api_from_api_string (&mp->interface_name), 0);
979
980   hash_set_mem (vam->sw_if_index_by_interface_name, s,
981                 ntohl (mp->sw_if_index));
982
983   /* In sub interface case, fill the sub interface table entry */
984   if (mp->sw_if_index != mp->sup_sw_if_index)
985     {
986       sw_interface_subif_t *sub = NULL;
987
988       vec_add2 (vam->sw_if_subif_table, sub, 1);
989
990       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
991       strncpy ((char *) sub->interface_name, (char *) s,
992                vec_len (sub->interface_name));
993       sub->sw_if_index = ntohl (mp->sw_if_index);
994       sub->sub_id = ntohl (mp->sub_id);
995
996       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
997
998       sub->sub_number_of_tags = mp->sub_number_of_tags;
999       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1000       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1001
1002       /* vlan tag rewrite */
1003       sub->vtr_op = ntohl (mp->vtr_op);
1004       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1005       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1006       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1007     }
1008 }
1009
1010 static void vl_api_sw_interface_details_t_handler_json
1011   (vl_api_sw_interface_details_t * mp)
1012 {
1013   vat_main_t *vam = &vat_main;
1014   vat_json_node_t *node = NULL;
1015
1016   if (VAT_JSON_ARRAY != vam->json_tree.type)
1017     {
1018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1019       vat_json_init_array (&vam->json_tree);
1020     }
1021   node = vat_json_array_add (&vam->json_tree);
1022
1023   vat_json_init_object (node);
1024   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1025   vat_json_object_add_uint (node, "sup_sw_if_index",
1026                             ntohl (mp->sup_sw_if_index));
1027   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1028                              sizeof (mp->l2_address));
1029   vat_json_object_add_string_copy (node, "interface_name",
1030                                    mp->interface_name.buf);
1031   vat_json_object_add_uint (node, "flags", mp->flags);
1032   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1033   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1034   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1035   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1036   vat_json_object_add_uint (node, "sub_number_of_tags",
1037                             mp->sub_number_of_tags);
1038   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1039                             ntohs (mp->sub_outer_vlan_id));
1040   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1041                             ntohs (mp->sub_inner_vlan_id));
1042   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1043   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1044   vat_json_object_add_uint (node, "vtr_push_dot1q",
1045                             ntohl (mp->vtr_push_dot1q));
1046   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1047   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1048   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1049     {
1050       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1051                                        format (0, "%U",
1052                                                format_ethernet_address,
1053                                                &mp->b_dmac));
1054       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1055                                        format (0, "%U",
1056                                                format_ethernet_address,
1057                                                &mp->b_smac));
1058       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1059       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1060     }
1061 }
1062
1063 #if VPP_API_TEST_BUILTIN == 0
1064 static void vl_api_sw_interface_event_t_handler
1065   (vl_api_sw_interface_event_t * mp)
1066 {
1067   vat_main_t *vam = &vat_main;
1068   if (vam->interface_event_display)
1069     errmsg ("interface flags: sw_if_index %d %s %s",
1070             ntohl (mp->sw_if_index),
1071             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1072             "admin-up" : "admin-down",
1073             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1074             "link-up" : "link-down");
1075 }
1076 #endif
1077
1078 __clib_unused static void
1079 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1080 {
1081   /* JSON output not supported */
1082 }
1083
1084 static void
1085 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   vam->retval = retval;
1091   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1092   vam->result_ready = 1;
1093 }
1094
1095 static void
1096 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1097 {
1098   vat_main_t *vam = &vat_main;
1099   vat_json_node_t node;
1100   api_main_t *am = &api_main;
1101   void *oldheap;
1102   u8 *reply;
1103
1104   vat_json_init_object (&node);
1105   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1106   vat_json_object_add_uint (&node, "reply_in_shmem",
1107                             ntohl (mp->reply_in_shmem));
1108   /* Toss the shared-memory original... */
1109   pthread_mutex_lock (&am->vlib_rp->mutex);
1110   oldheap = svm_push_data_heap (am->vlib_rp);
1111
1112   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1113   vec_free (reply);
1114
1115   svm_pop_heap (oldheap);
1116   pthread_mutex_unlock (&am->vlib_rp->mutex);
1117
1118   vat_json_print (vam->ofp, &node);
1119   vat_json_free (&node);
1120
1121   vam->retval = ntohl (mp->retval);
1122   vam->result_ready = 1;
1123 }
1124
1125 static void
1126 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1127 {
1128   vat_main_t *vam = &vat_main;
1129   i32 retval = ntohl (mp->retval);
1130   u32 length = vl_api_string_len (&mp->reply);
1131
1132   vec_reset_length (vam->cmd_reply);
1133
1134   vam->retval = retval;
1135   if (retval == 0)
1136     {
1137       vec_validate (vam->cmd_reply, length);
1138       clib_memcpy ((char *) (vam->cmd_reply),
1139                    vl_api_from_api_string (&mp->reply), length);
1140       vam->cmd_reply[length] = 0;
1141     }
1142   vam->result_ready = 1;
1143 }
1144
1145 static void
1146 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vec_reset_length (vam->cmd_reply);
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "reply",
1156                                    vl_api_from_api_string (&mp->reply));
1157
1158   vat_json_print (vam->ofp, &node);
1159   vat_json_free (&node);
1160
1161   vam->retval = ntohl (mp->retval);
1162   vam->result_ready = 1;
1163 }
1164
1165 static void vl_api_classify_add_del_table_reply_t_handler
1166   (vl_api_classify_add_del_table_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   i32 retval = ntohl (mp->retval);
1170   if (vam->async_mode)
1171     {
1172       vam->async_errors += (retval < 0);
1173     }
1174   else
1175     {
1176       vam->retval = retval;
1177       if (retval == 0 &&
1178           ((mp->new_table_index != 0xFFFFFFFF) ||
1179            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1180            (mp->match_n_vectors != 0xFFFFFFFF)))
1181         /*
1182          * Note: this is just barely thread-safe, depends on
1183          * the main thread spinning waiting for an answer...
1184          */
1185         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1186                 ntohl (mp->new_table_index),
1187                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1188       vam->result_ready = 1;
1189     }
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler_json
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   vat_json_node_t node;
1197
1198   vat_json_init_object (&node);
1199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1200   vat_json_object_add_uint (&node, "new_table_index",
1201                             ntohl (mp->new_table_index));
1202   vat_json_object_add_uint (&node, "skip_n_vectors",
1203                             ntohl (mp->skip_n_vectors));
1204   vat_json_object_add_uint (&node, "match_n_vectors",
1205                             ntohl (mp->match_n_vectors));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_node_index_reply_t_handler
1215   (vl_api_get_node_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("node index %d", ntohl (mp->node_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_node_index_reply_t_handler_json
1233   (vl_api_get_node_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_get_next_index_reply_t_handler
1250   (vl_api_get_next_index_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next node index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_get_next_index_reply_t_handler_json
1268   (vl_api_get_next_index_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_add_node_next_reply_t_handler
1285   (vl_api_add_node_next_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289   if (vam->async_mode)
1290     {
1291       vam->async_errors += (retval < 0);
1292     }
1293   else
1294     {
1295       vam->retval = retval;
1296       if (retval == 0)
1297         errmsg ("next index %d", ntohl (mp->next_index));
1298       vam->result_ready = 1;
1299     }
1300 }
1301
1302 static void vl_api_add_node_next_reply_t_handler_json
1303   (vl_api_add_node_next_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   vat_json_node_t node;
1307
1308   vat_json_init_object (&node);
1309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1310   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1311
1312   vat_json_print (vam->ofp, &node);
1313   vat_json_free (&node);
1314
1315   vam->retval = ntohl (mp->retval);
1316   vam->result_ready = 1;
1317 }
1318
1319 static void vl_api_show_version_reply_t_handler
1320   (vl_api_show_version_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   i32 retval = ntohl (mp->retval);
1324
1325   if (retval >= 0)
1326     {
1327       u8 *s = 0;
1328       char *p = (char *) &mp->program;
1329
1330       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1331       errmsg ("        program: %v\n", s);
1332       vec_free (s);
1333
1334       p +=
1335         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1336       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1337       errmsg ("        version: %v\n", s);
1338       vec_free (s);
1339
1340       p +=
1341         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1342       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1343       errmsg ("     build date: %v\n", s);
1344       vec_free (s);
1345
1346       p +=
1347         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1348       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1349       errmsg ("build directory: %v\n", s);
1350       vec_free (s);
1351     }
1352   vam->retval = retval;
1353   vam->result_ready = 1;
1354 }
1355
1356 static void vl_api_show_version_reply_t_handler_json
1357   (vl_api_show_version_reply_t * mp)
1358 {
1359   vat_main_t *vam = &vat_main;
1360   vat_json_node_t node;
1361
1362   vat_json_init_object (&node);
1363   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1364   char *p = (char *) &mp->program;
1365   vat_json_object_add_string_copy (&node, "program",
1366                                    vl_api_from_api_string ((vl_api_string_t *)
1367                                                            p));
1368   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1369   vat_json_object_add_string_copy (&node, "version",
1370                                    vl_api_from_api_string ((vl_api_string_t *)
1371                                                            p));
1372   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1373   vat_json_object_add_string_copy (&node, "build_date",
1374                                    vl_api_from_api_string ((vl_api_string_t *)
1375                                                            p));
1376   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1377   vat_json_object_add_string_copy (&node, "build_directory",
1378                                    vl_api_from_api_string ((vl_api_string_t *)
1379                                                            p));
1380
1381   vat_json_print (vam->ofp, &node);
1382   vat_json_free (&node);
1383
1384   vam->retval = ntohl (mp->retval);
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_show_threads_reply_t_handler
1389   (vl_api_show_threads_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   i32 retval = ntohl (mp->retval);
1393   int i, count = 0;
1394
1395   if (retval >= 0)
1396     count = ntohl (mp->count);
1397
1398   for (i = 0; i < count; i++)
1399     print (vam->ofp,
1400            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1401            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1402            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1403            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1404            ntohl (mp->thread_data[i].cpu_socket));
1405
1406   vam->retval = retval;
1407   vam->result_ready = 1;
1408 }
1409
1410 static void vl_api_show_threads_reply_t_handler_json
1411   (vl_api_show_threads_reply_t * mp)
1412 {
1413   vat_main_t *vam = &vat_main;
1414   vat_json_node_t node;
1415   vl_api_thread_data_t *td;
1416   i32 retval = ntohl (mp->retval);
1417   int i, count = 0;
1418
1419   if (retval >= 0)
1420     count = ntohl (mp->count);
1421
1422   vat_json_init_object (&node);
1423   vat_json_object_add_int (&node, "retval", retval);
1424   vat_json_object_add_uint (&node, "count", count);
1425
1426   for (i = 0; i < count; i++)
1427     {
1428       td = &mp->thread_data[i];
1429       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1430       vat_json_object_add_string_copy (&node, "name", td->name);
1431       vat_json_object_add_string_copy (&node, "type", td->type);
1432       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1433       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1434       vat_json_object_add_int (&node, "core", ntohl (td->id));
1435       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1436     }
1437
1438   vat_json_print (vam->ofp, &node);
1439   vat_json_free (&node);
1440
1441   vam->retval = retval;
1442   vam->result_ready = 1;
1443 }
1444
1445 static int
1446 api_show_threads (vat_main_t * vam)
1447 {
1448   vl_api_show_threads_t *mp;
1449   int ret;
1450
1451   print (vam->ofp,
1452          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1453          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1454
1455   M (SHOW_THREADS, mp);
1456
1457   S (mp);
1458   W (ret);
1459   return ret;
1460 }
1461
1462 static void
1463 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1464 {
1465   u32 sw_if_index = ntohl (mp->sw_if_index);
1466   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1467           mp->mac_ip ? "mac/ip binding" : "address resolution",
1468           ntohl (mp->pid), format_ip4_address, mp->ip,
1469           format_vl_api_mac_address, &mp->mac, sw_if_index);
1470 }
1471
1472 static void
1473 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1474 {
1475   /* JSON output not supported */
1476 }
1477
1478 static void
1479 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1480 {
1481   u32 sw_if_index = ntohl (mp->sw_if_index);
1482   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1483           mp->mac_ip ? "mac/ip binding" : "address resolution",
1484           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1485           format_vl_api_mac_address, mp->mac, sw_if_index);
1486 }
1487
1488 static void
1489 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1490 {
1491   /* JSON output not supported */
1492 }
1493
1494 static void
1495 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1496 {
1497   u32 n_macs = ntohl (mp->n_macs);
1498   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1499           ntohl (mp->pid), mp->client_index, n_macs);
1500   int i;
1501   for (i = 0; i < n_macs; i++)
1502     {
1503       vl_api_mac_entry_t *mac = &mp->mac[i];
1504       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1505               i + 1, ntohl (mac->sw_if_index),
1506               format_ethernet_address, mac->mac_addr, mac->action);
1507       if (i == 1000)
1508         break;
1509     }
1510 }
1511
1512 static void
1513 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1514 {
1515   /* JSON output not supported */
1516 }
1517
1518 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1519 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1520
1521 /*
1522  * Special-case: build the bridge domain table, maintain
1523  * the next bd id vbl.
1524  */
1525 static void vl_api_bridge_domain_details_t_handler
1526   (vl_api_bridge_domain_details_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1530   int i;
1531
1532   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1533          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1534
1535   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1536          ntohl (mp->bd_id), mp->learn, mp->forward,
1537          mp->flood, ntohl (mp->bvi_sw_if_index),
1538          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1539
1540   if (n_sw_ifs)
1541     {
1542       vl_api_bridge_domain_sw_if_t *sw_ifs;
1543       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1544              "Interface Name");
1545
1546       sw_ifs = mp->sw_if_details;
1547       for (i = 0; i < n_sw_ifs; i++)
1548         {
1549           u8 *sw_if_name = 0;
1550           u32 sw_if_index;
1551           hash_pair_t *p;
1552
1553           sw_if_index = ntohl (sw_ifs->sw_if_index);
1554
1555           /* *INDENT-OFF* */
1556           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1557                              ({
1558                                if ((u32) p->value[0] == sw_if_index)
1559                                  {
1560                                    sw_if_name = (u8 *)(p->key);
1561                                    break;
1562                                  }
1563                              }));
1564           /* *INDENT-ON* */
1565           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1566                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1567                  "sw_if_index not found!");
1568
1569           sw_ifs++;
1570         }
1571     }
1572 }
1573
1574 static void vl_api_bridge_domain_details_t_handler_json
1575   (vl_api_bridge_domain_details_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   vat_json_node_t *node, *array = NULL;
1579   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1580
1581   if (VAT_JSON_ARRAY != vam->json_tree.type)
1582     {
1583       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1584       vat_json_init_array (&vam->json_tree);
1585     }
1586   node = vat_json_array_add (&vam->json_tree);
1587
1588   vat_json_init_object (node);
1589   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1590   vat_json_object_add_uint (node, "flood", mp->flood);
1591   vat_json_object_add_uint (node, "forward", mp->forward);
1592   vat_json_object_add_uint (node, "learn", mp->learn);
1593   vat_json_object_add_uint (node, "bvi_sw_if_index",
1594                             ntohl (mp->bvi_sw_if_index));
1595   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1596   array = vat_json_object_add (node, "sw_if");
1597   vat_json_init_array (array);
1598
1599
1600
1601   if (n_sw_ifs)
1602     {
1603       vl_api_bridge_domain_sw_if_t *sw_ifs;
1604       int i;
1605
1606       sw_ifs = mp->sw_if_details;
1607       for (i = 0; i < n_sw_ifs; i++)
1608         {
1609           node = vat_json_array_add (array);
1610           vat_json_init_object (node);
1611           vat_json_object_add_uint (node, "sw_if_index",
1612                                     ntohl (sw_ifs->sw_if_index));
1613           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1614           sw_ifs++;
1615         }
1616     }
1617 }
1618
1619 static void vl_api_control_ping_reply_t_handler
1620   (vl_api_control_ping_reply_t * mp)
1621 {
1622   vat_main_t *vam = &vat_main;
1623   i32 retval = ntohl (mp->retval);
1624   if (vam->async_mode)
1625     {
1626       vam->async_errors += (retval < 0);
1627     }
1628   else
1629     {
1630       vam->retval = retval;
1631       vam->result_ready = 1;
1632     }
1633   if (vam->socket_client_main)
1634     vam->socket_client_main->control_pings_outstanding--;
1635 }
1636
1637 static void vl_api_control_ping_reply_t_handler_json
1638   (vl_api_control_ping_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642
1643   if (VAT_JSON_NONE != vam->json_tree.type)
1644     {
1645       vat_json_print (vam->ofp, &vam->json_tree);
1646       vat_json_free (&vam->json_tree);
1647       vam->json_tree.type = VAT_JSON_NONE;
1648     }
1649   else
1650     {
1651       /* just print [] */
1652       vat_json_init_array (&vam->json_tree);
1653       vat_json_print (vam->ofp, &vam->json_tree);
1654       vam->json_tree.type = VAT_JSON_NONE;
1655     }
1656
1657   vam->retval = retval;
1658   vam->result_ready = 1;
1659 }
1660
1661 static void
1662   vl_api_bridge_domain_set_mac_age_reply_t_handler
1663   (vl_api_bridge_domain_set_mac_age_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_bridge_domain_set_mac_age_reply_t_handler_json
1679   (vl_api_bridge_domain_set_mac_age_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
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void
1695 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   i32 retval = ntohl (mp->retval);
1699   if (vam->async_mode)
1700     {
1701       vam->async_errors += (retval < 0);
1702     }
1703   else
1704     {
1705       vam->retval = retval;
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_l2_flags_reply_t_handler_json
1711   (vl_api_l2_flags_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1719                             ntohl (mp->resulting_feature_bitmap));
1720
1721   vat_json_print (vam->ofp, &node);
1722   vat_json_free (&node);
1723
1724   vam->retval = ntohl (mp->retval);
1725   vam->result_ready = 1;
1726 }
1727
1728 static void vl_api_bridge_flags_reply_t_handler
1729   (vl_api_bridge_flags_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   i32 retval = ntohl (mp->retval);
1733   if (vam->async_mode)
1734     {
1735       vam->async_errors += (retval < 0);
1736     }
1737   else
1738     {
1739       vam->retval = retval;
1740       vam->result_ready = 1;
1741     }
1742 }
1743
1744 static void vl_api_bridge_flags_reply_t_handler_json
1745   (vl_api_bridge_flags_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1753                             ntohl (mp->resulting_feature_bitmap));
1754
1755   vat_json_print (vam->ofp, &node);
1756   vat_json_free (&node);
1757
1758   vam->retval = ntohl (mp->retval);
1759   vam->result_ready = 1;
1760 }
1761
1762 static void
1763 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   i32 retval = ntohl (mp->retval);
1767   if (vam->async_mode)
1768     {
1769       vam->async_errors += (retval < 0);
1770     }
1771   else
1772     {
1773       vam->retval = retval;
1774       vam->sw_if_index = ntohl (mp->sw_if_index);
1775       vam->result_ready = 1;
1776     }
1777
1778 }
1779
1780 static void vl_api_tap_create_v2_reply_t_handler_json
1781   (vl_api_tap_create_v2_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1789
1790   vat_json_print (vam->ofp, &node);
1791   vat_json_free (&node);
1792
1793   vam->retval = ntohl (mp->retval);
1794   vam->result_ready = 1;
1795
1796 }
1797
1798 static void
1799 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->result_ready = 1;
1811     }
1812 }
1813
1814 static void vl_api_tap_delete_v2_reply_t_handler_json
1815   (vl_api_tap_delete_v2_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   vat_json_node_t node;
1819
1820   vat_json_init_object (&node);
1821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1822
1823   vat_json_print (vam->ofp, &node);
1824   vat_json_free (&node);
1825
1826   vam->retval = ntohl (mp->retval);
1827   vam->result_ready = 1;
1828 }
1829
1830 static void
1831 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1832                                           mp)
1833 {
1834   vat_main_t *vam = &vat_main;
1835   i32 retval = ntohl (mp->retval);
1836   if (vam->async_mode)
1837     {
1838       vam->async_errors += (retval < 0);
1839     }
1840   else
1841     {
1842       vam->retval = retval;
1843       vam->sw_if_index = ntohl (mp->sw_if_index);
1844       vam->result_ready = 1;
1845     }
1846 }
1847
1848 static void vl_api_virtio_pci_create_reply_t_handler_json
1849   (vl_api_virtio_pci_create_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   vat_json_node_t node;
1853
1854   vat_json_init_object (&node);
1855   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1856   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1857
1858   vat_json_print (vam->ofp, &node);
1859   vat_json_free (&node);
1860
1861   vam->retval = ntohl (mp->retval);
1862   vam->result_ready = 1;
1863
1864 }
1865
1866 static void
1867 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1868                                           mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   i32 retval = ntohl (mp->retval);
1872   if (vam->async_mode)
1873     {
1874       vam->async_errors += (retval < 0);
1875     }
1876   else
1877     {
1878       vam->retval = retval;
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_virtio_pci_delete_reply_t_handler_json
1884   (vl_api_virtio_pci_delete_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891
1892   vat_json_print (vam->ofp, &node);
1893   vat_json_free (&node);
1894
1895   vam->retval = ntohl (mp->retval);
1896   vam->result_ready = 1;
1897 }
1898
1899 static void
1900 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   i32 retval = ntohl (mp->retval);
1904
1905   if (vam->async_mode)
1906     {
1907       vam->async_errors += (retval < 0);
1908     }
1909   else
1910     {
1911       vam->retval = retval;
1912       vam->sw_if_index = ntohl (mp->sw_if_index);
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_create_reply_t_handler_json
1918   (vl_api_bond_create_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922
1923   vat_json_init_object (&node);
1924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1926
1927   vat_json_print (vam->ofp, &node);
1928   vat_json_free (&node);
1929
1930   vam->retval = ntohl (mp->retval);
1931   vam->result_ready = 1;
1932 }
1933
1934 static void
1935 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1936 {
1937   vat_main_t *vam = &vat_main;
1938   i32 retval = ntohl (mp->retval);
1939
1940   if (vam->async_mode)
1941     {
1942       vam->async_errors += (retval < 0);
1943     }
1944   else
1945     {
1946       vam->retval = retval;
1947       vam->result_ready = 1;
1948     }
1949 }
1950
1951 static void vl_api_bond_delete_reply_t_handler_json
1952   (vl_api_bond_delete_reply_t * mp)
1953 {
1954   vat_main_t *vam = &vat_main;
1955   vat_json_node_t node;
1956
1957   vat_json_init_object (&node);
1958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1959
1960   vat_json_print (vam->ofp, &node);
1961   vat_json_free (&node);
1962
1963   vam->retval = ntohl (mp->retval);
1964   vam->result_ready = 1;
1965 }
1966
1967 static void
1968 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   i32 retval = ntohl (mp->retval);
1972
1973   if (vam->async_mode)
1974     {
1975       vam->async_errors += (retval < 0);
1976     }
1977   else
1978     {
1979       vam->retval = retval;
1980       vam->result_ready = 1;
1981     }
1982 }
1983
1984 static void vl_api_bond_enslave_reply_t_handler_json
1985   (vl_api_bond_enslave_reply_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t node;
1989
1990   vat_json_init_object (&node);
1991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993   vat_json_print (vam->ofp, &node);
1994   vat_json_free (&node);
1995
1996   vam->retval = ntohl (mp->retval);
1997   vam->result_ready = 1;
1998 }
1999
2000 static void
2001 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2002                                           mp)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   i32 retval = ntohl (mp->retval);
2006
2007   if (vam->async_mode)
2008     {
2009       vam->async_errors += (retval < 0);
2010     }
2011   else
2012     {
2013       vam->retval = retval;
2014       vam->result_ready = 1;
2015     }
2016 }
2017
2018 static void vl_api_bond_detach_slave_reply_t_handler_json
2019   (vl_api_bond_detach_slave_reply_t * mp)
2020 {
2021   vat_main_t *vam = &vat_main;
2022   vat_json_node_t node;
2023
2024   vat_json_init_object (&node);
2025   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2026
2027   vat_json_print (vam->ofp, &node);
2028   vat_json_free (&node);
2029
2030   vam->retval = ntohl (mp->retval);
2031   vam->result_ready = 1;
2032 }
2033
2034 static void vl_api_sw_interface_bond_details_t_handler
2035   (vl_api_sw_interface_bond_details_t * mp)
2036 {
2037   vat_main_t *vam = &vat_main;
2038
2039   print (vam->ofp,
2040          "%-16s %-12d %-12U %-13U %-14u %-14u",
2041          mp->interface_name, ntohl (mp->sw_if_index),
2042          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2043          ntohl (mp->active_slaves), ntohl (mp->slaves));
2044 }
2045
2046 static void vl_api_sw_interface_bond_details_t_handler_json
2047   (vl_api_sw_interface_bond_details_t * mp)
2048 {
2049   vat_main_t *vam = &vat_main;
2050   vat_json_node_t *node = NULL;
2051
2052   if (VAT_JSON_ARRAY != vam->json_tree.type)
2053     {
2054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2055       vat_json_init_array (&vam->json_tree);
2056     }
2057   node = vat_json_array_add (&vam->json_tree);
2058
2059   vat_json_init_object (node);
2060   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2061   vat_json_object_add_string_copy (node, "interface_name",
2062                                    mp->interface_name);
2063   vat_json_object_add_uint (node, "mode", mp->mode);
2064   vat_json_object_add_uint (node, "load_balance", mp->lb);
2065   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2066   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2067 }
2068
2069 static int
2070 api_sw_interface_bond_dump (vat_main_t * vam)
2071 {
2072   vl_api_sw_interface_bond_dump_t *mp;
2073   vl_api_control_ping_t *mp_ping;
2074   int ret;
2075
2076   print (vam->ofp,
2077          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2078          "interface name", "sw_if_index", "mode", "load balance",
2079          "active slaves", "slaves");
2080
2081   /* Get list of bond interfaces */
2082   M (SW_INTERFACE_BOND_DUMP, mp);
2083   S (mp);
2084
2085   /* Use a control ping for synchronization */
2086   MPING (CONTROL_PING, mp_ping);
2087   S (mp_ping);
2088
2089   W (ret);
2090   return ret;
2091 }
2092
2093 static void vl_api_sw_interface_slave_details_t_handler
2094   (vl_api_sw_interface_slave_details_t * mp)
2095 {
2096   vat_main_t *vam = &vat_main;
2097
2098   print (vam->ofp,
2099          "%-25s %-12d %-12d %d", mp->interface_name,
2100          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2101 }
2102
2103 static void vl_api_sw_interface_slave_details_t_handler_json
2104   (vl_api_sw_interface_slave_details_t * mp)
2105 {
2106   vat_main_t *vam = &vat_main;
2107   vat_json_node_t *node = NULL;
2108
2109   if (VAT_JSON_ARRAY != vam->json_tree.type)
2110     {
2111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2112       vat_json_init_array (&vam->json_tree);
2113     }
2114   node = vat_json_array_add (&vam->json_tree);
2115
2116   vat_json_init_object (node);
2117   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2118   vat_json_object_add_string_copy (node, "interface_name",
2119                                    mp->interface_name);
2120   vat_json_object_add_uint (node, "passive", mp->is_passive);
2121   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2122 }
2123
2124 static int
2125 api_sw_interface_slave_dump (vat_main_t * vam)
2126 {
2127   unformat_input_t *i = vam->input;
2128   vl_api_sw_interface_slave_dump_t *mp;
2129   vl_api_control_ping_t *mp_ping;
2130   u32 sw_if_index = ~0;
2131   u8 sw_if_index_set = 0;
2132   int ret;
2133
2134   /* Parse args required to build the message */
2135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2136     {
2137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2138         sw_if_index_set = 1;
2139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2140         sw_if_index_set = 1;
2141       else
2142         break;
2143     }
2144
2145   if (sw_if_index_set == 0)
2146     {
2147       errmsg ("missing vpp interface name. ");
2148       return -99;
2149     }
2150
2151   print (vam->ofp,
2152          "\n%-25s %-12s %-12s %s",
2153          "slave interface name", "sw_if_index", "passive", "long_timeout");
2154
2155   /* Get list of bond interfaces */
2156   M (SW_INTERFACE_SLAVE_DUMP, mp);
2157   mp->sw_if_index = ntohl (sw_if_index);
2158   S (mp);
2159
2160   /* Use a control ping for synchronization */
2161   MPING (CONTROL_PING, mp_ping);
2162   S (mp_ping);
2163
2164   W (ret);
2165   return ret;
2166 }
2167
2168 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2169   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2170 {
2171   vat_main_t *vam = &vat_main;
2172   i32 retval = ntohl (mp->retval);
2173   if (vam->async_mode)
2174     {
2175       vam->async_errors += (retval < 0);
2176     }
2177   else
2178     {
2179       vam->retval = retval;
2180       vam->sw_if_index = ntohl (mp->sw_if_index);
2181       vam->result_ready = 1;
2182     }
2183   vam->regenerate_interface_table = 1;
2184 }
2185
2186 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2187   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2188 {
2189   vat_main_t *vam = &vat_main;
2190   vat_json_node_t node;
2191
2192   vat_json_init_object (&node);
2193   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2194   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2195                             ntohl (mp->sw_if_index));
2196
2197   vat_json_print (vam->ofp, &node);
2198   vat_json_free (&node);
2199
2200   vam->retval = ntohl (mp->retval);
2201   vam->result_ready = 1;
2202 }
2203
2204 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2205   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2206 {
2207   vat_main_t *vam = &vat_main;
2208   i32 retval = ntohl (mp->retval);
2209   if (vam->async_mode)
2210     {
2211       vam->async_errors += (retval < 0);
2212     }
2213   else
2214     {
2215       vam->retval = retval;
2216       vam->sw_if_index = ntohl (mp->sw_if_index);
2217       vam->result_ready = 1;
2218     }
2219 }
2220
2221 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2222   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2223 {
2224   vat_main_t *vam = &vat_main;
2225   vat_json_node_t node;
2226
2227   vat_json_init_object (&node);
2228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2229   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2230
2231   vat_json_print (vam->ofp, &node);
2232   vat_json_free (&node);
2233
2234   vam->retval = ntohl (mp->retval);
2235   vam->result_ready = 1;
2236 }
2237
2238 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2239   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   i32 retval = ntohl (mp->retval);
2243   if (vam->async_mode)
2244     {
2245       vam->async_errors += (retval < 0);
2246     }
2247   else
2248     {
2249       vam->retval = retval;
2250       vam->result_ready = 1;
2251     }
2252 }
2253
2254 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2255   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   vat_json_node_t node;
2259
2260   vat_json_init_object (&node);
2261   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2262   vat_json_object_add_uint (&node, "fwd_entry_index",
2263                             clib_net_to_host_u32 (mp->fwd_entry_index));
2264
2265   vat_json_print (vam->ofp, &node);
2266   vat_json_free (&node);
2267
2268   vam->retval = ntohl (mp->retval);
2269   vam->result_ready = 1;
2270 }
2271
2272 u8 *
2273 format_lisp_transport_protocol (u8 * s, va_list * args)
2274 {
2275   u32 proto = va_arg (*args, u32);
2276
2277   switch (proto)
2278     {
2279     case 1:
2280       return format (s, "udp");
2281     case 2:
2282       return format (s, "api");
2283     default:
2284       return 0;
2285     }
2286   return 0;
2287 }
2288
2289 static void vl_api_one_get_transport_protocol_reply_t_handler
2290   (vl_api_one_get_transport_protocol_reply_t * mp)
2291 {
2292   vat_main_t *vam = &vat_main;
2293   i32 retval = ntohl (mp->retval);
2294   if (vam->async_mode)
2295     {
2296       vam->async_errors += (retval < 0);
2297     }
2298   else
2299     {
2300       u32 proto = mp->protocol;
2301       print (vam->ofp, "Transport protocol: %U",
2302              format_lisp_transport_protocol, proto);
2303       vam->retval = retval;
2304       vam->result_ready = 1;
2305     }
2306 }
2307
2308 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2309   (vl_api_one_get_transport_protocol_reply_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   vat_json_node_t node;
2313   u8 *s;
2314
2315   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2316   vec_add1 (s, 0);
2317
2318   vat_json_init_object (&node);
2319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2320   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2321
2322   vec_free (s);
2323   vat_json_print (vam->ofp, &node);
2324   vat_json_free (&node);
2325
2326   vam->retval = ntohl (mp->retval);
2327   vam->result_ready = 1;
2328 }
2329
2330 static void vl_api_one_add_del_locator_set_reply_t_handler
2331   (vl_api_one_add_del_locator_set_reply_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   i32 retval = ntohl (mp->retval);
2335   if (vam->async_mode)
2336     {
2337       vam->async_errors += (retval < 0);
2338     }
2339   else
2340     {
2341       vam->retval = retval;
2342       vam->result_ready = 1;
2343     }
2344 }
2345
2346 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2347   (vl_api_one_add_del_locator_set_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   vat_json_node_t node;
2351
2352   vat_json_init_object (&node);
2353   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2354   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2355
2356   vat_json_print (vam->ofp, &node);
2357   vat_json_free (&node);
2358
2359   vam->retval = ntohl (mp->retval);
2360   vam->result_ready = 1;
2361 }
2362
2363 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2364   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   i32 retval = ntohl (mp->retval);
2368   if (vam->async_mode)
2369     {
2370       vam->async_errors += (retval < 0);
2371     }
2372   else
2373     {
2374       vam->retval = retval;
2375       vam->sw_if_index = ntohl (mp->sw_if_index);
2376       vam->result_ready = 1;
2377     }
2378   vam->regenerate_interface_table = 1;
2379 }
2380
2381 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2382   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   vat_json_node_t node;
2386
2387   vat_json_init_object (&node);
2388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2389   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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_vxlan_offload_rx_reply_t_handler
2399   (vl_api_vxlan_offload_rx_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->result_ready = 1;
2411     }
2412 }
2413
2414 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2415   (vl_api_vxlan_offload_rx_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   vat_json_node_t node;
2419
2420   vat_json_init_object (&node);
2421   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2422
2423   vat_json_print (vam->ofp, &node);
2424   vat_json_free (&node);
2425
2426   vam->retval = ntohl (mp->retval);
2427   vam->result_ready = 1;
2428 }
2429
2430 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2431   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2432 {
2433   vat_main_t *vam = &vat_main;
2434   i32 retval = ntohl (mp->retval);
2435   if (vam->async_mode)
2436     {
2437       vam->async_errors += (retval < 0);
2438     }
2439   else
2440     {
2441       vam->retval = retval;
2442       vam->sw_if_index = ntohl (mp->sw_if_index);
2443       vam->result_ready = 1;
2444     }
2445 }
2446
2447 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2448   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451   vat_json_node_t node;
2452
2453   vat_json_init_object (&node);
2454   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2455   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2456
2457   vat_json_print (vam->ofp, &node);
2458   vat_json_free (&node);
2459
2460   vam->retval = ntohl (mp->retval);
2461   vam->result_ready = 1;
2462 }
2463
2464 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2465   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2466 {
2467   vat_main_t *vam = &vat_main;
2468   i32 retval = ntohl (mp->retval);
2469   if (vam->async_mode)
2470     {
2471       vam->async_errors += (retval < 0);
2472     }
2473   else
2474     {
2475       vam->retval = retval;
2476       vam->sw_if_index = ntohl (mp->sw_if_index);
2477       vam->result_ready = 1;
2478     }
2479   vam->regenerate_interface_table = 1;
2480 }
2481
2482 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2483   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2484 {
2485   vat_main_t *vam = &vat_main;
2486   vat_json_node_t node;
2487
2488   vat_json_init_object (&node);
2489   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2490   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2491
2492   vat_json_print (vam->ofp, &node);
2493   vat_json_free (&node);
2494
2495   vam->retval = ntohl (mp->retval);
2496   vam->result_ready = 1;
2497 }
2498
2499 static void vl_api_gre_tunnel_add_del_reply_t_handler
2500   (vl_api_gre_tunnel_add_del_reply_t * mp)
2501 {
2502   vat_main_t *vam = &vat_main;
2503   i32 retval = ntohl (mp->retval);
2504   if (vam->async_mode)
2505     {
2506       vam->async_errors += (retval < 0);
2507     }
2508   else
2509     {
2510       vam->retval = retval;
2511       vam->sw_if_index = ntohl (mp->sw_if_index);
2512       vam->result_ready = 1;
2513     }
2514 }
2515
2516 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2517   (vl_api_gre_tunnel_add_del_reply_t * mp)
2518 {
2519   vat_main_t *vam = &vat_main;
2520   vat_json_node_t node;
2521
2522   vat_json_init_object (&node);
2523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2524   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2525
2526   vat_json_print (vam->ofp, &node);
2527   vat_json_free (&node);
2528
2529   vam->retval = ntohl (mp->retval);
2530   vam->result_ready = 1;
2531 }
2532
2533 static void vl_api_create_vhost_user_if_reply_t_handler
2534   (vl_api_create_vhost_user_if_reply_t * mp)
2535 {
2536   vat_main_t *vam = &vat_main;
2537   i32 retval = ntohl (mp->retval);
2538   if (vam->async_mode)
2539     {
2540       vam->async_errors += (retval < 0);
2541     }
2542   else
2543     {
2544       vam->retval = retval;
2545       vam->sw_if_index = ntohl (mp->sw_if_index);
2546       vam->result_ready = 1;
2547     }
2548   vam->regenerate_interface_table = 1;
2549 }
2550
2551 static void vl_api_create_vhost_user_if_reply_t_handler_json
2552   (vl_api_create_vhost_user_if_reply_t * mp)
2553 {
2554   vat_main_t *vam = &vat_main;
2555   vat_json_node_t node;
2556
2557   vat_json_init_object (&node);
2558   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2559   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2560
2561   vat_json_print (vam->ofp, &node);
2562   vat_json_free (&node);
2563
2564   vam->retval = ntohl (mp->retval);
2565   vam->result_ready = 1;
2566 }
2567
2568 static void vl_api_ip_address_details_t_handler
2569   (vl_api_ip_address_details_t * mp)
2570 {
2571   vat_main_t *vam = &vat_main;
2572   static ip_address_details_t empty_ip_address_details = { {0} };
2573   ip_address_details_t *address = NULL;
2574   ip_details_t *current_ip_details = NULL;
2575   ip_details_t *details = NULL;
2576
2577   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2578
2579   if (!details || vam->current_sw_if_index >= vec_len (details)
2580       || !details[vam->current_sw_if_index].present)
2581     {
2582       errmsg ("ip address details arrived but not stored");
2583       errmsg ("ip_dump should be called first");
2584       return;
2585     }
2586
2587   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2588
2589 #define addresses (current_ip_details->addr)
2590
2591   vec_validate_init_empty (addresses, vec_len (addresses),
2592                            empty_ip_address_details);
2593
2594   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2595
2596   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2597   address->prefix_length = mp->prefix.len;
2598 #undef addresses
2599 }
2600
2601 static void vl_api_ip_address_details_t_handler_json
2602   (vl_api_ip_address_details_t * mp)
2603 {
2604   vat_main_t *vam = &vat_main;
2605   vat_json_node_t *node = NULL;
2606
2607   if (VAT_JSON_ARRAY != vam->json_tree.type)
2608     {
2609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2610       vat_json_init_array (&vam->json_tree);
2611     }
2612   node = vat_json_array_add (&vam->json_tree);
2613
2614   vat_json_init_object (node);
2615   vat_json_object_add_prefix (node, &mp->prefix);
2616 }
2617
2618 static void
2619 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2620 {
2621   vat_main_t *vam = &vat_main;
2622   static ip_details_t empty_ip_details = { 0 };
2623   ip_details_t *ip = NULL;
2624   u32 sw_if_index = ~0;
2625
2626   sw_if_index = ntohl (mp->sw_if_index);
2627
2628   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2629                            sw_if_index, empty_ip_details);
2630
2631   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2632                          sw_if_index);
2633
2634   ip->present = 1;
2635 }
2636
2637 static void
2638 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2639 {
2640   vat_main_t *vam = &vat_main;
2641
2642   if (VAT_JSON_ARRAY != vam->json_tree.type)
2643     {
2644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2645       vat_json_init_array (&vam->json_tree);
2646     }
2647   vat_json_array_add_uint (&vam->json_tree,
2648                            clib_net_to_host_u32 (mp->sw_if_index));
2649 }
2650
2651 static void
2652 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2653 {
2654   u8 *s, i;
2655
2656   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2657               "host_mac %U router_addr %U",
2658               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2659               mp->lease.hostname,
2660               format_ip4_address, mp->lease.host_address,
2661               format_ethernet_address, mp->lease.host_mac,
2662               format_ip4_address, mp->lease.router_address);
2663
2664   for (i = 0; i < mp->lease.count; i++)
2665     s =
2666       format (s, " domain_server_addr %U", format_ip4_address,
2667               mp->lease.domain_server[i].address);
2668
2669   errmsg ((char *) s);
2670   vec_free (s);
2671 }
2672
2673 static void vl_api_dhcp_compl_event_t_handler_json
2674   (vl_api_dhcp_compl_event_t * mp)
2675 {
2676   /* JSON output not supported */
2677 }
2678
2679 static void vl_api_get_first_msg_id_reply_t_handler
2680   (vl_api_get_first_msg_id_reply_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   i32 retval = ntohl (mp->retval);
2684
2685   if (vam->async_mode)
2686     {
2687       vam->async_errors += (retval < 0);
2688     }
2689   else
2690     {
2691       vam->retval = retval;
2692       vam->result_ready = 1;
2693     }
2694   if (retval >= 0)
2695     {
2696       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2697     }
2698 }
2699
2700 static void vl_api_get_first_msg_id_reply_t_handler_json
2701   (vl_api_get_first_msg_id_reply_t * mp)
2702 {
2703   vat_main_t *vam = &vat_main;
2704   vat_json_node_t node;
2705
2706   vat_json_init_object (&node);
2707   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2708   vat_json_object_add_uint (&node, "first_msg_id",
2709                             (uint) ntohs (mp->first_msg_id));
2710
2711   vat_json_print (vam->ofp, &node);
2712   vat_json_free (&node);
2713
2714   vam->retval = ntohl (mp->retval);
2715   vam->result_ready = 1;
2716 }
2717
2718 static void vl_api_get_node_graph_reply_t_handler
2719   (vl_api_get_node_graph_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   api_main_t *am = &api_main;
2723   i32 retval = ntohl (mp->retval);
2724   u8 *pvt_copy, *reply;
2725   void *oldheap;
2726   vlib_node_t *node;
2727   int i;
2728
2729   if (vam->async_mode)
2730     {
2731       vam->async_errors += (retval < 0);
2732     }
2733   else
2734     {
2735       vam->retval = retval;
2736       vam->result_ready = 1;
2737     }
2738
2739   /* "Should never happen..." */
2740   if (retval != 0)
2741     return;
2742
2743   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2744   pvt_copy = vec_dup (reply);
2745
2746   /* Toss the shared-memory original... */
2747   pthread_mutex_lock (&am->vlib_rp->mutex);
2748   oldheap = svm_push_data_heap (am->vlib_rp);
2749
2750   vec_free (reply);
2751
2752   svm_pop_heap (oldheap);
2753   pthread_mutex_unlock (&am->vlib_rp->mutex);
2754
2755   if (vam->graph_nodes)
2756     {
2757       hash_free (vam->graph_node_index_by_name);
2758
2759       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2760         {
2761           node = vam->graph_nodes[0][i];
2762           vec_free (node->name);
2763           vec_free (node->next_nodes);
2764           vec_free (node);
2765         }
2766       vec_free (vam->graph_nodes[0]);
2767       vec_free (vam->graph_nodes);
2768     }
2769
2770   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2771   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2772   vec_free (pvt_copy);
2773
2774   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2775     {
2776       node = vam->graph_nodes[0][i];
2777       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2778     }
2779 }
2780
2781 static void vl_api_get_node_graph_reply_t_handler_json
2782   (vl_api_get_node_graph_reply_t * mp)
2783 {
2784   vat_main_t *vam = &vat_main;
2785   api_main_t *am = &api_main;
2786   void *oldheap;
2787   vat_json_node_t node;
2788   u8 *reply;
2789
2790   /* $$$$ make this real? */
2791   vat_json_init_object (&node);
2792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2793   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2794
2795   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2796
2797   /* Toss the shared-memory original... */
2798   pthread_mutex_lock (&am->vlib_rp->mutex);
2799   oldheap = svm_push_data_heap (am->vlib_rp);
2800
2801   vec_free (reply);
2802
2803   svm_pop_heap (oldheap);
2804   pthread_mutex_unlock (&am->vlib_rp->mutex);
2805
2806   vat_json_print (vam->ofp, &node);
2807   vat_json_free (&node);
2808
2809   vam->retval = ntohl (mp->retval);
2810   vam->result_ready = 1;
2811 }
2812
2813 static void
2814 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2815 {
2816   vat_main_t *vam = &vat_main;
2817   u8 *s = 0;
2818
2819   if (mp->local)
2820     {
2821       s = format (s, "%=16d%=16d%=16d",
2822                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2823     }
2824   else
2825     {
2826       s = format (s, "%=16U%=16d%=16d",
2827                   mp->is_ipv6 ? format_ip6_address :
2828                   format_ip4_address,
2829                   mp->ip_address, mp->priority, mp->weight);
2830     }
2831
2832   print (vam->ofp, "%v", s);
2833   vec_free (s);
2834 }
2835
2836 static void
2837 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2838 {
2839   vat_main_t *vam = &vat_main;
2840   vat_json_node_t *node = NULL;
2841   struct in6_addr ip6;
2842   struct in_addr ip4;
2843
2844   if (VAT_JSON_ARRAY != vam->json_tree.type)
2845     {
2846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2847       vat_json_init_array (&vam->json_tree);
2848     }
2849   node = vat_json_array_add (&vam->json_tree);
2850   vat_json_init_object (node);
2851
2852   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2853   vat_json_object_add_uint (node, "priority", mp->priority);
2854   vat_json_object_add_uint (node, "weight", mp->weight);
2855
2856   if (mp->local)
2857     vat_json_object_add_uint (node, "sw_if_index",
2858                               clib_net_to_host_u32 (mp->sw_if_index));
2859   else
2860     {
2861       if (mp->is_ipv6)
2862         {
2863           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2864           vat_json_object_add_ip6 (node, "address", ip6);
2865         }
2866       else
2867         {
2868           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2869           vat_json_object_add_ip4 (node, "address", ip4);
2870         }
2871     }
2872 }
2873
2874 static void
2875 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2876                                           mp)
2877 {
2878   vat_main_t *vam = &vat_main;
2879   u8 *ls_name = 0;
2880
2881   ls_name = format (0, "%s", mp->ls_name);
2882
2883   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2884          ls_name);
2885   vec_free (ls_name);
2886 }
2887
2888 static void
2889   vl_api_one_locator_set_details_t_handler_json
2890   (vl_api_one_locator_set_details_t * mp)
2891 {
2892   vat_main_t *vam = &vat_main;
2893   vat_json_node_t *node = 0;
2894   u8 *ls_name = 0;
2895
2896   ls_name = format (0, "%s", mp->ls_name);
2897   vec_add1 (ls_name, 0);
2898
2899   if (VAT_JSON_ARRAY != vam->json_tree.type)
2900     {
2901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2902       vat_json_init_array (&vam->json_tree);
2903     }
2904   node = vat_json_array_add (&vam->json_tree);
2905
2906   vat_json_init_object (node);
2907   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2908   vat_json_object_add_uint (node, "ls_index",
2909                             clib_net_to_host_u32 (mp->ls_index));
2910   vec_free (ls_name);
2911 }
2912
2913 typedef struct
2914 {
2915   u32 spi;
2916   u8 si;
2917 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2918
2919 uword
2920 unformat_nsh_address (unformat_input_t * input, va_list * args)
2921 {
2922   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2923   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2924 }
2925
2926 u8 *
2927 format_nsh_address_vat (u8 * s, va_list * args)
2928 {
2929   nsh_t *a = va_arg (*args, nsh_t *);
2930   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2931 }
2932
2933 static u8 *
2934 format_lisp_flat_eid (u8 * s, va_list * args)
2935 {
2936   u32 type = va_arg (*args, u32);
2937   u8 *eid = va_arg (*args, u8 *);
2938   u32 eid_len = va_arg (*args, u32);
2939
2940   switch (type)
2941     {
2942     case 0:
2943       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2944     case 1:
2945       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2946     case 2:
2947       return format (s, "%U", format_ethernet_address, eid);
2948     case 3:
2949       return format (s, "%U", format_nsh_address_vat, eid);
2950     }
2951   return 0;
2952 }
2953
2954 static u8 *
2955 format_lisp_eid_vat (u8 * s, va_list * args)
2956 {
2957   u32 type = va_arg (*args, u32);
2958   u8 *eid = va_arg (*args, u8 *);
2959   u32 eid_len = va_arg (*args, u32);
2960   u8 *seid = va_arg (*args, u8 *);
2961   u32 seid_len = va_arg (*args, u32);
2962   u32 is_src_dst = va_arg (*args, u32);
2963
2964   if (is_src_dst)
2965     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2966
2967   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2968
2969   return s;
2970 }
2971
2972 static void
2973 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2974 {
2975   vat_main_t *vam = &vat_main;
2976   u8 *s = 0, *eid = 0;
2977
2978   if (~0 == mp->locator_set_index)
2979     s = format (0, "action: %d", mp->action);
2980   else
2981     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2982
2983   eid = format (0, "%U", format_lisp_eid_vat,
2984                 mp->eid_type,
2985                 mp->eid,
2986                 mp->eid_prefix_len,
2987                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2988   vec_add1 (eid, 0);
2989
2990   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2991          clib_net_to_host_u32 (mp->vni),
2992          eid,
2993          mp->is_local ? "local" : "remote",
2994          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2995          clib_net_to_host_u16 (mp->key_id), mp->key);
2996
2997   vec_free (s);
2998   vec_free (eid);
2999 }
3000
3001 static void
3002 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3003                                              * mp)
3004 {
3005   vat_main_t *vam = &vat_main;
3006   vat_json_node_t *node = 0;
3007   u8 *eid = 0;
3008
3009   if (VAT_JSON_ARRAY != vam->json_tree.type)
3010     {
3011       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3012       vat_json_init_array (&vam->json_tree);
3013     }
3014   node = vat_json_array_add (&vam->json_tree);
3015
3016   vat_json_init_object (node);
3017   if (~0 == mp->locator_set_index)
3018     vat_json_object_add_uint (node, "action", mp->action);
3019   else
3020     vat_json_object_add_uint (node, "locator_set_index",
3021                               clib_net_to_host_u32 (mp->locator_set_index));
3022
3023   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3024   if (mp->eid_type == 3)
3025     {
3026       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3027       vat_json_init_object (nsh_json);
3028       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3029       vat_json_object_add_uint (nsh_json, "spi",
3030                                 clib_net_to_host_u32 (nsh->spi));
3031       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3032     }
3033   else
3034     {
3035       eid = format (0, "%U", format_lisp_eid_vat,
3036                     mp->eid_type,
3037                     mp->eid,
3038                     mp->eid_prefix_len,
3039                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3040       vec_add1 (eid, 0);
3041       vat_json_object_add_string_copy (node, "eid", eid);
3042       vec_free (eid);
3043     }
3044   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3045   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3046   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3047
3048   if (mp->key_id)
3049     {
3050       vat_json_object_add_uint (node, "key_id",
3051                                 clib_net_to_host_u16 (mp->key_id));
3052       vat_json_object_add_string_copy (node, "key", mp->key);
3053     }
3054 }
3055
3056 static void
3057 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3058 {
3059   vat_main_t *vam = &vat_main;
3060   u8 *seid = 0, *deid = 0;
3061   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3062
3063   deid = format (0, "%U", format_lisp_eid_vat,
3064                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3065
3066   seid = format (0, "%U", format_lisp_eid_vat,
3067                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3068
3069   vec_add1 (deid, 0);
3070   vec_add1 (seid, 0);
3071
3072   if (mp->is_ip4)
3073     format_ip_address_fcn = format_ip4_address;
3074   else
3075     format_ip_address_fcn = format_ip6_address;
3076
3077
3078   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3079          clib_net_to_host_u32 (mp->vni),
3080          seid, deid,
3081          format_ip_address_fcn, mp->lloc,
3082          format_ip_address_fcn, mp->rloc,
3083          clib_net_to_host_u32 (mp->pkt_count),
3084          clib_net_to_host_u32 (mp->bytes));
3085
3086   vec_free (deid);
3087   vec_free (seid);
3088 }
3089
3090 static void
3091 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3092 {
3093   struct in6_addr ip6;
3094   struct in_addr ip4;
3095   vat_main_t *vam = &vat_main;
3096   vat_json_node_t *node = 0;
3097   u8 *deid = 0, *seid = 0;
3098
3099   if (VAT_JSON_ARRAY != vam->json_tree.type)
3100     {
3101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3102       vat_json_init_array (&vam->json_tree);
3103     }
3104   node = vat_json_array_add (&vam->json_tree);
3105
3106   vat_json_init_object (node);
3107   deid = format (0, "%U", format_lisp_eid_vat,
3108                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3109
3110   seid = format (0, "%U", format_lisp_eid_vat,
3111                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3112
3113   vec_add1 (deid, 0);
3114   vec_add1 (seid, 0);
3115
3116   vat_json_object_add_string_copy (node, "seid", seid);
3117   vat_json_object_add_string_copy (node, "deid", deid);
3118   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3119
3120   if (mp->is_ip4)
3121     {
3122       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3123       vat_json_object_add_ip4 (node, "lloc", ip4);
3124       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3125       vat_json_object_add_ip4 (node, "rloc", ip4);
3126     }
3127   else
3128     {
3129       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3130       vat_json_object_add_ip6 (node, "lloc", ip6);
3131       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3132       vat_json_object_add_ip6 (node, "rloc", ip6);
3133     }
3134   vat_json_object_add_uint (node, "pkt_count",
3135                             clib_net_to_host_u32 (mp->pkt_count));
3136   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3137
3138   vec_free (deid);
3139   vec_free (seid);
3140 }
3141
3142 static void
3143   vl_api_one_eid_table_map_details_t_handler
3144   (vl_api_one_eid_table_map_details_t * mp)
3145 {
3146   vat_main_t *vam = &vat_main;
3147
3148   u8 *line = format (0, "%=10d%=10d",
3149                      clib_net_to_host_u32 (mp->vni),
3150                      clib_net_to_host_u32 (mp->dp_table));
3151   print (vam->ofp, "%v", line);
3152   vec_free (line);
3153 }
3154
3155 static void
3156   vl_api_one_eid_table_map_details_t_handler_json
3157   (vl_api_one_eid_table_map_details_t * mp)
3158 {
3159   vat_main_t *vam = &vat_main;
3160   vat_json_node_t *node = NULL;
3161
3162   if (VAT_JSON_ARRAY != vam->json_tree.type)
3163     {
3164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3165       vat_json_init_array (&vam->json_tree);
3166     }
3167   node = vat_json_array_add (&vam->json_tree);
3168   vat_json_init_object (node);
3169   vat_json_object_add_uint (node, "dp_table",
3170                             clib_net_to_host_u32 (mp->dp_table));
3171   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3172 }
3173
3174 static void
3175   vl_api_one_eid_table_vni_details_t_handler
3176   (vl_api_one_eid_table_vni_details_t * mp)
3177 {
3178   vat_main_t *vam = &vat_main;
3179
3180   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3181   print (vam->ofp, "%v", line);
3182   vec_free (line);
3183 }
3184
3185 static void
3186   vl_api_one_eid_table_vni_details_t_handler_json
3187   (vl_api_one_eid_table_vni_details_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   vat_json_node_t *node = NULL;
3191
3192   if (VAT_JSON_ARRAY != vam->json_tree.type)
3193     {
3194       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3195       vat_json_init_array (&vam->json_tree);
3196     }
3197   node = vat_json_array_add (&vam->json_tree);
3198   vat_json_init_object (node);
3199   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3200 }
3201
3202 static void
3203   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3204   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   int retval = clib_net_to_host_u32 (mp->retval);
3208
3209   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3210   print (vam->ofp, "fallback threshold value: %d", mp->value);
3211
3212   vam->retval = retval;
3213   vam->result_ready = 1;
3214 }
3215
3216 static void
3217   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3218   (vl_api_show_one_map_register_fallback_threshold_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   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3225   vat_json_init_object (node);
3226   vat_json_object_add_uint (node, "value", mp->value);
3227
3228   vat_json_print (vam->ofp, node);
3229   vat_json_free (node);
3230
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_map_register_state_reply_t_handler
3237   (vl_api_show_one_map_register_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   int retval = clib_net_to_host_u32 (mp->retval);
3241
3242   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3243
3244   vam->retval = retval;
3245   vam->result_ready = 1;
3246 }
3247
3248 static void
3249   vl_api_show_one_map_register_state_reply_t_handler_json
3250   (vl_api_show_one_map_register_state_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   vat_json_node_t _node, *node = &_node;
3254   int retval = clib_net_to_host_u32 (mp->retval);
3255
3256   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3257
3258   vat_json_init_object (node);
3259   vat_json_object_add_string_copy (node, "state", s);
3260
3261   vat_json_print (vam->ofp, node);
3262   vat_json_free (node);
3263
3264   vam->retval = retval;
3265   vam->result_ready = 1;
3266   vec_free (s);
3267 }
3268
3269 static void
3270   vl_api_show_one_rloc_probe_state_reply_t_handler
3271   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3272 {
3273   vat_main_t *vam = &vat_main;
3274   int retval = clib_net_to_host_u32 (mp->retval);
3275
3276   if (retval)
3277     goto end;
3278
3279   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3280 end:
3281   vam->retval = retval;
3282   vam->result_ready = 1;
3283 }
3284
3285 static void
3286   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3287   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3288 {
3289   vat_main_t *vam = &vat_main;
3290   vat_json_node_t _node, *node = &_node;
3291   int retval = clib_net_to_host_u32 (mp->retval);
3292
3293   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3294   vat_json_init_object (node);
3295   vat_json_object_add_string_copy (node, "state", s);
3296
3297   vat_json_print (vam->ofp, node);
3298   vat_json_free (node);
3299
3300   vam->retval = retval;
3301   vam->result_ready = 1;
3302   vec_free (s);
3303 }
3304
3305 static void
3306   vl_api_show_one_stats_enable_disable_reply_t_handler
3307   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   int retval = clib_net_to_host_u32 (mp->retval);
3311
3312   if (retval)
3313     goto end;
3314
3315   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3316 end:
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319 }
3320
3321 static void
3322   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3323   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   vat_json_node_t _node, *node = &_node;
3327   int retval = clib_net_to_host_u32 (mp->retval);
3328
3329   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3330   vat_json_init_object (node);
3331   vat_json_object_add_string_copy (node, "state", s);
3332
3333   vat_json_print (vam->ofp, node);
3334   vat_json_free (node);
3335
3336   vam->retval = retval;
3337   vam->result_ready = 1;
3338   vec_free (s);
3339 }
3340
3341 static void
3342 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3343 {
3344   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3345   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3346   e->vni = clib_net_to_host_u32 (e->vni);
3347 }
3348
3349 static void
3350   gpe_fwd_entries_get_reply_t_net_to_host
3351   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3352 {
3353   u32 i;
3354
3355   mp->count = clib_net_to_host_u32 (mp->count);
3356   for (i = 0; i < mp->count; i++)
3357     {
3358       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3359     }
3360 }
3361
3362 static u8 *
3363 format_gpe_encap_mode (u8 * s, va_list * args)
3364 {
3365   u32 mode = va_arg (*args, u32);
3366
3367   switch (mode)
3368     {
3369     case 0:
3370       return format (s, "lisp");
3371     case 1:
3372       return format (s, "vxlan");
3373     }
3374   return 0;
3375 }
3376
3377 static void
3378   vl_api_gpe_get_encap_mode_reply_t_handler
3379   (vl_api_gpe_get_encap_mode_reply_t * mp)
3380 {
3381   vat_main_t *vam = &vat_main;
3382
3383   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3384   vam->retval = ntohl (mp->retval);
3385   vam->result_ready = 1;
3386 }
3387
3388 static void
3389   vl_api_gpe_get_encap_mode_reply_t_handler_json
3390   (vl_api_gpe_get_encap_mode_reply_t * mp)
3391 {
3392   vat_main_t *vam = &vat_main;
3393   vat_json_node_t node;
3394
3395   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3396   vec_add1 (encap_mode, 0);
3397
3398   vat_json_init_object (&node);
3399   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3400
3401   vec_free (encap_mode);
3402   vat_json_print (vam->ofp, &node);
3403   vat_json_free (&node);
3404
3405   vam->retval = ntohl (mp->retval);
3406   vam->result_ready = 1;
3407 }
3408
3409 static void
3410   vl_api_gpe_fwd_entry_path_details_t_handler
3411   (vl_api_gpe_fwd_entry_path_details_t * mp)
3412 {
3413   vat_main_t *vam = &vat_main;
3414   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3415
3416   if (mp->lcl_loc.is_ip4)
3417     format_ip_address_fcn = format_ip4_address;
3418   else
3419     format_ip_address_fcn = format_ip6_address;
3420
3421   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3422          format_ip_address_fcn, &mp->lcl_loc,
3423          format_ip_address_fcn, &mp->rmt_loc);
3424 }
3425
3426 static void
3427 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3428 {
3429   struct in6_addr ip6;
3430   struct in_addr ip4;
3431
3432   if (loc->is_ip4)
3433     {
3434       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3435       vat_json_object_add_ip4 (n, "address", ip4);
3436     }
3437   else
3438     {
3439       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3440       vat_json_object_add_ip6 (n, "address", ip6);
3441     }
3442   vat_json_object_add_uint (n, "weight", loc->weight);
3443 }
3444
3445 static void
3446   vl_api_gpe_fwd_entry_path_details_t_handler_json
3447   (vl_api_gpe_fwd_entry_path_details_t * mp)
3448 {
3449   vat_main_t *vam = &vat_main;
3450   vat_json_node_t *node = NULL;
3451   vat_json_node_t *loc_node;
3452
3453   if (VAT_JSON_ARRAY != vam->json_tree.type)
3454     {
3455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3456       vat_json_init_array (&vam->json_tree);
3457     }
3458   node = vat_json_array_add (&vam->json_tree);
3459   vat_json_init_object (node);
3460
3461   loc_node = vat_json_object_add (node, "local_locator");
3462   vat_json_init_object (loc_node);
3463   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3464
3465   loc_node = vat_json_object_add (node, "remote_locator");
3466   vat_json_init_object (loc_node);
3467   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3468 }
3469
3470 static void
3471   vl_api_gpe_fwd_entries_get_reply_t_handler
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   vat_main_t *vam = &vat_main;
3475   u32 i;
3476   int retval = clib_net_to_host_u32 (mp->retval);
3477   vl_api_gpe_fwd_entry_t *e;
3478
3479   if (retval)
3480     goto end;
3481
3482   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3483
3484   for (i = 0; i < mp->count; i++)
3485     {
3486       e = &mp->entries[i];
3487       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3488              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3489              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3490     }
3491
3492 end:
3493   vam->retval = retval;
3494   vam->result_ready = 1;
3495 }
3496
3497 static void
3498   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3499   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3500 {
3501   u8 *s = 0;
3502   vat_main_t *vam = &vat_main;
3503   vat_json_node_t *e = 0, root;
3504   u32 i;
3505   int retval = clib_net_to_host_u32 (mp->retval);
3506   vl_api_gpe_fwd_entry_t *fwd;
3507
3508   if (retval)
3509     goto end;
3510
3511   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3512   vat_json_init_array (&root);
3513
3514   for (i = 0; i < mp->count; i++)
3515     {
3516       e = vat_json_array_add (&root);
3517       fwd = &mp->entries[i];
3518
3519       vat_json_init_object (e);
3520       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3521       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3522       vat_json_object_add_int (e, "vni", fwd->vni);
3523       vat_json_object_add_int (e, "action", fwd->action);
3524
3525       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3526                   fwd->leid_prefix_len);
3527       vec_add1 (s, 0);
3528       vat_json_object_add_string_copy (e, "leid", s);
3529       vec_free (s);
3530
3531       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3532                   fwd->reid_prefix_len);
3533       vec_add1 (s, 0);
3534       vat_json_object_add_string_copy (e, "reid", s);
3535       vec_free (s);
3536     }
3537
3538   vat_json_print (vam->ofp, &root);
3539   vat_json_free (&root);
3540
3541 end:
3542   vam->retval = retval;
3543   vam->result_ready = 1;
3544 }
3545
3546 static void
3547   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3548   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3549 {
3550   vat_main_t *vam = &vat_main;
3551   u32 i, n;
3552   int retval = clib_net_to_host_u32 (mp->retval);
3553   vl_api_gpe_native_fwd_rpath_t *r;
3554
3555   if (retval)
3556     goto end;
3557
3558   n = clib_net_to_host_u32 (mp->count);
3559
3560   for (i = 0; i < n; i++)
3561     {
3562       r = &mp->entries[i];
3563       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3564              clib_net_to_host_u32 (r->fib_index),
3565              clib_net_to_host_u32 (r->nh_sw_if_index),
3566              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3567     }
3568
3569 end:
3570   vam->retval = retval;
3571   vam->result_ready = 1;
3572 }
3573
3574 static void
3575   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3576   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3577 {
3578   vat_main_t *vam = &vat_main;
3579   vat_json_node_t root, *e;
3580   u32 i, n;
3581   int retval = clib_net_to_host_u32 (mp->retval);
3582   vl_api_gpe_native_fwd_rpath_t *r;
3583   u8 *s;
3584
3585   if (retval)
3586     goto end;
3587
3588   n = clib_net_to_host_u32 (mp->count);
3589   vat_json_init_array (&root);
3590
3591   for (i = 0; i < n; i++)
3592     {
3593       e = vat_json_array_add (&root);
3594       vat_json_init_object (e);
3595       r = &mp->entries[i];
3596       s =
3597         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3598                 r->nh_addr);
3599       vec_add1 (s, 0);
3600       vat_json_object_add_string_copy (e, "ip4", s);
3601       vec_free (s);
3602
3603       vat_json_object_add_uint (e, "fib_index",
3604                                 clib_net_to_host_u32 (r->fib_index));
3605       vat_json_object_add_uint (e, "nh_sw_if_index",
3606                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3607     }
3608
3609   vat_json_print (vam->ofp, &root);
3610   vat_json_free (&root);
3611
3612 end:
3613   vam->retval = retval;
3614   vam->result_ready = 1;
3615 }
3616
3617 static void
3618   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3619   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3620 {
3621   vat_main_t *vam = &vat_main;
3622   u32 i, n;
3623   int retval = clib_net_to_host_u32 (mp->retval);
3624
3625   if (retval)
3626     goto end;
3627
3628   n = clib_net_to_host_u32 (mp->count);
3629
3630   for (i = 0; i < n; i++)
3631     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3632
3633 end:
3634   vam->retval = retval;
3635   vam->result_ready = 1;
3636 }
3637
3638 static void
3639   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3640   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3641 {
3642   vat_main_t *vam = &vat_main;
3643   vat_json_node_t root;
3644   u32 i, n;
3645   int retval = clib_net_to_host_u32 (mp->retval);
3646
3647   if (retval)
3648     goto end;
3649
3650   n = clib_net_to_host_u32 (mp->count);
3651   vat_json_init_array (&root);
3652
3653   for (i = 0; i < n; i++)
3654     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3655
3656   vat_json_print (vam->ofp, &root);
3657   vat_json_free (&root);
3658
3659 end:
3660   vam->retval = retval;
3661   vam->result_ready = 1;
3662 }
3663
3664 static void
3665   vl_api_one_ndp_entries_get_reply_t_handler
3666   (vl_api_one_ndp_entries_get_reply_t * mp)
3667 {
3668   vat_main_t *vam = &vat_main;
3669   u32 i, n;
3670   int retval = clib_net_to_host_u32 (mp->retval);
3671
3672   if (retval)
3673     goto end;
3674
3675   n = clib_net_to_host_u32 (mp->count);
3676
3677   for (i = 0; i < n; i++)
3678     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3679            format_ethernet_address, mp->entries[i].mac);
3680
3681 end:
3682   vam->retval = retval;
3683   vam->result_ready = 1;
3684 }
3685
3686 static void
3687   vl_api_one_ndp_entries_get_reply_t_handler_json
3688   (vl_api_one_ndp_entries_get_reply_t * mp)
3689 {
3690   u8 *s = 0;
3691   vat_main_t *vam = &vat_main;
3692   vat_json_node_t *e = 0, root;
3693   u32 i, n;
3694   int retval = clib_net_to_host_u32 (mp->retval);
3695   vl_api_one_ndp_entry_t *arp_entry;
3696
3697   if (retval)
3698     goto end;
3699
3700   n = clib_net_to_host_u32 (mp->count);
3701   vat_json_init_array (&root);
3702
3703   for (i = 0; i < n; i++)
3704     {
3705       e = vat_json_array_add (&root);
3706       arp_entry = &mp->entries[i];
3707
3708       vat_json_init_object (e);
3709       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3710       vec_add1 (s, 0);
3711
3712       vat_json_object_add_string_copy (e, "mac", s);
3713       vec_free (s);
3714
3715       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3716       vec_add1 (s, 0);
3717       vat_json_object_add_string_copy (e, "ip6", s);
3718       vec_free (s);
3719     }
3720
3721   vat_json_print (vam->ofp, &root);
3722   vat_json_free (&root);
3723
3724 end:
3725   vam->retval = retval;
3726   vam->result_ready = 1;
3727 }
3728
3729 static void
3730   vl_api_one_l2_arp_entries_get_reply_t_handler
3731   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3732 {
3733   vat_main_t *vam = &vat_main;
3734   u32 i, n;
3735   int retval = clib_net_to_host_u32 (mp->retval);
3736
3737   if (retval)
3738     goto end;
3739
3740   n = clib_net_to_host_u32 (mp->count);
3741
3742   for (i = 0; i < n; i++)
3743     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3744            format_ethernet_address, mp->entries[i].mac);
3745
3746 end:
3747   vam->retval = retval;
3748   vam->result_ready = 1;
3749 }
3750
3751 static void
3752   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3753   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3754 {
3755   u8 *s = 0;
3756   vat_main_t *vam = &vat_main;
3757   vat_json_node_t *e = 0, root;
3758   u32 i, n;
3759   int retval = clib_net_to_host_u32 (mp->retval);
3760   vl_api_one_l2_arp_entry_t *arp_entry;
3761
3762   if (retval)
3763     goto end;
3764
3765   n = clib_net_to_host_u32 (mp->count);
3766   vat_json_init_array (&root);
3767
3768   for (i = 0; i < n; i++)
3769     {
3770       e = vat_json_array_add (&root);
3771       arp_entry = &mp->entries[i];
3772
3773       vat_json_init_object (e);
3774       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3775       vec_add1 (s, 0);
3776
3777       vat_json_object_add_string_copy (e, "mac", s);
3778       vec_free (s);
3779
3780       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3781       vec_add1 (s, 0);
3782       vat_json_object_add_string_copy (e, "ip4", s);
3783       vec_free (s);
3784     }
3785
3786   vat_json_print (vam->ofp, &root);
3787   vat_json_free (&root);
3788
3789 end:
3790   vam->retval = retval;
3791   vam->result_ready = 1;
3792 }
3793
3794 static void
3795 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3796 {
3797   vat_main_t *vam = &vat_main;
3798   u32 i, n;
3799   int retval = clib_net_to_host_u32 (mp->retval);
3800
3801   if (retval)
3802     goto end;
3803
3804   n = clib_net_to_host_u32 (mp->count);
3805
3806   for (i = 0; i < n; i++)
3807     {
3808       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3809     }
3810
3811 end:
3812   vam->retval = retval;
3813   vam->result_ready = 1;
3814 }
3815
3816 static void
3817   vl_api_one_ndp_bd_get_reply_t_handler_json
3818   (vl_api_one_ndp_bd_get_reply_t * mp)
3819 {
3820   vat_main_t *vam = &vat_main;
3821   vat_json_node_t root;
3822   u32 i, n;
3823   int retval = clib_net_to_host_u32 (mp->retval);
3824
3825   if (retval)
3826     goto end;
3827
3828   n = clib_net_to_host_u32 (mp->count);
3829   vat_json_init_array (&root);
3830
3831   for (i = 0; i < n; i++)
3832     {
3833       vat_json_array_add_uint (&root,
3834                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3835     }
3836
3837   vat_json_print (vam->ofp, &root);
3838   vat_json_free (&root);
3839
3840 end:
3841   vam->retval = retval;
3842   vam->result_ready = 1;
3843 }
3844
3845 static void
3846   vl_api_one_l2_arp_bd_get_reply_t_handler
3847   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3848 {
3849   vat_main_t *vam = &vat_main;
3850   u32 i, n;
3851   int retval = clib_net_to_host_u32 (mp->retval);
3852
3853   if (retval)
3854     goto end;
3855
3856   n = clib_net_to_host_u32 (mp->count);
3857
3858   for (i = 0; i < n; i++)
3859     {
3860       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3861     }
3862
3863 end:
3864   vam->retval = retval;
3865   vam->result_ready = 1;
3866 }
3867
3868 static void
3869   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3870   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3871 {
3872   vat_main_t *vam = &vat_main;
3873   vat_json_node_t root;
3874   u32 i, n;
3875   int retval = clib_net_to_host_u32 (mp->retval);
3876
3877   if (retval)
3878     goto end;
3879
3880   n = clib_net_to_host_u32 (mp->count);
3881   vat_json_init_array (&root);
3882
3883   for (i = 0; i < n; i++)
3884     {
3885       vat_json_array_add_uint (&root,
3886                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3887     }
3888
3889   vat_json_print (vam->ofp, &root);
3890   vat_json_free (&root);
3891
3892 end:
3893   vam->retval = retval;
3894   vam->result_ready = 1;
3895 }
3896
3897 static void
3898   vl_api_one_adjacencies_get_reply_t_handler
3899   (vl_api_one_adjacencies_get_reply_t * mp)
3900 {
3901   vat_main_t *vam = &vat_main;
3902   u32 i, n;
3903   int retval = clib_net_to_host_u32 (mp->retval);
3904   vl_api_one_adjacency_t *a;
3905
3906   if (retval)
3907     goto end;
3908
3909   n = clib_net_to_host_u32 (mp->count);
3910
3911   for (i = 0; i < n; i++)
3912     {
3913       a = &mp->adjacencies[i];
3914       print (vam->ofp, "%U %40U",
3915              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3916              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3917     }
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_one_adjacencies_get_reply_t_handler_json
3926   (vl_api_one_adjacencies_get_reply_t * mp)
3927 {
3928   u8 *s = 0;
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t *e = 0, root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933   vl_api_one_adjacency_t *a;
3934
3935   if (retval)
3936     goto end;
3937
3938   n = clib_net_to_host_u32 (mp->count);
3939   vat_json_init_array (&root);
3940
3941   for (i = 0; i < n; i++)
3942     {
3943       e = vat_json_array_add (&root);
3944       a = &mp->adjacencies[i];
3945
3946       vat_json_init_object (e);
3947       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3948                   a->leid_prefix_len);
3949       vec_add1 (s, 0);
3950       vat_json_object_add_string_copy (e, "leid", s);
3951       vec_free (s);
3952
3953       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3954                   a->reid_prefix_len);
3955       vec_add1 (s, 0);
3956       vat_json_object_add_string_copy (e, "reid", s);
3957       vec_free (s);
3958     }
3959
3960   vat_json_print (vam->ofp, &root);
3961   vat_json_free (&root);
3962
3963 end:
3964   vam->retval = retval;
3965   vam->result_ready = 1;
3966 }
3967
3968 static void
3969 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972
3973   print (vam->ofp, "%=20U",
3974          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3975          mp->ip_address);
3976 }
3977
3978 static void
3979   vl_api_one_map_server_details_t_handler_json
3980   (vl_api_one_map_server_details_t * mp)
3981 {
3982   vat_main_t *vam = &vat_main;
3983   vat_json_node_t *node = NULL;
3984   struct in6_addr ip6;
3985   struct in_addr ip4;
3986
3987   if (VAT_JSON_ARRAY != vam->json_tree.type)
3988     {
3989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3990       vat_json_init_array (&vam->json_tree);
3991     }
3992   node = vat_json_array_add (&vam->json_tree);
3993
3994   vat_json_init_object (node);
3995   if (mp->is_ipv6)
3996     {
3997       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3998       vat_json_object_add_ip6 (node, "map-server", ip6);
3999     }
4000   else
4001     {
4002       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4003       vat_json_object_add_ip4 (node, "map-server", ip4);
4004     }
4005 }
4006
4007 static void
4008 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4009                                            * mp)
4010 {
4011   vat_main_t *vam = &vat_main;
4012
4013   print (vam->ofp, "%=20U",
4014          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4015          mp->ip_address);
4016 }
4017
4018 static void
4019   vl_api_one_map_resolver_details_t_handler_json
4020   (vl_api_one_map_resolver_details_t * mp)
4021 {
4022   vat_main_t *vam = &vat_main;
4023   vat_json_node_t *node = NULL;
4024   struct in6_addr ip6;
4025   struct in_addr ip4;
4026
4027   if (VAT_JSON_ARRAY != vam->json_tree.type)
4028     {
4029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4030       vat_json_init_array (&vam->json_tree);
4031     }
4032   node = vat_json_array_add (&vam->json_tree);
4033
4034   vat_json_init_object (node);
4035   if (mp->is_ipv6)
4036     {
4037       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4038       vat_json_object_add_ip6 (node, "map resolver", ip6);
4039     }
4040   else
4041     {
4042       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4043       vat_json_object_add_ip4 (node, "map resolver", ip4);
4044     }
4045 }
4046
4047 static void
4048 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4049 {
4050   vat_main_t *vam = &vat_main;
4051   i32 retval = ntohl (mp->retval);
4052
4053   if (0 <= retval)
4054     {
4055       print (vam->ofp, "feature: %s\ngpe: %s",
4056              mp->feature_status ? "enabled" : "disabled",
4057              mp->gpe_status ? "enabled" : "disabled");
4058     }
4059
4060   vam->retval = retval;
4061   vam->result_ready = 1;
4062 }
4063
4064 static void
4065   vl_api_show_one_status_reply_t_handler_json
4066   (vl_api_show_one_status_reply_t * mp)
4067 {
4068   vat_main_t *vam = &vat_main;
4069   vat_json_node_t node;
4070   u8 *gpe_status = NULL;
4071   u8 *feature_status = NULL;
4072
4073   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4074   feature_status = format (0, "%s",
4075                            mp->feature_status ? "enabled" : "disabled");
4076   vec_add1 (gpe_status, 0);
4077   vec_add1 (feature_status, 0);
4078
4079   vat_json_init_object (&node);
4080   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4081   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4082
4083   vec_free (gpe_status);
4084   vec_free (feature_status);
4085
4086   vat_json_print (vam->ofp, &node);
4087   vat_json_free (&node);
4088
4089   vam->retval = ntohl (mp->retval);
4090   vam->result_ready = 1;
4091 }
4092
4093 static void
4094   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4095   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4096 {
4097   vat_main_t *vam = &vat_main;
4098   i32 retval = ntohl (mp->retval);
4099
4100   if (retval >= 0)
4101     {
4102       print (vam->ofp, "%=20s", mp->locator_set_name);
4103     }
4104
4105   vam->retval = retval;
4106   vam->result_ready = 1;
4107 }
4108
4109 static void
4110   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4111   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4112 {
4113   vat_main_t *vam = &vat_main;
4114   vat_json_node_t *node = NULL;
4115
4116   if (VAT_JSON_ARRAY != vam->json_tree.type)
4117     {
4118       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4119       vat_json_init_array (&vam->json_tree);
4120     }
4121   node = vat_json_array_add (&vam->json_tree);
4122
4123   vat_json_init_object (node);
4124   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4125
4126   vat_json_print (vam->ofp, node);
4127   vat_json_free (node);
4128
4129   vam->retval = ntohl (mp->retval);
4130   vam->result_ready = 1;
4131 }
4132
4133 static u8 *
4134 format_lisp_map_request_mode (u8 * s, va_list * args)
4135 {
4136   u32 mode = va_arg (*args, u32);
4137
4138   switch (mode)
4139     {
4140     case 0:
4141       return format (0, "dst-only");
4142     case 1:
4143       return format (0, "src-dst");
4144     }
4145   return 0;
4146 }
4147
4148 static void
4149   vl_api_show_one_map_request_mode_reply_t_handler
4150   (vl_api_show_one_map_request_mode_reply_t * mp)
4151 {
4152   vat_main_t *vam = &vat_main;
4153   i32 retval = ntohl (mp->retval);
4154
4155   if (0 <= retval)
4156     {
4157       u32 mode = mp->mode;
4158       print (vam->ofp, "map_request_mode: %U",
4159              format_lisp_map_request_mode, mode);
4160     }
4161
4162   vam->retval = retval;
4163   vam->result_ready = 1;
4164 }
4165
4166 static void
4167   vl_api_show_one_map_request_mode_reply_t_handler_json
4168   (vl_api_show_one_map_request_mode_reply_t * mp)
4169 {
4170   vat_main_t *vam = &vat_main;
4171   vat_json_node_t node;
4172   u8 *s = 0;
4173   u32 mode;
4174
4175   mode = mp->mode;
4176   s = format (0, "%U", format_lisp_map_request_mode, mode);
4177   vec_add1 (s, 0);
4178
4179   vat_json_init_object (&node);
4180   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4181   vat_json_print (vam->ofp, &node);
4182   vat_json_free (&node);
4183
4184   vec_free (s);
4185   vam->retval = ntohl (mp->retval);
4186   vam->result_ready = 1;
4187 }
4188
4189 static void
4190   vl_api_one_show_xtr_mode_reply_t_handler
4191   (vl_api_one_show_xtr_mode_reply_t * mp)
4192 {
4193   vat_main_t *vam = &vat_main;
4194   i32 retval = ntohl (mp->retval);
4195
4196   if (0 <= retval)
4197     {
4198       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4199     }
4200
4201   vam->retval = retval;
4202   vam->result_ready = 1;
4203 }
4204
4205 static void
4206   vl_api_one_show_xtr_mode_reply_t_handler_json
4207   (vl_api_one_show_xtr_mode_reply_t * mp)
4208 {
4209   vat_main_t *vam = &vat_main;
4210   vat_json_node_t node;
4211   u8 *status = 0;
4212
4213   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4214   vec_add1 (status, 0);
4215
4216   vat_json_init_object (&node);
4217   vat_json_object_add_string_copy (&node, "status", status);
4218
4219   vec_free (status);
4220
4221   vat_json_print (vam->ofp, &node);
4222   vat_json_free (&node);
4223
4224   vam->retval = ntohl (mp->retval);
4225   vam->result_ready = 1;
4226 }
4227
4228 static void
4229   vl_api_one_show_pitr_mode_reply_t_handler
4230   (vl_api_one_show_pitr_mode_reply_t * mp)
4231 {
4232   vat_main_t *vam = &vat_main;
4233   i32 retval = ntohl (mp->retval);
4234
4235   if (0 <= retval)
4236     {
4237       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4238     }
4239
4240   vam->retval = retval;
4241   vam->result_ready = 1;
4242 }
4243
4244 static void
4245   vl_api_one_show_pitr_mode_reply_t_handler_json
4246   (vl_api_one_show_pitr_mode_reply_t * mp)
4247 {
4248   vat_main_t *vam = &vat_main;
4249   vat_json_node_t node;
4250   u8 *status = 0;
4251
4252   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4253   vec_add1 (status, 0);
4254
4255   vat_json_init_object (&node);
4256   vat_json_object_add_string_copy (&node, "status", status);
4257
4258   vec_free (status);
4259
4260   vat_json_print (vam->ofp, &node);
4261   vat_json_free (&node);
4262
4263   vam->retval = ntohl (mp->retval);
4264   vam->result_ready = 1;
4265 }
4266
4267 static void
4268   vl_api_one_show_petr_mode_reply_t_handler
4269   (vl_api_one_show_petr_mode_reply_t * mp)
4270 {
4271   vat_main_t *vam = &vat_main;
4272   i32 retval = ntohl (mp->retval);
4273
4274   if (0 <= retval)
4275     {
4276       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4277     }
4278
4279   vam->retval = retval;
4280   vam->result_ready = 1;
4281 }
4282
4283 static void
4284   vl_api_one_show_petr_mode_reply_t_handler_json
4285   (vl_api_one_show_petr_mode_reply_t * mp)
4286 {
4287   vat_main_t *vam = &vat_main;
4288   vat_json_node_t node;
4289   u8 *status = 0;
4290
4291   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4292   vec_add1 (status, 0);
4293
4294   vat_json_init_object (&node);
4295   vat_json_object_add_string_copy (&node, "status", status);
4296
4297   vec_free (status);
4298
4299   vat_json_print (vam->ofp, &node);
4300   vat_json_free (&node);
4301
4302   vam->retval = ntohl (mp->retval);
4303   vam->result_ready = 1;
4304 }
4305
4306 static void
4307   vl_api_show_one_use_petr_reply_t_handler
4308   (vl_api_show_one_use_petr_reply_t * mp)
4309 {
4310   vat_main_t *vam = &vat_main;
4311   i32 retval = ntohl (mp->retval);
4312
4313   if (0 <= retval)
4314     {
4315       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4316       if (mp->status)
4317         {
4318           print (vam->ofp, "Proxy-ETR address; %U",
4319                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4320                  mp->address);
4321         }
4322     }
4323
4324   vam->retval = retval;
4325   vam->result_ready = 1;
4326 }
4327
4328 static void
4329   vl_api_show_one_use_petr_reply_t_handler_json
4330   (vl_api_show_one_use_petr_reply_t * mp)
4331 {
4332   vat_main_t *vam = &vat_main;
4333   vat_json_node_t node;
4334   u8 *status = 0;
4335   struct in_addr ip4;
4336   struct in6_addr ip6;
4337
4338   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4339   vec_add1 (status, 0);
4340
4341   vat_json_init_object (&node);
4342   vat_json_object_add_string_copy (&node, "status", status);
4343   if (mp->status)
4344     {
4345       if (mp->is_ip4)
4346         {
4347           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4348           vat_json_object_add_ip6 (&node, "address", ip6);
4349         }
4350       else
4351         {
4352           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4353           vat_json_object_add_ip4 (&node, "address", ip4);
4354         }
4355     }
4356
4357   vec_free (status);
4358
4359   vat_json_print (vam->ofp, &node);
4360   vat_json_free (&node);
4361
4362   vam->retval = ntohl (mp->retval);
4363   vam->result_ready = 1;
4364 }
4365
4366 static void
4367   vl_api_show_one_nsh_mapping_reply_t_handler
4368   (vl_api_show_one_nsh_mapping_reply_t * mp)
4369 {
4370   vat_main_t *vam = &vat_main;
4371   i32 retval = ntohl (mp->retval);
4372
4373   if (0 <= retval)
4374     {
4375       print (vam->ofp, "%-20s%-16s",
4376              mp->is_set ? "set" : "not-set",
4377              mp->is_set ? (char *) mp->locator_set_name : "");
4378     }
4379
4380   vam->retval = retval;
4381   vam->result_ready = 1;
4382 }
4383
4384 static void
4385   vl_api_show_one_nsh_mapping_reply_t_handler_json
4386   (vl_api_show_one_nsh_mapping_reply_t * mp)
4387 {
4388   vat_main_t *vam = &vat_main;
4389   vat_json_node_t node;
4390   u8 *status = 0;
4391
4392   status = format (0, "%s", mp->is_set ? "yes" : "no");
4393   vec_add1 (status, 0);
4394
4395   vat_json_init_object (&node);
4396   vat_json_object_add_string_copy (&node, "is_set", status);
4397   if (mp->is_set)
4398     {
4399       vat_json_object_add_string_copy (&node, "locator_set",
4400                                        mp->locator_set_name);
4401     }
4402
4403   vec_free (status);
4404
4405   vat_json_print (vam->ofp, &node);
4406   vat_json_free (&node);
4407
4408   vam->retval = ntohl (mp->retval);
4409   vam->result_ready = 1;
4410 }
4411
4412 static void
4413   vl_api_show_one_map_register_ttl_reply_t_handler
4414   (vl_api_show_one_map_register_ttl_reply_t * mp)
4415 {
4416   vat_main_t *vam = &vat_main;
4417   i32 retval = ntohl (mp->retval);
4418
4419   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4420
4421   if (0 <= retval)
4422     {
4423       print (vam->ofp, "ttl: %u", mp->ttl);
4424     }
4425
4426   vam->retval = retval;
4427   vam->result_ready = 1;
4428 }
4429
4430 static void
4431   vl_api_show_one_map_register_ttl_reply_t_handler_json
4432   (vl_api_show_one_map_register_ttl_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   vat_json_node_t node;
4436
4437   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4438   vat_json_init_object (&node);
4439   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4440
4441   vat_json_print (vam->ofp, &node);
4442   vat_json_free (&node);
4443
4444   vam->retval = ntohl (mp->retval);
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4450 {
4451   vat_main_t *vam = &vat_main;
4452   i32 retval = ntohl (mp->retval);
4453
4454   if (0 <= retval)
4455     {
4456       print (vam->ofp, "%-20s%-16s",
4457              mp->status ? "enabled" : "disabled",
4458              mp->status ? (char *) mp->locator_set_name : "");
4459     }
4460
4461   vam->retval = retval;
4462   vam->result_ready = 1;
4463 }
4464
4465 static void
4466 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4467 {
4468   vat_main_t *vam = &vat_main;
4469   vat_json_node_t node;
4470   u8 *status = 0;
4471
4472   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4473   vec_add1 (status, 0);
4474
4475   vat_json_init_object (&node);
4476   vat_json_object_add_string_copy (&node, "status", status);
4477   if (mp->status)
4478     {
4479       vat_json_object_add_string_copy (&node, "locator_set",
4480                                        mp->locator_set_name);
4481     }
4482
4483   vec_free (status);
4484
4485   vat_json_print (vam->ofp, &node);
4486   vat_json_free (&node);
4487
4488   vam->retval = ntohl (mp->retval);
4489   vam->result_ready = 1;
4490 }
4491
4492 static u8 *
4493 format_policer_type (u8 * s, va_list * va)
4494 {
4495   u32 i = va_arg (*va, u32);
4496
4497   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4498     s = format (s, "1r2c");
4499   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4500     s = format (s, "1r3c");
4501   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4502     s = format (s, "2r3c-2698");
4503   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4504     s = format (s, "2r3c-4115");
4505   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4506     s = format (s, "2r3c-mef5cf1");
4507   else
4508     s = format (s, "ILLEGAL");
4509   return s;
4510 }
4511
4512 static u8 *
4513 format_policer_rate_type (u8 * s, va_list * va)
4514 {
4515   u32 i = va_arg (*va, u32);
4516
4517   if (i == SSE2_QOS_RATE_KBPS)
4518     s = format (s, "kbps");
4519   else if (i == SSE2_QOS_RATE_PPS)
4520     s = format (s, "pps");
4521   else
4522     s = format (s, "ILLEGAL");
4523   return s;
4524 }
4525
4526 static u8 *
4527 format_policer_round_type (u8 * s, va_list * va)
4528 {
4529   u32 i = va_arg (*va, u32);
4530
4531   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4532     s = format (s, "closest");
4533   else if (i == SSE2_QOS_ROUND_TO_UP)
4534     s = format (s, "up");
4535   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4536     s = format (s, "down");
4537   else
4538     s = format (s, "ILLEGAL");
4539   return s;
4540 }
4541
4542 static u8 *
4543 format_policer_action_type (u8 * s, va_list * va)
4544 {
4545   u32 i = va_arg (*va, u32);
4546
4547   if (i == SSE2_QOS_ACTION_DROP)
4548     s = format (s, "drop");
4549   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4550     s = format (s, "transmit");
4551   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4552     s = format (s, "mark-and-transmit");
4553   else
4554     s = format (s, "ILLEGAL");
4555   return s;
4556 }
4557
4558 static u8 *
4559 format_dscp (u8 * s, va_list * va)
4560 {
4561   u32 i = va_arg (*va, u32);
4562   char *t = 0;
4563
4564   switch (i)
4565     {
4566 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4567       foreach_vnet_dscp
4568 #undef _
4569     default:
4570       return format (s, "ILLEGAL");
4571     }
4572   s = format (s, "%s", t);
4573   return s;
4574 }
4575
4576 static void
4577 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4578 {
4579   vat_main_t *vam = &vat_main;
4580   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4581
4582   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4583     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4584   else
4585     conform_dscp_str = format (0, "");
4586
4587   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4588     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4589   else
4590     exceed_dscp_str = format (0, "");
4591
4592   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4593     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4594   else
4595     violate_dscp_str = format (0, "");
4596
4597   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4598          "rate type %U, round type %U, %s rate, %s color-aware, "
4599          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4600          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4601          "conform action %U%s, exceed action %U%s, violate action %U%s",
4602          mp->name,
4603          format_policer_type, mp->type,
4604          ntohl (mp->cir),
4605          ntohl (mp->eir),
4606          clib_net_to_host_u64 (mp->cb),
4607          clib_net_to_host_u64 (mp->eb),
4608          format_policer_rate_type, mp->rate_type,
4609          format_policer_round_type, mp->round_type,
4610          mp->single_rate ? "single" : "dual",
4611          mp->color_aware ? "is" : "not",
4612          ntohl (mp->cir_tokens_per_period),
4613          ntohl (mp->pir_tokens_per_period),
4614          ntohl (mp->scale),
4615          ntohl (mp->current_limit),
4616          ntohl (mp->current_bucket),
4617          ntohl (mp->extended_limit),
4618          ntohl (mp->extended_bucket),
4619          clib_net_to_host_u64 (mp->last_update_time),
4620          format_policer_action_type, mp->conform_action_type,
4621          conform_dscp_str,
4622          format_policer_action_type, mp->exceed_action_type,
4623          exceed_dscp_str,
4624          format_policer_action_type, mp->violate_action_type,
4625          violate_dscp_str);
4626
4627   vec_free (conform_dscp_str);
4628   vec_free (exceed_dscp_str);
4629   vec_free (violate_dscp_str);
4630 }
4631
4632 static void vl_api_policer_details_t_handler_json
4633   (vl_api_policer_details_t * mp)
4634 {
4635   vat_main_t *vam = &vat_main;
4636   vat_json_node_t *node;
4637   u8 *rate_type_str, *round_type_str, *type_str;
4638   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4639
4640   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4641   round_type_str =
4642     format (0, "%U", format_policer_round_type, mp->round_type);
4643   type_str = format (0, "%U", format_policer_type, mp->type);
4644   conform_action_str = format (0, "%U", format_policer_action_type,
4645                                mp->conform_action_type);
4646   exceed_action_str = format (0, "%U", format_policer_action_type,
4647                               mp->exceed_action_type);
4648   violate_action_str = format (0, "%U", format_policer_action_type,
4649                                mp->violate_action_type);
4650
4651   if (VAT_JSON_ARRAY != vam->json_tree.type)
4652     {
4653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4654       vat_json_init_array (&vam->json_tree);
4655     }
4656   node = vat_json_array_add (&vam->json_tree);
4657
4658   vat_json_init_object (node);
4659   vat_json_object_add_string_copy (node, "name", mp->name);
4660   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4661   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4662   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4663   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4664   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4665   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4666   vat_json_object_add_string_copy (node, "type", type_str);
4667   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4668   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4669   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4670   vat_json_object_add_uint (node, "cir_tokens_per_period",
4671                             ntohl (mp->cir_tokens_per_period));
4672   vat_json_object_add_uint (node, "eir_tokens_per_period",
4673                             ntohl (mp->pir_tokens_per_period));
4674   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4675   vat_json_object_add_uint (node, "current_bucket",
4676                             ntohl (mp->current_bucket));
4677   vat_json_object_add_uint (node, "extended_limit",
4678                             ntohl (mp->extended_limit));
4679   vat_json_object_add_uint (node, "extended_bucket",
4680                             ntohl (mp->extended_bucket));
4681   vat_json_object_add_uint (node, "last_update_time",
4682                             ntohl (mp->last_update_time));
4683   vat_json_object_add_string_copy (node, "conform_action",
4684                                    conform_action_str);
4685   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4686     {
4687       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4688       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4689       vec_free (dscp_str);
4690     }
4691   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4692   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4693     {
4694       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4695       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4696       vec_free (dscp_str);
4697     }
4698   vat_json_object_add_string_copy (node, "violate_action",
4699                                    violate_action_str);
4700   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4701     {
4702       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4703       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4704       vec_free (dscp_str);
4705     }
4706
4707   vec_free (rate_type_str);
4708   vec_free (round_type_str);
4709   vec_free (type_str);
4710   vec_free (conform_action_str);
4711   vec_free (exceed_action_str);
4712   vec_free (violate_action_str);
4713 }
4714
4715 static void
4716 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4717                                            mp)
4718 {
4719   vat_main_t *vam = &vat_main;
4720   int i, count = ntohl (mp->count);
4721
4722   if (count > 0)
4723     print (vam->ofp, "classify table ids (%d) : ", count);
4724   for (i = 0; i < count; i++)
4725     {
4726       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4727       print (vam->ofp, (i < count - 1) ? "," : "");
4728     }
4729   vam->retval = ntohl (mp->retval);
4730   vam->result_ready = 1;
4731 }
4732
4733 static void
4734   vl_api_classify_table_ids_reply_t_handler_json
4735   (vl_api_classify_table_ids_reply_t * mp)
4736 {
4737   vat_main_t *vam = &vat_main;
4738   int i, count = ntohl (mp->count);
4739
4740   if (count > 0)
4741     {
4742       vat_json_node_t node;
4743
4744       vat_json_init_object (&node);
4745       for (i = 0; i < count; i++)
4746         {
4747           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4748         }
4749       vat_json_print (vam->ofp, &node);
4750       vat_json_free (&node);
4751     }
4752   vam->retval = ntohl (mp->retval);
4753   vam->result_ready = 1;
4754 }
4755
4756 static void
4757   vl_api_classify_table_by_interface_reply_t_handler
4758   (vl_api_classify_table_by_interface_reply_t * mp)
4759 {
4760   vat_main_t *vam = &vat_main;
4761   u32 table_id;
4762
4763   table_id = ntohl (mp->l2_table_id);
4764   if (table_id != ~0)
4765     print (vam->ofp, "l2 table id : %d", table_id);
4766   else
4767     print (vam->ofp, "l2 table id : No input ACL tables configured");
4768   table_id = ntohl (mp->ip4_table_id);
4769   if (table_id != ~0)
4770     print (vam->ofp, "ip4 table id : %d", table_id);
4771   else
4772     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4773   table_id = ntohl (mp->ip6_table_id);
4774   if (table_id != ~0)
4775     print (vam->ofp, "ip6 table id : %d", table_id);
4776   else
4777     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4778   vam->retval = ntohl (mp->retval);
4779   vam->result_ready = 1;
4780 }
4781
4782 static void
4783   vl_api_classify_table_by_interface_reply_t_handler_json
4784   (vl_api_classify_table_by_interface_reply_t * mp)
4785 {
4786   vat_main_t *vam = &vat_main;
4787   vat_json_node_t node;
4788
4789   vat_json_init_object (&node);
4790
4791   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4792   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4793   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4794
4795   vat_json_print (vam->ofp, &node);
4796   vat_json_free (&node);
4797
4798   vam->retval = ntohl (mp->retval);
4799   vam->result_ready = 1;
4800 }
4801
4802 static void vl_api_policer_add_del_reply_t_handler
4803   (vl_api_policer_add_del_reply_t * mp)
4804 {
4805   vat_main_t *vam = &vat_main;
4806   i32 retval = ntohl (mp->retval);
4807   if (vam->async_mode)
4808     {
4809       vam->async_errors += (retval < 0);
4810     }
4811   else
4812     {
4813       vam->retval = retval;
4814       vam->result_ready = 1;
4815       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4816         /*
4817          * Note: this is just barely thread-safe, depends on
4818          * the main thread spinning waiting for an answer...
4819          */
4820         errmsg ("policer index %d", ntohl (mp->policer_index));
4821     }
4822 }
4823
4824 static void vl_api_policer_add_del_reply_t_handler_json
4825   (vl_api_policer_add_del_reply_t * mp)
4826 {
4827   vat_main_t *vam = &vat_main;
4828   vat_json_node_t node;
4829
4830   vat_json_init_object (&node);
4831   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4832   vat_json_object_add_uint (&node, "policer_index",
4833                             ntohl (mp->policer_index));
4834
4835   vat_json_print (vam->ofp, &node);
4836   vat_json_free (&node);
4837
4838   vam->retval = ntohl (mp->retval);
4839   vam->result_ready = 1;
4840 }
4841
4842 /* Format hex dump. */
4843 u8 *
4844 format_hex_bytes (u8 * s, va_list * va)
4845 {
4846   u8 *bytes = va_arg (*va, u8 *);
4847   int n_bytes = va_arg (*va, int);
4848   uword i;
4849
4850   /* Print short or long form depending on byte count. */
4851   uword short_form = n_bytes <= 32;
4852   u32 indent = format_get_indent (s);
4853
4854   if (n_bytes == 0)
4855     return s;
4856
4857   for (i = 0; i < n_bytes; i++)
4858     {
4859       if (!short_form && (i % 32) == 0)
4860         s = format (s, "%08x: ", i);
4861       s = format (s, "%02x", bytes[i]);
4862       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4863         s = format (s, "\n%U", format_white_space, indent);
4864     }
4865
4866   return s;
4867 }
4868
4869 static void
4870 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4871                                             * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   i32 retval = ntohl (mp->retval);
4875   if (retval == 0)
4876     {
4877       print (vam->ofp, "classify table info :");
4878       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4879              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4880              ntohl (mp->miss_next_index));
4881       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4882              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4883              ntohl (mp->match_n_vectors));
4884       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4885              ntohl (mp->mask_length));
4886     }
4887   vam->retval = retval;
4888   vam->result_ready = 1;
4889 }
4890
4891 static void
4892   vl_api_classify_table_info_reply_t_handler_json
4893   (vl_api_classify_table_info_reply_t * mp)
4894 {
4895   vat_main_t *vam = &vat_main;
4896   vat_json_node_t node;
4897
4898   i32 retval = ntohl (mp->retval);
4899   if (retval == 0)
4900     {
4901       vat_json_init_object (&node);
4902
4903       vat_json_object_add_int (&node, "sessions",
4904                                ntohl (mp->active_sessions));
4905       vat_json_object_add_int (&node, "nexttbl",
4906                                ntohl (mp->next_table_index));
4907       vat_json_object_add_int (&node, "nextnode",
4908                                ntohl (mp->miss_next_index));
4909       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4910       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4911       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4912       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4913                       ntohl (mp->mask_length), 0);
4914       vat_json_object_add_string_copy (&node, "mask", s);
4915
4916       vat_json_print (vam->ofp, &node);
4917       vat_json_free (&node);
4918     }
4919   vam->retval = ntohl (mp->retval);
4920   vam->result_ready = 1;
4921 }
4922
4923 static void
4924 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4925                                            mp)
4926 {
4927   vat_main_t *vam = &vat_main;
4928
4929   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4930          ntohl (mp->hit_next_index), ntohl (mp->advance),
4931          ntohl (mp->opaque_index));
4932   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4933          ntohl (mp->match_length));
4934 }
4935
4936 static void
4937   vl_api_classify_session_details_t_handler_json
4938   (vl_api_classify_session_details_t * mp)
4939 {
4940   vat_main_t *vam = &vat_main;
4941   vat_json_node_t *node = NULL;
4942
4943   if (VAT_JSON_ARRAY != vam->json_tree.type)
4944     {
4945       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4946       vat_json_init_array (&vam->json_tree);
4947     }
4948   node = vat_json_array_add (&vam->json_tree);
4949
4950   vat_json_init_object (node);
4951   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4952   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4953   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4954   u8 *s =
4955     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4956             0);
4957   vat_json_object_add_string_copy (node, "match", s);
4958 }
4959
4960 static void vl_api_pg_create_interface_reply_t_handler
4961   (vl_api_pg_create_interface_reply_t * mp)
4962 {
4963   vat_main_t *vam = &vat_main;
4964
4965   vam->retval = ntohl (mp->retval);
4966   vam->result_ready = 1;
4967 }
4968
4969 static void vl_api_pg_create_interface_reply_t_handler_json
4970   (vl_api_pg_create_interface_reply_t * mp)
4971 {
4972   vat_main_t *vam = &vat_main;
4973   vat_json_node_t node;
4974
4975   i32 retval = ntohl (mp->retval);
4976   if (retval == 0)
4977     {
4978       vat_json_init_object (&node);
4979
4980       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4981
4982       vat_json_print (vam->ofp, &node);
4983       vat_json_free (&node);
4984     }
4985   vam->retval = ntohl (mp->retval);
4986   vam->result_ready = 1;
4987 }
4988
4989 static void vl_api_policer_classify_details_t_handler
4990   (vl_api_policer_classify_details_t * mp)
4991 {
4992   vat_main_t *vam = &vat_main;
4993
4994   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4995          ntohl (mp->table_index));
4996 }
4997
4998 static void vl_api_policer_classify_details_t_handler_json
4999   (vl_api_policer_classify_details_t * mp)
5000 {
5001   vat_main_t *vam = &vat_main;
5002   vat_json_node_t *node;
5003
5004   if (VAT_JSON_ARRAY != vam->json_tree.type)
5005     {
5006       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5007       vat_json_init_array (&vam->json_tree);
5008     }
5009   node = vat_json_array_add (&vam->json_tree);
5010
5011   vat_json_init_object (node);
5012   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5013   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5014 }
5015
5016 static void vl_api_flow_classify_details_t_handler
5017   (vl_api_flow_classify_details_t * mp)
5018 {
5019   vat_main_t *vam = &vat_main;
5020
5021   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5022          ntohl (mp->table_index));
5023 }
5024
5025 static void vl_api_flow_classify_details_t_handler_json
5026   (vl_api_flow_classify_details_t * mp)
5027 {
5028   vat_main_t *vam = &vat_main;
5029   vat_json_node_t *node;
5030
5031   if (VAT_JSON_ARRAY != vam->json_tree.type)
5032     {
5033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5034       vat_json_init_array (&vam->json_tree);
5035     }
5036   node = vat_json_array_add (&vam->json_tree);
5037
5038   vat_json_init_object (node);
5039   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5040   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5041 }
5042
5043 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5044 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5045 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5046 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5047 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5048 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5049 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5050 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5051 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5052 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5053
5054 /*
5055  * Generate boilerplate reply handlers, which
5056  * dig the return value out of the xxx_reply_t API message,
5057  * stick it into vam->retval, and set vam->result_ready
5058  *
5059  * Could also do this by pointing N message decode slots at
5060  * a single function, but that could break in subtle ways.
5061  */
5062
5063 #define foreach_standard_reply_retval_handler           \
5064 _(sw_interface_set_flags_reply)                         \
5065 _(sw_interface_add_del_address_reply)                   \
5066 _(sw_interface_set_rx_mode_reply)                       \
5067 _(sw_interface_set_rx_placement_reply)                  \
5068 _(sw_interface_set_table_reply)                         \
5069 _(sw_interface_set_mpls_enable_reply)                   \
5070 _(sw_interface_set_vpath_reply)                         \
5071 _(sw_interface_set_vxlan_bypass_reply)                  \
5072 _(sw_interface_set_geneve_bypass_reply)                 \
5073 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5074 _(sw_interface_set_l2_bridge_reply)                     \
5075 _(bridge_domain_add_del_reply)                          \
5076 _(sw_interface_set_l2_xconnect_reply)                   \
5077 _(l2fib_add_del_reply)                                  \
5078 _(l2fib_flush_int_reply)                                \
5079 _(l2fib_flush_bd_reply)                                 \
5080 _(ip_route_add_del_reply)                               \
5081 _(ip_table_add_del_reply)                               \
5082 _(ip_mroute_add_del_reply)                              \
5083 _(mpls_route_add_del_reply)                             \
5084 _(mpls_table_add_del_reply)                             \
5085 _(mpls_ip_bind_unbind_reply)                            \
5086 _(bier_route_add_del_reply)                             \
5087 _(bier_table_add_del_reply)                             \
5088 _(proxy_arp_add_del_reply)                              \
5089 _(proxy_arp_intfc_enable_disable_reply)                 \
5090 _(sw_interface_set_unnumbered_reply)                    \
5091 _(ip_neighbor_add_del_reply)                            \
5092 _(reset_fib_reply)                                      \
5093 _(dhcp_proxy_config_reply)                              \
5094 _(dhcp_proxy_set_vss_reply)                             \
5095 _(dhcp_client_config_reply)                             \
5096 _(set_ip_flow_hash_reply)                               \
5097 _(sw_interface_ip6_enable_disable_reply)                \
5098 _(ip6nd_proxy_add_del_reply)                            \
5099 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5100 _(sw_interface_ip6nd_ra_config_reply)                   \
5101 _(set_arp_neighbor_limit_reply)                         \
5102 _(l2_patch_add_del_reply)                               \
5103 _(sr_mpls_policy_add_reply)                             \
5104 _(sr_mpls_policy_mod_reply)                             \
5105 _(sr_mpls_policy_del_reply)                             \
5106 _(sr_policy_add_reply)                                  \
5107 _(sr_policy_mod_reply)                                  \
5108 _(sr_policy_del_reply)                                  \
5109 _(sr_localsid_add_del_reply)                            \
5110 _(sr_steering_add_del_reply)                            \
5111 _(classify_add_del_session_reply)                       \
5112 _(classify_set_interface_ip_table_reply)                \
5113 _(classify_set_interface_l2_tables_reply)               \
5114 _(l2tpv3_set_tunnel_cookies_reply)                      \
5115 _(l2tpv3_interface_enable_disable_reply)                \
5116 _(l2tpv3_set_lookup_key_reply)                          \
5117 _(l2_fib_clear_table_reply)                             \
5118 _(l2_interface_efp_filter_reply)                        \
5119 _(l2_interface_vlan_tag_rewrite_reply)                  \
5120 _(modify_vhost_user_if_reply)                           \
5121 _(delete_vhost_user_if_reply)                           \
5122 _(ip_probe_neighbor_reply)                              \
5123 _(ip_scan_neighbor_enable_disable_reply)                \
5124 _(want_ip4_arp_events_reply)                            \
5125 _(want_ip6_nd_events_reply)                             \
5126 _(want_l2_macs_events_reply)                            \
5127 _(input_acl_set_interface_reply)                        \
5128 _(ipsec_spd_add_del_reply)                              \
5129 _(ipsec_interface_add_del_spd_reply)                    \
5130 _(ipsec_spd_entry_add_del_reply)                        \
5131 _(ipsec_sad_entry_add_del_reply)                        \
5132 _(ipsec_tunnel_if_add_del_reply)                        \
5133 _(ipsec_tunnel_if_set_sa_reply)                         \
5134 _(delete_loopback_reply)                                \
5135 _(bd_ip_mac_add_del_reply)                              \
5136 _(bd_ip_mac_flush_reply)                                \
5137 _(want_interface_events_reply)                          \
5138 _(cop_interface_enable_disable_reply)                   \
5139 _(cop_whitelist_enable_disable_reply)                   \
5140 _(sw_interface_clear_stats_reply)                       \
5141 _(ioam_enable_reply)                                    \
5142 _(ioam_disable_reply)                                   \
5143 _(one_add_del_locator_reply)                            \
5144 _(one_add_del_local_eid_reply)                          \
5145 _(one_add_del_remote_mapping_reply)                     \
5146 _(one_add_del_adjacency_reply)                          \
5147 _(one_add_del_map_resolver_reply)                       \
5148 _(one_add_del_map_server_reply)                         \
5149 _(one_enable_disable_reply)                             \
5150 _(one_rloc_probe_enable_disable_reply)                  \
5151 _(one_map_register_enable_disable_reply)                \
5152 _(one_map_register_set_ttl_reply)                       \
5153 _(one_set_transport_protocol_reply)                     \
5154 _(one_map_register_fallback_threshold_reply)            \
5155 _(one_pitr_set_locator_set_reply)                       \
5156 _(one_map_request_mode_reply)                           \
5157 _(one_add_del_map_request_itr_rlocs_reply)              \
5158 _(one_eid_table_add_del_map_reply)                      \
5159 _(one_use_petr_reply)                                   \
5160 _(one_stats_enable_disable_reply)                       \
5161 _(one_add_del_l2_arp_entry_reply)                       \
5162 _(one_add_del_ndp_entry_reply)                          \
5163 _(one_stats_flush_reply)                                \
5164 _(one_enable_disable_xtr_mode_reply)                    \
5165 _(one_enable_disable_pitr_mode_reply)                   \
5166 _(one_enable_disable_petr_mode_reply)                   \
5167 _(gpe_enable_disable_reply)                             \
5168 _(gpe_set_encap_mode_reply)                             \
5169 _(gpe_add_del_iface_reply)                              \
5170 _(gpe_add_del_native_fwd_rpath_reply)                   \
5171 _(af_packet_delete_reply)                               \
5172 _(policer_classify_set_interface_reply)                 \
5173 _(netmap_create_reply)                                  \
5174 _(netmap_delete_reply)                                  \
5175 _(set_ipfix_exporter_reply)                             \
5176 _(set_ipfix_classify_stream_reply)                      \
5177 _(ipfix_classify_table_add_del_reply)                   \
5178 _(flow_classify_set_interface_reply)                    \
5179 _(sw_interface_span_enable_disable_reply)               \
5180 _(pg_capture_reply)                                     \
5181 _(pg_enable_disable_reply)                              \
5182 _(ip_source_and_port_range_check_add_del_reply)         \
5183 _(ip_source_and_port_range_check_interface_add_del_reply)\
5184 _(delete_subif_reply)                                   \
5185 _(l2_interface_pbb_tag_rewrite_reply)                   \
5186 _(set_punt_reply)                                       \
5187 _(feature_enable_disable_reply)                         \
5188 _(sw_interface_tag_add_del_reply)                       \
5189 _(hw_interface_set_mtu_reply)                           \
5190 _(p2p_ethernet_add_reply)                               \
5191 _(p2p_ethernet_del_reply)                               \
5192 _(lldp_config_reply)                                    \
5193 _(sw_interface_set_lldp_reply)                          \
5194 _(tcp_configure_src_addresses_reply)                    \
5195 _(session_rule_add_del_reply)                           \
5196 _(ip_container_proxy_add_del_reply)                     \
5197 _(output_acl_set_interface_reply)                       \
5198 _(qos_record_enable_disable_reply)
5199
5200 #define _(n)                                    \
5201     static void vl_api_##n##_t_handler          \
5202     (vl_api_##n##_t * mp)                       \
5203     {                                           \
5204         vat_main_t * vam = &vat_main;           \
5205         i32 retval = ntohl(mp->retval);         \
5206         if (vam->async_mode) {                  \
5207             vam->async_errors += (retval < 0);  \
5208         } else {                                \
5209             vam->retval = retval;               \
5210             vam->result_ready = 1;              \
5211         }                                       \
5212     }
5213 foreach_standard_reply_retval_handler;
5214 #undef _
5215
5216 #define _(n)                                    \
5217     static void vl_api_##n##_t_handler_json     \
5218     (vl_api_##n##_t * mp)                       \
5219     {                                           \
5220         vat_main_t * vam = &vat_main;           \
5221         vat_json_node_t node;                   \
5222         vat_json_init_object(&node);            \
5223         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5224         vat_json_print(vam->ofp, &node);        \
5225         vam->retval = ntohl(mp->retval);        \
5226         vam->result_ready = 1;                  \
5227     }
5228 foreach_standard_reply_retval_handler;
5229 #undef _
5230
5231 /*
5232  * Table of message reply handlers, must include boilerplate handlers
5233  * we just generated
5234  */
5235
5236 #define foreach_vpe_api_reply_msg                                       \
5237 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5238 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5239 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5240 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5241 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5242 _(CLI_REPLY, cli_reply)                                                 \
5243 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5244 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5245   sw_interface_add_del_address_reply)                                   \
5246 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5247 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5248 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5249 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5250 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5251 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5252 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5253 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5254 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5255 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5256   sw_interface_set_l2_xconnect_reply)                                   \
5257 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5258   sw_interface_set_l2_bridge_reply)                                     \
5259 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5260 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5261 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5262 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5263 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5264 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5265 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5266 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5267 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5268 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5269 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5270 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5271 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5272 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5273 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5274 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5275 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5276 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5277 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5278 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5279 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5280 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5281 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5282 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5283 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5284 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5285 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5286 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5287 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5288 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5289   proxy_arp_intfc_enable_disable_reply)                                 \
5290 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5291 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5292   sw_interface_set_unnumbered_reply)                                    \
5293 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5294 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5295 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5296 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5297 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5298 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5299 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5300 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5301 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5302 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5303   sw_interface_ip6_enable_disable_reply)                                \
5304 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5305 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5306 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5307   sw_interface_ip6nd_ra_prefix_reply)                                   \
5308 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5309   sw_interface_ip6nd_ra_config_reply)                                   \
5310 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5311 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5312 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5313 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5314 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5315 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5316 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5317 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5318 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5319 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5320 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5321 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5322 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5323 classify_set_interface_ip_table_reply)                                  \
5324 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5325   classify_set_interface_l2_tables_reply)                               \
5326 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5327 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5328 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5329 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5330 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5331   l2tpv3_interface_enable_disable_reply)                                \
5332 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5333 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5334 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5335 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5336 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5337 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5338 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5339 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5340 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5341 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5342 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5343 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5344 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5345 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5346 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5347 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5348 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5349 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5350 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5351 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5352 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5353 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5354 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5355 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5356 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5357 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5358 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5359 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5360 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5361 _(L2_MACS_EVENT, l2_macs_event)                                         \
5362 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5363 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5364 _(IP_DETAILS, ip_details)                                               \
5365 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5366 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5367 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5368 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5369 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5370 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5371 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5372 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5373 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5374 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5375 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5376 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5377 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5378 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5379 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5380 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5381 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5382 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5383 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5384 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5385 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5386 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5387 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5388 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5389 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5390 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5391 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5392 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5393 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5394   one_map_register_enable_disable_reply)                                \
5395 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5396 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5397 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5398 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5399   one_map_register_fallback_threshold_reply)                            \
5400 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5401   one_rloc_probe_enable_disable_reply)                                  \
5402 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5403 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5404 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5405 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5406 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5407 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5408 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5409 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5410 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5411 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5412 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5413 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5414 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5415 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5416 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5417 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5418   show_one_stats_enable_disable_reply)                                  \
5419 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5420 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5421 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5422 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5423 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5424 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5425 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5426 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5427   one_enable_disable_pitr_mode_reply)                                   \
5428 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5429   one_enable_disable_petr_mode_reply)                                   \
5430 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5431 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5432 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5433 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5434 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5435 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5436 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5437 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5438 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5439 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5440 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5441 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5442   gpe_add_del_native_fwd_rpath_reply)                                   \
5443 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5444   gpe_fwd_entry_path_details)                                           \
5445 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5446 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5447   one_add_del_map_request_itr_rlocs_reply)                              \
5448 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5449   one_get_map_request_itr_rlocs_reply)                                  \
5450 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5451 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5452 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5453 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5454 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5455 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5456   show_one_map_register_state_reply)                                    \
5457 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5458 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5459   show_one_map_register_fallback_threshold_reply)                       \
5460 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5461 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5462 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5463 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5464 _(POLICER_DETAILS, policer_details)                                     \
5465 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5466 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5467 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5468 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5469 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5470 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5471 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5472 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5473 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5474 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5475 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5476 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5477 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5478 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5479 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5480 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5481 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5482 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5483 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5484 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5485 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5486 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5487 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5488 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5489 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5490 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5491  ip_source_and_port_range_check_add_del_reply)                          \
5492 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5493  ip_source_and_port_range_check_interface_add_del_reply)                \
5494 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5495 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5496 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5497 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5498 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5499 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5500 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5501 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5502 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5503 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5504 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5505 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5506 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5507 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5508 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5509 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5510 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5511 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5512 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5513 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5514 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5515 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5516
5517 #define foreach_standalone_reply_msg                                    \
5518 _(SW_INTERFACE_EVENT, sw_interface_event)
5519
5520 typedef struct
5521 {
5522   u8 *name;
5523   u32 value;
5524 } name_sort_t;
5525
5526 #define STR_VTR_OP_CASE(op)     \
5527     case L2_VTR_ ## op:         \
5528         return "" # op;
5529
5530 static const char *
5531 str_vtr_op (u32 vtr_op)
5532 {
5533   switch (vtr_op)
5534     {
5535       STR_VTR_OP_CASE (DISABLED);
5536       STR_VTR_OP_CASE (PUSH_1);
5537       STR_VTR_OP_CASE (PUSH_2);
5538       STR_VTR_OP_CASE (POP_1);
5539       STR_VTR_OP_CASE (POP_2);
5540       STR_VTR_OP_CASE (TRANSLATE_1_1);
5541       STR_VTR_OP_CASE (TRANSLATE_1_2);
5542       STR_VTR_OP_CASE (TRANSLATE_2_1);
5543       STR_VTR_OP_CASE (TRANSLATE_2_2);
5544     }
5545
5546   return "UNKNOWN";
5547 }
5548
5549 static int
5550 dump_sub_interface_table (vat_main_t * vam)
5551 {
5552   const sw_interface_subif_t *sub = NULL;
5553
5554   if (vam->json_output)
5555     {
5556       clib_warning
5557         ("JSON output supported only for VPE API calls and dump_stats_table");
5558       return -99;
5559     }
5560
5561   print (vam->ofp,
5562          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5563          "Interface", "sw_if_index",
5564          "sub id", "dot1ad", "tags", "outer id",
5565          "inner id", "exact", "default", "outer any", "inner any");
5566
5567   vec_foreach (sub, vam->sw_if_subif_table)
5568   {
5569     print (vam->ofp,
5570            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5571            sub->interface_name,
5572            sub->sw_if_index,
5573            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5574            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5575            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5576            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5577     if (sub->vtr_op != L2_VTR_DISABLED)
5578       {
5579         print (vam->ofp,
5580                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5581                "tag1: %d tag2: %d ]",
5582                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5583                sub->vtr_tag1, sub->vtr_tag2);
5584       }
5585   }
5586
5587   return 0;
5588 }
5589
5590 static int
5591 name_sort_cmp (void *a1, void *a2)
5592 {
5593   name_sort_t *n1 = a1;
5594   name_sort_t *n2 = a2;
5595
5596   return strcmp ((char *) n1->name, (char *) n2->name);
5597 }
5598
5599 static int
5600 dump_interface_table (vat_main_t * vam)
5601 {
5602   hash_pair_t *p;
5603   name_sort_t *nses = 0, *ns;
5604
5605   if (vam->json_output)
5606     {
5607       clib_warning
5608         ("JSON output supported only for VPE API calls and dump_stats_table");
5609       return -99;
5610     }
5611
5612   /* *INDENT-OFF* */
5613   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5614   ({
5615     vec_add2 (nses, ns, 1);
5616     ns->name = (u8 *)(p->key);
5617     ns->value = (u32) p->value[0];
5618   }));
5619   /* *INDENT-ON* */
5620
5621   vec_sort_with_function (nses, name_sort_cmp);
5622
5623   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5624   vec_foreach (ns, nses)
5625   {
5626     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5627   }
5628   vec_free (nses);
5629   return 0;
5630 }
5631
5632 static int
5633 dump_ip_table (vat_main_t * vam, int is_ipv6)
5634 {
5635   const ip_details_t *det = NULL;
5636   const ip_address_details_t *address = NULL;
5637   u32 i = ~0;
5638
5639   print (vam->ofp, "%-12s", "sw_if_index");
5640
5641   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5642   {
5643     i++;
5644     if (!det->present)
5645       {
5646         continue;
5647       }
5648     print (vam->ofp, "%-12d", i);
5649     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5650     if (!det->addr)
5651       {
5652         continue;
5653       }
5654     vec_foreach (address, det->addr)
5655     {
5656       print (vam->ofp,
5657              "            %-30U%-13d",
5658              is_ipv6 ? format_ip6_address : format_ip4_address,
5659              address->ip, address->prefix_length);
5660     }
5661   }
5662
5663   return 0;
5664 }
5665
5666 static int
5667 dump_ipv4_table (vat_main_t * vam)
5668 {
5669   if (vam->json_output)
5670     {
5671       clib_warning
5672         ("JSON output supported only for VPE API calls and dump_stats_table");
5673       return -99;
5674     }
5675
5676   return dump_ip_table (vam, 0);
5677 }
5678
5679 static int
5680 dump_ipv6_table (vat_main_t * vam)
5681 {
5682   if (vam->json_output)
5683     {
5684       clib_warning
5685         ("JSON output supported only for VPE API calls and dump_stats_table");
5686       return -99;
5687     }
5688
5689   return dump_ip_table (vam, 1);
5690 }
5691
5692 /*
5693  * Pass CLI buffers directly in the CLI_INBAND API message,
5694  * instead of an additional shared memory area.
5695  */
5696 static int
5697 exec_inband (vat_main_t * vam)
5698 {
5699   vl_api_cli_inband_t *mp;
5700   unformat_input_t *i = vam->input;
5701   int ret;
5702
5703   if (vec_len (i->buffer) == 0)
5704     return -1;
5705
5706   if (vam->exec_mode == 0 && unformat (i, "mode"))
5707     {
5708       vam->exec_mode = 1;
5709       return 0;
5710     }
5711   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5712     {
5713       vam->exec_mode = 0;
5714       return 0;
5715     }
5716
5717   /*
5718    * In order for the CLI command to work, it
5719    * must be a vector ending in \n, not a C-string ending
5720    * in \n\0.
5721    */
5722   u32 len = vec_len (vam->input->buffer);
5723   M2 (CLI_INBAND, mp, len);
5724   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5725
5726   S (mp);
5727   W (ret);
5728   /* json responses may or may not include a useful reply... */
5729   if (vec_len (vam->cmd_reply))
5730     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5731   return ret;
5732 }
5733
5734 int
5735 exec (vat_main_t * vam)
5736 {
5737   return exec_inband (vam);
5738 }
5739
5740 static int
5741 api_create_loopback (vat_main_t * vam)
5742 {
5743   unformat_input_t *i = vam->input;
5744   vl_api_create_loopback_t *mp;
5745   vl_api_create_loopback_instance_t *mp_lbi;
5746   u8 mac_address[6];
5747   u8 mac_set = 0;
5748   u8 is_specified = 0;
5749   u32 user_instance = 0;
5750   int ret;
5751
5752   clib_memset (mac_address, 0, sizeof (mac_address));
5753
5754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5755     {
5756       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5757         mac_set = 1;
5758       if (unformat (i, "instance %d", &user_instance))
5759         is_specified = 1;
5760       else
5761         break;
5762     }
5763
5764   if (is_specified)
5765     {
5766       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5767       mp_lbi->is_specified = is_specified;
5768       if (is_specified)
5769         mp_lbi->user_instance = htonl (user_instance);
5770       if (mac_set)
5771         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5772       S (mp_lbi);
5773     }
5774   else
5775     {
5776       /* Construct the API message */
5777       M (CREATE_LOOPBACK, mp);
5778       if (mac_set)
5779         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5780       S (mp);
5781     }
5782
5783   W (ret);
5784   return ret;
5785 }
5786
5787 static int
5788 api_delete_loopback (vat_main_t * vam)
5789 {
5790   unformat_input_t *i = vam->input;
5791   vl_api_delete_loopback_t *mp;
5792   u32 sw_if_index = ~0;
5793   int ret;
5794
5795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5796     {
5797       if (unformat (i, "sw_if_index %d", &sw_if_index))
5798         ;
5799       else
5800         break;
5801     }
5802
5803   if (sw_if_index == ~0)
5804     {
5805       errmsg ("missing sw_if_index");
5806       return -99;
5807     }
5808
5809   /* Construct the API message */
5810   M (DELETE_LOOPBACK, mp);
5811   mp->sw_if_index = ntohl (sw_if_index);
5812
5813   S (mp);
5814   W (ret);
5815   return ret;
5816 }
5817
5818 static int
5819 api_want_interface_events (vat_main_t * vam)
5820 {
5821   unformat_input_t *i = vam->input;
5822   vl_api_want_interface_events_t *mp;
5823   int enable = -1;
5824   int ret;
5825
5826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5827     {
5828       if (unformat (i, "enable"))
5829         enable = 1;
5830       else if (unformat (i, "disable"))
5831         enable = 0;
5832       else
5833         break;
5834     }
5835
5836   if (enable == -1)
5837     {
5838       errmsg ("missing enable|disable");
5839       return -99;
5840     }
5841
5842   M (WANT_INTERFACE_EVENTS, mp);
5843   mp->enable_disable = enable;
5844
5845   vam->interface_event_display = enable;
5846
5847   S (mp);
5848   W (ret);
5849   return ret;
5850 }
5851
5852
5853 /* Note: non-static, called once to set up the initial intfc table */
5854 int
5855 api_sw_interface_dump (vat_main_t * vam)
5856 {
5857   vl_api_sw_interface_dump_t *mp;
5858   vl_api_control_ping_t *mp_ping;
5859   hash_pair_t *p;
5860   name_sort_t *nses = 0, *ns;
5861   sw_interface_subif_t *sub = NULL;
5862   int ret;
5863
5864   /* Toss the old name table */
5865   /* *INDENT-OFF* */
5866   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5867   ({
5868     vec_add2 (nses, ns, 1);
5869     ns->name = (u8 *)(p->key);
5870     ns->value = (u32) p->value[0];
5871   }));
5872   /* *INDENT-ON* */
5873
5874   hash_free (vam->sw_if_index_by_interface_name);
5875
5876   vec_foreach (ns, nses) vec_free (ns->name);
5877
5878   vec_free (nses);
5879
5880   vec_foreach (sub, vam->sw_if_subif_table)
5881   {
5882     vec_free (sub->interface_name);
5883   }
5884   vec_free (vam->sw_if_subif_table);
5885
5886   /* recreate the interface name hash table */
5887   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5888
5889   /*
5890    * Ask for all interface names. Otherwise, the epic catalog of
5891    * name filters becomes ridiculously long, and vat ends up needing
5892    * to be taught about new interface types.
5893    */
5894   M (SW_INTERFACE_DUMP, mp);
5895   S (mp);
5896
5897   /* Use a control ping for synchronization */
5898   MPING (CONTROL_PING, mp_ping);
5899   S (mp_ping);
5900
5901   W (ret);
5902   return ret;
5903 }
5904
5905 static int
5906 api_sw_interface_set_flags (vat_main_t * vam)
5907 {
5908   unformat_input_t *i = vam->input;
5909   vl_api_sw_interface_set_flags_t *mp;
5910   u32 sw_if_index;
5911   u8 sw_if_index_set = 0;
5912   u8 admin_up = 0;
5913   int ret;
5914
5915   /* Parse args required to build the message */
5916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5917     {
5918       if (unformat (i, "admin-up"))
5919         admin_up = 1;
5920       else if (unformat (i, "admin-down"))
5921         admin_up = 0;
5922       else
5923         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5924         sw_if_index_set = 1;
5925       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5926         sw_if_index_set = 1;
5927       else
5928         break;
5929     }
5930
5931   if (sw_if_index_set == 0)
5932     {
5933       errmsg ("missing interface name or sw_if_index");
5934       return -99;
5935     }
5936
5937   /* Construct the API message */
5938   M (SW_INTERFACE_SET_FLAGS, mp);
5939   mp->sw_if_index = ntohl (sw_if_index);
5940   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5941
5942   /* send it... */
5943   S (mp);
5944
5945   /* Wait for a reply, return the good/bad news... */
5946   W (ret);
5947   return ret;
5948 }
5949
5950 static int
5951 api_sw_interface_set_rx_mode (vat_main_t * vam)
5952 {
5953   unformat_input_t *i = vam->input;
5954   vl_api_sw_interface_set_rx_mode_t *mp;
5955   u32 sw_if_index;
5956   u8 sw_if_index_set = 0;
5957   int ret;
5958   u8 queue_id_valid = 0;
5959   u32 queue_id;
5960   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5961
5962   /* Parse args required to build the message */
5963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5964     {
5965       if (unformat (i, "queue %d", &queue_id))
5966         queue_id_valid = 1;
5967       else if (unformat (i, "polling"))
5968         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5969       else if (unformat (i, "interrupt"))
5970         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5971       else if (unformat (i, "adaptive"))
5972         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5973       else
5974         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5975         sw_if_index_set = 1;
5976       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5977         sw_if_index_set = 1;
5978       else
5979         break;
5980     }
5981
5982   if (sw_if_index_set == 0)
5983     {
5984       errmsg ("missing interface name or sw_if_index");
5985       return -99;
5986     }
5987   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5988     {
5989       errmsg ("missing rx-mode");
5990       return -99;
5991     }
5992
5993   /* Construct the API message */
5994   M (SW_INTERFACE_SET_RX_MODE, mp);
5995   mp->sw_if_index = ntohl (sw_if_index);
5996   mp->mode = (vl_api_rx_mode_t) mode;
5997   mp->queue_id_valid = queue_id_valid;
5998   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5999
6000   /* send it... */
6001   S (mp);
6002
6003   /* Wait for a reply, return the good/bad news... */
6004   W (ret);
6005   return ret;
6006 }
6007
6008 static int
6009 api_sw_interface_set_rx_placement (vat_main_t * vam)
6010 {
6011   unformat_input_t *i = vam->input;
6012   vl_api_sw_interface_set_rx_placement_t *mp;
6013   u32 sw_if_index;
6014   u8 sw_if_index_set = 0;
6015   int ret;
6016   u8 is_main = 0;
6017   u32 queue_id, thread_index;
6018
6019   /* Parse args required to build the message */
6020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6021     {
6022       if (unformat (i, "queue %d", &queue_id))
6023         ;
6024       else if (unformat (i, "main"))
6025         is_main = 1;
6026       else if (unformat (i, "worker %d", &thread_index))
6027         ;
6028       else
6029         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6030         sw_if_index_set = 1;
6031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6032         sw_if_index_set = 1;
6033       else
6034         break;
6035     }
6036
6037   if (sw_if_index_set == 0)
6038     {
6039       errmsg ("missing interface name or sw_if_index");
6040       return -99;
6041     }
6042
6043   if (is_main)
6044     thread_index = 0;
6045   /* Construct the API message */
6046   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6047   mp->sw_if_index = ntohl (sw_if_index);
6048   mp->worker_id = ntohl (thread_index);
6049   mp->queue_id = ntohl (queue_id);
6050   mp->is_main = is_main;
6051
6052   /* send it... */
6053   S (mp);
6054   /* Wait for a reply, return the good/bad news... */
6055   W (ret);
6056   return ret;
6057 }
6058
6059 static void vl_api_sw_interface_rx_placement_details_t_handler
6060   (vl_api_sw_interface_rx_placement_details_t * mp)
6061 {
6062   vat_main_t *vam = &vat_main;
6063   u32 worker_id = ntohl (mp->worker_id);
6064
6065   print (vam->ofp,
6066          "\n%-11d %-11s %-6d %-5d %-9s",
6067          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6068          worker_id, ntohl (mp->queue_id),
6069          (mp->mode ==
6070           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6071 }
6072
6073 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6074   (vl_api_sw_interface_rx_placement_details_t * mp)
6075 {
6076   vat_main_t *vam = &vat_main;
6077   vat_json_node_t *node = NULL;
6078
6079   if (VAT_JSON_ARRAY != vam->json_tree.type)
6080     {
6081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6082       vat_json_init_array (&vam->json_tree);
6083     }
6084   node = vat_json_array_add (&vam->json_tree);
6085
6086   vat_json_init_object (node);
6087   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6088   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6089   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6090   vat_json_object_add_uint (node, "mode", mp->mode);
6091 }
6092
6093 static int
6094 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6095 {
6096   unformat_input_t *i = vam->input;
6097   vl_api_sw_interface_rx_placement_dump_t *mp;
6098   vl_api_control_ping_t *mp_ping;
6099   int ret;
6100   u32 sw_if_index;
6101   u8 sw_if_index_set = 0;
6102
6103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6104     {
6105       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6106         sw_if_index_set++;
6107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6108         sw_if_index_set++;
6109       else
6110         break;
6111     }
6112
6113   print (vam->ofp,
6114          "\n%-11s %-11s %-6s %-5s %-4s",
6115          "sw_if_index", "main/worker", "thread", "queue", "mode");
6116
6117   /* Dump Interface rx placement */
6118   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6119
6120   if (sw_if_index_set)
6121     mp->sw_if_index = htonl (sw_if_index);
6122   else
6123     mp->sw_if_index = ~0;
6124
6125   S (mp);
6126
6127   /* Use a control ping for synchronization */
6128   MPING (CONTROL_PING, mp_ping);
6129   S (mp_ping);
6130
6131   W (ret);
6132   return ret;
6133 }
6134
6135 static int
6136 api_sw_interface_clear_stats (vat_main_t * vam)
6137 {
6138   unformat_input_t *i = vam->input;
6139   vl_api_sw_interface_clear_stats_t *mp;
6140   u32 sw_if_index;
6141   u8 sw_if_index_set = 0;
6142   int ret;
6143
6144   /* Parse args required to build the message */
6145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6146     {
6147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6148         sw_if_index_set = 1;
6149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6150         sw_if_index_set = 1;
6151       else
6152         break;
6153     }
6154
6155   /* Construct the API message */
6156   M (SW_INTERFACE_CLEAR_STATS, mp);
6157
6158   if (sw_if_index_set == 1)
6159     mp->sw_if_index = ntohl (sw_if_index);
6160   else
6161     mp->sw_if_index = ~0;
6162
6163   /* send it... */
6164   S (mp);
6165
6166   /* Wait for a reply, return the good/bad news... */
6167   W (ret);
6168   return ret;
6169 }
6170
6171 static int
6172 api_sw_interface_add_del_address (vat_main_t * vam)
6173 {
6174   unformat_input_t *i = vam->input;
6175   vl_api_sw_interface_add_del_address_t *mp;
6176   u32 sw_if_index;
6177   u8 sw_if_index_set = 0;
6178   u8 is_add = 1, del_all = 0;
6179   u32 address_length = 0;
6180   u8 v4_address_set = 0;
6181   u8 v6_address_set = 0;
6182   ip4_address_t v4address;
6183   ip6_address_t v6address;
6184   int ret;
6185
6186   /* Parse args required to build the message */
6187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6188     {
6189       if (unformat (i, "del-all"))
6190         del_all = 1;
6191       else if (unformat (i, "del"))
6192         is_add = 0;
6193       else
6194         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6195         sw_if_index_set = 1;
6196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6197         sw_if_index_set = 1;
6198       else if (unformat (i, "%U/%d",
6199                          unformat_ip4_address, &v4address, &address_length))
6200         v4_address_set = 1;
6201       else if (unformat (i, "%U/%d",
6202                          unformat_ip6_address, &v6address, &address_length))
6203         v6_address_set = 1;
6204       else
6205         break;
6206     }
6207
6208   if (sw_if_index_set == 0)
6209     {
6210       errmsg ("missing interface name or sw_if_index");
6211       return -99;
6212     }
6213   if (v4_address_set && v6_address_set)
6214     {
6215       errmsg ("both v4 and v6 addresses set");
6216       return -99;
6217     }
6218   if (!v4_address_set && !v6_address_set && !del_all)
6219     {
6220       errmsg ("no addresses set");
6221       return -99;
6222     }
6223
6224   /* Construct the API message */
6225   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6226
6227   mp->sw_if_index = ntohl (sw_if_index);
6228   mp->is_add = is_add;
6229   mp->del_all = del_all;
6230   if (v6_address_set)
6231     {
6232       mp->prefix.address.af = ADDRESS_IP6;
6233       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6234     }
6235   else
6236     {
6237       mp->prefix.address.af = ADDRESS_IP4;
6238       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6239     }
6240   mp->prefix.len = address_length;
6241
6242   /* send it... */
6243   S (mp);
6244
6245   /* Wait for a reply, return good/bad news  */
6246   W (ret);
6247   return ret;
6248 }
6249
6250 static int
6251 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6252 {
6253   unformat_input_t *i = vam->input;
6254   vl_api_sw_interface_set_mpls_enable_t *mp;
6255   u32 sw_if_index;
6256   u8 sw_if_index_set = 0;
6257   u8 enable = 1;
6258   int ret;
6259
6260   /* Parse args required to build the message */
6261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6262     {
6263       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6264         sw_if_index_set = 1;
6265       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6266         sw_if_index_set = 1;
6267       else if (unformat (i, "disable"))
6268         enable = 0;
6269       else if (unformat (i, "dis"))
6270         enable = 0;
6271       else
6272         break;
6273     }
6274
6275   if (sw_if_index_set == 0)
6276     {
6277       errmsg ("missing interface name or sw_if_index");
6278       return -99;
6279     }
6280
6281   /* Construct the API message */
6282   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6283
6284   mp->sw_if_index = ntohl (sw_if_index);
6285   mp->enable = enable;
6286
6287   /* send it... */
6288   S (mp);
6289
6290   /* Wait for a reply... */
6291   W (ret);
6292   return ret;
6293 }
6294
6295 static int
6296 api_sw_interface_set_table (vat_main_t * vam)
6297 {
6298   unformat_input_t *i = vam->input;
6299   vl_api_sw_interface_set_table_t *mp;
6300   u32 sw_if_index, vrf_id = 0;
6301   u8 sw_if_index_set = 0;
6302   u8 is_ipv6 = 0;
6303   int ret;
6304
6305   /* Parse args required to build the message */
6306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6307     {
6308       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6309         sw_if_index_set = 1;
6310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6311         sw_if_index_set = 1;
6312       else if (unformat (i, "vrf %d", &vrf_id))
6313         ;
6314       else if (unformat (i, "ipv6"))
6315         is_ipv6 = 1;
6316       else
6317         break;
6318     }
6319
6320   if (sw_if_index_set == 0)
6321     {
6322       errmsg ("missing interface name or sw_if_index");
6323       return -99;
6324     }
6325
6326   /* Construct the API message */
6327   M (SW_INTERFACE_SET_TABLE, mp);
6328
6329   mp->sw_if_index = ntohl (sw_if_index);
6330   mp->is_ipv6 = is_ipv6;
6331   mp->vrf_id = ntohl (vrf_id);
6332
6333   /* send it... */
6334   S (mp);
6335
6336   /* Wait for a reply... */
6337   W (ret);
6338   return ret;
6339 }
6340
6341 static void vl_api_sw_interface_get_table_reply_t_handler
6342   (vl_api_sw_interface_get_table_reply_t * mp)
6343 {
6344   vat_main_t *vam = &vat_main;
6345
6346   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6347
6348   vam->retval = ntohl (mp->retval);
6349   vam->result_ready = 1;
6350
6351 }
6352
6353 static void vl_api_sw_interface_get_table_reply_t_handler_json
6354   (vl_api_sw_interface_get_table_reply_t * mp)
6355 {
6356   vat_main_t *vam = &vat_main;
6357   vat_json_node_t node;
6358
6359   vat_json_init_object (&node);
6360   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6361   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6362
6363   vat_json_print (vam->ofp, &node);
6364   vat_json_free (&node);
6365
6366   vam->retval = ntohl (mp->retval);
6367   vam->result_ready = 1;
6368 }
6369
6370 static int
6371 api_sw_interface_get_table (vat_main_t * vam)
6372 {
6373   unformat_input_t *i = vam->input;
6374   vl_api_sw_interface_get_table_t *mp;
6375   u32 sw_if_index;
6376   u8 sw_if_index_set = 0;
6377   u8 is_ipv6 = 0;
6378   int ret;
6379
6380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6381     {
6382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6383         sw_if_index_set = 1;
6384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6385         sw_if_index_set = 1;
6386       else if (unformat (i, "ipv6"))
6387         is_ipv6 = 1;
6388       else
6389         break;
6390     }
6391
6392   if (sw_if_index_set == 0)
6393     {
6394       errmsg ("missing interface name or sw_if_index");
6395       return -99;
6396     }
6397
6398   M (SW_INTERFACE_GET_TABLE, mp);
6399   mp->sw_if_index = htonl (sw_if_index);
6400   mp->is_ipv6 = is_ipv6;
6401
6402   S (mp);
6403   W (ret);
6404   return ret;
6405 }
6406
6407 static int
6408 api_sw_interface_set_vpath (vat_main_t * vam)
6409 {
6410   unformat_input_t *i = vam->input;
6411   vl_api_sw_interface_set_vpath_t *mp;
6412   u32 sw_if_index = 0;
6413   u8 sw_if_index_set = 0;
6414   u8 is_enable = 0;
6415   int ret;
6416
6417   /* Parse args required to build the message */
6418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6419     {
6420       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6421         sw_if_index_set = 1;
6422       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6423         sw_if_index_set = 1;
6424       else if (unformat (i, "enable"))
6425         is_enable = 1;
6426       else if (unformat (i, "disable"))
6427         is_enable = 0;
6428       else
6429         break;
6430     }
6431
6432   if (sw_if_index_set == 0)
6433     {
6434       errmsg ("missing interface name or sw_if_index");
6435       return -99;
6436     }
6437
6438   /* Construct the API message */
6439   M (SW_INTERFACE_SET_VPATH, mp);
6440
6441   mp->sw_if_index = ntohl (sw_if_index);
6442   mp->enable = is_enable;
6443
6444   /* send it... */
6445   S (mp);
6446
6447   /* Wait for a reply... */
6448   W (ret);
6449   return ret;
6450 }
6451
6452 static int
6453 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6454 {
6455   unformat_input_t *i = vam->input;
6456   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6457   u32 sw_if_index = 0;
6458   u8 sw_if_index_set = 0;
6459   u8 is_enable = 1;
6460   u8 is_ipv6 = 0;
6461   int ret;
6462
6463   /* Parse args required to build the message */
6464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6465     {
6466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6467         sw_if_index_set = 1;
6468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6469         sw_if_index_set = 1;
6470       else if (unformat (i, "enable"))
6471         is_enable = 1;
6472       else if (unformat (i, "disable"))
6473         is_enable = 0;
6474       else if (unformat (i, "ip4"))
6475         is_ipv6 = 0;
6476       else if (unformat (i, "ip6"))
6477         is_ipv6 = 1;
6478       else
6479         break;
6480     }
6481
6482   if (sw_if_index_set == 0)
6483     {
6484       errmsg ("missing interface name or sw_if_index");
6485       return -99;
6486     }
6487
6488   /* Construct the API message */
6489   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6490
6491   mp->sw_if_index = ntohl (sw_if_index);
6492   mp->enable = is_enable;
6493   mp->is_ipv6 = is_ipv6;
6494
6495   /* send it... */
6496   S (mp);
6497
6498   /* Wait for a reply... */
6499   W (ret);
6500   return ret;
6501 }
6502
6503 static int
6504 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6505 {
6506   unformat_input_t *i = vam->input;
6507   vl_api_sw_interface_set_geneve_bypass_t *mp;
6508   u32 sw_if_index = 0;
6509   u8 sw_if_index_set = 0;
6510   u8 is_enable = 1;
6511   u8 is_ipv6 = 0;
6512   int ret;
6513
6514   /* Parse args required to build the message */
6515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6516     {
6517       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6518         sw_if_index_set = 1;
6519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6520         sw_if_index_set = 1;
6521       else if (unformat (i, "enable"))
6522         is_enable = 1;
6523       else if (unformat (i, "disable"))
6524         is_enable = 0;
6525       else if (unformat (i, "ip4"))
6526         is_ipv6 = 0;
6527       else if (unformat (i, "ip6"))
6528         is_ipv6 = 1;
6529       else
6530         break;
6531     }
6532
6533   if (sw_if_index_set == 0)
6534     {
6535       errmsg ("missing interface name or sw_if_index");
6536       return -99;
6537     }
6538
6539   /* Construct the API message */
6540   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6541
6542   mp->sw_if_index = ntohl (sw_if_index);
6543   mp->enable = is_enable;
6544   mp->is_ipv6 = is_ipv6;
6545
6546   /* send it... */
6547   S (mp);
6548
6549   /* Wait for a reply... */
6550   W (ret);
6551   return ret;
6552 }
6553
6554 static int
6555 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6556 {
6557   unformat_input_t *i = vam->input;
6558   vl_api_sw_interface_set_l2_xconnect_t *mp;
6559   u32 rx_sw_if_index;
6560   u8 rx_sw_if_index_set = 0;
6561   u32 tx_sw_if_index;
6562   u8 tx_sw_if_index_set = 0;
6563   u8 enable = 1;
6564   int ret;
6565
6566   /* Parse args required to build the message */
6567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6568     {
6569       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6570         rx_sw_if_index_set = 1;
6571       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6572         tx_sw_if_index_set = 1;
6573       else if (unformat (i, "rx"))
6574         {
6575           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6576             {
6577               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6578                             &rx_sw_if_index))
6579                 rx_sw_if_index_set = 1;
6580             }
6581           else
6582             break;
6583         }
6584       else if (unformat (i, "tx"))
6585         {
6586           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6587             {
6588               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6589                             &tx_sw_if_index))
6590                 tx_sw_if_index_set = 1;
6591             }
6592           else
6593             break;
6594         }
6595       else if (unformat (i, "enable"))
6596         enable = 1;
6597       else if (unformat (i, "disable"))
6598         enable = 0;
6599       else
6600         break;
6601     }
6602
6603   if (rx_sw_if_index_set == 0)
6604     {
6605       errmsg ("missing rx interface name or rx_sw_if_index");
6606       return -99;
6607     }
6608
6609   if (enable && (tx_sw_if_index_set == 0))
6610     {
6611       errmsg ("missing tx interface name or tx_sw_if_index");
6612       return -99;
6613     }
6614
6615   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6616
6617   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6618   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6619   mp->enable = enable;
6620
6621   S (mp);
6622   W (ret);
6623   return ret;
6624 }
6625
6626 static int
6627 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6628 {
6629   unformat_input_t *i = vam->input;
6630   vl_api_sw_interface_set_l2_bridge_t *mp;
6631   vl_api_l2_port_type_t port_type;
6632   u32 rx_sw_if_index;
6633   u8 rx_sw_if_index_set = 0;
6634   u32 bd_id;
6635   u8 bd_id_set = 0;
6636   u32 shg = 0;
6637   u8 enable = 1;
6638   int ret;
6639
6640   port_type = L2_API_PORT_TYPE_NORMAL;
6641
6642   /* Parse args required to build the message */
6643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6644     {
6645       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6646         rx_sw_if_index_set = 1;
6647       else if (unformat (i, "bd_id %d", &bd_id))
6648         bd_id_set = 1;
6649       else
6650         if (unformat
6651             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6652         rx_sw_if_index_set = 1;
6653       else if (unformat (i, "shg %d", &shg))
6654         ;
6655       else if (unformat (i, "bvi"))
6656         port_type = L2_API_PORT_TYPE_BVI;
6657       else if (unformat (i, "uu-fwd"))
6658         port_type = L2_API_PORT_TYPE_UU_FWD;
6659       else if (unformat (i, "enable"))
6660         enable = 1;
6661       else if (unformat (i, "disable"))
6662         enable = 0;
6663       else
6664         break;
6665     }
6666
6667   if (rx_sw_if_index_set == 0)
6668     {
6669       errmsg ("missing rx interface name or sw_if_index");
6670       return -99;
6671     }
6672
6673   if (enable && (bd_id_set == 0))
6674     {
6675       errmsg ("missing bridge domain");
6676       return -99;
6677     }
6678
6679   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6680
6681   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6682   mp->bd_id = ntohl (bd_id);
6683   mp->shg = (u8) shg;
6684   mp->port_type = ntohl (port_type);
6685   mp->enable = enable;
6686
6687   S (mp);
6688   W (ret);
6689   return ret;
6690 }
6691
6692 static int
6693 api_bridge_domain_dump (vat_main_t * vam)
6694 {
6695   unformat_input_t *i = vam->input;
6696   vl_api_bridge_domain_dump_t *mp;
6697   vl_api_control_ping_t *mp_ping;
6698   u32 bd_id = ~0;
6699   int ret;
6700
6701   /* Parse args required to build the message */
6702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6703     {
6704       if (unformat (i, "bd_id %d", &bd_id))
6705         ;
6706       else
6707         break;
6708     }
6709
6710   M (BRIDGE_DOMAIN_DUMP, mp);
6711   mp->bd_id = ntohl (bd_id);
6712   S (mp);
6713
6714   /* Use a control ping for synchronization */
6715   MPING (CONTROL_PING, mp_ping);
6716   S (mp_ping);
6717
6718   W (ret);
6719   return ret;
6720 }
6721
6722 static int
6723 api_bridge_domain_add_del (vat_main_t * vam)
6724 {
6725   unformat_input_t *i = vam->input;
6726   vl_api_bridge_domain_add_del_t *mp;
6727   u32 bd_id = ~0;
6728   u8 is_add = 1;
6729   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6730   u8 *bd_tag = NULL;
6731   u32 mac_age = 0;
6732   int ret;
6733
6734   /* Parse args required to build the message */
6735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6736     {
6737       if (unformat (i, "bd_id %d", &bd_id))
6738         ;
6739       else if (unformat (i, "flood %d", &flood))
6740         ;
6741       else if (unformat (i, "uu-flood %d", &uu_flood))
6742         ;
6743       else if (unformat (i, "forward %d", &forward))
6744         ;
6745       else if (unformat (i, "learn %d", &learn))
6746         ;
6747       else if (unformat (i, "arp-term %d", &arp_term))
6748         ;
6749       else if (unformat (i, "mac-age %d", &mac_age))
6750         ;
6751       else if (unformat (i, "bd-tag %s", &bd_tag))
6752         ;
6753       else if (unformat (i, "del"))
6754         {
6755           is_add = 0;
6756           flood = uu_flood = forward = learn = 0;
6757         }
6758       else
6759         break;
6760     }
6761
6762   if (bd_id == ~0)
6763     {
6764       errmsg ("missing bridge domain");
6765       ret = -99;
6766       goto done;
6767     }
6768
6769   if (mac_age > 255)
6770     {
6771       errmsg ("mac age must be less than 256 ");
6772       ret = -99;
6773       goto done;
6774     }
6775
6776   if ((bd_tag) && (vec_len (bd_tag) > 63))
6777     {
6778       errmsg ("bd-tag cannot be longer than 63");
6779       ret = -99;
6780       goto done;
6781     }
6782
6783   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6784
6785   mp->bd_id = ntohl (bd_id);
6786   mp->flood = flood;
6787   mp->uu_flood = uu_flood;
6788   mp->forward = forward;
6789   mp->learn = learn;
6790   mp->arp_term = arp_term;
6791   mp->is_add = is_add;
6792   mp->mac_age = (u8) mac_age;
6793   if (bd_tag)
6794     {
6795       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6796       mp->bd_tag[vec_len (bd_tag)] = 0;
6797     }
6798   S (mp);
6799   W (ret);
6800
6801 done:
6802   vec_free (bd_tag);
6803   return ret;
6804 }
6805
6806 static int
6807 api_l2fib_flush_bd (vat_main_t * vam)
6808 {
6809   unformat_input_t *i = vam->input;
6810   vl_api_l2fib_flush_bd_t *mp;
6811   u32 bd_id = ~0;
6812   int ret;
6813
6814   /* Parse args required to build the message */
6815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6816     {
6817       if (unformat (i, "bd_id %d", &bd_id));
6818       else
6819         break;
6820     }
6821
6822   if (bd_id == ~0)
6823     {
6824       errmsg ("missing bridge domain");
6825       return -99;
6826     }
6827
6828   M (L2FIB_FLUSH_BD, mp);
6829
6830   mp->bd_id = htonl (bd_id);
6831
6832   S (mp);
6833   W (ret);
6834   return ret;
6835 }
6836
6837 static int
6838 api_l2fib_flush_int (vat_main_t * vam)
6839 {
6840   unformat_input_t *i = vam->input;
6841   vl_api_l2fib_flush_int_t *mp;
6842   u32 sw_if_index = ~0;
6843   int ret;
6844
6845   /* Parse args required to build the message */
6846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6847     {
6848       if (unformat (i, "sw_if_index %d", &sw_if_index));
6849       else
6850         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6851       else
6852         break;
6853     }
6854
6855   if (sw_if_index == ~0)
6856     {
6857       errmsg ("missing interface name or sw_if_index");
6858       return -99;
6859     }
6860
6861   M (L2FIB_FLUSH_INT, mp);
6862
6863   mp->sw_if_index = ntohl (sw_if_index);
6864
6865   S (mp);
6866   W (ret);
6867   return ret;
6868 }
6869
6870 static int
6871 api_l2fib_add_del (vat_main_t * vam)
6872 {
6873   unformat_input_t *i = vam->input;
6874   vl_api_l2fib_add_del_t *mp;
6875   f64 timeout;
6876   u8 mac[6] = { 0 };
6877   u8 mac_set = 0;
6878   u32 bd_id;
6879   u8 bd_id_set = 0;
6880   u32 sw_if_index = 0;
6881   u8 sw_if_index_set = 0;
6882   u8 is_add = 1;
6883   u8 static_mac = 0;
6884   u8 filter_mac = 0;
6885   u8 bvi_mac = 0;
6886   int count = 1;
6887   f64 before = 0;
6888   int j;
6889
6890   /* Parse args required to build the message */
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6894         mac_set = 1;
6895       else if (unformat (i, "bd_id %d", &bd_id))
6896         bd_id_set = 1;
6897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6898         sw_if_index_set = 1;
6899       else if (unformat (i, "sw_if"))
6900         {
6901           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6902             {
6903               if (unformat
6904                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6905                 sw_if_index_set = 1;
6906             }
6907           else
6908             break;
6909         }
6910       else if (unformat (i, "static"))
6911         static_mac = 1;
6912       else if (unformat (i, "filter"))
6913         {
6914           filter_mac = 1;
6915           static_mac = 1;
6916         }
6917       else if (unformat (i, "bvi"))
6918         {
6919           bvi_mac = 1;
6920           static_mac = 1;
6921         }
6922       else if (unformat (i, "del"))
6923         is_add = 0;
6924       else if (unformat (i, "count %d", &count))
6925         ;
6926       else
6927         break;
6928     }
6929
6930   if (mac_set == 0)
6931     {
6932       errmsg ("missing mac address");
6933       return -99;
6934     }
6935
6936   if (bd_id_set == 0)
6937     {
6938       errmsg ("missing bridge domain");
6939       return -99;
6940     }
6941
6942   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6943     {
6944       errmsg ("missing interface name or sw_if_index");
6945       return -99;
6946     }
6947
6948   if (count > 1)
6949     {
6950       /* Turn on async mode */
6951       vam->async_mode = 1;
6952       vam->async_errors = 0;
6953       before = vat_time_now (vam);
6954     }
6955
6956   for (j = 0; j < count; j++)
6957     {
6958       M (L2FIB_ADD_DEL, mp);
6959
6960       clib_memcpy (mp->mac, mac, 6);
6961       mp->bd_id = ntohl (bd_id);
6962       mp->is_add = is_add;
6963       mp->sw_if_index = ntohl (sw_if_index);
6964
6965       if (is_add)
6966         {
6967           mp->static_mac = static_mac;
6968           mp->filter_mac = filter_mac;
6969           mp->bvi_mac = bvi_mac;
6970         }
6971       increment_mac_address (mac);
6972       /* send it... */
6973       S (mp);
6974     }
6975
6976   if (count > 1)
6977     {
6978       vl_api_control_ping_t *mp_ping;
6979       f64 after;
6980
6981       /* Shut off async mode */
6982       vam->async_mode = 0;
6983
6984       MPING (CONTROL_PING, mp_ping);
6985       S (mp_ping);
6986
6987       timeout = vat_time_now (vam) + 1.0;
6988       while (vat_time_now (vam) < timeout)
6989         if (vam->result_ready == 1)
6990           goto out;
6991       vam->retval = -99;
6992
6993     out:
6994       if (vam->retval == -99)
6995         errmsg ("timeout");
6996
6997       if (vam->async_errors > 0)
6998         {
6999           errmsg ("%d asynchronous errors", vam->async_errors);
7000           vam->retval = -98;
7001         }
7002       vam->async_errors = 0;
7003       after = vat_time_now (vam);
7004
7005       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7006              count, after - before, count / (after - before));
7007     }
7008   else
7009     {
7010       int ret;
7011
7012       /* Wait for a reply... */
7013       W (ret);
7014       return ret;
7015     }
7016   /* Return the good/bad news */
7017   return (vam->retval);
7018 }
7019
7020 static int
7021 api_bridge_domain_set_mac_age (vat_main_t * vam)
7022 {
7023   unformat_input_t *i = vam->input;
7024   vl_api_bridge_domain_set_mac_age_t *mp;
7025   u32 bd_id = ~0;
7026   u32 mac_age = 0;
7027   int ret;
7028
7029   /* Parse args required to build the message */
7030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7031     {
7032       if (unformat (i, "bd_id %d", &bd_id));
7033       else if (unformat (i, "mac-age %d", &mac_age));
7034       else
7035         break;
7036     }
7037
7038   if (bd_id == ~0)
7039     {
7040       errmsg ("missing bridge domain");
7041       return -99;
7042     }
7043
7044   if (mac_age > 255)
7045     {
7046       errmsg ("mac age must be less than 256 ");
7047       return -99;
7048     }
7049
7050   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7051
7052   mp->bd_id = htonl (bd_id);
7053   mp->mac_age = (u8) mac_age;
7054
7055   S (mp);
7056   W (ret);
7057   return ret;
7058 }
7059
7060 static int
7061 api_l2_flags (vat_main_t * vam)
7062 {
7063   unformat_input_t *i = vam->input;
7064   vl_api_l2_flags_t *mp;
7065   u32 sw_if_index;
7066   u32 flags = 0;
7067   u8 sw_if_index_set = 0;
7068   u8 is_set = 0;
7069   int ret;
7070
7071   /* Parse args required to build the message */
7072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7073     {
7074       if (unformat (i, "sw_if_index %d", &sw_if_index))
7075         sw_if_index_set = 1;
7076       else if (unformat (i, "sw_if"))
7077         {
7078           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7079             {
7080               if (unformat
7081                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7082                 sw_if_index_set = 1;
7083             }
7084           else
7085             break;
7086         }
7087       else if (unformat (i, "learn"))
7088         flags |= L2_LEARN;
7089       else if (unformat (i, "forward"))
7090         flags |= L2_FWD;
7091       else if (unformat (i, "flood"))
7092         flags |= L2_FLOOD;
7093       else if (unformat (i, "uu-flood"))
7094         flags |= L2_UU_FLOOD;
7095       else if (unformat (i, "arp-term"))
7096         flags |= L2_ARP_TERM;
7097       else if (unformat (i, "off"))
7098         is_set = 0;
7099       else if (unformat (i, "disable"))
7100         is_set = 0;
7101       else
7102         break;
7103     }
7104
7105   if (sw_if_index_set == 0)
7106     {
7107       errmsg ("missing interface name or sw_if_index");
7108       return -99;
7109     }
7110
7111   M (L2_FLAGS, mp);
7112
7113   mp->sw_if_index = ntohl (sw_if_index);
7114   mp->feature_bitmap = ntohl (flags);
7115   mp->is_set = is_set;
7116
7117   S (mp);
7118   W (ret);
7119   return ret;
7120 }
7121
7122 static int
7123 api_bridge_flags (vat_main_t * vam)
7124 {
7125   unformat_input_t *i = vam->input;
7126   vl_api_bridge_flags_t *mp;
7127   u32 bd_id;
7128   u8 bd_id_set = 0;
7129   u8 is_set = 1;
7130   bd_flags_t flags = 0;
7131   int ret;
7132
7133   /* Parse args required to build the message */
7134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7135     {
7136       if (unformat (i, "bd_id %d", &bd_id))
7137         bd_id_set = 1;
7138       else if (unformat (i, "learn"))
7139         flags |= BRIDGE_API_FLAG_LEARN;
7140       else if (unformat (i, "forward"))
7141         flags |= BRIDGE_API_FLAG_FWD;
7142       else if (unformat (i, "flood"))
7143         flags |= BRIDGE_API_FLAG_FLOOD;
7144       else if (unformat (i, "uu-flood"))
7145         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7146       else if (unformat (i, "arp-term"))
7147         flags |= BRIDGE_API_FLAG_ARP_TERM;
7148       else if (unformat (i, "off"))
7149         is_set = 0;
7150       else if (unformat (i, "disable"))
7151         is_set = 0;
7152       else
7153         break;
7154     }
7155
7156   if (bd_id_set == 0)
7157     {
7158       errmsg ("missing bridge domain");
7159       return -99;
7160     }
7161
7162   M (BRIDGE_FLAGS, mp);
7163
7164   mp->bd_id = ntohl (bd_id);
7165   mp->flags = ntohl (flags);
7166   mp->is_set = is_set;
7167
7168   S (mp);
7169   W (ret);
7170   return ret;
7171 }
7172
7173 static int
7174 api_bd_ip_mac_add_del (vat_main_t * vam)
7175 {
7176   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7177   vl_api_mac_address_t mac = { 0 };
7178   unformat_input_t *i = vam->input;
7179   vl_api_bd_ip_mac_add_del_t *mp;
7180   u32 bd_id;
7181   u8 is_add = 1;
7182   u8 bd_id_set = 0;
7183   u8 ip_set = 0;
7184   u8 mac_set = 0;
7185   int ret;
7186
7187
7188   /* Parse args required to build the message */
7189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7190     {
7191       if (unformat (i, "bd_id %d", &bd_id))
7192         {
7193           bd_id_set++;
7194         }
7195       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7196         {
7197           ip_set++;
7198         }
7199       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7200         {
7201           mac_set++;
7202         }
7203       else if (unformat (i, "del"))
7204         is_add = 0;
7205       else
7206         break;
7207     }
7208
7209   if (bd_id_set == 0)
7210     {
7211       errmsg ("missing bridge domain");
7212       return -99;
7213     }
7214   else if (ip_set == 0)
7215     {
7216       errmsg ("missing IP address");
7217       return -99;
7218     }
7219   else if (mac_set == 0)
7220     {
7221       errmsg ("missing MAC address");
7222       return -99;
7223     }
7224
7225   M (BD_IP_MAC_ADD_DEL, mp);
7226
7227   mp->entry.bd_id = ntohl (bd_id);
7228   mp->is_add = is_add;
7229
7230   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7231   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7232
7233   S (mp);
7234   W (ret);
7235   return ret;
7236 }
7237
7238 static int
7239 api_bd_ip_mac_flush (vat_main_t * vam)
7240 {
7241   unformat_input_t *i = vam->input;
7242   vl_api_bd_ip_mac_flush_t *mp;
7243   u32 bd_id;
7244   u8 bd_id_set = 0;
7245   int ret;
7246
7247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7248     {
7249       if (unformat (i, "bd_id %d", &bd_id))
7250         {
7251           bd_id_set++;
7252         }
7253       else
7254         break;
7255     }
7256
7257   if (bd_id_set == 0)
7258     {
7259       errmsg ("missing bridge domain");
7260       return -99;
7261     }
7262
7263   M (BD_IP_MAC_FLUSH, mp);
7264
7265   mp->bd_id = ntohl (bd_id);
7266
7267   S (mp);
7268   W (ret);
7269   return ret;
7270 }
7271
7272 static void vl_api_bd_ip_mac_details_t_handler
7273   (vl_api_bd_ip_mac_details_t * mp)
7274 {
7275   vat_main_t *vam = &vat_main;
7276
7277   print (vam->ofp,
7278          "\n%-5d %U %U",
7279          ntohl (mp->entry.bd_id),
7280          format_vl_api_mac_address, mp->entry.mac,
7281          format_vl_api_address, &mp->entry.ip);
7282 }
7283
7284 static void vl_api_bd_ip_mac_details_t_handler_json
7285   (vl_api_bd_ip_mac_details_t * mp)
7286 {
7287   vat_main_t *vam = &vat_main;
7288   vat_json_node_t *node = NULL;
7289
7290   if (VAT_JSON_ARRAY != vam->json_tree.type)
7291     {
7292       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7293       vat_json_init_array (&vam->json_tree);
7294     }
7295   node = vat_json_array_add (&vam->json_tree);
7296
7297   vat_json_init_object (node);
7298   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7299   vat_json_object_add_string_copy (node, "mac_address",
7300                                    format (0, "%U", format_vl_api_mac_address,
7301                                            &mp->entry.mac));
7302   u8 *ip = 0;
7303
7304   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7305   vat_json_object_add_string_copy (node, "ip_address", ip);
7306   vec_free (ip);
7307 }
7308
7309 static int
7310 api_bd_ip_mac_dump (vat_main_t * vam)
7311 {
7312   unformat_input_t *i = vam->input;
7313   vl_api_bd_ip_mac_dump_t *mp;
7314   vl_api_control_ping_t *mp_ping;
7315   int ret;
7316   u32 bd_id;
7317   u8 bd_id_set = 0;
7318
7319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7320     {
7321       if (unformat (i, "bd_id %d", &bd_id))
7322         {
7323           bd_id_set++;
7324         }
7325       else
7326         break;
7327     }
7328
7329   print (vam->ofp,
7330          "\n%-5s %-7s %-20s %-30s",
7331          "bd_id", "is_ipv6", "mac_address", "ip_address");
7332
7333   /* Dump Bridge Domain Ip to Mac entries */
7334   M (BD_IP_MAC_DUMP, mp);
7335
7336   if (bd_id_set)
7337     mp->bd_id = htonl (bd_id);
7338   else
7339     mp->bd_id = ~0;
7340
7341   S (mp);
7342
7343   /* Use a control ping for synchronization */
7344   MPING (CONTROL_PING, mp_ping);
7345   S (mp_ping);
7346
7347   W (ret);
7348   return ret;
7349 }
7350
7351 static int
7352 api_tap_create_v2 (vat_main_t * vam)
7353 {
7354   unformat_input_t *i = vam->input;
7355   vl_api_tap_create_v2_t *mp;
7356 #define TAP_FLAG_GSO (1 << 0)
7357   u8 mac_address[6];
7358   u8 random_mac = 1;
7359   u32 id = ~0;
7360   u8 *host_if_name = 0;
7361   u8 *host_ns = 0;
7362   u8 host_mac_addr[6];
7363   u8 host_mac_addr_set = 0;
7364   u8 *host_bridge = 0;
7365   ip4_address_t host_ip4_addr;
7366   ip4_address_t host_ip4_gw;
7367   u8 host_ip4_gw_set = 0;
7368   u32 host_ip4_prefix_len = 0;
7369   ip6_address_t host_ip6_addr;
7370   ip6_address_t host_ip6_gw;
7371   u8 host_ip6_gw_set = 0;
7372   u32 host_ip6_prefix_len = 0;
7373   u8 host_mtu_set = 0;
7374   u32 host_mtu_size = 0;
7375   u32 tap_flags = 0;
7376   int ret;
7377   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7378
7379   clib_memset (mac_address, 0, sizeof (mac_address));
7380
7381   /* Parse args required to build the message */
7382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7383     {
7384       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7385         {
7386           random_mac = 0;
7387         }
7388       else if (unformat (i, "id %u", &id))
7389         ;
7390       else if (unformat (i, "host-if-name %s", &host_if_name))
7391         ;
7392       else if (unformat (i, "host-ns %s", &host_ns))
7393         ;
7394       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7395                          host_mac_addr))
7396         host_mac_addr_set = 1;
7397       else if (unformat (i, "host-bridge %s", &host_bridge))
7398         ;
7399       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7400                          &host_ip4_addr, &host_ip4_prefix_len))
7401         ;
7402       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7403                          &host_ip6_addr, &host_ip6_prefix_len))
7404         ;
7405       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7406                          &host_ip4_gw))
7407         host_ip4_gw_set = 1;
7408       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7409                          &host_ip6_gw))
7410         host_ip6_gw_set = 1;
7411       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7412         ;
7413       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7414         ;
7415       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7416         host_mtu_set = 1;
7417       else if (unformat (i, "no-gso"))
7418         tap_flags &= ~TAP_FLAG_GSO;
7419       else if (unformat (i, "gso"))
7420         tap_flags |= TAP_FLAG_GSO;
7421       else
7422         break;
7423     }
7424
7425   if (vec_len (host_if_name) > 63)
7426     {
7427       errmsg ("tap name too long. ");
7428       return -99;
7429     }
7430   if (vec_len (host_ns) > 63)
7431     {
7432       errmsg ("host name space too long. ");
7433       return -99;
7434     }
7435   if (vec_len (host_bridge) > 63)
7436     {
7437       errmsg ("host bridge name too long. ");
7438       return -99;
7439     }
7440   if (host_ip4_prefix_len > 32)
7441     {
7442       errmsg ("host ip4 prefix length not valid. ");
7443       return -99;
7444     }
7445   if (host_ip6_prefix_len > 128)
7446     {
7447       errmsg ("host ip6 prefix length not valid. ");
7448       return -99;
7449     }
7450   if (!is_pow2 (rx_ring_sz))
7451     {
7452       errmsg ("rx ring size must be power of 2. ");
7453       return -99;
7454     }
7455   if (rx_ring_sz > 32768)
7456     {
7457       errmsg ("rx ring size must be 32768 or lower. ");
7458       return -99;
7459     }
7460   if (!is_pow2 (tx_ring_sz))
7461     {
7462       errmsg ("tx ring size must be power of 2. ");
7463       return -99;
7464     }
7465   if (tx_ring_sz > 32768)
7466     {
7467       errmsg ("tx ring size must be 32768 or lower. ");
7468       return -99;
7469     }
7470   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7471     {
7472       errmsg ("host MTU size must be in between 64 and 65355. ");
7473       return -99;
7474     }
7475
7476   /* Construct the API message */
7477   M (TAP_CREATE_V2, mp);
7478
7479   mp->use_random_mac = random_mac;
7480
7481   mp->id = ntohl (id);
7482   mp->host_namespace_set = host_ns != 0;
7483   mp->host_bridge_set = host_bridge != 0;
7484   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7485   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7486   mp->rx_ring_sz = ntohs (rx_ring_sz);
7487   mp->tx_ring_sz = ntohs (tx_ring_sz);
7488   mp->host_mtu_set = host_mtu_set;
7489   mp->host_mtu_size = ntohl (host_mtu_size);
7490   mp->tap_flags = ntohl (tap_flags);
7491
7492   if (random_mac == 0)
7493     clib_memcpy (mp->mac_address, mac_address, 6);
7494   if (host_mac_addr_set)
7495     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7496   if (host_if_name)
7497     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7498   if (host_ns)
7499     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7500   if (host_bridge)
7501     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7502   if (host_ip4_prefix_len)
7503     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7504   if (host_ip6_prefix_len)
7505     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7506   if (host_ip4_gw_set)
7507     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7508   if (host_ip6_gw_set)
7509     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7510
7511   vec_free (host_ns);
7512   vec_free (host_if_name);
7513   vec_free (host_bridge);
7514
7515   /* send it... */
7516   S (mp);
7517
7518   /* Wait for a reply... */
7519   W (ret);
7520   return ret;
7521 }
7522
7523 static int
7524 api_tap_delete_v2 (vat_main_t * vam)
7525 {
7526   unformat_input_t *i = vam->input;
7527   vl_api_tap_delete_v2_t *mp;
7528   u32 sw_if_index = ~0;
7529   u8 sw_if_index_set = 0;
7530   int ret;
7531
7532   /* Parse args required to build the message */
7533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7534     {
7535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7536         sw_if_index_set = 1;
7537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7538         sw_if_index_set = 1;
7539       else
7540         break;
7541     }
7542
7543   if (sw_if_index_set == 0)
7544     {
7545       errmsg ("missing vpp interface name. ");
7546       return -99;
7547     }
7548
7549   /* Construct the API message */
7550   M (TAP_DELETE_V2, mp);
7551
7552   mp->sw_if_index = ntohl (sw_if_index);
7553
7554   /* send it... */
7555   S (mp);
7556
7557   /* Wait for a reply... */
7558   W (ret);
7559   return ret;
7560 }
7561
7562 uword
7563 unformat_pci_addr (unformat_input_t * input, va_list * args)
7564 {
7565   struct pci_addr_t
7566   {
7567     u16 domain;
7568     u8 bus;
7569     u8 slot:5;
7570     u8 function:3;
7571   } *addr;
7572   addr = va_arg (*args, struct pci_addr_t *);
7573   u32 x[4];
7574
7575   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7576     return 0;
7577
7578   addr->domain = x[0];
7579   addr->bus = x[1];
7580   addr->slot = x[2];
7581   addr->function = x[3];
7582
7583   return 1;
7584 }
7585
7586 static int
7587 api_virtio_pci_create (vat_main_t * vam)
7588 {
7589   unformat_input_t *i = vam->input;
7590   vl_api_virtio_pci_create_t *mp;
7591   u8 mac_address[6];
7592   u8 random_mac = 1;
7593   u8 gso_enabled = 0;
7594   u32 pci_addr = 0;
7595   u64 features = (u64) ~ (0ULL);
7596   int ret;
7597
7598   clib_memset (mac_address, 0, sizeof (mac_address));
7599
7600   /* Parse args required to build the message */
7601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7602     {
7603       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7604         {
7605           random_mac = 0;
7606         }
7607       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7608         ;
7609       else if (unformat (i, "features 0x%llx", &features))
7610         ;
7611       else if (unformat (i, "gso-enabled"))
7612         gso_enabled = 1;
7613       else
7614         break;
7615     }
7616
7617   if (pci_addr == 0)
7618     {
7619       errmsg ("pci address must be non zero. ");
7620       return -99;
7621     }
7622
7623   /* Construct the API message */
7624   M (VIRTIO_PCI_CREATE, mp);
7625
7626   mp->use_random_mac = random_mac;
7627
7628   mp->pci_addr = htonl (pci_addr);
7629   mp->features = clib_host_to_net_u64 (features);
7630   mp->gso_enabled = gso_enabled;
7631
7632   if (random_mac == 0)
7633     clib_memcpy (mp->mac_address, mac_address, 6);
7634
7635   /* send it... */
7636   S (mp);
7637
7638   /* Wait for a reply... */
7639   W (ret);
7640   return ret;
7641 }
7642
7643 static int
7644 api_virtio_pci_delete (vat_main_t * vam)
7645 {
7646   unformat_input_t *i = vam->input;
7647   vl_api_virtio_pci_delete_t *mp;
7648   u32 sw_if_index = ~0;
7649   u8 sw_if_index_set = 0;
7650   int ret;
7651
7652   /* Parse args required to build the message */
7653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7654     {
7655       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7656         sw_if_index_set = 1;
7657       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7658         sw_if_index_set = 1;
7659       else
7660         break;
7661     }
7662
7663   if (sw_if_index_set == 0)
7664     {
7665       errmsg ("missing vpp interface name. ");
7666       return -99;
7667     }
7668
7669   /* Construct the API message */
7670   M (VIRTIO_PCI_DELETE, mp);
7671
7672   mp->sw_if_index = htonl (sw_if_index);
7673
7674   /* send it... */
7675   S (mp);
7676
7677   /* Wait for a reply... */
7678   W (ret);
7679   return ret;
7680 }
7681
7682 static int
7683 api_bond_create (vat_main_t * vam)
7684 {
7685   unformat_input_t *i = vam->input;
7686   vl_api_bond_create_t *mp;
7687   u8 mac_address[6];
7688   u8 custom_mac = 0;
7689   int ret;
7690   u8 mode;
7691   u8 lb;
7692   u8 mode_is_set = 0;
7693   u32 id = ~0;
7694   u8 numa_only = 0;
7695
7696   clib_memset (mac_address, 0, sizeof (mac_address));
7697   lb = BOND_LB_L2;
7698
7699   /* Parse args required to build the message */
7700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7701     {
7702       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7703         mode_is_set = 1;
7704       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7705                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7706         ;
7707       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7708                          mac_address))
7709         custom_mac = 1;
7710       else if (unformat (i, "numa-only"))
7711         numa_only = 1;
7712       else if (unformat (i, "id %u", &id))
7713         ;
7714       else
7715         break;
7716     }
7717
7718   if (mode_is_set == 0)
7719     {
7720       errmsg ("Missing bond mode. ");
7721       return -99;
7722     }
7723
7724   /* Construct the API message */
7725   M (BOND_CREATE, mp);
7726
7727   mp->use_custom_mac = custom_mac;
7728
7729   mp->mode = mode;
7730   mp->lb = lb;
7731   mp->id = htonl (id);
7732   mp->numa_only = numa_only;
7733
7734   if (custom_mac)
7735     clib_memcpy (mp->mac_address, mac_address, 6);
7736
7737   /* send it... */
7738   S (mp);
7739
7740   /* Wait for a reply... */
7741   W (ret);
7742   return ret;
7743 }
7744
7745 static int
7746 api_bond_delete (vat_main_t * vam)
7747 {
7748   unformat_input_t *i = vam->input;
7749   vl_api_bond_delete_t *mp;
7750   u32 sw_if_index = ~0;
7751   u8 sw_if_index_set = 0;
7752   int ret;
7753
7754   /* Parse args required to build the message */
7755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7756     {
7757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7758         sw_if_index_set = 1;
7759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7760         sw_if_index_set = 1;
7761       else
7762         break;
7763     }
7764
7765   if (sw_if_index_set == 0)
7766     {
7767       errmsg ("missing vpp interface name. ");
7768       return -99;
7769     }
7770
7771   /* Construct the API message */
7772   M (BOND_DELETE, mp);
7773
7774   mp->sw_if_index = ntohl (sw_if_index);
7775
7776   /* send it... */
7777   S (mp);
7778
7779   /* Wait for a reply... */
7780   W (ret);
7781   return ret;
7782 }
7783
7784 static int
7785 api_bond_enslave (vat_main_t * vam)
7786 {
7787   unformat_input_t *i = vam->input;
7788   vl_api_bond_enslave_t *mp;
7789   u32 bond_sw_if_index;
7790   int ret;
7791   u8 is_passive;
7792   u8 is_long_timeout;
7793   u32 bond_sw_if_index_is_set = 0;
7794   u32 sw_if_index;
7795   u8 sw_if_index_is_set = 0;
7796
7797   /* Parse args required to build the message */
7798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7799     {
7800       if (unformat (i, "sw_if_index %d", &sw_if_index))
7801         sw_if_index_is_set = 1;
7802       else if (unformat (i, "bond %u", &bond_sw_if_index))
7803         bond_sw_if_index_is_set = 1;
7804       else if (unformat (i, "passive %d", &is_passive))
7805         ;
7806       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7807         ;
7808       else
7809         break;
7810     }
7811
7812   if (bond_sw_if_index_is_set == 0)
7813     {
7814       errmsg ("Missing bond sw_if_index. ");
7815       return -99;
7816     }
7817   if (sw_if_index_is_set == 0)
7818     {
7819       errmsg ("Missing slave sw_if_index. ");
7820       return -99;
7821     }
7822
7823   /* Construct the API message */
7824   M (BOND_ENSLAVE, mp);
7825
7826   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7827   mp->sw_if_index = ntohl (sw_if_index);
7828   mp->is_long_timeout = is_long_timeout;
7829   mp->is_passive = is_passive;
7830
7831   /* send it... */
7832   S (mp);
7833
7834   /* Wait for a reply... */
7835   W (ret);
7836   return ret;
7837 }
7838
7839 static int
7840 api_bond_detach_slave (vat_main_t * vam)
7841 {
7842   unformat_input_t *i = vam->input;
7843   vl_api_bond_detach_slave_t *mp;
7844   u32 sw_if_index = ~0;
7845   u8 sw_if_index_set = 0;
7846   int ret;
7847
7848   /* Parse args required to build the message */
7849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7850     {
7851       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7852         sw_if_index_set = 1;
7853       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7854         sw_if_index_set = 1;
7855       else
7856         break;
7857     }
7858
7859   if (sw_if_index_set == 0)
7860     {
7861       errmsg ("missing vpp interface name. ");
7862       return -99;
7863     }
7864
7865   /* Construct the API message */
7866   M (BOND_DETACH_SLAVE, mp);
7867
7868   mp->sw_if_index = ntohl (sw_if_index);
7869
7870   /* send it... */
7871   S (mp);
7872
7873   /* Wait for a reply... */
7874   W (ret);
7875   return ret;
7876 }
7877
7878 static int
7879 api_ip_table_add_del (vat_main_t * vam)
7880 {
7881   unformat_input_t *i = vam->input;
7882   vl_api_ip_table_add_del_t *mp;
7883   u32 table_id = ~0;
7884   u8 is_ipv6 = 0;
7885   u8 is_add = 1;
7886   int ret = 0;
7887
7888   /* Parse args required to build the message */
7889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7890     {
7891       if (unformat (i, "ipv6"))
7892         is_ipv6 = 1;
7893       else if (unformat (i, "del"))
7894         is_add = 0;
7895       else if (unformat (i, "add"))
7896         is_add = 1;
7897       else if (unformat (i, "table %d", &table_id))
7898         ;
7899       else
7900         {
7901           clib_warning ("parse error '%U'", format_unformat_error, i);
7902           return -99;
7903         }
7904     }
7905
7906   if (~0 == table_id)
7907     {
7908       errmsg ("missing table-ID");
7909       return -99;
7910     }
7911
7912   /* Construct the API message */
7913   M (IP_TABLE_ADD_DEL, mp);
7914
7915   mp->table.table_id = ntohl (table_id);
7916   mp->table.is_ip6 = is_ipv6;
7917   mp->is_add = is_add;
7918
7919   /* send it... */
7920   S (mp);
7921
7922   /* Wait for a reply... */
7923   W (ret);
7924
7925   return ret;
7926 }
7927
7928 uword
7929 unformat_fib_path (unformat_input_t * input, va_list * args)
7930 {
7931   vat_main_t *vam = va_arg (*args, vat_main_t *);
7932   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7933   u32 weight, preference;
7934   mpls_label_t out_label;
7935
7936   clib_memset (path, 0, sizeof (*path));
7937   path->weight = 1;
7938   path->sw_if_index = ~0;
7939   path->rpf_id = ~0;
7940   path->n_labels = 0;
7941
7942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7943     {
7944       if (unformat (input, "%U %U",
7945                     unformat_vl_api_ip4_address,
7946                     &path->nh.address.ip4,
7947                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7948         {
7949           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7950         }
7951       else if (unformat (input, "%U %U",
7952                          unformat_vl_api_ip6_address,
7953                          &path->nh.address.ip6,
7954                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7955         {
7956           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7957         }
7958       else if (unformat (input, "weight %u", &weight))
7959         {
7960           path->weight = weight;
7961         }
7962       else if (unformat (input, "preference %u", &preference))
7963         {
7964           path->preference = preference;
7965         }
7966       else if (unformat (input, "%U next-hop-table %d",
7967                          unformat_vl_api_ip4_address,
7968                          &path->nh.address.ip4, &path->table_id))
7969         {
7970           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7971         }
7972       else if (unformat (input, "%U next-hop-table %d",
7973                          unformat_vl_api_ip6_address,
7974                          &path->nh.address.ip6, &path->table_id))
7975         {
7976           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7977         }
7978       else if (unformat (input, "%U",
7979                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7980         {
7981           /*
7982            * the recursive next-hops are by default in the default table
7983            */
7984           path->table_id = 0;
7985           path->sw_if_index = ~0;
7986           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7987         }
7988       else if (unformat (input, "%U",
7989                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7990         {
7991           /*
7992            * the recursive next-hops are by default in the default table
7993            */
7994           path->table_id = 0;
7995           path->sw_if_index = ~0;
7996           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7997         }
7998       else if (unformat (input, "resolve-via-host"))
7999         {
8000           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8001         }
8002       else if (unformat (input, "resolve-via-attached"))
8003         {
8004           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8005         }
8006       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8007         {
8008           path->type = FIB_API_PATH_TYPE_LOCAL;
8009           path->sw_if_index = ~0;
8010           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8011         }
8012       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8013         {
8014           path->type = FIB_API_PATH_TYPE_LOCAL;
8015           path->sw_if_index = ~0;
8016           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8017         }
8018       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8019         ;
8020       else if (unformat (input, "via-label %d", &path->nh.via_label))
8021         {
8022           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8023           path->sw_if_index = ~0;
8024         }
8025       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8026         {
8027           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8028           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8029         }
8030       else if (unformat (input, "local"))
8031         {
8032           path->type = FIB_API_PATH_TYPE_LOCAL;
8033         }
8034       else if (unformat (input, "out-labels"))
8035         {
8036           while (unformat (input, "%d", &out_label))
8037             {
8038               path->label_stack[path->n_labels].label = out_label;
8039               path->label_stack[path->n_labels].is_uniform = 0;
8040               path->label_stack[path->n_labels].ttl = 64;
8041               path->n_labels++;
8042             }
8043         }
8044       else if (unformat (input, "via"))
8045         {
8046           /* new path, back up and return */
8047           unformat_put_input (input);
8048           unformat_put_input (input);
8049           unformat_put_input (input);
8050           unformat_put_input (input);
8051           break;
8052         }
8053       else
8054         {
8055           return (0);
8056         }
8057     }
8058
8059   path->proto = ntohl (path->proto);
8060   path->type = ntohl (path->type);
8061   path->flags = ntohl (path->flags);
8062   path->table_id = ntohl (path->table_id);
8063   path->sw_if_index = ntohl (path->sw_if_index);
8064
8065   return (1);
8066 }
8067
8068 static int
8069 api_ip_route_add_del (vat_main_t * vam)
8070 {
8071   unformat_input_t *i = vam->input;
8072   vl_api_ip_route_add_del_t *mp;
8073   u32 vrf_id = 0;
8074   u8 is_add = 1;
8075   u8 is_multipath = 0;
8076   u8 prefix_set = 0;
8077   u8 path_count = 0;
8078   vl_api_prefix_t pfx = { };
8079   vl_api_fib_path_t paths[8];
8080   int count = 1;
8081   int j;
8082   f64 before = 0;
8083   u32 random_add_del = 0;
8084   u32 *random_vector = 0;
8085   u32 random_seed = 0xdeaddabe;
8086
8087   /* Parse args required to build the message */
8088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8089     {
8090       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8091         prefix_set = 1;
8092       else if (unformat (i, "del"))
8093         is_add = 0;
8094       else if (unformat (i, "add"))
8095         is_add = 1;
8096       else if (unformat (i, "vrf %d", &vrf_id))
8097         ;
8098       else if (unformat (i, "count %d", &count))
8099         ;
8100       else if (unformat (i, "random"))
8101         random_add_del = 1;
8102       else if (unformat (i, "multipath"))
8103         is_multipath = 1;
8104       else if (unformat (i, "seed %d", &random_seed))
8105         ;
8106       else
8107         if (unformat
8108             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8109         {
8110           path_count++;
8111           if (8 == path_count)
8112             {
8113               errmsg ("max 8 paths");
8114               return -99;
8115             }
8116         }
8117       else
8118         {
8119           clib_warning ("parse error '%U'", format_unformat_error, i);
8120           return -99;
8121         }
8122     }
8123
8124   if (!path_count)
8125     {
8126       errmsg ("specify a path; via ...");
8127       return -99;
8128     }
8129   if (prefix_set == 0)
8130     {
8131       errmsg ("missing prefix");
8132       return -99;
8133     }
8134
8135   /* Generate a pile of unique, random routes */
8136   if (random_add_del)
8137     {
8138       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8139       u32 this_random_address;
8140       uword *random_hash;
8141
8142       random_hash = hash_create (count, sizeof (uword));
8143
8144       hash_set (random_hash, i->as_u32, 1);
8145       for (j = 0; j <= count; j++)
8146         {
8147           do
8148             {
8149               this_random_address = random_u32 (&random_seed);
8150               this_random_address =
8151                 clib_host_to_net_u32 (this_random_address);
8152             }
8153           while (hash_get (random_hash, this_random_address));
8154           vec_add1 (random_vector, this_random_address);
8155           hash_set (random_hash, this_random_address, 1);
8156         }
8157       hash_free (random_hash);
8158       set_ip4_address (&pfx.address, random_vector[0]);
8159     }
8160
8161   if (count > 1)
8162     {
8163       /* Turn on async mode */
8164       vam->async_mode = 1;
8165       vam->async_errors = 0;
8166       before = vat_time_now (vam);
8167     }
8168
8169   for (j = 0; j < count; j++)
8170     {
8171       /* Construct the API message */
8172       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8173
8174       mp->is_add = is_add;
8175       mp->is_multipath = is_multipath;
8176
8177       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8178       mp->route.table_id = ntohl (vrf_id);
8179       mp->route.n_paths = path_count;
8180
8181       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8182
8183       if (random_add_del)
8184         set_ip4_address (&pfx.address, random_vector[j + 1]);
8185       else
8186         increment_address (&pfx.address);
8187       /* send it... */
8188       S (mp);
8189       /* If we receive SIGTERM, stop now... */
8190       if (vam->do_exit)
8191         break;
8192     }
8193
8194   /* When testing multiple add/del ops, use a control-ping to sync */
8195   if (count > 1)
8196     {
8197       vl_api_control_ping_t *mp_ping;
8198       f64 after;
8199       f64 timeout;
8200
8201       /* Shut off async mode */
8202       vam->async_mode = 0;
8203
8204       MPING (CONTROL_PING, mp_ping);
8205       S (mp_ping);
8206
8207       timeout = vat_time_now (vam) + 1.0;
8208       while (vat_time_now (vam) < timeout)
8209         if (vam->result_ready == 1)
8210           goto out;
8211       vam->retval = -99;
8212
8213     out:
8214       if (vam->retval == -99)
8215         errmsg ("timeout");
8216
8217       if (vam->async_errors > 0)
8218         {
8219           errmsg ("%d asynchronous errors", vam->async_errors);
8220           vam->retval = -98;
8221         }
8222       vam->async_errors = 0;
8223       after = vat_time_now (vam);
8224
8225       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8226       if (j > 0)
8227         count = j;
8228
8229       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8230              count, after - before, count / (after - before));
8231     }
8232   else
8233     {
8234       int ret;
8235
8236       /* Wait for a reply... */
8237       W (ret);
8238       return ret;
8239     }
8240
8241   /* Return the good/bad news */
8242   return (vam->retval);
8243 }
8244
8245 static int
8246 api_ip_mroute_add_del (vat_main_t * vam)
8247 {
8248   unformat_input_t *i = vam->input;
8249   u8 path_set = 0, prefix_set = 0, is_add = 1;
8250   vl_api_ip_mroute_add_del_t *mp;
8251   mfib_entry_flags_t eflags = 0;
8252   vl_api_mfib_path_t path;
8253   vl_api_mprefix_t pfx = { };
8254   u32 vrf_id = 0;
8255   int ret;
8256
8257   /* Parse args required to build the message */
8258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8259     {
8260       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8261         {
8262           prefix_set = 1;
8263           pfx.grp_address_length = htons (pfx.grp_address_length);
8264         }
8265       else if (unformat (i, "del"))
8266         is_add = 0;
8267       else if (unformat (i, "add"))
8268         is_add = 1;
8269       else if (unformat (i, "vrf %d", &vrf_id))
8270         ;
8271       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8272         path.itf_flags = htonl (path.itf_flags);
8273       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8274         ;
8275       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8276         path_set = 1;
8277       else
8278         {
8279           clib_warning ("parse error '%U'", format_unformat_error, i);
8280           return -99;
8281         }
8282     }
8283
8284   if (prefix_set == 0)
8285     {
8286       errmsg ("missing addresses\n");
8287       return -99;
8288     }
8289   if (path_set == 0)
8290     {
8291       errmsg ("missing path\n");
8292       return -99;
8293     }
8294
8295   /* Construct the API message */
8296   M (IP_MROUTE_ADD_DEL, mp);
8297
8298   mp->is_add = is_add;
8299   mp->is_multipath = 1;
8300
8301   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8302   mp->route.table_id = htonl (vrf_id);
8303   mp->route.n_paths = 1;
8304   mp->route.entry_flags = htonl (eflags);
8305
8306   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8307
8308   /* send it... */
8309   S (mp);
8310   /* Wait for a reply... */
8311   W (ret);
8312   return ret;
8313 }
8314
8315 static int
8316 api_mpls_table_add_del (vat_main_t * vam)
8317 {
8318   unformat_input_t *i = vam->input;
8319   vl_api_mpls_table_add_del_t *mp;
8320   u32 table_id = ~0;
8321   u8 is_add = 1;
8322   int ret = 0;
8323
8324   /* Parse args required to build the message */
8325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8326     {
8327       if (unformat (i, "table %d", &table_id))
8328         ;
8329       else if (unformat (i, "del"))
8330         is_add = 0;
8331       else if (unformat (i, "add"))
8332         is_add = 1;
8333       else
8334         {
8335           clib_warning ("parse error '%U'", format_unformat_error, i);
8336           return -99;
8337         }
8338     }
8339
8340   if (~0 == table_id)
8341     {
8342       errmsg ("missing table-ID");
8343       return -99;
8344     }
8345
8346   /* Construct the API message */
8347   M (MPLS_TABLE_ADD_DEL, mp);
8348
8349   mp->mt_table.mt_table_id = ntohl (table_id);
8350   mp->mt_is_add = is_add;
8351
8352   /* send it... */
8353   S (mp);
8354
8355   /* Wait for a reply... */
8356   W (ret);
8357
8358   return ret;
8359 }
8360
8361 static int
8362 api_mpls_route_add_del (vat_main_t * vam)
8363 {
8364   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8365   mpls_label_t local_label = MPLS_LABEL_INVALID;
8366   unformat_input_t *i = vam->input;
8367   vl_api_mpls_route_add_del_t *mp;
8368   vl_api_fib_path_t paths[8];
8369   int count = 1, j;
8370   f64 before = 0;
8371
8372   /* Parse args required to build the message */
8373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8374     {
8375       if (unformat (i, "%d", &local_label))
8376         ;
8377       else if (unformat (i, "eos"))
8378         is_eos = 1;
8379       else if (unformat (i, "non-eos"))
8380         is_eos = 0;
8381       else if (unformat (i, "del"))
8382         is_add = 0;
8383       else if (unformat (i, "add"))
8384         is_add = 1;
8385       else if (unformat (i, "multipath"))
8386         is_multipath = 1;
8387       else if (unformat (i, "count %d", &count))
8388         ;
8389       else
8390         if (unformat
8391             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8392         {
8393           path_count++;
8394           if (8 == path_count)
8395             {
8396               errmsg ("max 8 paths");
8397               return -99;
8398             }
8399         }
8400       else
8401         {
8402           clib_warning ("parse error '%U'", format_unformat_error, i);
8403           return -99;
8404         }
8405     }
8406
8407   if (!path_count)
8408     {
8409       errmsg ("specify a path; via ...");
8410       return -99;
8411     }
8412
8413   if (MPLS_LABEL_INVALID == local_label)
8414     {
8415       errmsg ("missing label");
8416       return -99;
8417     }
8418
8419   if (count > 1)
8420     {
8421       /* Turn on async mode */
8422       vam->async_mode = 1;
8423       vam->async_errors = 0;
8424       before = vat_time_now (vam);
8425     }
8426
8427   for (j = 0; j < count; j++)
8428     {
8429       /* Construct the API message */
8430       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8431
8432       mp->mr_is_add = is_add;
8433       mp->mr_is_multipath = is_multipath;
8434
8435       mp->mr_route.mr_label = local_label;
8436       mp->mr_route.mr_eos = is_eos;
8437       mp->mr_route.mr_table_id = 0;
8438       mp->mr_route.mr_n_paths = path_count;
8439
8440       clib_memcpy (&mp->mr_route.mr_paths, paths,
8441                    sizeof (paths[0]) * path_count);
8442
8443       local_label++;
8444
8445       /* send it... */
8446       S (mp);
8447       /* If we receive SIGTERM, stop now... */
8448       if (vam->do_exit)
8449         break;
8450     }
8451
8452   /* When testing multiple add/del ops, use a control-ping to sync */
8453   if (count > 1)
8454     {
8455       vl_api_control_ping_t *mp_ping;
8456       f64 after;
8457       f64 timeout;
8458
8459       /* Shut off async mode */
8460       vam->async_mode = 0;
8461
8462       MPING (CONTROL_PING, mp_ping);
8463       S (mp_ping);
8464
8465       timeout = vat_time_now (vam) + 1.0;
8466       while (vat_time_now (vam) < timeout)
8467         if (vam->result_ready == 1)
8468           goto out;
8469       vam->retval = -99;
8470
8471     out:
8472       if (vam->retval == -99)
8473         errmsg ("timeout");
8474
8475       if (vam->async_errors > 0)
8476         {
8477           errmsg ("%d asynchronous errors", vam->async_errors);
8478           vam->retval = -98;
8479         }
8480       vam->async_errors = 0;
8481       after = vat_time_now (vam);
8482
8483       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8484       if (j > 0)
8485         count = j;
8486
8487       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8488              count, after - before, count / (after - before));
8489     }
8490   else
8491     {
8492       int ret;
8493
8494       /* Wait for a reply... */
8495       W (ret);
8496       return ret;
8497     }
8498
8499   /* Return the good/bad news */
8500   return (vam->retval);
8501   return (0);
8502 }
8503
8504 static int
8505 api_mpls_ip_bind_unbind (vat_main_t * vam)
8506 {
8507   unformat_input_t *i = vam->input;
8508   vl_api_mpls_ip_bind_unbind_t *mp;
8509   u32 ip_table_id = 0;
8510   u8 is_bind = 1;
8511   vl_api_prefix_t pfx;
8512   u8 prefix_set = 0;
8513   mpls_label_t local_label = MPLS_LABEL_INVALID;
8514   int ret;
8515
8516   /* Parse args required to build the message */
8517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8518     {
8519       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8520         prefix_set = 1;
8521       else if (unformat (i, "%d", &local_label))
8522         ;
8523       else if (unformat (i, "table-id %d", &ip_table_id))
8524         ;
8525       else if (unformat (i, "unbind"))
8526         is_bind = 0;
8527       else if (unformat (i, "bind"))
8528         is_bind = 1;
8529       else
8530         {
8531           clib_warning ("parse error '%U'", format_unformat_error, i);
8532           return -99;
8533         }
8534     }
8535
8536   if (!prefix_set)
8537     {
8538       errmsg ("IP prefix not set");
8539       return -99;
8540     }
8541
8542   if (MPLS_LABEL_INVALID == local_label)
8543     {
8544       errmsg ("missing label");
8545       return -99;
8546     }
8547
8548   /* Construct the API message */
8549   M (MPLS_IP_BIND_UNBIND, mp);
8550
8551   mp->mb_is_bind = is_bind;
8552   mp->mb_ip_table_id = ntohl (ip_table_id);
8553   mp->mb_mpls_table_id = 0;
8554   mp->mb_label = ntohl (local_label);
8555   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8556
8557   /* send it... */
8558   S (mp);
8559
8560   /* Wait for a reply... */
8561   W (ret);
8562   return ret;
8563   return (0);
8564 }
8565
8566 static int
8567 api_sr_mpls_policy_add (vat_main_t * vam)
8568 {
8569   unformat_input_t *i = vam->input;
8570   vl_api_sr_mpls_policy_add_t *mp;
8571   u32 bsid = 0;
8572   u32 weight = 1;
8573   u8 type = 0;
8574   u8 n_segments = 0;
8575   u32 sid;
8576   u32 *segments = NULL;
8577   int ret;
8578
8579   /* Parse args required to build the message */
8580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8581     {
8582       if (unformat (i, "bsid %d", &bsid))
8583         ;
8584       else if (unformat (i, "weight %d", &weight))
8585         ;
8586       else if (unformat (i, "spray"))
8587         type = 1;
8588       else if (unformat (i, "next %d", &sid))
8589         {
8590           n_segments += 1;
8591           vec_add1 (segments, htonl (sid));
8592         }
8593       else
8594         {
8595           clib_warning ("parse error '%U'", format_unformat_error, i);
8596           return -99;
8597         }
8598     }
8599
8600   if (bsid == 0)
8601     {
8602       errmsg ("bsid not set");
8603       return -99;
8604     }
8605
8606   if (n_segments == 0)
8607     {
8608       errmsg ("no sid in segment stack");
8609       return -99;
8610     }
8611
8612   /* Construct the API message */
8613   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8614
8615   mp->bsid = htonl (bsid);
8616   mp->weight = htonl (weight);
8617   mp->type = type;
8618   mp->n_segments = n_segments;
8619   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8620   vec_free (segments);
8621
8622   /* send it... */
8623   S (mp);
8624
8625   /* Wait for a reply... */
8626   W (ret);
8627   return ret;
8628 }
8629
8630 static int
8631 api_sr_mpls_policy_del (vat_main_t * vam)
8632 {
8633   unformat_input_t *i = vam->input;
8634   vl_api_sr_mpls_policy_del_t *mp;
8635   u32 bsid = 0;
8636   int ret;
8637
8638   /* Parse args required to build the message */
8639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8640     {
8641       if (unformat (i, "bsid %d", &bsid))
8642         ;
8643       else
8644         {
8645           clib_warning ("parse error '%U'", format_unformat_error, i);
8646           return -99;
8647         }
8648     }
8649
8650   if (bsid == 0)
8651     {
8652       errmsg ("bsid not set");
8653       return -99;
8654     }
8655
8656   /* Construct the API message */
8657   M (SR_MPLS_POLICY_DEL, mp);
8658
8659   mp->bsid = htonl (bsid);
8660
8661   /* send it... */
8662   S (mp);
8663
8664   /* Wait for a reply... */
8665   W (ret);
8666   return ret;
8667 }
8668
8669 static int
8670 api_bier_table_add_del (vat_main_t * vam)
8671 {
8672   unformat_input_t *i = vam->input;
8673   vl_api_bier_table_add_del_t *mp;
8674   u8 is_add = 1;
8675   u32 set = 0, sub_domain = 0, hdr_len = 3;
8676   mpls_label_t local_label = MPLS_LABEL_INVALID;
8677   int ret;
8678
8679   /* Parse args required to build the message */
8680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8681     {
8682       if (unformat (i, "sub-domain %d", &sub_domain))
8683         ;
8684       else if (unformat (i, "set %d", &set))
8685         ;
8686       else if (unformat (i, "label %d", &local_label))
8687         ;
8688       else if (unformat (i, "hdr-len %d", &hdr_len))
8689         ;
8690       else if (unformat (i, "add"))
8691         is_add = 1;
8692       else if (unformat (i, "del"))
8693         is_add = 0;
8694       else
8695         {
8696           clib_warning ("parse error '%U'", format_unformat_error, i);
8697           return -99;
8698         }
8699     }
8700
8701   if (MPLS_LABEL_INVALID == local_label)
8702     {
8703       errmsg ("missing label\n");
8704       return -99;
8705     }
8706
8707   /* Construct the API message */
8708   M (BIER_TABLE_ADD_DEL, mp);
8709
8710   mp->bt_is_add = is_add;
8711   mp->bt_label = ntohl (local_label);
8712   mp->bt_tbl_id.bt_set = set;
8713   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8714   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8715
8716   /* send it... */
8717   S (mp);
8718
8719   /* Wait for a reply... */
8720   W (ret);
8721
8722   return (ret);
8723 }
8724
8725 static int
8726 api_bier_route_add_del (vat_main_t * vam)
8727 {
8728   unformat_input_t *i = vam->input;
8729   vl_api_bier_route_add_del_t *mp;
8730   u8 is_add = 1;
8731   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8732   ip4_address_t v4_next_hop_address;
8733   ip6_address_t v6_next_hop_address;
8734   u8 next_hop_set = 0;
8735   u8 next_hop_proto_is_ip4 = 1;
8736   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8737   int ret;
8738
8739   /* Parse args required to build the message */
8740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8741     {
8742       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8743         {
8744           next_hop_proto_is_ip4 = 1;
8745           next_hop_set = 1;
8746         }
8747       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8748         {
8749           next_hop_proto_is_ip4 = 0;
8750           next_hop_set = 1;
8751         }
8752       if (unformat (i, "sub-domain %d", &sub_domain))
8753         ;
8754       else if (unformat (i, "set %d", &set))
8755         ;
8756       else if (unformat (i, "hdr-len %d", &hdr_len))
8757         ;
8758       else if (unformat (i, "bp %d", &bp))
8759         ;
8760       else if (unformat (i, "add"))
8761         is_add = 1;
8762       else if (unformat (i, "del"))
8763         is_add = 0;
8764       else if (unformat (i, "out-label %d", &next_hop_out_label))
8765         ;
8766       else
8767         {
8768           clib_warning ("parse error '%U'", format_unformat_error, i);
8769           return -99;
8770         }
8771     }
8772
8773   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8774     {
8775       errmsg ("next hop / label set\n");
8776       return -99;
8777     }
8778   if (0 == bp)
8779     {
8780       errmsg ("bit=position not set\n");
8781       return -99;
8782     }
8783
8784   /* Construct the API message */
8785   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8786
8787   mp->br_is_add = is_add;
8788   mp->br_route.br_tbl_id.bt_set = set;
8789   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8790   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8791   mp->br_route.br_bp = ntohs (bp);
8792   mp->br_route.br_n_paths = 1;
8793   mp->br_route.br_paths[0].n_labels = 1;
8794   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8795   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8796                                     FIB_API_PATH_NH_PROTO_IP4 :
8797                                     FIB_API_PATH_NH_PROTO_IP6);
8798
8799   if (next_hop_proto_is_ip4)
8800     {
8801       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8802                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8803     }
8804   else
8805     {
8806       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8807                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8808     }
8809
8810   /* send it... */
8811   S (mp);
8812
8813   /* Wait for a reply... */
8814   W (ret);
8815
8816   return (ret);
8817 }
8818
8819 static int
8820 api_proxy_arp_add_del (vat_main_t * vam)
8821 {
8822   unformat_input_t *i = vam->input;
8823   vl_api_proxy_arp_add_del_t *mp;
8824   u32 vrf_id = 0;
8825   u8 is_add = 1;
8826   vl_api_ip4_address_t lo, hi;
8827   u8 range_set = 0;
8828   int ret;
8829
8830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8831     {
8832       if (unformat (i, "vrf %d", &vrf_id))
8833         ;
8834       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8835                          unformat_vl_api_ip4_address, &hi))
8836         range_set = 1;
8837       else if (unformat (i, "del"))
8838         is_add = 0;
8839       else
8840         {
8841           clib_warning ("parse error '%U'", format_unformat_error, i);
8842           return -99;
8843         }
8844     }
8845
8846   if (range_set == 0)
8847     {
8848       errmsg ("address range not set");
8849       return -99;
8850     }
8851
8852   M (PROXY_ARP_ADD_DEL, mp);
8853
8854   mp->proxy.table_id = ntohl (vrf_id);
8855   mp->is_add = is_add;
8856   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8857   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8858
8859   S (mp);
8860   W (ret);
8861   return ret;
8862 }
8863
8864 static int
8865 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8866 {
8867   unformat_input_t *i = vam->input;
8868   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8869   u32 sw_if_index;
8870   u8 enable = 1;
8871   u8 sw_if_index_set = 0;
8872   int ret;
8873
8874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8875     {
8876       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8877         sw_if_index_set = 1;
8878       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8879         sw_if_index_set = 1;
8880       else if (unformat (i, "enable"))
8881         enable = 1;
8882       else if (unformat (i, "disable"))
8883         enable = 0;
8884       else
8885         {
8886           clib_warning ("parse error '%U'", format_unformat_error, i);
8887           return -99;
8888         }
8889     }
8890
8891   if (sw_if_index_set == 0)
8892     {
8893       errmsg ("missing interface name or sw_if_index");
8894       return -99;
8895     }
8896
8897   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8898
8899   mp->sw_if_index = ntohl (sw_if_index);
8900   mp->enable_disable = enable;
8901
8902   S (mp);
8903   W (ret);
8904   return ret;
8905 }
8906
8907 static int
8908 api_mpls_tunnel_add_del (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_mpls_tunnel_add_del_t *mp;
8912
8913   vl_api_fib_path_t paths[8];
8914   u32 sw_if_index = ~0;
8915   u8 path_count = 0;
8916   u8 l2_only = 0;
8917   u8 is_add = 1;
8918   int ret;
8919
8920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8921     {
8922       if (unformat (i, "add"))
8923         is_add = 1;
8924       else
8925         if (unformat
8926             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8927         is_add = 0;
8928       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8929         is_add = 0;
8930       else if (unformat (i, "l2-only"))
8931         l2_only = 1;
8932       else
8933         if (unformat
8934             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8935         {
8936           path_count++;
8937           if (8 == path_count)
8938             {
8939               errmsg ("max 8 paths");
8940               return -99;
8941             }
8942         }
8943       else
8944         {
8945           clib_warning ("parse error '%U'", format_unformat_error, i);
8946           return -99;
8947         }
8948     }
8949
8950   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8951
8952   mp->mt_is_add = is_add;
8953   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8954   mp->mt_tunnel.mt_l2_only = l2_only;
8955   mp->mt_tunnel.mt_is_multicast = 0;
8956   mp->mt_tunnel.mt_n_paths = path_count;
8957
8958   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8959                sizeof (paths[0]) * path_count);
8960
8961   S (mp);
8962   W (ret);
8963   return ret;
8964 }
8965
8966 static int
8967 api_sw_interface_set_unnumbered (vat_main_t * vam)
8968 {
8969   unformat_input_t *i = vam->input;
8970   vl_api_sw_interface_set_unnumbered_t *mp;
8971   u32 sw_if_index;
8972   u32 unnum_sw_index = ~0;
8973   u8 is_add = 1;
8974   u8 sw_if_index_set = 0;
8975   int ret;
8976
8977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8978     {
8979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8980         sw_if_index_set = 1;
8981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8982         sw_if_index_set = 1;
8983       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8984         ;
8985       else if (unformat (i, "del"))
8986         is_add = 0;
8987       else
8988         {
8989           clib_warning ("parse error '%U'", format_unformat_error, i);
8990           return -99;
8991         }
8992     }
8993
8994   if (sw_if_index_set == 0)
8995     {
8996       errmsg ("missing interface name or sw_if_index");
8997       return -99;
8998     }
8999
9000   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9001
9002   mp->sw_if_index = ntohl (sw_if_index);
9003   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9004   mp->is_add = is_add;
9005
9006   S (mp);
9007   W (ret);
9008   return ret;
9009 }
9010
9011 static int
9012 api_ip_neighbor_add_del (vat_main_t * vam)
9013 {
9014   vl_api_mac_address_t mac_address;
9015   unformat_input_t *i = vam->input;
9016   vl_api_ip_neighbor_add_del_t *mp;
9017   vl_api_address_t ip_address;
9018   u32 sw_if_index;
9019   u8 sw_if_index_set = 0;
9020   u8 is_add = 1;
9021   u8 mac_set = 0;
9022   u8 address_set = 0;
9023   int ret;
9024   ip_neighbor_flags_t flags;
9025
9026   flags = IP_NEIGHBOR_FLAG_NONE;
9027   clib_memset (&ip_address, 0, sizeof (ip_address));
9028   clib_memset (&mac_address, 0, sizeof (mac_address));
9029
9030   /* Parse args required to build the message */
9031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9032     {
9033       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9034         {
9035           mac_set = 1;
9036         }
9037       else if (unformat (i, "del"))
9038         is_add = 0;
9039       else
9040         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9041         sw_if_index_set = 1;
9042       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9043         sw_if_index_set = 1;
9044       else if (unformat (i, "static"))
9045         flags |= IP_NEIGHBOR_FLAG_STATIC;
9046       else if (unformat (i, "no-fib-entry"))
9047         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9048       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9049         address_set = 1;
9050       else
9051         {
9052           clib_warning ("parse error '%U'", format_unformat_error, i);
9053           return -99;
9054         }
9055     }
9056
9057   if (sw_if_index_set == 0)
9058     {
9059       errmsg ("missing interface name or sw_if_index");
9060       return -99;
9061     }
9062   if (!address_set)
9063     {
9064       errmsg ("no address set");
9065       return -99;
9066     }
9067
9068   /* Construct the API message */
9069   M (IP_NEIGHBOR_ADD_DEL, mp);
9070
9071   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9072   mp->is_add = is_add;
9073   mp->neighbor.flags = htonl (flags);
9074   if (mac_set)
9075     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9076                  sizeof (mac_address));
9077   if (address_set)
9078     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9079
9080   /* send it... */
9081   S (mp);
9082
9083   /* Wait for a reply, return good/bad news  */
9084   W (ret);
9085   return ret;
9086 }
9087
9088 static int
9089 api_create_vlan_subif (vat_main_t * vam)
9090 {
9091   unformat_input_t *i = vam->input;
9092   vl_api_create_vlan_subif_t *mp;
9093   u32 sw_if_index;
9094   u8 sw_if_index_set = 0;
9095   u32 vlan_id;
9096   u8 vlan_id_set = 0;
9097   int ret;
9098
9099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9100     {
9101       if (unformat (i, "sw_if_index %d", &sw_if_index))
9102         sw_if_index_set = 1;
9103       else
9104         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9105         sw_if_index_set = 1;
9106       else if (unformat (i, "vlan %d", &vlan_id))
9107         vlan_id_set = 1;
9108       else
9109         {
9110           clib_warning ("parse error '%U'", format_unformat_error, i);
9111           return -99;
9112         }
9113     }
9114
9115   if (sw_if_index_set == 0)
9116     {
9117       errmsg ("missing interface name or sw_if_index");
9118       return -99;
9119     }
9120
9121   if (vlan_id_set == 0)
9122     {
9123       errmsg ("missing vlan_id");
9124       return -99;
9125     }
9126   M (CREATE_VLAN_SUBIF, mp);
9127
9128   mp->sw_if_index = ntohl (sw_if_index);
9129   mp->vlan_id = ntohl (vlan_id);
9130
9131   S (mp);
9132   W (ret);
9133   return ret;
9134 }
9135
9136 #define foreach_create_subif_bit                \
9137 _(no_tags)                                      \
9138 _(one_tag)                                      \
9139 _(two_tags)                                     \
9140 _(dot1ad)                                       \
9141 _(exact_match)                                  \
9142 _(default_sub)                                  \
9143 _(outer_vlan_id_any)                            \
9144 _(inner_vlan_id_any)
9145
9146 #define foreach_create_subif_flag               \
9147 _(0, "no_tags")                                 \
9148 _(1, "one_tag")                                 \
9149 _(2, "two_tags")                                \
9150 _(3, "dot1ad")                                  \
9151 _(4, "exact_match")                             \
9152 _(5, "default_sub")                             \
9153 _(6, "outer_vlan_id_any")                       \
9154 _(7, "inner_vlan_id_any")
9155
9156 static int
9157 api_create_subif (vat_main_t * vam)
9158 {
9159   unformat_input_t *i = vam->input;
9160   vl_api_create_subif_t *mp;
9161   u32 sw_if_index;
9162   u8 sw_if_index_set = 0;
9163   u32 sub_id;
9164   u8 sub_id_set = 0;
9165   u32 __attribute__ ((unused)) no_tags = 0;
9166   u32 __attribute__ ((unused)) one_tag = 0;
9167   u32 __attribute__ ((unused)) two_tags = 0;
9168   u32 __attribute__ ((unused)) dot1ad = 0;
9169   u32 __attribute__ ((unused)) exact_match = 0;
9170   u32 __attribute__ ((unused)) default_sub = 0;
9171   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9172   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9173   u32 tmp;
9174   u16 outer_vlan_id = 0;
9175   u16 inner_vlan_id = 0;
9176   int ret;
9177
9178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9179     {
9180       if (unformat (i, "sw_if_index %d", &sw_if_index))
9181         sw_if_index_set = 1;
9182       else
9183         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9184         sw_if_index_set = 1;
9185       else if (unformat (i, "sub_id %d", &sub_id))
9186         sub_id_set = 1;
9187       else if (unformat (i, "outer_vlan_id %d", &tmp))
9188         outer_vlan_id = tmp;
9189       else if (unformat (i, "inner_vlan_id %d", &tmp))
9190         inner_vlan_id = tmp;
9191
9192 #define _(a) else if (unformat (i, #a)) a = 1 ;
9193       foreach_create_subif_bit
9194 #undef _
9195         else
9196         {
9197           clib_warning ("parse error '%U'", format_unformat_error, i);
9198           return -99;
9199         }
9200     }
9201
9202   if (sw_if_index_set == 0)
9203     {
9204       errmsg ("missing interface name or sw_if_index");
9205       return -99;
9206     }
9207
9208   if (sub_id_set == 0)
9209     {
9210       errmsg ("missing sub_id");
9211       return -99;
9212     }
9213   M (CREATE_SUBIF, mp);
9214
9215   mp->sw_if_index = ntohl (sw_if_index);
9216   mp->sub_id = ntohl (sub_id);
9217
9218 #define _(a,b) mp->sub_if_flags |= (1 << a);
9219   foreach_create_subif_flag;
9220 #undef _
9221
9222   mp->outer_vlan_id = ntohs (outer_vlan_id);
9223   mp->inner_vlan_id = ntohs (inner_vlan_id);
9224
9225   S (mp);
9226   W (ret);
9227   return ret;
9228 }
9229
9230 static int
9231 api_reset_fib (vat_main_t * vam)
9232 {
9233   unformat_input_t *i = vam->input;
9234   vl_api_reset_fib_t *mp;
9235   u32 vrf_id = 0;
9236   u8 is_ipv6 = 0;
9237   u8 vrf_id_set = 0;
9238
9239   int ret;
9240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9241     {
9242       if (unformat (i, "vrf %d", &vrf_id))
9243         vrf_id_set = 1;
9244       else if (unformat (i, "ipv6"))
9245         is_ipv6 = 1;
9246       else
9247         {
9248           clib_warning ("parse error '%U'", format_unformat_error, i);
9249           return -99;
9250         }
9251     }
9252
9253   if (vrf_id_set == 0)
9254     {
9255       errmsg ("missing vrf id");
9256       return -99;
9257     }
9258
9259   M (RESET_FIB, mp);
9260
9261   mp->vrf_id = ntohl (vrf_id);
9262   mp->is_ipv6 = is_ipv6;
9263
9264   S (mp);
9265   W (ret);
9266   return ret;
9267 }
9268
9269 static int
9270 api_dhcp_proxy_config (vat_main_t * vam)
9271 {
9272   unformat_input_t *i = vam->input;
9273   vl_api_dhcp_proxy_config_t *mp;
9274   u32 rx_vrf_id = 0;
9275   u32 server_vrf_id = 0;
9276   u8 is_add = 1;
9277   u8 v4_address_set = 0;
9278   u8 v6_address_set = 0;
9279   ip4_address_t v4address;
9280   ip6_address_t v6address;
9281   u8 v4_src_address_set = 0;
9282   u8 v6_src_address_set = 0;
9283   ip4_address_t v4srcaddress;
9284   ip6_address_t v6srcaddress;
9285   int ret;
9286
9287   /* Parse args required to build the message */
9288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9289     {
9290       if (unformat (i, "del"))
9291         is_add = 0;
9292       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9293         ;
9294       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9295         ;
9296       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9297         v4_address_set = 1;
9298       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9299         v6_address_set = 1;
9300       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9301         v4_src_address_set = 1;
9302       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9303         v6_src_address_set = 1;
9304       else
9305         break;
9306     }
9307
9308   if (v4_address_set && v6_address_set)
9309     {
9310       errmsg ("both v4 and v6 server addresses set");
9311       return -99;
9312     }
9313   if (!v4_address_set && !v6_address_set)
9314     {
9315       errmsg ("no server addresses set");
9316       return -99;
9317     }
9318
9319   if (v4_src_address_set && v6_src_address_set)
9320     {
9321       errmsg ("both v4 and v6  src addresses set");
9322       return -99;
9323     }
9324   if (!v4_src_address_set && !v6_src_address_set)
9325     {
9326       errmsg ("no src addresses set");
9327       return -99;
9328     }
9329
9330   if (!(v4_src_address_set && v4_address_set) &&
9331       !(v6_src_address_set && v6_address_set))
9332     {
9333       errmsg ("no matching server and src addresses set");
9334       return -99;
9335     }
9336
9337   /* Construct the API message */
9338   M (DHCP_PROXY_CONFIG, mp);
9339
9340   mp->is_add = is_add;
9341   mp->rx_vrf_id = ntohl (rx_vrf_id);
9342   mp->server_vrf_id = ntohl (server_vrf_id);
9343   if (v6_address_set)
9344     {
9345       mp->is_ipv6 = 1;
9346       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9347       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9348     }
9349   else
9350     {
9351       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9352       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9353     }
9354
9355   /* send it... */
9356   S (mp);
9357
9358   /* Wait for a reply, return good/bad news  */
9359   W (ret);
9360   return ret;
9361 }
9362
9363 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9364 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9365
9366 static void
9367 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9368 {
9369   vat_main_t *vam = &vat_main;
9370   u32 i, count = mp->count;
9371   vl_api_dhcp_server_t *s;
9372
9373   if (mp->is_ipv6)
9374     print (vam->ofp,
9375            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9376            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9377            ntohl (mp->rx_vrf_id),
9378            format_ip6_address, mp->dhcp_src_address,
9379            mp->vss_type, mp->vss_vpn_ascii_id,
9380            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9381   else
9382     print (vam->ofp,
9383            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9384            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9385            ntohl (mp->rx_vrf_id),
9386            format_ip4_address, mp->dhcp_src_address,
9387            mp->vss_type, mp->vss_vpn_ascii_id,
9388            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9389
9390   for (i = 0; i < count; i++)
9391     {
9392       s = &mp->servers[i];
9393
9394       if (mp->is_ipv6)
9395         print (vam->ofp,
9396                " Server Table-ID %d, Server Address %U",
9397                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9398       else
9399         print (vam->ofp,
9400                " Server Table-ID %d, Server Address %U",
9401                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9402     }
9403 }
9404
9405 static void vl_api_dhcp_proxy_details_t_handler_json
9406   (vl_api_dhcp_proxy_details_t * mp)
9407 {
9408   vat_main_t *vam = &vat_main;
9409   vat_json_node_t *node = NULL;
9410   u32 i, count = mp->count;
9411   struct in_addr ip4;
9412   struct in6_addr ip6;
9413   vl_api_dhcp_server_t *s;
9414
9415   if (VAT_JSON_ARRAY != vam->json_tree.type)
9416     {
9417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9418       vat_json_init_array (&vam->json_tree);
9419     }
9420   node = vat_json_array_add (&vam->json_tree);
9421
9422   vat_json_init_object (node);
9423   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9424   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9425                              sizeof (mp->vss_type));
9426   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9427                                    mp->vss_vpn_ascii_id);
9428   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9429   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9430
9431   if (mp->is_ipv6)
9432     {
9433       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9434       vat_json_object_add_ip6 (node, "src_address", ip6);
9435     }
9436   else
9437     {
9438       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9439       vat_json_object_add_ip4 (node, "src_address", ip4);
9440     }
9441
9442   for (i = 0; i < count; i++)
9443     {
9444       s = &mp->servers[i];
9445
9446       vat_json_object_add_uint (node, "server-table-id",
9447                                 ntohl (s->server_vrf_id));
9448
9449       if (mp->is_ipv6)
9450         {
9451           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9452           vat_json_object_add_ip4 (node, "src_address", ip4);
9453         }
9454       else
9455         {
9456           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9457           vat_json_object_add_ip6 (node, "server_address", ip6);
9458         }
9459     }
9460 }
9461
9462 static int
9463 api_dhcp_proxy_dump (vat_main_t * vam)
9464 {
9465   unformat_input_t *i = vam->input;
9466   vl_api_control_ping_t *mp_ping;
9467   vl_api_dhcp_proxy_dump_t *mp;
9468   u8 is_ipv6 = 0;
9469   int ret;
9470
9471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9472     {
9473       if (unformat (i, "ipv6"))
9474         is_ipv6 = 1;
9475       else
9476         {
9477           clib_warning ("parse error '%U'", format_unformat_error, i);
9478           return -99;
9479         }
9480     }
9481
9482   M (DHCP_PROXY_DUMP, mp);
9483
9484   mp->is_ip6 = is_ipv6;
9485   S (mp);
9486
9487   /* Use a control ping for synchronization */
9488   MPING (CONTROL_PING, mp_ping);
9489   S (mp_ping);
9490
9491   W (ret);
9492   return ret;
9493 }
9494
9495 static int
9496 api_dhcp_proxy_set_vss (vat_main_t * vam)
9497 {
9498   unformat_input_t *i = vam->input;
9499   vl_api_dhcp_proxy_set_vss_t *mp;
9500   u8 is_ipv6 = 0;
9501   u8 is_add = 1;
9502   u32 tbl_id = ~0;
9503   u8 vss_type = VSS_TYPE_DEFAULT;
9504   u8 *vpn_ascii_id = 0;
9505   u32 oui = 0;
9506   u32 fib_id = 0;
9507   int ret;
9508
9509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9510     {
9511       if (unformat (i, "tbl_id %d", &tbl_id))
9512         ;
9513       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9514         vss_type = VSS_TYPE_ASCII;
9515       else if (unformat (i, "fib_id %d", &fib_id))
9516         vss_type = VSS_TYPE_VPN_ID;
9517       else if (unformat (i, "oui %d", &oui))
9518         vss_type = VSS_TYPE_VPN_ID;
9519       else if (unformat (i, "ipv6"))
9520         is_ipv6 = 1;
9521       else if (unformat (i, "del"))
9522         is_add = 0;
9523       else
9524         break;
9525     }
9526
9527   if (tbl_id == ~0)
9528     {
9529       errmsg ("missing tbl_id ");
9530       vec_free (vpn_ascii_id);
9531       return -99;
9532     }
9533
9534   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9535     {
9536       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9537       vec_free (vpn_ascii_id);
9538       return -99;
9539     }
9540
9541   M (DHCP_PROXY_SET_VSS, mp);
9542   mp->tbl_id = ntohl (tbl_id);
9543   mp->vss_type = vss_type;
9544   if (vpn_ascii_id)
9545     {
9546       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9547       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9548     }
9549   mp->vpn_index = ntohl (fib_id);
9550   mp->oui = ntohl (oui);
9551   mp->is_ipv6 = is_ipv6;
9552   mp->is_add = is_add;
9553
9554   S (mp);
9555   W (ret);
9556
9557   vec_free (vpn_ascii_id);
9558   return ret;
9559 }
9560
9561 static int
9562 api_dhcp_client_config (vat_main_t * vam)
9563 {
9564   unformat_input_t *i = vam->input;
9565   vl_api_dhcp_client_config_t *mp;
9566   u32 sw_if_index;
9567   u8 sw_if_index_set = 0;
9568   u8 is_add = 1;
9569   u8 *hostname = 0;
9570   u8 disable_event = 0;
9571   int ret;
9572
9573   /* Parse args required to build the message */
9574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (i, "del"))
9577         is_add = 0;
9578       else
9579         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9580         sw_if_index_set = 1;
9581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9582         sw_if_index_set = 1;
9583       else if (unformat (i, "hostname %s", &hostname))
9584         ;
9585       else if (unformat (i, "disable_event"))
9586         disable_event = 1;
9587       else
9588         break;
9589     }
9590
9591   if (sw_if_index_set == 0)
9592     {
9593       errmsg ("missing interface name or sw_if_index");
9594       return -99;
9595     }
9596
9597   if (vec_len (hostname) > 63)
9598     {
9599       errmsg ("hostname too long");
9600     }
9601   vec_add1 (hostname, 0);
9602
9603   /* Construct the API message */
9604   M (DHCP_CLIENT_CONFIG, mp);
9605
9606   mp->is_add = is_add;
9607   mp->client.sw_if_index = htonl (sw_if_index);
9608   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9609   vec_free (hostname);
9610   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9611   mp->client.pid = htonl (getpid ());
9612
9613   /* send it... */
9614   S (mp);
9615
9616   /* Wait for a reply, return good/bad news  */
9617   W (ret);
9618   return ret;
9619 }
9620
9621 static int
9622 api_set_ip_flow_hash (vat_main_t * vam)
9623 {
9624   unformat_input_t *i = vam->input;
9625   vl_api_set_ip_flow_hash_t *mp;
9626   u32 vrf_id = 0;
9627   u8 is_ipv6 = 0;
9628   u8 vrf_id_set = 0;
9629   u8 src = 0;
9630   u8 dst = 0;
9631   u8 sport = 0;
9632   u8 dport = 0;
9633   u8 proto = 0;
9634   u8 reverse = 0;
9635   int ret;
9636
9637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9638     {
9639       if (unformat (i, "vrf %d", &vrf_id))
9640         vrf_id_set = 1;
9641       else if (unformat (i, "ipv6"))
9642         is_ipv6 = 1;
9643       else if (unformat (i, "src"))
9644         src = 1;
9645       else if (unformat (i, "dst"))
9646         dst = 1;
9647       else if (unformat (i, "sport"))
9648         sport = 1;
9649       else if (unformat (i, "dport"))
9650         dport = 1;
9651       else if (unformat (i, "proto"))
9652         proto = 1;
9653       else if (unformat (i, "reverse"))
9654         reverse = 1;
9655
9656       else
9657         {
9658           clib_warning ("parse error '%U'", format_unformat_error, i);
9659           return -99;
9660         }
9661     }
9662
9663   if (vrf_id_set == 0)
9664     {
9665       errmsg ("missing vrf id");
9666       return -99;
9667     }
9668
9669   M (SET_IP_FLOW_HASH, mp);
9670   mp->src = src;
9671   mp->dst = dst;
9672   mp->sport = sport;
9673   mp->dport = dport;
9674   mp->proto = proto;
9675   mp->reverse = reverse;
9676   mp->vrf_id = ntohl (vrf_id);
9677   mp->is_ipv6 = is_ipv6;
9678
9679   S (mp);
9680   W (ret);
9681   return ret;
9682 }
9683
9684 static int
9685 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9686 {
9687   unformat_input_t *i = vam->input;
9688   vl_api_sw_interface_ip6_enable_disable_t *mp;
9689   u32 sw_if_index;
9690   u8 sw_if_index_set = 0;
9691   u8 enable = 0;
9692   int ret;
9693
9694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9695     {
9696       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9697         sw_if_index_set = 1;
9698       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9699         sw_if_index_set = 1;
9700       else if (unformat (i, "enable"))
9701         enable = 1;
9702       else if (unformat (i, "disable"))
9703         enable = 0;
9704       else
9705         {
9706           clib_warning ("parse error '%U'", format_unformat_error, i);
9707           return -99;
9708         }
9709     }
9710
9711   if (sw_if_index_set == 0)
9712     {
9713       errmsg ("missing interface name or sw_if_index");
9714       return -99;
9715     }
9716
9717   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9718
9719   mp->sw_if_index = ntohl (sw_if_index);
9720   mp->enable = enable;
9721
9722   S (mp);
9723   W (ret);
9724   return ret;
9725 }
9726
9727 static int
9728 api_ip6nd_proxy_add_del (vat_main_t * vam)
9729 {
9730   unformat_input_t *i = vam->input;
9731   vl_api_ip6nd_proxy_add_del_t *mp;
9732   u32 sw_if_index = ~0;
9733   u8 v6_address_set = 0;
9734   vl_api_ip6_address_t v6address;
9735   u8 is_del = 0;
9736   int ret;
9737
9738   /* Parse args required to build the message */
9739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9740     {
9741       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9742         ;
9743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9744         ;
9745       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9746         v6_address_set = 1;
9747       if (unformat (i, "del"))
9748         is_del = 1;
9749       else
9750         {
9751           clib_warning ("parse error '%U'", format_unformat_error, i);
9752           return -99;
9753         }
9754     }
9755
9756   if (sw_if_index == ~0)
9757     {
9758       errmsg ("missing interface name or sw_if_index");
9759       return -99;
9760     }
9761   if (!v6_address_set)
9762     {
9763       errmsg ("no address set");
9764       return -99;
9765     }
9766
9767   /* Construct the API message */
9768   M (IP6ND_PROXY_ADD_DEL, mp);
9769
9770   mp->is_del = is_del;
9771   mp->sw_if_index = ntohl (sw_if_index);
9772   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9773
9774   /* send it... */
9775   S (mp);
9776
9777   /* Wait for a reply, return good/bad news  */
9778   W (ret);
9779   return ret;
9780 }
9781
9782 static int
9783 api_ip6nd_proxy_dump (vat_main_t * vam)
9784 {
9785   vl_api_ip6nd_proxy_dump_t *mp;
9786   vl_api_control_ping_t *mp_ping;
9787   int ret;
9788
9789   M (IP6ND_PROXY_DUMP, mp);
9790
9791   S (mp);
9792
9793   /* Use a control ping for synchronization */
9794   MPING (CONTROL_PING, mp_ping);
9795   S (mp_ping);
9796
9797   W (ret);
9798   return ret;
9799 }
9800
9801 static void vl_api_ip6nd_proxy_details_t_handler
9802   (vl_api_ip6nd_proxy_details_t * mp)
9803 {
9804   vat_main_t *vam = &vat_main;
9805
9806   print (vam->ofp, "host %U sw_if_index %d",
9807          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9808 }
9809
9810 static void vl_api_ip6nd_proxy_details_t_handler_json
9811   (vl_api_ip6nd_proxy_details_t * mp)
9812 {
9813   vat_main_t *vam = &vat_main;
9814   struct in6_addr ip6;
9815   vat_json_node_t *node = NULL;
9816
9817   if (VAT_JSON_ARRAY != vam->json_tree.type)
9818     {
9819       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9820       vat_json_init_array (&vam->json_tree);
9821     }
9822   node = vat_json_array_add (&vam->json_tree);
9823
9824   vat_json_init_object (node);
9825   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9826
9827   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9828   vat_json_object_add_ip6 (node, "host", ip6);
9829 }
9830
9831 static int
9832 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9833 {
9834   unformat_input_t *i = vam->input;
9835   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9836   u32 sw_if_index;
9837   u8 sw_if_index_set = 0;
9838   u8 v6_address_set = 0;
9839   vl_api_prefix_t pfx;
9840   u8 use_default = 0;
9841   u8 no_advertise = 0;
9842   u8 off_link = 0;
9843   u8 no_autoconfig = 0;
9844   u8 no_onlink = 0;
9845   u8 is_no = 0;
9846   u32 val_lifetime = 0;
9847   u32 pref_lifetime = 0;
9848   int ret;
9849
9850   /* Parse args required to build the message */
9851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9852     {
9853       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9854         sw_if_index_set = 1;
9855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9856         sw_if_index_set = 1;
9857       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9858         v6_address_set = 1;
9859       else if (unformat (i, "val_life %d", &val_lifetime))
9860         ;
9861       else if (unformat (i, "pref_life %d", &pref_lifetime))
9862         ;
9863       else if (unformat (i, "def"))
9864         use_default = 1;
9865       else if (unformat (i, "noadv"))
9866         no_advertise = 1;
9867       else if (unformat (i, "offl"))
9868         off_link = 1;
9869       else if (unformat (i, "noauto"))
9870         no_autoconfig = 1;
9871       else if (unformat (i, "nolink"))
9872         no_onlink = 1;
9873       else if (unformat (i, "isno"))
9874         is_no = 1;
9875       else
9876         {
9877           clib_warning ("parse error '%U'", format_unformat_error, i);
9878           return -99;
9879         }
9880     }
9881
9882   if (sw_if_index_set == 0)
9883     {
9884       errmsg ("missing interface name or sw_if_index");
9885       return -99;
9886     }
9887   if (!v6_address_set)
9888     {
9889       errmsg ("no address set");
9890       return -99;
9891     }
9892
9893   /* Construct the API message */
9894   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9895
9896   mp->sw_if_index = ntohl (sw_if_index);
9897   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9898   mp->use_default = use_default;
9899   mp->no_advertise = no_advertise;
9900   mp->off_link = off_link;
9901   mp->no_autoconfig = no_autoconfig;
9902   mp->no_onlink = no_onlink;
9903   mp->is_no = is_no;
9904   mp->val_lifetime = ntohl (val_lifetime);
9905   mp->pref_lifetime = ntohl (pref_lifetime);
9906
9907   /* send it... */
9908   S (mp);
9909
9910   /* Wait for a reply, return good/bad news  */
9911   W (ret);
9912   return ret;
9913 }
9914
9915 static int
9916 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9917 {
9918   unformat_input_t *i = vam->input;
9919   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9920   u32 sw_if_index;
9921   u8 sw_if_index_set = 0;
9922   u8 suppress = 0;
9923   u8 managed = 0;
9924   u8 other = 0;
9925   u8 ll_option = 0;
9926   u8 send_unicast = 0;
9927   u8 cease = 0;
9928   u8 is_no = 0;
9929   u8 default_router = 0;
9930   u32 max_interval = 0;
9931   u32 min_interval = 0;
9932   u32 lifetime = 0;
9933   u32 initial_count = 0;
9934   u32 initial_interval = 0;
9935   int ret;
9936
9937
9938   /* Parse args required to build the message */
9939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9940     {
9941       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9942         sw_if_index_set = 1;
9943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9944         sw_if_index_set = 1;
9945       else if (unformat (i, "maxint %d", &max_interval))
9946         ;
9947       else if (unformat (i, "minint %d", &min_interval))
9948         ;
9949       else if (unformat (i, "life %d", &lifetime))
9950         ;
9951       else if (unformat (i, "count %d", &initial_count))
9952         ;
9953       else if (unformat (i, "interval %d", &initial_interval))
9954         ;
9955       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9956         suppress = 1;
9957       else if (unformat (i, "managed"))
9958         managed = 1;
9959       else if (unformat (i, "other"))
9960         other = 1;
9961       else if (unformat (i, "ll"))
9962         ll_option = 1;
9963       else if (unformat (i, "send"))
9964         send_unicast = 1;
9965       else if (unformat (i, "cease"))
9966         cease = 1;
9967       else if (unformat (i, "isno"))
9968         is_no = 1;
9969       else if (unformat (i, "def"))
9970         default_router = 1;
9971       else
9972         {
9973           clib_warning ("parse error '%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   if (sw_if_index_set == 0)
9979     {
9980       errmsg ("missing interface name or sw_if_index");
9981       return -99;
9982     }
9983
9984   /* Construct the API message */
9985   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9986
9987   mp->sw_if_index = ntohl (sw_if_index);
9988   mp->max_interval = ntohl (max_interval);
9989   mp->min_interval = ntohl (min_interval);
9990   mp->lifetime = ntohl (lifetime);
9991   mp->initial_count = ntohl (initial_count);
9992   mp->initial_interval = ntohl (initial_interval);
9993   mp->suppress = suppress;
9994   mp->managed = managed;
9995   mp->other = other;
9996   mp->ll_option = ll_option;
9997   mp->send_unicast = send_unicast;
9998   mp->cease = cease;
9999   mp->is_no = is_no;
10000   mp->default_router = default_router;
10001
10002   /* send it... */
10003   S (mp);
10004
10005   /* Wait for a reply, return good/bad news  */
10006   W (ret);
10007   return ret;
10008 }
10009
10010 static int
10011 api_set_arp_neighbor_limit (vat_main_t * vam)
10012 {
10013   unformat_input_t *i = vam->input;
10014   vl_api_set_arp_neighbor_limit_t *mp;
10015   u32 arp_nbr_limit;
10016   u8 limit_set = 0;
10017   u8 is_ipv6 = 0;
10018   int ret;
10019
10020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10021     {
10022       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10023         limit_set = 1;
10024       else if (unformat (i, "ipv6"))
10025         is_ipv6 = 1;
10026       else
10027         {
10028           clib_warning ("parse error '%U'", format_unformat_error, i);
10029           return -99;
10030         }
10031     }
10032
10033   if (limit_set == 0)
10034     {
10035       errmsg ("missing limit value");
10036       return -99;
10037     }
10038
10039   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10040
10041   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10042   mp->is_ipv6 = is_ipv6;
10043
10044   S (mp);
10045   W (ret);
10046   return ret;
10047 }
10048
10049 static int
10050 api_l2_patch_add_del (vat_main_t * vam)
10051 {
10052   unformat_input_t *i = vam->input;
10053   vl_api_l2_patch_add_del_t *mp;
10054   u32 rx_sw_if_index;
10055   u8 rx_sw_if_index_set = 0;
10056   u32 tx_sw_if_index;
10057   u8 tx_sw_if_index_set = 0;
10058   u8 is_add = 1;
10059   int ret;
10060
10061   /* Parse args required to build the message */
10062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10063     {
10064       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10065         rx_sw_if_index_set = 1;
10066       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10067         tx_sw_if_index_set = 1;
10068       else if (unformat (i, "rx"))
10069         {
10070           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10071             {
10072               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10073                             &rx_sw_if_index))
10074                 rx_sw_if_index_set = 1;
10075             }
10076           else
10077             break;
10078         }
10079       else if (unformat (i, "tx"))
10080         {
10081           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10082             {
10083               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10084                             &tx_sw_if_index))
10085                 tx_sw_if_index_set = 1;
10086             }
10087           else
10088             break;
10089         }
10090       else if (unformat (i, "del"))
10091         is_add = 0;
10092       else
10093         break;
10094     }
10095
10096   if (rx_sw_if_index_set == 0)
10097     {
10098       errmsg ("missing rx interface name or rx_sw_if_index");
10099       return -99;
10100     }
10101
10102   if (tx_sw_if_index_set == 0)
10103     {
10104       errmsg ("missing tx interface name or tx_sw_if_index");
10105       return -99;
10106     }
10107
10108   M (L2_PATCH_ADD_DEL, mp);
10109
10110   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10111   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10112   mp->is_add = is_add;
10113
10114   S (mp);
10115   W (ret);
10116   return ret;
10117 }
10118
10119 u8 is_del;
10120 u8 localsid_addr[16];
10121 u8 end_psp;
10122 u8 behavior;
10123 u32 sw_if_index;
10124 u32 vlan_index;
10125 u32 fib_table;
10126 u8 nh_addr[16];
10127
10128 static int
10129 api_sr_localsid_add_del (vat_main_t * vam)
10130 {
10131   unformat_input_t *i = vam->input;
10132   vl_api_sr_localsid_add_del_t *mp;
10133
10134   u8 is_del;
10135   ip6_address_t localsid;
10136   u8 end_psp = 0;
10137   u8 behavior = ~0;
10138   u32 sw_if_index;
10139   u32 fib_table = ~(u32) 0;
10140   ip6_address_t nh_addr6;
10141   ip4_address_t nh_addr4;
10142   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10143   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10144
10145   bool nexthop_set = 0;
10146
10147   int ret;
10148
10149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10150     {
10151       if (unformat (i, "del"))
10152         is_del = 1;
10153       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10154       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10155         nexthop_set = 1;
10156       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10157         nexthop_set = 1;
10158       else if (unformat (i, "behavior %u", &behavior));
10159       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10160       else if (unformat (i, "fib-table %u", &fib_table));
10161       else if (unformat (i, "end.psp %u", &behavior));
10162       else
10163         break;
10164     }
10165
10166   M (SR_LOCALSID_ADD_DEL, mp);
10167
10168   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10169   if (nexthop_set)
10170     {
10171       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10172       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10173     }
10174   mp->behavior = behavior;
10175   mp->sw_if_index = ntohl (sw_if_index);
10176   mp->fib_table = ntohl (fib_table);
10177   mp->end_psp = end_psp;
10178   mp->is_del = is_del;
10179
10180   S (mp);
10181   W (ret);
10182   return ret;
10183 }
10184
10185 static int
10186 api_ioam_enable (vat_main_t * vam)
10187 {
10188   unformat_input_t *input = vam->input;
10189   vl_api_ioam_enable_t *mp;
10190   u32 id = 0;
10191   int has_trace_option = 0;
10192   int has_pot_option = 0;
10193   int has_seqno_option = 0;
10194   int has_analyse_option = 0;
10195   int ret;
10196
10197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10198     {
10199       if (unformat (input, "trace"))
10200         has_trace_option = 1;
10201       else if (unformat (input, "pot"))
10202         has_pot_option = 1;
10203       else if (unformat (input, "seqno"))
10204         has_seqno_option = 1;
10205       else if (unformat (input, "analyse"))
10206         has_analyse_option = 1;
10207       else
10208         break;
10209     }
10210   M (IOAM_ENABLE, mp);
10211   mp->id = htons (id);
10212   mp->seqno = has_seqno_option;
10213   mp->analyse = has_analyse_option;
10214   mp->pot_enable = has_pot_option;
10215   mp->trace_enable = has_trace_option;
10216
10217   S (mp);
10218   W (ret);
10219   return ret;
10220 }
10221
10222
10223 static int
10224 api_ioam_disable (vat_main_t * vam)
10225 {
10226   vl_api_ioam_disable_t *mp;
10227   int ret;
10228
10229   M (IOAM_DISABLE, mp);
10230   S (mp);
10231   W (ret);
10232   return ret;
10233 }
10234
10235 #define foreach_tcp_proto_field                 \
10236 _(src_port)                                     \
10237 _(dst_port)
10238
10239 #define foreach_udp_proto_field                 \
10240 _(src_port)                                     \
10241 _(dst_port)
10242
10243 #define foreach_ip4_proto_field                 \
10244 _(src_address)                                  \
10245 _(dst_address)                                  \
10246 _(tos)                                          \
10247 _(length)                                       \
10248 _(fragment_id)                                  \
10249 _(ttl)                                          \
10250 _(protocol)                                     \
10251 _(checksum)
10252
10253 typedef struct
10254 {
10255   u16 src_port, dst_port;
10256 } tcpudp_header_t;
10257
10258 #if VPP_API_TEST_BUILTIN == 0
10259 uword
10260 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10261 {
10262   u8 **maskp = va_arg (*args, u8 **);
10263   u8 *mask = 0;
10264   u8 found_something = 0;
10265   tcp_header_t *tcp;
10266
10267 #define _(a) u8 a=0;
10268   foreach_tcp_proto_field;
10269 #undef _
10270
10271   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10272     {
10273       if (0);
10274 #define _(a) else if (unformat (input, #a)) a=1;
10275       foreach_tcp_proto_field
10276 #undef _
10277         else
10278         break;
10279     }
10280
10281 #define _(a) found_something += a;
10282   foreach_tcp_proto_field;
10283 #undef _
10284
10285   if (found_something == 0)
10286     return 0;
10287
10288   vec_validate (mask, sizeof (*tcp) - 1);
10289
10290   tcp = (tcp_header_t *) mask;
10291
10292 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10293   foreach_tcp_proto_field;
10294 #undef _
10295
10296   *maskp = mask;
10297   return 1;
10298 }
10299
10300 uword
10301 unformat_udp_mask (unformat_input_t * input, va_list * args)
10302 {
10303   u8 **maskp = va_arg (*args, u8 **);
10304   u8 *mask = 0;
10305   u8 found_something = 0;
10306   udp_header_t *udp;
10307
10308 #define _(a) u8 a=0;
10309   foreach_udp_proto_field;
10310 #undef _
10311
10312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10313     {
10314       if (0);
10315 #define _(a) else if (unformat (input, #a)) a=1;
10316       foreach_udp_proto_field
10317 #undef _
10318         else
10319         break;
10320     }
10321
10322 #define _(a) found_something += a;
10323   foreach_udp_proto_field;
10324 #undef _
10325
10326   if (found_something == 0)
10327     return 0;
10328
10329   vec_validate (mask, sizeof (*udp) - 1);
10330
10331   udp = (udp_header_t *) mask;
10332
10333 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10334   foreach_udp_proto_field;
10335 #undef _
10336
10337   *maskp = mask;
10338   return 1;
10339 }
10340
10341 uword
10342 unformat_l4_mask (unformat_input_t * input, va_list * args)
10343 {
10344   u8 **maskp = va_arg (*args, u8 **);
10345   u16 src_port = 0, dst_port = 0;
10346   tcpudp_header_t *tcpudp;
10347
10348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10349     {
10350       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10351         return 1;
10352       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10353         return 1;
10354       else if (unformat (input, "src_port"))
10355         src_port = 0xFFFF;
10356       else if (unformat (input, "dst_port"))
10357         dst_port = 0xFFFF;
10358       else
10359         return 0;
10360     }
10361
10362   if (!src_port && !dst_port)
10363     return 0;
10364
10365   u8 *mask = 0;
10366   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10367
10368   tcpudp = (tcpudp_header_t *) mask;
10369   tcpudp->src_port = src_port;
10370   tcpudp->dst_port = dst_port;
10371
10372   *maskp = mask;
10373
10374   return 1;
10375 }
10376
10377 uword
10378 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10379 {
10380   u8 **maskp = va_arg (*args, u8 **);
10381   u8 *mask = 0;
10382   u8 found_something = 0;
10383   ip4_header_t *ip;
10384
10385 #define _(a) u8 a=0;
10386   foreach_ip4_proto_field;
10387 #undef _
10388   u8 version = 0;
10389   u8 hdr_length = 0;
10390
10391
10392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10393     {
10394       if (unformat (input, "version"))
10395         version = 1;
10396       else if (unformat (input, "hdr_length"))
10397         hdr_length = 1;
10398       else if (unformat (input, "src"))
10399         src_address = 1;
10400       else if (unformat (input, "dst"))
10401         dst_address = 1;
10402       else if (unformat (input, "proto"))
10403         protocol = 1;
10404
10405 #define _(a) else if (unformat (input, #a)) a=1;
10406       foreach_ip4_proto_field
10407 #undef _
10408         else
10409         break;
10410     }
10411
10412 #define _(a) found_something += a;
10413   foreach_ip4_proto_field;
10414 #undef _
10415
10416   if (found_something == 0)
10417     return 0;
10418
10419   vec_validate (mask, sizeof (*ip) - 1);
10420
10421   ip = (ip4_header_t *) mask;
10422
10423 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10424   foreach_ip4_proto_field;
10425 #undef _
10426
10427   ip->ip_version_and_header_length = 0;
10428
10429   if (version)
10430     ip->ip_version_and_header_length |= 0xF0;
10431
10432   if (hdr_length)
10433     ip->ip_version_and_header_length |= 0x0F;
10434
10435   *maskp = mask;
10436   return 1;
10437 }
10438
10439 #define foreach_ip6_proto_field                 \
10440 _(src_address)                                  \
10441 _(dst_address)                                  \
10442 _(payload_length)                               \
10443 _(hop_limit)                                    \
10444 _(protocol)
10445
10446 uword
10447 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10448 {
10449   u8 **maskp = va_arg (*args, u8 **);
10450   u8 *mask = 0;
10451   u8 found_something = 0;
10452   ip6_header_t *ip;
10453   u32 ip_version_traffic_class_and_flow_label;
10454
10455 #define _(a) u8 a=0;
10456   foreach_ip6_proto_field;
10457 #undef _
10458   u8 version = 0;
10459   u8 traffic_class = 0;
10460   u8 flow_label = 0;
10461
10462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10463     {
10464       if (unformat (input, "version"))
10465         version = 1;
10466       else if (unformat (input, "traffic-class"))
10467         traffic_class = 1;
10468       else if (unformat (input, "flow-label"))
10469         flow_label = 1;
10470       else if (unformat (input, "src"))
10471         src_address = 1;
10472       else if (unformat (input, "dst"))
10473         dst_address = 1;
10474       else if (unformat (input, "proto"))
10475         protocol = 1;
10476
10477 #define _(a) else if (unformat (input, #a)) a=1;
10478       foreach_ip6_proto_field
10479 #undef _
10480         else
10481         break;
10482     }
10483
10484 #define _(a) found_something += a;
10485   foreach_ip6_proto_field;
10486 #undef _
10487
10488   if (found_something == 0)
10489     return 0;
10490
10491   vec_validate (mask, sizeof (*ip) - 1);
10492
10493   ip = (ip6_header_t *) mask;
10494
10495 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10496   foreach_ip6_proto_field;
10497 #undef _
10498
10499   ip_version_traffic_class_and_flow_label = 0;
10500
10501   if (version)
10502     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10503
10504   if (traffic_class)
10505     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10506
10507   if (flow_label)
10508     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10509
10510   ip->ip_version_traffic_class_and_flow_label =
10511     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10512
10513   *maskp = mask;
10514   return 1;
10515 }
10516
10517 uword
10518 unformat_l3_mask (unformat_input_t * input, va_list * args)
10519 {
10520   u8 **maskp = va_arg (*args, u8 **);
10521
10522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10523     {
10524       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10525         return 1;
10526       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10527         return 1;
10528       else
10529         break;
10530     }
10531   return 0;
10532 }
10533
10534 uword
10535 unformat_l2_mask (unformat_input_t * input, va_list * args)
10536 {
10537   u8 **maskp = va_arg (*args, u8 **);
10538   u8 *mask = 0;
10539   u8 src = 0;
10540   u8 dst = 0;
10541   u8 proto = 0;
10542   u8 tag1 = 0;
10543   u8 tag2 = 0;
10544   u8 ignore_tag1 = 0;
10545   u8 ignore_tag2 = 0;
10546   u8 cos1 = 0;
10547   u8 cos2 = 0;
10548   u8 dot1q = 0;
10549   u8 dot1ad = 0;
10550   int len = 14;
10551
10552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10553     {
10554       if (unformat (input, "src"))
10555         src = 1;
10556       else if (unformat (input, "dst"))
10557         dst = 1;
10558       else if (unformat (input, "proto"))
10559         proto = 1;
10560       else if (unformat (input, "tag1"))
10561         tag1 = 1;
10562       else if (unformat (input, "tag2"))
10563         tag2 = 1;
10564       else if (unformat (input, "ignore-tag1"))
10565         ignore_tag1 = 1;
10566       else if (unformat (input, "ignore-tag2"))
10567         ignore_tag2 = 1;
10568       else if (unformat (input, "cos1"))
10569         cos1 = 1;
10570       else if (unformat (input, "cos2"))
10571         cos2 = 1;
10572       else if (unformat (input, "dot1q"))
10573         dot1q = 1;
10574       else if (unformat (input, "dot1ad"))
10575         dot1ad = 1;
10576       else
10577         break;
10578     }
10579   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10580        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10581     return 0;
10582
10583   if (tag1 || ignore_tag1 || cos1 || dot1q)
10584     len = 18;
10585   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10586     len = 22;
10587
10588   vec_validate (mask, len - 1);
10589
10590   if (dst)
10591     clib_memset (mask, 0xff, 6);
10592
10593   if (src)
10594     clib_memset (mask + 6, 0xff, 6);
10595
10596   if (tag2 || dot1ad)
10597     {
10598       /* inner vlan tag */
10599       if (tag2)
10600         {
10601           mask[19] = 0xff;
10602           mask[18] = 0x0f;
10603         }
10604       if (cos2)
10605         mask[18] |= 0xe0;
10606       if (proto)
10607         mask[21] = mask[20] = 0xff;
10608       if (tag1)
10609         {
10610           mask[15] = 0xff;
10611           mask[14] = 0x0f;
10612         }
10613       if (cos1)
10614         mask[14] |= 0xe0;
10615       *maskp = mask;
10616       return 1;
10617     }
10618   if (tag1 | dot1q)
10619     {
10620       if (tag1)
10621         {
10622           mask[15] = 0xff;
10623           mask[14] = 0x0f;
10624         }
10625       if (cos1)
10626         mask[14] |= 0xe0;
10627       if (proto)
10628         mask[16] = mask[17] = 0xff;
10629
10630       *maskp = mask;
10631       return 1;
10632     }
10633   if (cos2)
10634     mask[18] |= 0xe0;
10635   if (cos1)
10636     mask[14] |= 0xe0;
10637   if (proto)
10638     mask[12] = mask[13] = 0xff;
10639
10640   *maskp = mask;
10641   return 1;
10642 }
10643
10644 uword
10645 unformat_classify_mask (unformat_input_t * input, va_list * args)
10646 {
10647   u8 **maskp = va_arg (*args, u8 **);
10648   u32 *skipp = va_arg (*args, u32 *);
10649   u32 *matchp = va_arg (*args, u32 *);
10650   u32 match;
10651   u8 *mask = 0;
10652   u8 *l2 = 0;
10653   u8 *l3 = 0;
10654   u8 *l4 = 0;
10655   int i;
10656
10657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10658     {
10659       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10660         ;
10661       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10662         ;
10663       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10664         ;
10665       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10666         ;
10667       else
10668         break;
10669     }
10670
10671   if (l4 && !l3)
10672     {
10673       vec_free (mask);
10674       vec_free (l2);
10675       vec_free (l4);
10676       return 0;
10677     }
10678
10679   if (mask || l2 || l3 || l4)
10680     {
10681       if (l2 || l3 || l4)
10682         {
10683           /* "With a free Ethernet header in every package" */
10684           if (l2 == 0)
10685             vec_validate (l2, 13);
10686           mask = l2;
10687           if (vec_len (l3))
10688             {
10689               vec_append (mask, l3);
10690               vec_free (l3);
10691             }
10692           if (vec_len (l4))
10693             {
10694               vec_append (mask, l4);
10695               vec_free (l4);
10696             }
10697         }
10698
10699       /* Scan forward looking for the first significant mask octet */
10700       for (i = 0; i < vec_len (mask); i++)
10701         if (mask[i])
10702           break;
10703
10704       /* compute (skip, match) params */
10705       *skipp = i / sizeof (u32x4);
10706       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10707
10708       /* Pad mask to an even multiple of the vector size */
10709       while (vec_len (mask) % sizeof (u32x4))
10710         vec_add1 (mask, 0);
10711
10712       match = vec_len (mask) / sizeof (u32x4);
10713
10714       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10715         {
10716           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10717           if (*tmp || *(tmp + 1))
10718             break;
10719           match--;
10720         }
10721       if (match == 0)
10722         clib_warning ("BUG: match 0");
10723
10724       _vec_len (mask) = match * sizeof (u32x4);
10725
10726       *matchp = match;
10727       *maskp = mask;
10728
10729       return 1;
10730     }
10731
10732   return 0;
10733 }
10734 #endif /* VPP_API_TEST_BUILTIN */
10735
10736 #define foreach_l2_next                         \
10737 _(drop, DROP)                                   \
10738 _(ethernet, ETHERNET_INPUT)                     \
10739 _(ip4, IP4_INPUT)                               \
10740 _(ip6, IP6_INPUT)
10741
10742 uword
10743 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10744 {
10745   u32 *miss_next_indexp = va_arg (*args, u32 *);
10746   u32 next_index = 0;
10747   u32 tmp;
10748
10749 #define _(n,N) \
10750   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10751   foreach_l2_next;
10752 #undef _
10753
10754   if (unformat (input, "%d", &tmp))
10755     {
10756       next_index = tmp;
10757       goto out;
10758     }
10759
10760   return 0;
10761
10762 out:
10763   *miss_next_indexp = next_index;
10764   return 1;
10765 }
10766
10767 #define foreach_ip_next                         \
10768 _(drop, DROP)                                   \
10769 _(local, LOCAL)                                 \
10770 _(rewrite, REWRITE)
10771
10772 uword
10773 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10774 {
10775   u32 *miss_next_indexp = va_arg (*args, u32 *);
10776   u32 next_index = 0;
10777   u32 tmp;
10778
10779 #define _(n,N) \
10780   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10781   foreach_ip_next;
10782 #undef _
10783
10784   if (unformat (input, "%d", &tmp))
10785     {
10786       next_index = tmp;
10787       goto out;
10788     }
10789
10790   return 0;
10791
10792 out:
10793   *miss_next_indexp = next_index;
10794   return 1;
10795 }
10796
10797 #define foreach_acl_next                        \
10798 _(deny, DENY)
10799
10800 uword
10801 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10802 {
10803   u32 *miss_next_indexp = va_arg (*args, u32 *);
10804   u32 next_index = 0;
10805   u32 tmp;
10806
10807 #define _(n,N) \
10808   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10809   foreach_acl_next;
10810 #undef _
10811
10812   if (unformat (input, "permit"))
10813     {
10814       next_index = ~0;
10815       goto out;
10816     }
10817   else if (unformat (input, "%d", &tmp))
10818     {
10819       next_index = tmp;
10820       goto out;
10821     }
10822
10823   return 0;
10824
10825 out:
10826   *miss_next_indexp = next_index;
10827   return 1;
10828 }
10829
10830 uword
10831 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10832 {
10833   u32 *r = va_arg (*args, u32 *);
10834
10835   if (unformat (input, "conform-color"))
10836     *r = POLICE_CONFORM;
10837   else if (unformat (input, "exceed-color"))
10838     *r = POLICE_EXCEED;
10839   else
10840     return 0;
10841
10842   return 1;
10843 }
10844
10845 static int
10846 api_classify_add_del_table (vat_main_t * vam)
10847 {
10848   unformat_input_t *i = vam->input;
10849   vl_api_classify_add_del_table_t *mp;
10850
10851   u32 nbuckets = 2;
10852   u32 skip = ~0;
10853   u32 match = ~0;
10854   int is_add = 1;
10855   int del_chain = 0;
10856   u32 table_index = ~0;
10857   u32 next_table_index = ~0;
10858   u32 miss_next_index = ~0;
10859   u32 memory_size = 32 << 20;
10860   u8 *mask = 0;
10861   u32 current_data_flag = 0;
10862   int current_data_offset = 0;
10863   int ret;
10864
10865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10866     {
10867       if (unformat (i, "del"))
10868         is_add = 0;
10869       else if (unformat (i, "del-chain"))
10870         {
10871           is_add = 0;
10872           del_chain = 1;
10873         }
10874       else if (unformat (i, "buckets %d", &nbuckets))
10875         ;
10876       else if (unformat (i, "memory_size %d", &memory_size))
10877         ;
10878       else if (unformat (i, "skip %d", &skip))
10879         ;
10880       else if (unformat (i, "match %d", &match))
10881         ;
10882       else if (unformat (i, "table %d", &table_index))
10883         ;
10884       else if (unformat (i, "mask %U", unformat_classify_mask,
10885                          &mask, &skip, &match))
10886         ;
10887       else if (unformat (i, "next-table %d", &next_table_index))
10888         ;
10889       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10890                          &miss_next_index))
10891         ;
10892       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10893                          &miss_next_index))
10894         ;
10895       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10896                          &miss_next_index))
10897         ;
10898       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10899         ;
10900       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10901         ;
10902       else
10903         break;
10904     }
10905
10906   if (is_add && mask == 0)
10907     {
10908       errmsg ("Mask required");
10909       return -99;
10910     }
10911
10912   if (is_add && skip == ~0)
10913     {
10914       errmsg ("skip count required");
10915       return -99;
10916     }
10917
10918   if (is_add && match == ~0)
10919     {
10920       errmsg ("match count required");
10921       return -99;
10922     }
10923
10924   if (!is_add && table_index == ~0)
10925     {
10926       errmsg ("table index required for delete");
10927       return -99;
10928     }
10929
10930   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10931
10932   mp->is_add = is_add;
10933   mp->del_chain = del_chain;
10934   mp->table_index = ntohl (table_index);
10935   mp->nbuckets = ntohl (nbuckets);
10936   mp->memory_size = ntohl (memory_size);
10937   mp->skip_n_vectors = ntohl (skip);
10938   mp->match_n_vectors = ntohl (match);
10939   mp->next_table_index = ntohl (next_table_index);
10940   mp->miss_next_index = ntohl (miss_next_index);
10941   mp->current_data_flag = ntohl (current_data_flag);
10942   mp->current_data_offset = ntohl (current_data_offset);
10943   mp->mask_len = ntohl (vec_len (mask));
10944   clib_memcpy (mp->mask, mask, vec_len (mask));
10945
10946   vec_free (mask);
10947
10948   S (mp);
10949   W (ret);
10950   return ret;
10951 }
10952
10953 #if VPP_API_TEST_BUILTIN == 0
10954 uword
10955 unformat_l4_match (unformat_input_t * input, va_list * args)
10956 {
10957   u8 **matchp = va_arg (*args, u8 **);
10958
10959   u8 *proto_header = 0;
10960   int src_port = 0;
10961   int dst_port = 0;
10962
10963   tcpudp_header_t h;
10964
10965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10966     {
10967       if (unformat (input, "src_port %d", &src_port))
10968         ;
10969       else if (unformat (input, "dst_port %d", &dst_port))
10970         ;
10971       else
10972         return 0;
10973     }
10974
10975   h.src_port = clib_host_to_net_u16 (src_port);
10976   h.dst_port = clib_host_to_net_u16 (dst_port);
10977   vec_validate (proto_header, sizeof (h) - 1);
10978   memcpy (proto_header, &h, sizeof (h));
10979
10980   *matchp = proto_header;
10981
10982   return 1;
10983 }
10984
10985 uword
10986 unformat_ip4_match (unformat_input_t * input, va_list * args)
10987 {
10988   u8 **matchp = va_arg (*args, u8 **);
10989   u8 *match = 0;
10990   ip4_header_t *ip;
10991   int version = 0;
10992   u32 version_val;
10993   int hdr_length = 0;
10994   u32 hdr_length_val;
10995   int src = 0, dst = 0;
10996   ip4_address_t src_val, dst_val;
10997   int proto = 0;
10998   u32 proto_val;
10999   int tos = 0;
11000   u32 tos_val;
11001   int length = 0;
11002   u32 length_val;
11003   int fragment_id = 0;
11004   u32 fragment_id_val;
11005   int ttl = 0;
11006   int ttl_val;
11007   int checksum = 0;
11008   u32 checksum_val;
11009
11010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11011     {
11012       if (unformat (input, "version %d", &version_val))
11013         version = 1;
11014       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11015         hdr_length = 1;
11016       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11017         src = 1;
11018       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11019         dst = 1;
11020       else if (unformat (input, "proto %d", &proto_val))
11021         proto = 1;
11022       else if (unformat (input, "tos %d", &tos_val))
11023         tos = 1;
11024       else if (unformat (input, "length %d", &length_val))
11025         length = 1;
11026       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11027         fragment_id = 1;
11028       else if (unformat (input, "ttl %d", &ttl_val))
11029         ttl = 1;
11030       else if (unformat (input, "checksum %d", &checksum_val))
11031         checksum = 1;
11032       else
11033         break;
11034     }
11035
11036   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11037       + ttl + checksum == 0)
11038     return 0;
11039
11040   /*
11041    * Aligned because we use the real comparison functions
11042    */
11043   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11044
11045   ip = (ip4_header_t *) match;
11046
11047   /* These are realistically matched in practice */
11048   if (src)
11049     ip->src_address.as_u32 = src_val.as_u32;
11050
11051   if (dst)
11052     ip->dst_address.as_u32 = dst_val.as_u32;
11053
11054   if (proto)
11055     ip->protocol = proto_val;
11056
11057
11058   /* These are not, but they're included for completeness */
11059   if (version)
11060     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11061
11062   if (hdr_length)
11063     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11064
11065   if (tos)
11066     ip->tos = tos_val;
11067
11068   if (length)
11069     ip->length = clib_host_to_net_u16 (length_val);
11070
11071   if (ttl)
11072     ip->ttl = ttl_val;
11073
11074   if (checksum)
11075     ip->checksum = clib_host_to_net_u16 (checksum_val);
11076
11077   *matchp = match;
11078   return 1;
11079 }
11080
11081 uword
11082 unformat_ip6_match (unformat_input_t * input, va_list * args)
11083 {
11084   u8 **matchp = va_arg (*args, u8 **);
11085   u8 *match = 0;
11086   ip6_header_t *ip;
11087   int version = 0;
11088   u32 version_val;
11089   u8 traffic_class = 0;
11090   u32 traffic_class_val = 0;
11091   u8 flow_label = 0;
11092   u8 flow_label_val;
11093   int src = 0, dst = 0;
11094   ip6_address_t src_val, dst_val;
11095   int proto = 0;
11096   u32 proto_val;
11097   int payload_length = 0;
11098   u32 payload_length_val;
11099   int hop_limit = 0;
11100   int hop_limit_val;
11101   u32 ip_version_traffic_class_and_flow_label;
11102
11103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11104     {
11105       if (unformat (input, "version %d", &version_val))
11106         version = 1;
11107       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11108         traffic_class = 1;
11109       else if (unformat (input, "flow_label %d", &flow_label_val))
11110         flow_label = 1;
11111       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11112         src = 1;
11113       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11114         dst = 1;
11115       else if (unformat (input, "proto %d", &proto_val))
11116         proto = 1;
11117       else if (unformat (input, "payload_length %d", &payload_length_val))
11118         payload_length = 1;
11119       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11120         hop_limit = 1;
11121       else
11122         break;
11123     }
11124
11125   if (version + traffic_class + flow_label + src + dst + proto +
11126       payload_length + hop_limit == 0)
11127     return 0;
11128
11129   /*
11130    * Aligned because we use the real comparison functions
11131    */
11132   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11133
11134   ip = (ip6_header_t *) match;
11135
11136   if (src)
11137     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11138
11139   if (dst)
11140     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11141
11142   if (proto)
11143     ip->protocol = proto_val;
11144
11145   ip_version_traffic_class_and_flow_label = 0;
11146
11147   if (version)
11148     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11149
11150   if (traffic_class)
11151     ip_version_traffic_class_and_flow_label |=
11152       (traffic_class_val & 0xFF) << 20;
11153
11154   if (flow_label)
11155     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11156
11157   ip->ip_version_traffic_class_and_flow_label =
11158     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11159
11160   if (payload_length)
11161     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11162
11163   if (hop_limit)
11164     ip->hop_limit = hop_limit_val;
11165
11166   *matchp = match;
11167   return 1;
11168 }
11169
11170 uword
11171 unformat_l3_match (unformat_input_t * input, va_list * args)
11172 {
11173   u8 **matchp = va_arg (*args, u8 **);
11174
11175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11176     {
11177       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11178         return 1;
11179       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11180         return 1;
11181       else
11182         break;
11183     }
11184   return 0;
11185 }
11186
11187 uword
11188 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11189 {
11190   u8 *tagp = va_arg (*args, u8 *);
11191   u32 tag;
11192
11193   if (unformat (input, "%d", &tag))
11194     {
11195       tagp[0] = (tag >> 8) & 0x0F;
11196       tagp[1] = tag & 0xFF;
11197       return 1;
11198     }
11199
11200   return 0;
11201 }
11202
11203 uword
11204 unformat_l2_match (unformat_input_t * input, va_list * args)
11205 {
11206   u8 **matchp = va_arg (*args, u8 **);
11207   u8 *match = 0;
11208   u8 src = 0;
11209   u8 src_val[6];
11210   u8 dst = 0;
11211   u8 dst_val[6];
11212   u8 proto = 0;
11213   u16 proto_val;
11214   u8 tag1 = 0;
11215   u8 tag1_val[2];
11216   u8 tag2 = 0;
11217   u8 tag2_val[2];
11218   int len = 14;
11219   u8 ignore_tag1 = 0;
11220   u8 ignore_tag2 = 0;
11221   u8 cos1 = 0;
11222   u8 cos2 = 0;
11223   u32 cos1_val = 0;
11224   u32 cos2_val = 0;
11225
11226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11227     {
11228       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11229         src = 1;
11230       else
11231         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11232         dst = 1;
11233       else if (unformat (input, "proto %U",
11234                          unformat_ethernet_type_host_byte_order, &proto_val))
11235         proto = 1;
11236       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11237         tag1 = 1;
11238       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11239         tag2 = 1;
11240       else if (unformat (input, "ignore-tag1"))
11241         ignore_tag1 = 1;
11242       else if (unformat (input, "ignore-tag2"))
11243         ignore_tag2 = 1;
11244       else if (unformat (input, "cos1 %d", &cos1_val))
11245         cos1 = 1;
11246       else if (unformat (input, "cos2 %d", &cos2_val))
11247         cos2 = 1;
11248       else
11249         break;
11250     }
11251   if ((src + dst + proto + tag1 + tag2 +
11252        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11253     return 0;
11254
11255   if (tag1 || ignore_tag1 || cos1)
11256     len = 18;
11257   if (tag2 || ignore_tag2 || cos2)
11258     len = 22;
11259
11260   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11261
11262   if (dst)
11263     clib_memcpy (match, dst_val, 6);
11264
11265   if (src)
11266     clib_memcpy (match + 6, src_val, 6);
11267
11268   if (tag2)
11269     {
11270       /* inner vlan tag */
11271       match[19] = tag2_val[1];
11272       match[18] = tag2_val[0];
11273       if (cos2)
11274         match[18] |= (cos2_val & 0x7) << 5;
11275       if (proto)
11276         {
11277           match[21] = proto_val & 0xff;
11278           match[20] = proto_val >> 8;
11279         }
11280       if (tag1)
11281         {
11282           match[15] = tag1_val[1];
11283           match[14] = tag1_val[0];
11284         }
11285       if (cos1)
11286         match[14] |= (cos1_val & 0x7) << 5;
11287       *matchp = match;
11288       return 1;
11289     }
11290   if (tag1)
11291     {
11292       match[15] = tag1_val[1];
11293       match[14] = tag1_val[0];
11294       if (proto)
11295         {
11296           match[17] = proto_val & 0xff;
11297           match[16] = proto_val >> 8;
11298         }
11299       if (cos1)
11300         match[14] |= (cos1_val & 0x7) << 5;
11301
11302       *matchp = match;
11303       return 1;
11304     }
11305   if (cos2)
11306     match[18] |= (cos2_val & 0x7) << 5;
11307   if (cos1)
11308     match[14] |= (cos1_val & 0x7) << 5;
11309   if (proto)
11310     {
11311       match[13] = proto_val & 0xff;
11312       match[12] = proto_val >> 8;
11313     }
11314
11315   *matchp = match;
11316   return 1;
11317 }
11318
11319 uword
11320 unformat_qos_source (unformat_input_t * input, va_list * args)
11321 {
11322   int *qs = va_arg (*args, int *);
11323
11324   if (unformat (input, "ip"))
11325     *qs = QOS_SOURCE_IP;
11326   else if (unformat (input, "mpls"))
11327     *qs = QOS_SOURCE_MPLS;
11328   else if (unformat (input, "ext"))
11329     *qs = QOS_SOURCE_EXT;
11330   else if (unformat (input, "vlan"))
11331     *qs = QOS_SOURCE_VLAN;
11332   else
11333     return 0;
11334
11335   return 1;
11336 }
11337 #endif
11338
11339 uword
11340 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11341 {
11342   u8 **matchp = va_arg (*args, u8 **);
11343   u32 skip_n_vectors = va_arg (*args, u32);
11344   u32 match_n_vectors = va_arg (*args, u32);
11345
11346   u8 *match = 0;
11347   u8 *l2 = 0;
11348   u8 *l3 = 0;
11349   u8 *l4 = 0;
11350
11351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11352     {
11353       if (unformat (input, "hex %U", unformat_hex_string, &match))
11354         ;
11355       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11356         ;
11357       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11358         ;
11359       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11360         ;
11361       else
11362         break;
11363     }
11364
11365   if (l4 && !l3)
11366     {
11367       vec_free (match);
11368       vec_free (l2);
11369       vec_free (l4);
11370       return 0;
11371     }
11372
11373   if (match || l2 || l3 || l4)
11374     {
11375       if (l2 || l3 || l4)
11376         {
11377           /* "Win a free Ethernet header in every packet" */
11378           if (l2 == 0)
11379             vec_validate_aligned (l2, 13, sizeof (u32x4));
11380           match = l2;
11381           if (vec_len (l3))
11382             {
11383               vec_append_aligned (match, l3, sizeof (u32x4));
11384               vec_free (l3);
11385             }
11386           if (vec_len (l4))
11387             {
11388               vec_append_aligned (match, l4, sizeof (u32x4));
11389               vec_free (l4);
11390             }
11391         }
11392
11393       /* Make sure the vector is big enough even if key is all 0's */
11394       vec_validate_aligned
11395         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11396          sizeof (u32x4));
11397
11398       /* Set size, include skipped vectors */
11399       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11400
11401       *matchp = match;
11402
11403       return 1;
11404     }
11405
11406   return 0;
11407 }
11408
11409 static int
11410 api_classify_add_del_session (vat_main_t * vam)
11411 {
11412   unformat_input_t *i = vam->input;
11413   vl_api_classify_add_del_session_t *mp;
11414   int is_add = 1;
11415   u32 table_index = ~0;
11416   u32 hit_next_index = ~0;
11417   u32 opaque_index = ~0;
11418   u8 *match = 0;
11419   i32 advance = 0;
11420   u32 skip_n_vectors = 0;
11421   u32 match_n_vectors = 0;
11422   u32 action = 0;
11423   u32 metadata = 0;
11424   int ret;
11425
11426   /*
11427    * Warning: you have to supply skip_n and match_n
11428    * because the API client cant simply look at the classify
11429    * table object.
11430    */
11431
11432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11433     {
11434       if (unformat (i, "del"))
11435         is_add = 0;
11436       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11437                          &hit_next_index))
11438         ;
11439       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11440                          &hit_next_index))
11441         ;
11442       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11443                          &hit_next_index))
11444         ;
11445       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11446         ;
11447       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11448         ;
11449       else if (unformat (i, "opaque-index %d", &opaque_index))
11450         ;
11451       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11452         ;
11453       else if (unformat (i, "match_n %d", &match_n_vectors))
11454         ;
11455       else if (unformat (i, "match %U", api_unformat_classify_match,
11456                          &match, skip_n_vectors, match_n_vectors))
11457         ;
11458       else if (unformat (i, "advance %d", &advance))
11459         ;
11460       else if (unformat (i, "table-index %d", &table_index))
11461         ;
11462       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11463         action = 1;
11464       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11465         action = 2;
11466       else if (unformat (i, "action %d", &action))
11467         ;
11468       else if (unformat (i, "metadata %d", &metadata))
11469         ;
11470       else
11471         break;
11472     }
11473
11474   if (table_index == ~0)
11475     {
11476       errmsg ("Table index required");
11477       return -99;
11478     }
11479
11480   if (is_add && match == 0)
11481     {
11482       errmsg ("Match value required");
11483       return -99;
11484     }
11485
11486   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11487
11488   mp->is_add = is_add;
11489   mp->table_index = ntohl (table_index);
11490   mp->hit_next_index = ntohl (hit_next_index);
11491   mp->opaque_index = ntohl (opaque_index);
11492   mp->advance = ntohl (advance);
11493   mp->action = action;
11494   mp->metadata = ntohl (metadata);
11495   mp->match_len = ntohl (vec_len (match));
11496   clib_memcpy (mp->match, match, vec_len (match));
11497   vec_free (match);
11498
11499   S (mp);
11500   W (ret);
11501   return ret;
11502 }
11503
11504 static int
11505 api_classify_set_interface_ip_table (vat_main_t * vam)
11506 {
11507   unformat_input_t *i = vam->input;
11508   vl_api_classify_set_interface_ip_table_t *mp;
11509   u32 sw_if_index;
11510   int sw_if_index_set;
11511   u32 table_index = ~0;
11512   u8 is_ipv6 = 0;
11513   int ret;
11514
11515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11516     {
11517       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11518         sw_if_index_set = 1;
11519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11520         sw_if_index_set = 1;
11521       else if (unformat (i, "table %d", &table_index))
11522         ;
11523       else
11524         {
11525           clib_warning ("parse error '%U'", format_unformat_error, i);
11526           return -99;
11527         }
11528     }
11529
11530   if (sw_if_index_set == 0)
11531     {
11532       errmsg ("missing interface name or sw_if_index");
11533       return -99;
11534     }
11535
11536
11537   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11538
11539   mp->sw_if_index = ntohl (sw_if_index);
11540   mp->table_index = ntohl (table_index);
11541   mp->is_ipv6 = is_ipv6;
11542
11543   S (mp);
11544   W (ret);
11545   return ret;
11546 }
11547
11548 static int
11549 api_classify_set_interface_l2_tables (vat_main_t * vam)
11550 {
11551   unformat_input_t *i = vam->input;
11552   vl_api_classify_set_interface_l2_tables_t *mp;
11553   u32 sw_if_index;
11554   int sw_if_index_set;
11555   u32 ip4_table_index = ~0;
11556   u32 ip6_table_index = ~0;
11557   u32 other_table_index = ~0;
11558   u32 is_input = 1;
11559   int ret;
11560
11561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11562     {
11563       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11564         sw_if_index_set = 1;
11565       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11566         sw_if_index_set = 1;
11567       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11568         ;
11569       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11570         ;
11571       else if (unformat (i, "other-table %d", &other_table_index))
11572         ;
11573       else if (unformat (i, "is-input %d", &is_input))
11574         ;
11575       else
11576         {
11577           clib_warning ("parse error '%U'", format_unformat_error, i);
11578           return -99;
11579         }
11580     }
11581
11582   if (sw_if_index_set == 0)
11583     {
11584       errmsg ("missing interface name or sw_if_index");
11585       return -99;
11586     }
11587
11588
11589   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11590
11591   mp->sw_if_index = ntohl (sw_if_index);
11592   mp->ip4_table_index = ntohl (ip4_table_index);
11593   mp->ip6_table_index = ntohl (ip6_table_index);
11594   mp->other_table_index = ntohl (other_table_index);
11595   mp->is_input = (u8) is_input;
11596
11597   S (mp);
11598   W (ret);
11599   return ret;
11600 }
11601
11602 static int
11603 api_set_ipfix_exporter (vat_main_t * vam)
11604 {
11605   unformat_input_t *i = vam->input;
11606   vl_api_set_ipfix_exporter_t *mp;
11607   ip4_address_t collector_address;
11608   u8 collector_address_set = 0;
11609   u32 collector_port = ~0;
11610   ip4_address_t src_address;
11611   u8 src_address_set = 0;
11612   u32 vrf_id = ~0;
11613   u32 path_mtu = ~0;
11614   u32 template_interval = ~0;
11615   u8 udp_checksum = 0;
11616   int ret;
11617
11618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11619     {
11620       if (unformat (i, "collector_address %U", unformat_ip4_address,
11621                     &collector_address))
11622         collector_address_set = 1;
11623       else if (unformat (i, "collector_port %d", &collector_port))
11624         ;
11625       else if (unformat (i, "src_address %U", unformat_ip4_address,
11626                          &src_address))
11627         src_address_set = 1;
11628       else if (unformat (i, "vrf_id %d", &vrf_id))
11629         ;
11630       else if (unformat (i, "path_mtu %d", &path_mtu))
11631         ;
11632       else if (unformat (i, "template_interval %d", &template_interval))
11633         ;
11634       else if (unformat (i, "udp_checksum"))
11635         udp_checksum = 1;
11636       else
11637         break;
11638     }
11639
11640   if (collector_address_set == 0)
11641     {
11642       errmsg ("collector_address required");
11643       return -99;
11644     }
11645
11646   if (src_address_set == 0)
11647     {
11648       errmsg ("src_address required");
11649       return -99;
11650     }
11651
11652   M (SET_IPFIX_EXPORTER, mp);
11653
11654   memcpy (mp->collector_address, collector_address.data,
11655           sizeof (collector_address.data));
11656   mp->collector_port = htons ((u16) collector_port);
11657   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11658   mp->vrf_id = htonl (vrf_id);
11659   mp->path_mtu = htonl (path_mtu);
11660   mp->template_interval = htonl (template_interval);
11661   mp->udp_checksum = udp_checksum;
11662
11663   S (mp);
11664   W (ret);
11665   return ret;
11666 }
11667
11668 static int
11669 api_set_ipfix_classify_stream (vat_main_t * vam)
11670 {
11671   unformat_input_t *i = vam->input;
11672   vl_api_set_ipfix_classify_stream_t *mp;
11673   u32 domain_id = 0;
11674   u32 src_port = UDP_DST_PORT_ipfix;
11675   int ret;
11676
11677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11678     {
11679       if (unformat (i, "domain %d", &domain_id))
11680         ;
11681       else if (unformat (i, "src_port %d", &src_port))
11682         ;
11683       else
11684         {
11685           errmsg ("unknown input `%U'", format_unformat_error, i);
11686           return -99;
11687         }
11688     }
11689
11690   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11691
11692   mp->domain_id = htonl (domain_id);
11693   mp->src_port = htons ((u16) src_port);
11694
11695   S (mp);
11696   W (ret);
11697   return ret;
11698 }
11699
11700 static int
11701 api_ipfix_classify_table_add_del (vat_main_t * vam)
11702 {
11703   unformat_input_t *i = vam->input;
11704   vl_api_ipfix_classify_table_add_del_t *mp;
11705   int is_add = -1;
11706   u32 classify_table_index = ~0;
11707   u8 ip_version = 0;
11708   u8 transport_protocol = 255;
11709   int ret;
11710
11711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11712     {
11713       if (unformat (i, "add"))
11714         is_add = 1;
11715       else if (unformat (i, "del"))
11716         is_add = 0;
11717       else if (unformat (i, "table %d", &classify_table_index))
11718         ;
11719       else if (unformat (i, "ip4"))
11720         ip_version = 4;
11721       else if (unformat (i, "ip6"))
11722         ip_version = 6;
11723       else if (unformat (i, "tcp"))
11724         transport_protocol = 6;
11725       else if (unformat (i, "udp"))
11726         transport_protocol = 17;
11727       else
11728         {
11729           errmsg ("unknown input `%U'", format_unformat_error, i);
11730           return -99;
11731         }
11732     }
11733
11734   if (is_add == -1)
11735     {
11736       errmsg ("expecting: add|del");
11737       return -99;
11738     }
11739   if (classify_table_index == ~0)
11740     {
11741       errmsg ("classifier table not specified");
11742       return -99;
11743     }
11744   if (ip_version == 0)
11745     {
11746       errmsg ("IP version not specified");
11747       return -99;
11748     }
11749
11750   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11751
11752   mp->is_add = is_add;
11753   mp->table_id = htonl (classify_table_index);
11754   mp->ip_version = ip_version;
11755   mp->transport_protocol = transport_protocol;
11756
11757   S (mp);
11758   W (ret);
11759   return ret;
11760 }
11761
11762 static int
11763 api_get_node_index (vat_main_t * vam)
11764 {
11765   unformat_input_t *i = vam->input;
11766   vl_api_get_node_index_t *mp;
11767   u8 *name = 0;
11768   int ret;
11769
11770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11771     {
11772       if (unformat (i, "node %s", &name))
11773         ;
11774       else
11775         break;
11776     }
11777   if (name == 0)
11778     {
11779       errmsg ("node name required");
11780       return -99;
11781     }
11782   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11783     {
11784       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11785       return -99;
11786     }
11787
11788   M (GET_NODE_INDEX, mp);
11789   clib_memcpy (mp->node_name, name, vec_len (name));
11790   vec_free (name);
11791
11792   S (mp);
11793   W (ret);
11794   return ret;
11795 }
11796
11797 static int
11798 api_get_next_index (vat_main_t * vam)
11799 {
11800   unformat_input_t *i = vam->input;
11801   vl_api_get_next_index_t *mp;
11802   u8 *node_name = 0, *next_node_name = 0;
11803   int ret;
11804
11805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11806     {
11807       if (unformat (i, "node-name %s", &node_name))
11808         ;
11809       else if (unformat (i, "next-node-name %s", &next_node_name))
11810         break;
11811     }
11812
11813   if (node_name == 0)
11814     {
11815       errmsg ("node name required");
11816       return -99;
11817     }
11818   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11819     {
11820       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11821       return -99;
11822     }
11823
11824   if (next_node_name == 0)
11825     {
11826       errmsg ("next node name required");
11827       return -99;
11828     }
11829   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11830     {
11831       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11832       return -99;
11833     }
11834
11835   M (GET_NEXT_INDEX, mp);
11836   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11837   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11838   vec_free (node_name);
11839   vec_free (next_node_name);
11840
11841   S (mp);
11842   W (ret);
11843   return ret;
11844 }
11845
11846 static int
11847 api_add_node_next (vat_main_t * vam)
11848 {
11849   unformat_input_t *i = vam->input;
11850   vl_api_add_node_next_t *mp;
11851   u8 *name = 0;
11852   u8 *next = 0;
11853   int ret;
11854
11855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11856     {
11857       if (unformat (i, "node %s", &name))
11858         ;
11859       else if (unformat (i, "next %s", &next))
11860         ;
11861       else
11862         break;
11863     }
11864   if (name == 0)
11865     {
11866       errmsg ("node name required");
11867       return -99;
11868     }
11869   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11870     {
11871       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11872       return -99;
11873     }
11874   if (next == 0)
11875     {
11876       errmsg ("next node required");
11877       return -99;
11878     }
11879   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11880     {
11881       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11882       return -99;
11883     }
11884
11885   M (ADD_NODE_NEXT, mp);
11886   clib_memcpy (mp->node_name, name, vec_len (name));
11887   clib_memcpy (mp->next_name, next, vec_len (next));
11888   vec_free (name);
11889   vec_free (next);
11890
11891   S (mp);
11892   W (ret);
11893   return ret;
11894 }
11895
11896 static int
11897 api_l2tpv3_create_tunnel (vat_main_t * vam)
11898 {
11899   unformat_input_t *i = vam->input;
11900   ip6_address_t client_address, our_address;
11901   int client_address_set = 0;
11902   int our_address_set = 0;
11903   u32 local_session_id = 0;
11904   u32 remote_session_id = 0;
11905   u64 local_cookie = 0;
11906   u64 remote_cookie = 0;
11907   u8 l2_sublayer_present = 0;
11908   vl_api_l2tpv3_create_tunnel_t *mp;
11909   int ret;
11910
11911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11912     {
11913       if (unformat (i, "client_address %U", unformat_ip6_address,
11914                     &client_address))
11915         client_address_set = 1;
11916       else if (unformat (i, "our_address %U", unformat_ip6_address,
11917                          &our_address))
11918         our_address_set = 1;
11919       else if (unformat (i, "local_session_id %d", &local_session_id))
11920         ;
11921       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11922         ;
11923       else if (unformat (i, "local_cookie %lld", &local_cookie))
11924         ;
11925       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11926         ;
11927       else if (unformat (i, "l2-sublayer-present"))
11928         l2_sublayer_present = 1;
11929       else
11930         break;
11931     }
11932
11933   if (client_address_set == 0)
11934     {
11935       errmsg ("client_address required");
11936       return -99;
11937     }
11938
11939   if (our_address_set == 0)
11940     {
11941       errmsg ("our_address required");
11942       return -99;
11943     }
11944
11945   M (L2TPV3_CREATE_TUNNEL, mp);
11946
11947   clib_memcpy (mp->client_address, client_address.as_u8,
11948                sizeof (mp->client_address));
11949
11950   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11951
11952   mp->local_session_id = ntohl (local_session_id);
11953   mp->remote_session_id = ntohl (remote_session_id);
11954   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11955   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11956   mp->l2_sublayer_present = l2_sublayer_present;
11957   mp->is_ipv6 = 1;
11958
11959   S (mp);
11960   W (ret);
11961   return ret;
11962 }
11963
11964 static int
11965 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11966 {
11967   unformat_input_t *i = vam->input;
11968   u32 sw_if_index;
11969   u8 sw_if_index_set = 0;
11970   u64 new_local_cookie = 0;
11971   u64 new_remote_cookie = 0;
11972   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11973   int ret;
11974
11975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11976     {
11977       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11978         sw_if_index_set = 1;
11979       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11980         sw_if_index_set = 1;
11981       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11982         ;
11983       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11984         ;
11985       else
11986         break;
11987     }
11988
11989   if (sw_if_index_set == 0)
11990     {
11991       errmsg ("missing interface name or sw_if_index");
11992       return -99;
11993     }
11994
11995   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11996
11997   mp->sw_if_index = ntohl (sw_if_index);
11998   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11999   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12000
12001   S (mp);
12002   W (ret);
12003   return ret;
12004 }
12005
12006 static int
12007 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12008 {
12009   unformat_input_t *i = vam->input;
12010   vl_api_l2tpv3_interface_enable_disable_t *mp;
12011   u32 sw_if_index;
12012   u8 sw_if_index_set = 0;
12013   u8 enable_disable = 1;
12014   int ret;
12015
12016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12017     {
12018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12019         sw_if_index_set = 1;
12020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12021         sw_if_index_set = 1;
12022       else if (unformat (i, "enable"))
12023         enable_disable = 1;
12024       else if (unformat (i, "disable"))
12025         enable_disable = 0;
12026       else
12027         break;
12028     }
12029
12030   if (sw_if_index_set == 0)
12031     {
12032       errmsg ("missing interface name or sw_if_index");
12033       return -99;
12034     }
12035
12036   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12037
12038   mp->sw_if_index = ntohl (sw_if_index);
12039   mp->enable_disable = enable_disable;
12040
12041   S (mp);
12042   W (ret);
12043   return ret;
12044 }
12045
12046 static int
12047 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12048 {
12049   unformat_input_t *i = vam->input;
12050   vl_api_l2tpv3_set_lookup_key_t *mp;
12051   u8 key = ~0;
12052   int ret;
12053
12054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12055     {
12056       if (unformat (i, "lookup_v6_src"))
12057         key = L2T_LOOKUP_SRC_ADDRESS;
12058       else if (unformat (i, "lookup_v6_dst"))
12059         key = L2T_LOOKUP_DST_ADDRESS;
12060       else if (unformat (i, "lookup_session_id"))
12061         key = L2T_LOOKUP_SESSION_ID;
12062       else
12063         break;
12064     }
12065
12066   if (key == (u8) ~ 0)
12067     {
12068       errmsg ("l2tp session lookup key unset");
12069       return -99;
12070     }
12071
12072   M (L2TPV3_SET_LOOKUP_KEY, mp);
12073
12074   mp->key = key;
12075
12076   S (mp);
12077   W (ret);
12078   return ret;
12079 }
12080
12081 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12082   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12083 {
12084   vat_main_t *vam = &vat_main;
12085
12086   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12087          format_ip6_address, mp->our_address,
12088          format_ip6_address, mp->client_address,
12089          clib_net_to_host_u32 (mp->sw_if_index));
12090
12091   print (vam->ofp,
12092          "   local cookies %016llx %016llx remote cookie %016llx",
12093          clib_net_to_host_u64 (mp->local_cookie[0]),
12094          clib_net_to_host_u64 (mp->local_cookie[1]),
12095          clib_net_to_host_u64 (mp->remote_cookie));
12096
12097   print (vam->ofp, "   local session-id %d remote session-id %d",
12098          clib_net_to_host_u32 (mp->local_session_id),
12099          clib_net_to_host_u32 (mp->remote_session_id));
12100
12101   print (vam->ofp, "   l2 specific sublayer %s\n",
12102          mp->l2_sublayer_present ? "preset" : "absent");
12103
12104 }
12105
12106 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12107   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12108 {
12109   vat_main_t *vam = &vat_main;
12110   vat_json_node_t *node = NULL;
12111   struct in6_addr addr;
12112
12113   if (VAT_JSON_ARRAY != vam->json_tree.type)
12114     {
12115       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12116       vat_json_init_array (&vam->json_tree);
12117     }
12118   node = vat_json_array_add (&vam->json_tree);
12119
12120   vat_json_init_object (node);
12121
12122   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12123   vat_json_object_add_ip6 (node, "our_address", addr);
12124   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12125   vat_json_object_add_ip6 (node, "client_address", addr);
12126
12127   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12128   vat_json_init_array (lc);
12129   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12130   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12131   vat_json_object_add_uint (node, "remote_cookie",
12132                             clib_net_to_host_u64 (mp->remote_cookie));
12133
12134   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12135   vat_json_object_add_uint (node, "local_session_id",
12136                             clib_net_to_host_u32 (mp->local_session_id));
12137   vat_json_object_add_uint (node, "remote_session_id",
12138                             clib_net_to_host_u32 (mp->remote_session_id));
12139   vat_json_object_add_string_copy (node, "l2_sublayer",
12140                                    mp->l2_sublayer_present ? (u8 *) "present"
12141                                    : (u8 *) "absent");
12142 }
12143
12144 static int
12145 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12146 {
12147   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12148   vl_api_control_ping_t *mp_ping;
12149   int ret;
12150
12151   /* Get list of l2tpv3-tunnel interfaces */
12152   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12153   S (mp);
12154
12155   /* Use a control ping for synchronization */
12156   MPING (CONTROL_PING, mp_ping);
12157   S (mp_ping);
12158
12159   W (ret);
12160   return ret;
12161 }
12162
12163
12164 static void vl_api_sw_interface_tap_v2_details_t_handler
12165   (vl_api_sw_interface_tap_v2_details_t * mp)
12166 {
12167   vat_main_t *vam = &vat_main;
12168
12169   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12170                     mp->host_ip4_prefix_len);
12171   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12172                     mp->host_ip6_prefix_len);
12173
12174   print (vam->ofp,
12175          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12176          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12177          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12178          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12179          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12180
12181   vec_free (ip4);
12182   vec_free (ip6);
12183 }
12184
12185 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12186   (vl_api_sw_interface_tap_v2_details_t * mp)
12187 {
12188   vat_main_t *vam = &vat_main;
12189   vat_json_node_t *node = NULL;
12190
12191   if (VAT_JSON_ARRAY != vam->json_tree.type)
12192     {
12193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12194       vat_json_init_array (&vam->json_tree);
12195     }
12196   node = vat_json_array_add (&vam->json_tree);
12197
12198   vat_json_init_object (node);
12199   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12200   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12201   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12202   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12203   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12204   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12205   vat_json_object_add_string_copy (node, "host_mac_addr",
12206                                    format (0, "%U", format_ethernet_address,
12207                                            &mp->host_mac_addr));
12208   vat_json_object_add_string_copy (node, "host_namespace",
12209                                    mp->host_namespace);
12210   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12211   vat_json_object_add_string_copy (node, "host_ip4_addr",
12212                                    format (0, "%U/%d", format_ip4_address,
12213                                            mp->host_ip4_addr,
12214                                            mp->host_ip4_prefix_len));
12215   vat_json_object_add_string_copy (node, "host_ip6_addr",
12216                                    format (0, "%U/%d", format_ip6_address,
12217                                            mp->host_ip6_addr,
12218                                            mp->host_ip6_prefix_len));
12219
12220 }
12221
12222 static int
12223 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12224 {
12225   vl_api_sw_interface_tap_v2_dump_t *mp;
12226   vl_api_control_ping_t *mp_ping;
12227   int ret;
12228
12229   print (vam->ofp,
12230          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12231          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12232          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12233          "host_ip6_addr");
12234
12235   /* Get list of tap interfaces */
12236   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12237   S (mp);
12238
12239   /* Use a control ping for synchronization */
12240   MPING (CONTROL_PING, mp_ping);
12241   S (mp_ping);
12242
12243   W (ret);
12244   return ret;
12245 }
12246
12247 static void vl_api_sw_interface_virtio_pci_details_t_handler
12248   (vl_api_sw_interface_virtio_pci_details_t * mp)
12249 {
12250   vat_main_t *vam = &vat_main;
12251
12252   typedef union
12253   {
12254     struct
12255     {
12256       u16 domain;
12257       u8 bus;
12258       u8 slot:5;
12259       u8 function:3;
12260     };
12261     u32 as_u32;
12262   } pci_addr_t;
12263   pci_addr_t addr;
12264   addr.as_u32 = ntohl (mp->pci_addr);
12265   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12266                          addr.slot, addr.function);
12267
12268   print (vam->ofp,
12269          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12270          pci_addr, ntohl (mp->sw_if_index),
12271          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12272          format_ethernet_address, mp->mac_addr,
12273          clib_net_to_host_u64 (mp->features));
12274   vec_free (pci_addr);
12275 }
12276
12277 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12278   (vl_api_sw_interface_virtio_pci_details_t * mp)
12279 {
12280   vat_main_t *vam = &vat_main;
12281   vat_json_node_t *node = NULL;
12282
12283   if (VAT_JSON_ARRAY != vam->json_tree.type)
12284     {
12285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12286       vat_json_init_array (&vam->json_tree);
12287     }
12288   node = vat_json_array_add (&vam->json_tree);
12289
12290   vat_json_init_object (node);
12291   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12292   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12293   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12294   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12295   vat_json_object_add_uint (node, "features",
12296                             clib_net_to_host_u64 (mp->features));
12297   vat_json_object_add_string_copy (node, "mac_addr",
12298                                    format (0, "%U", format_ethernet_address,
12299                                            &mp->mac_addr));
12300 }
12301
12302 static int
12303 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12304 {
12305   vl_api_sw_interface_virtio_pci_dump_t *mp;
12306   vl_api_control_ping_t *mp_ping;
12307   int ret;
12308
12309   print (vam->ofp,
12310          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12311          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12312          "mac_addr", "features");
12313
12314   /* Get list of tap interfaces */
12315   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12316   S (mp);
12317
12318   /* Use a control ping for synchronization */
12319   MPING (CONTROL_PING, mp_ping);
12320   S (mp_ping);
12321
12322   W (ret);
12323   return ret;
12324 }
12325
12326 static int
12327 api_vxlan_offload_rx (vat_main_t * vam)
12328 {
12329   unformat_input_t *line_input = vam->input;
12330   vl_api_vxlan_offload_rx_t *mp;
12331   u32 hw_if_index = ~0, rx_if_index = ~0;
12332   u8 is_add = 1;
12333   int ret;
12334
12335   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12336     {
12337       if (unformat (line_input, "del"))
12338         is_add = 0;
12339       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12340                          &hw_if_index))
12341         ;
12342       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12343         ;
12344       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12345                          &rx_if_index))
12346         ;
12347       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12348         ;
12349       else
12350         {
12351           errmsg ("parse error '%U'", format_unformat_error, line_input);
12352           return -99;
12353         }
12354     }
12355
12356   if (hw_if_index == ~0)
12357     {
12358       errmsg ("no hw interface");
12359       return -99;
12360     }
12361
12362   if (rx_if_index == ~0)
12363     {
12364       errmsg ("no rx tunnel");
12365       return -99;
12366     }
12367
12368   M (VXLAN_OFFLOAD_RX, mp);
12369
12370   mp->hw_if_index = ntohl (hw_if_index);
12371   mp->sw_if_index = ntohl (rx_if_index);
12372   mp->enable = is_add;
12373
12374   S (mp);
12375   W (ret);
12376   return ret;
12377 }
12378
12379 static uword unformat_vxlan_decap_next
12380   (unformat_input_t * input, va_list * args)
12381 {
12382   u32 *result = va_arg (*args, u32 *);
12383   u32 tmp;
12384
12385   if (unformat (input, "l2"))
12386     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12387   else if (unformat (input, "%d", &tmp))
12388     *result = tmp;
12389   else
12390     return 0;
12391   return 1;
12392 }
12393
12394 static int
12395 api_vxlan_add_del_tunnel (vat_main_t * vam)
12396 {
12397   unformat_input_t *line_input = vam->input;
12398   vl_api_vxlan_add_del_tunnel_t *mp;
12399   ip46_address_t src, dst;
12400   u8 is_add = 1;
12401   u8 ipv4_set = 0, ipv6_set = 0;
12402   u8 src_set = 0;
12403   u8 dst_set = 0;
12404   u8 grp_set = 0;
12405   u32 instance = ~0;
12406   u32 mcast_sw_if_index = ~0;
12407   u32 encap_vrf_id = 0;
12408   u32 decap_next_index = ~0;
12409   u32 vni = 0;
12410   int ret;
12411
12412   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12413   clib_memset (&src, 0, sizeof src);
12414   clib_memset (&dst, 0, sizeof dst);
12415
12416   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12417     {
12418       if (unformat (line_input, "del"))
12419         is_add = 0;
12420       else if (unformat (line_input, "instance %d", &instance))
12421         ;
12422       else
12423         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12424         {
12425           ipv4_set = 1;
12426           src_set = 1;
12427         }
12428       else
12429         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12430         {
12431           ipv4_set = 1;
12432           dst_set = 1;
12433         }
12434       else
12435         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12436         {
12437           ipv6_set = 1;
12438           src_set = 1;
12439         }
12440       else
12441         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12442         {
12443           ipv6_set = 1;
12444           dst_set = 1;
12445         }
12446       else if (unformat (line_input, "group %U %U",
12447                          unformat_ip4_address, &dst.ip4,
12448                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12449         {
12450           grp_set = dst_set = 1;
12451           ipv4_set = 1;
12452         }
12453       else if (unformat (line_input, "group %U",
12454                          unformat_ip4_address, &dst.ip4))
12455         {
12456           grp_set = dst_set = 1;
12457           ipv4_set = 1;
12458         }
12459       else if (unformat (line_input, "group %U %U",
12460                          unformat_ip6_address, &dst.ip6,
12461                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12462         {
12463           grp_set = dst_set = 1;
12464           ipv6_set = 1;
12465         }
12466       else if (unformat (line_input, "group %U",
12467                          unformat_ip6_address, &dst.ip6))
12468         {
12469           grp_set = dst_set = 1;
12470           ipv6_set = 1;
12471         }
12472       else
12473         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12474         ;
12475       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12476         ;
12477       else if (unformat (line_input, "decap-next %U",
12478                          unformat_vxlan_decap_next, &decap_next_index))
12479         ;
12480       else if (unformat (line_input, "vni %d", &vni))
12481         ;
12482       else
12483         {
12484           errmsg ("parse error '%U'", format_unformat_error, line_input);
12485           return -99;
12486         }
12487     }
12488
12489   if (src_set == 0)
12490     {
12491       errmsg ("tunnel src address not specified");
12492       return -99;
12493     }
12494   if (dst_set == 0)
12495     {
12496       errmsg ("tunnel dst address not specified");
12497       return -99;
12498     }
12499
12500   if (grp_set && !ip46_address_is_multicast (&dst))
12501     {
12502       errmsg ("tunnel group address not multicast");
12503       return -99;
12504     }
12505   if (grp_set && mcast_sw_if_index == ~0)
12506     {
12507       errmsg ("tunnel nonexistent multicast device");
12508       return -99;
12509     }
12510   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12511     {
12512       errmsg ("tunnel dst address must be unicast");
12513       return -99;
12514     }
12515
12516
12517   if (ipv4_set && ipv6_set)
12518     {
12519       errmsg ("both IPv4 and IPv6 addresses specified");
12520       return -99;
12521     }
12522
12523   if ((vni == 0) || (vni >> 24))
12524     {
12525       errmsg ("vni not specified or out of range");
12526       return -99;
12527     }
12528
12529   M (VXLAN_ADD_DEL_TUNNEL, mp);
12530
12531   if (ipv6_set)
12532     {
12533       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12534       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12535     }
12536   else
12537     {
12538       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12539       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12540     }
12541
12542   mp->instance = htonl (instance);
12543   mp->encap_vrf_id = ntohl (encap_vrf_id);
12544   mp->decap_next_index = ntohl (decap_next_index);
12545   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12546   mp->vni = ntohl (vni);
12547   mp->is_add = is_add;
12548   mp->is_ipv6 = ipv6_set;
12549
12550   S (mp);
12551   W (ret);
12552   return ret;
12553 }
12554
12555 static void vl_api_vxlan_tunnel_details_t_handler
12556   (vl_api_vxlan_tunnel_details_t * mp)
12557 {
12558   vat_main_t *vam = &vat_main;
12559   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12560   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12561
12562   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12563          ntohl (mp->sw_if_index),
12564          ntohl (mp->instance),
12565          format_ip46_address, &src, IP46_TYPE_ANY,
12566          format_ip46_address, &dst, IP46_TYPE_ANY,
12567          ntohl (mp->encap_vrf_id),
12568          ntohl (mp->decap_next_index), ntohl (mp->vni),
12569          ntohl (mp->mcast_sw_if_index));
12570 }
12571
12572 static void vl_api_vxlan_tunnel_details_t_handler_json
12573   (vl_api_vxlan_tunnel_details_t * mp)
12574 {
12575   vat_main_t *vam = &vat_main;
12576   vat_json_node_t *node = NULL;
12577
12578   if (VAT_JSON_ARRAY != vam->json_tree.type)
12579     {
12580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12581       vat_json_init_array (&vam->json_tree);
12582     }
12583   node = vat_json_array_add (&vam->json_tree);
12584
12585   vat_json_init_object (node);
12586   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12587
12588   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12589
12590   if (mp->is_ipv6)
12591     {
12592       struct in6_addr ip6;
12593
12594       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12595       vat_json_object_add_ip6 (node, "src_address", ip6);
12596       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12597       vat_json_object_add_ip6 (node, "dst_address", ip6);
12598     }
12599   else
12600     {
12601       struct in_addr ip4;
12602
12603       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12604       vat_json_object_add_ip4 (node, "src_address", ip4);
12605       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12606       vat_json_object_add_ip4 (node, "dst_address", ip4);
12607     }
12608   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12609   vat_json_object_add_uint (node, "decap_next_index",
12610                             ntohl (mp->decap_next_index));
12611   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12612   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12613   vat_json_object_add_uint (node, "mcast_sw_if_index",
12614                             ntohl (mp->mcast_sw_if_index));
12615 }
12616
12617 static int
12618 api_vxlan_tunnel_dump (vat_main_t * vam)
12619 {
12620   unformat_input_t *i = vam->input;
12621   vl_api_vxlan_tunnel_dump_t *mp;
12622   vl_api_control_ping_t *mp_ping;
12623   u32 sw_if_index;
12624   u8 sw_if_index_set = 0;
12625   int ret;
12626
12627   /* Parse args required to build the message */
12628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12629     {
12630       if (unformat (i, "sw_if_index %d", &sw_if_index))
12631         sw_if_index_set = 1;
12632       else
12633         break;
12634     }
12635
12636   if (sw_if_index_set == 0)
12637     {
12638       sw_if_index = ~0;
12639     }
12640
12641   if (!vam->json_output)
12642     {
12643       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12644              "sw_if_index", "instance", "src_address", "dst_address",
12645              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12646     }
12647
12648   /* Get list of vxlan-tunnel interfaces */
12649   M (VXLAN_TUNNEL_DUMP, mp);
12650
12651   mp->sw_if_index = htonl (sw_if_index);
12652
12653   S (mp);
12654
12655   /* Use a control ping for synchronization */
12656   MPING (CONTROL_PING, mp_ping);
12657   S (mp_ping);
12658
12659   W (ret);
12660   return ret;
12661 }
12662
12663 static uword unformat_geneve_decap_next
12664   (unformat_input_t * input, va_list * args)
12665 {
12666   u32 *result = va_arg (*args, u32 *);
12667   u32 tmp;
12668
12669   if (unformat (input, "l2"))
12670     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12671   else if (unformat (input, "%d", &tmp))
12672     *result = tmp;
12673   else
12674     return 0;
12675   return 1;
12676 }
12677
12678 static int
12679 api_geneve_add_del_tunnel (vat_main_t * vam)
12680 {
12681   unformat_input_t *line_input = vam->input;
12682   vl_api_geneve_add_del_tunnel_t *mp;
12683   ip46_address_t src, dst;
12684   u8 is_add = 1;
12685   u8 ipv4_set = 0, ipv6_set = 0;
12686   u8 src_set = 0;
12687   u8 dst_set = 0;
12688   u8 grp_set = 0;
12689   u32 mcast_sw_if_index = ~0;
12690   u32 encap_vrf_id = 0;
12691   u32 decap_next_index = ~0;
12692   u32 vni = 0;
12693   int ret;
12694
12695   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12696   clib_memset (&src, 0, sizeof src);
12697   clib_memset (&dst, 0, sizeof dst);
12698
12699   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12700     {
12701       if (unformat (line_input, "del"))
12702         is_add = 0;
12703       else
12704         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12705         {
12706           ipv4_set = 1;
12707           src_set = 1;
12708         }
12709       else
12710         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12711         {
12712           ipv4_set = 1;
12713           dst_set = 1;
12714         }
12715       else
12716         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12717         {
12718           ipv6_set = 1;
12719           src_set = 1;
12720         }
12721       else
12722         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12723         {
12724           ipv6_set = 1;
12725           dst_set = 1;
12726         }
12727       else if (unformat (line_input, "group %U %U",
12728                          unformat_ip4_address, &dst.ip4,
12729                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12730         {
12731           grp_set = dst_set = 1;
12732           ipv4_set = 1;
12733         }
12734       else if (unformat (line_input, "group %U",
12735                          unformat_ip4_address, &dst.ip4))
12736         {
12737           grp_set = dst_set = 1;
12738           ipv4_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U %U",
12741                          unformat_ip6_address, &dst.ip6,
12742                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12743         {
12744           grp_set = dst_set = 1;
12745           ipv6_set = 1;
12746         }
12747       else if (unformat (line_input, "group %U",
12748                          unformat_ip6_address, &dst.ip6))
12749         {
12750           grp_set = dst_set = 1;
12751           ipv6_set = 1;
12752         }
12753       else
12754         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12755         ;
12756       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12757         ;
12758       else if (unformat (line_input, "decap-next %U",
12759                          unformat_geneve_decap_next, &decap_next_index))
12760         ;
12761       else if (unformat (line_input, "vni %d", &vni))
12762         ;
12763       else
12764         {
12765           errmsg ("parse error '%U'", format_unformat_error, line_input);
12766           return -99;
12767         }
12768     }
12769
12770   if (src_set == 0)
12771     {
12772       errmsg ("tunnel src address not specified");
12773       return -99;
12774     }
12775   if (dst_set == 0)
12776     {
12777       errmsg ("tunnel dst address not specified");
12778       return -99;
12779     }
12780
12781   if (grp_set && !ip46_address_is_multicast (&dst))
12782     {
12783       errmsg ("tunnel group address not multicast");
12784       return -99;
12785     }
12786   if (grp_set && mcast_sw_if_index == ~0)
12787     {
12788       errmsg ("tunnel nonexistent multicast device");
12789       return -99;
12790     }
12791   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12792     {
12793       errmsg ("tunnel dst address must be unicast");
12794       return -99;
12795     }
12796
12797
12798   if (ipv4_set && ipv6_set)
12799     {
12800       errmsg ("both IPv4 and IPv6 addresses specified");
12801       return -99;
12802     }
12803
12804   if ((vni == 0) || (vni >> 24))
12805     {
12806       errmsg ("vni not specified or out of range");
12807       return -99;
12808     }
12809
12810   M (GENEVE_ADD_DEL_TUNNEL, mp);
12811
12812   if (ipv6_set)
12813     {
12814       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12815       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12816     }
12817   else
12818     {
12819       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12820       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12821     }
12822   mp->encap_vrf_id = ntohl (encap_vrf_id);
12823   mp->decap_next_index = ntohl (decap_next_index);
12824   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12825   mp->vni = ntohl (vni);
12826   mp->is_add = is_add;
12827   mp->is_ipv6 = ipv6_set;
12828
12829   S (mp);
12830   W (ret);
12831   return ret;
12832 }
12833
12834 static void vl_api_geneve_tunnel_details_t_handler
12835   (vl_api_geneve_tunnel_details_t * mp)
12836 {
12837   vat_main_t *vam = &vat_main;
12838   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12839   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12840
12841   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12842          ntohl (mp->sw_if_index),
12843          format_ip46_address, &src, IP46_TYPE_ANY,
12844          format_ip46_address, &dst, IP46_TYPE_ANY,
12845          ntohl (mp->encap_vrf_id),
12846          ntohl (mp->decap_next_index), ntohl (mp->vni),
12847          ntohl (mp->mcast_sw_if_index));
12848 }
12849
12850 static void vl_api_geneve_tunnel_details_t_handler_json
12851   (vl_api_geneve_tunnel_details_t * mp)
12852 {
12853   vat_main_t *vam = &vat_main;
12854   vat_json_node_t *node = NULL;
12855
12856   if (VAT_JSON_ARRAY != vam->json_tree.type)
12857     {
12858       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12859       vat_json_init_array (&vam->json_tree);
12860     }
12861   node = vat_json_array_add (&vam->json_tree);
12862
12863   vat_json_init_object (node);
12864   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12865   if (mp->is_ipv6)
12866     {
12867       struct in6_addr ip6;
12868
12869       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12870       vat_json_object_add_ip6 (node, "src_address", ip6);
12871       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12872       vat_json_object_add_ip6 (node, "dst_address", ip6);
12873     }
12874   else
12875     {
12876       struct in_addr ip4;
12877
12878       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12879       vat_json_object_add_ip4 (node, "src_address", ip4);
12880       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12881       vat_json_object_add_ip4 (node, "dst_address", ip4);
12882     }
12883   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12884   vat_json_object_add_uint (node, "decap_next_index",
12885                             ntohl (mp->decap_next_index));
12886   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12887   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12888   vat_json_object_add_uint (node, "mcast_sw_if_index",
12889                             ntohl (mp->mcast_sw_if_index));
12890 }
12891
12892 static int
12893 api_geneve_tunnel_dump (vat_main_t * vam)
12894 {
12895   unformat_input_t *i = vam->input;
12896   vl_api_geneve_tunnel_dump_t *mp;
12897   vl_api_control_ping_t *mp_ping;
12898   u32 sw_if_index;
12899   u8 sw_if_index_set = 0;
12900   int ret;
12901
12902   /* Parse args required to build the message */
12903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12904     {
12905       if (unformat (i, "sw_if_index %d", &sw_if_index))
12906         sw_if_index_set = 1;
12907       else
12908         break;
12909     }
12910
12911   if (sw_if_index_set == 0)
12912     {
12913       sw_if_index = ~0;
12914     }
12915
12916   if (!vam->json_output)
12917     {
12918       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12919              "sw_if_index", "local_address", "remote_address",
12920              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12921     }
12922
12923   /* Get list of geneve-tunnel interfaces */
12924   M (GENEVE_TUNNEL_DUMP, mp);
12925
12926   mp->sw_if_index = htonl (sw_if_index);
12927
12928   S (mp);
12929
12930   /* Use a control ping for synchronization */
12931   M (CONTROL_PING, mp_ping);
12932   S (mp_ping);
12933
12934   W (ret);
12935   return ret;
12936 }
12937
12938 static int
12939 api_gre_tunnel_add_del (vat_main_t * vam)
12940 {
12941   unformat_input_t *line_input = vam->input;
12942   vl_api_address_t src = { }, dst =
12943   {
12944   };
12945   vl_api_gre_tunnel_add_del_t *mp;
12946   vl_api_gre_tunnel_type_t t_type;
12947   u8 is_add = 1;
12948   u8 src_set = 0;
12949   u8 dst_set = 0;
12950   u32 outer_fib_id = 0;
12951   u32 session_id = 0;
12952   u32 instance = ~0;
12953   int ret;
12954
12955   t_type = GRE_API_TUNNEL_TYPE_L3;
12956
12957   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12958     {
12959       if (unformat (line_input, "del"))
12960         is_add = 0;
12961       else if (unformat (line_input, "instance %d", &instance))
12962         ;
12963       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12964         {
12965           src_set = 1;
12966         }
12967       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12968         {
12969           dst_set = 1;
12970         }
12971       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12972         ;
12973       else if (unformat (line_input, "teb"))
12974         t_type = GRE_API_TUNNEL_TYPE_TEB;
12975       else if (unformat (line_input, "erspan %d", &session_id))
12976         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12977       else
12978         {
12979           errmsg ("parse error '%U'", format_unformat_error, line_input);
12980           return -99;
12981         }
12982     }
12983
12984   if (src_set == 0)
12985     {
12986       errmsg ("tunnel src address not specified");
12987       return -99;
12988     }
12989   if (dst_set == 0)
12990     {
12991       errmsg ("tunnel dst address not specified");
12992       return -99;
12993     }
12994
12995   M (GRE_TUNNEL_ADD_DEL, mp);
12996
12997   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12998   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12999
13000   mp->tunnel.instance = htonl (instance);
13001   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13002   mp->is_add = is_add;
13003   mp->tunnel.session_id = htons ((u16) session_id);
13004   mp->tunnel.type = htonl (t_type);
13005
13006   S (mp);
13007   W (ret);
13008   return ret;
13009 }
13010
13011 static void vl_api_gre_tunnel_details_t_handler
13012   (vl_api_gre_tunnel_details_t * mp)
13013 {
13014   vat_main_t *vam = &vat_main;
13015
13016   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13017          ntohl (mp->tunnel.sw_if_index),
13018          ntohl (mp->tunnel.instance),
13019          format_vl_api_address, &mp->tunnel.src,
13020          format_vl_api_address, &mp->tunnel.dst,
13021          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13022          ntohl (mp->tunnel.session_id));
13023 }
13024
13025 static void vl_api_gre_tunnel_details_t_handler_json
13026   (vl_api_gre_tunnel_details_t * mp)
13027 {
13028   vat_main_t *vam = &vat_main;
13029   vat_json_node_t *node = NULL;
13030
13031   if (VAT_JSON_ARRAY != vam->json_tree.type)
13032     {
13033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13034       vat_json_init_array (&vam->json_tree);
13035     }
13036   node = vat_json_array_add (&vam->json_tree);
13037
13038   vat_json_init_object (node);
13039   vat_json_object_add_uint (node, "sw_if_index",
13040                             ntohl (mp->tunnel.sw_if_index));
13041   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13042
13043   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13044   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13045   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13046   vat_json_object_add_uint (node, "outer_fib_id",
13047                             ntohl (mp->tunnel.outer_fib_id));
13048   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13049 }
13050
13051 static int
13052 api_gre_tunnel_dump (vat_main_t * vam)
13053 {
13054   unformat_input_t *i = vam->input;
13055   vl_api_gre_tunnel_dump_t *mp;
13056   vl_api_control_ping_t *mp_ping;
13057   u32 sw_if_index;
13058   u8 sw_if_index_set = 0;
13059   int ret;
13060
13061   /* Parse args required to build the message */
13062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13063     {
13064       if (unformat (i, "sw_if_index %d", &sw_if_index))
13065         sw_if_index_set = 1;
13066       else
13067         break;
13068     }
13069
13070   if (sw_if_index_set == 0)
13071     {
13072       sw_if_index = ~0;
13073     }
13074
13075   if (!vam->json_output)
13076     {
13077       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13078              "sw_if_index", "instance", "src_address", "dst_address",
13079              "tunnel_type", "outer_fib_id", "session_id");
13080     }
13081
13082   /* Get list of gre-tunnel interfaces */
13083   M (GRE_TUNNEL_DUMP, mp);
13084
13085   mp->sw_if_index = htonl (sw_if_index);
13086
13087   S (mp);
13088
13089   /* Use a control ping for synchronization */
13090   MPING (CONTROL_PING, mp_ping);
13091   S (mp_ping);
13092
13093   W (ret);
13094   return ret;
13095 }
13096
13097 static int
13098 api_l2_fib_clear_table (vat_main_t * vam)
13099 {
13100 //  unformat_input_t * i = vam->input;
13101   vl_api_l2_fib_clear_table_t *mp;
13102   int ret;
13103
13104   M (L2_FIB_CLEAR_TABLE, mp);
13105
13106   S (mp);
13107   W (ret);
13108   return ret;
13109 }
13110
13111 static int
13112 api_l2_interface_efp_filter (vat_main_t * vam)
13113 {
13114   unformat_input_t *i = vam->input;
13115   vl_api_l2_interface_efp_filter_t *mp;
13116   u32 sw_if_index;
13117   u8 enable = 1;
13118   u8 sw_if_index_set = 0;
13119   int ret;
13120
13121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13122     {
13123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13124         sw_if_index_set = 1;
13125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13126         sw_if_index_set = 1;
13127       else if (unformat (i, "enable"))
13128         enable = 1;
13129       else if (unformat (i, "disable"))
13130         enable = 0;
13131       else
13132         {
13133           clib_warning ("parse error '%U'", format_unformat_error, i);
13134           return -99;
13135         }
13136     }
13137
13138   if (sw_if_index_set == 0)
13139     {
13140       errmsg ("missing sw_if_index");
13141       return -99;
13142     }
13143
13144   M (L2_INTERFACE_EFP_FILTER, mp);
13145
13146   mp->sw_if_index = ntohl (sw_if_index);
13147   mp->enable_disable = enable;
13148
13149   S (mp);
13150   W (ret);
13151   return ret;
13152 }
13153
13154 #define foreach_vtr_op                          \
13155 _("disable",  L2_VTR_DISABLED)                  \
13156 _("push-1",  L2_VTR_PUSH_1)                     \
13157 _("push-2",  L2_VTR_PUSH_2)                     \
13158 _("pop-1",  L2_VTR_POP_1)                       \
13159 _("pop-2",  L2_VTR_POP_2)                       \
13160 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13161 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13162 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13163 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13164
13165 static int
13166 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13167 {
13168   unformat_input_t *i = vam->input;
13169   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13170   u32 sw_if_index;
13171   u8 sw_if_index_set = 0;
13172   u8 vtr_op_set = 0;
13173   u32 vtr_op = 0;
13174   u32 push_dot1q = 1;
13175   u32 tag1 = ~0;
13176   u32 tag2 = ~0;
13177   int ret;
13178
13179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13180     {
13181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13182         sw_if_index_set = 1;
13183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13184         sw_if_index_set = 1;
13185       else if (unformat (i, "vtr_op %d", &vtr_op))
13186         vtr_op_set = 1;
13187 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13188       foreach_vtr_op
13189 #undef _
13190         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13191         ;
13192       else if (unformat (i, "tag1 %d", &tag1))
13193         ;
13194       else if (unformat (i, "tag2 %d", &tag2))
13195         ;
13196       else
13197         {
13198           clib_warning ("parse error '%U'", format_unformat_error, i);
13199           return -99;
13200         }
13201     }
13202
13203   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13204     {
13205       errmsg ("missing vtr operation or sw_if_index");
13206       return -99;
13207     }
13208
13209   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13210   mp->sw_if_index = ntohl (sw_if_index);
13211   mp->vtr_op = ntohl (vtr_op);
13212   mp->push_dot1q = ntohl (push_dot1q);
13213   mp->tag1 = ntohl (tag1);
13214   mp->tag2 = ntohl (tag2);
13215
13216   S (mp);
13217   W (ret);
13218   return ret;
13219 }
13220
13221 static int
13222 api_create_vhost_user_if (vat_main_t * vam)
13223 {
13224   unformat_input_t *i = vam->input;
13225   vl_api_create_vhost_user_if_t *mp;
13226   u8 *file_name;
13227   u8 is_server = 0;
13228   u8 file_name_set = 0;
13229   u32 custom_dev_instance = ~0;
13230   u8 hwaddr[6];
13231   u8 use_custom_mac = 0;
13232   u8 disable_mrg_rxbuf = 0;
13233   u8 disable_indirect_desc = 0;
13234   u8 *tag = 0;
13235   u8 enable_gso = 0;
13236   int ret;
13237
13238   /* Shut up coverity */
13239   clib_memset (hwaddr, 0, sizeof (hwaddr));
13240
13241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13242     {
13243       if (unformat (i, "socket %s", &file_name))
13244         {
13245           file_name_set = 1;
13246         }
13247       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13248         ;
13249       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13250         use_custom_mac = 1;
13251       else if (unformat (i, "server"))
13252         is_server = 1;
13253       else if (unformat (i, "disable_mrg_rxbuf"))
13254         disable_mrg_rxbuf = 1;
13255       else if (unformat (i, "disable_indirect_desc"))
13256         disable_indirect_desc = 1;
13257       else if (unformat (i, "gso"))
13258         enable_gso = 1;
13259       else if (unformat (i, "tag %s", &tag))
13260         ;
13261       else
13262         break;
13263     }
13264
13265   if (file_name_set == 0)
13266     {
13267       errmsg ("missing socket file name");
13268       return -99;
13269     }
13270
13271   if (vec_len (file_name) > 255)
13272     {
13273       errmsg ("socket file name too long");
13274       return -99;
13275     }
13276   vec_add1 (file_name, 0);
13277
13278   M (CREATE_VHOST_USER_IF, mp);
13279
13280   mp->is_server = is_server;
13281   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13282   mp->disable_indirect_desc = disable_indirect_desc;
13283   mp->enable_gso = enable_gso;
13284   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13285   vec_free (file_name);
13286   if (custom_dev_instance != ~0)
13287     {
13288       mp->renumber = 1;
13289       mp->custom_dev_instance = ntohl (custom_dev_instance);
13290     }
13291
13292   mp->use_custom_mac = use_custom_mac;
13293   clib_memcpy (mp->mac_address, hwaddr, 6);
13294   if (tag)
13295     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13296   vec_free (tag);
13297
13298   S (mp);
13299   W (ret);
13300   return ret;
13301 }
13302
13303 static int
13304 api_modify_vhost_user_if (vat_main_t * vam)
13305 {
13306   unformat_input_t *i = vam->input;
13307   vl_api_modify_vhost_user_if_t *mp;
13308   u8 *file_name;
13309   u8 is_server = 0;
13310   u8 file_name_set = 0;
13311   u32 custom_dev_instance = ~0;
13312   u8 sw_if_index_set = 0;
13313   u32 sw_if_index = (u32) ~ 0;
13314   u8 enable_gso = 0;
13315   int ret;
13316
13317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13318     {
13319       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13320         sw_if_index_set = 1;
13321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13322         sw_if_index_set = 1;
13323       else if (unformat (i, "socket %s", &file_name))
13324         {
13325           file_name_set = 1;
13326         }
13327       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13328         ;
13329       else if (unformat (i, "server"))
13330         is_server = 1;
13331       else if (unformat (i, "gso"))
13332         enable_gso = 1;
13333       else
13334         break;
13335     }
13336
13337   if (sw_if_index_set == 0)
13338     {
13339       errmsg ("missing sw_if_index or interface name");
13340       return -99;
13341     }
13342
13343   if (file_name_set == 0)
13344     {
13345       errmsg ("missing socket file name");
13346       return -99;
13347     }
13348
13349   if (vec_len (file_name) > 255)
13350     {
13351       errmsg ("socket file name too long");
13352       return -99;
13353     }
13354   vec_add1 (file_name, 0);
13355
13356   M (MODIFY_VHOST_USER_IF, mp);
13357
13358   mp->sw_if_index = ntohl (sw_if_index);
13359   mp->is_server = is_server;
13360   mp->enable_gso = enable_gso;
13361   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13362   vec_free (file_name);
13363   if (custom_dev_instance != ~0)
13364     {
13365       mp->renumber = 1;
13366       mp->custom_dev_instance = ntohl (custom_dev_instance);
13367     }
13368
13369   S (mp);
13370   W (ret);
13371   return ret;
13372 }
13373
13374 static int
13375 api_delete_vhost_user_if (vat_main_t * vam)
13376 {
13377   unformat_input_t *i = vam->input;
13378   vl_api_delete_vhost_user_if_t *mp;
13379   u32 sw_if_index = ~0;
13380   u8 sw_if_index_set = 0;
13381   int ret;
13382
13383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13384     {
13385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13386         sw_if_index_set = 1;
13387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13388         sw_if_index_set = 1;
13389       else
13390         break;
13391     }
13392
13393   if (sw_if_index_set == 0)
13394     {
13395       errmsg ("missing sw_if_index or interface name");
13396       return -99;
13397     }
13398
13399
13400   M (DELETE_VHOST_USER_IF, mp);
13401
13402   mp->sw_if_index = ntohl (sw_if_index);
13403
13404   S (mp);
13405   W (ret);
13406   return ret;
13407 }
13408
13409 static void vl_api_sw_interface_vhost_user_details_t_handler
13410   (vl_api_sw_interface_vhost_user_details_t * mp)
13411 {
13412   vat_main_t *vam = &vat_main;
13413
13414   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13415          (char *) mp->interface_name,
13416          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13417          clib_net_to_host_u64 (mp->features), mp->is_server,
13418          ntohl (mp->num_regions), (char *) mp->sock_filename);
13419   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13420 }
13421
13422 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13423   (vl_api_sw_interface_vhost_user_details_t * mp)
13424 {
13425   vat_main_t *vam = &vat_main;
13426   vat_json_node_t *node = NULL;
13427
13428   if (VAT_JSON_ARRAY != vam->json_tree.type)
13429     {
13430       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13431       vat_json_init_array (&vam->json_tree);
13432     }
13433   node = vat_json_array_add (&vam->json_tree);
13434
13435   vat_json_init_object (node);
13436   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13437   vat_json_object_add_string_copy (node, "interface_name",
13438                                    mp->interface_name);
13439   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13440                             ntohl (mp->virtio_net_hdr_sz));
13441   vat_json_object_add_uint (node, "features",
13442                             clib_net_to_host_u64 (mp->features));
13443   vat_json_object_add_uint (node, "is_server", mp->is_server);
13444   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13445   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13446   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13447 }
13448
13449 static int
13450 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13451 {
13452   vl_api_sw_interface_vhost_user_dump_t *mp;
13453   vl_api_control_ping_t *mp_ping;
13454   int ret;
13455   print (vam->ofp,
13456          "Interface name            idx hdr_sz features server regions filename");
13457
13458   /* Get list of vhost-user interfaces */
13459   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13460   S (mp);
13461
13462   /* Use a control ping for synchronization */
13463   MPING (CONTROL_PING, mp_ping);
13464   S (mp_ping);
13465
13466   W (ret);
13467   return ret;
13468 }
13469
13470 static int
13471 api_show_version (vat_main_t * vam)
13472 {
13473   vl_api_show_version_t *mp;
13474   int ret;
13475
13476   M (SHOW_VERSION, mp);
13477
13478   S (mp);
13479   W (ret);
13480   return ret;
13481 }
13482
13483
13484 static int
13485 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13486 {
13487   unformat_input_t *line_input = vam->input;
13488   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13489   ip4_address_t local4, remote4;
13490   ip6_address_t local6, remote6;
13491   u8 is_add = 1;
13492   u8 ipv4_set = 0, ipv6_set = 0;
13493   u8 local_set = 0;
13494   u8 remote_set = 0;
13495   u8 grp_set = 0;
13496   u32 mcast_sw_if_index = ~0;
13497   u32 encap_vrf_id = 0;
13498   u32 decap_vrf_id = 0;
13499   u8 protocol = ~0;
13500   u32 vni;
13501   u8 vni_set = 0;
13502   int ret;
13503
13504   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13505   clib_memset (&local4, 0, sizeof local4);
13506   clib_memset (&remote4, 0, sizeof remote4);
13507   clib_memset (&local6, 0, sizeof local6);
13508   clib_memset (&remote6, 0, sizeof remote6);
13509
13510   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13511     {
13512       if (unformat (line_input, "del"))
13513         is_add = 0;
13514       else if (unformat (line_input, "local %U",
13515                          unformat_ip4_address, &local4))
13516         {
13517           local_set = 1;
13518           ipv4_set = 1;
13519         }
13520       else if (unformat (line_input, "remote %U",
13521                          unformat_ip4_address, &remote4))
13522         {
13523           remote_set = 1;
13524           ipv4_set = 1;
13525         }
13526       else if (unformat (line_input, "local %U",
13527                          unformat_ip6_address, &local6))
13528         {
13529           local_set = 1;
13530           ipv6_set = 1;
13531         }
13532       else if (unformat (line_input, "remote %U",
13533                          unformat_ip6_address, &remote6))
13534         {
13535           remote_set = 1;
13536           ipv6_set = 1;
13537         }
13538       else if (unformat (line_input, "group %U %U",
13539                          unformat_ip4_address, &remote4,
13540                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13541         {
13542           grp_set = remote_set = 1;
13543           ipv4_set = 1;
13544         }
13545       else if (unformat (line_input, "group %U",
13546                          unformat_ip4_address, &remote4))
13547         {
13548           grp_set = remote_set = 1;
13549           ipv4_set = 1;
13550         }
13551       else if (unformat (line_input, "group %U %U",
13552                          unformat_ip6_address, &remote6,
13553                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13554         {
13555           grp_set = remote_set = 1;
13556           ipv6_set = 1;
13557         }
13558       else if (unformat (line_input, "group %U",
13559                          unformat_ip6_address, &remote6))
13560         {
13561           grp_set = remote_set = 1;
13562           ipv6_set = 1;
13563         }
13564       else
13565         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13566         ;
13567       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13568         ;
13569       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13570         ;
13571       else if (unformat (line_input, "vni %d", &vni))
13572         vni_set = 1;
13573       else if (unformat (line_input, "next-ip4"))
13574         protocol = 1;
13575       else if (unformat (line_input, "next-ip6"))
13576         protocol = 2;
13577       else if (unformat (line_input, "next-ethernet"))
13578         protocol = 3;
13579       else if (unformat (line_input, "next-nsh"))
13580         protocol = 4;
13581       else
13582         {
13583           errmsg ("parse error '%U'", format_unformat_error, line_input);
13584           return -99;
13585         }
13586     }
13587
13588   if (local_set == 0)
13589     {
13590       errmsg ("tunnel local address not specified");
13591       return -99;
13592     }
13593   if (remote_set == 0)
13594     {
13595       errmsg ("tunnel remote address not specified");
13596       return -99;
13597     }
13598   if (grp_set && mcast_sw_if_index == ~0)
13599     {
13600       errmsg ("tunnel nonexistent multicast device");
13601       return -99;
13602     }
13603   if (ipv4_set && ipv6_set)
13604     {
13605       errmsg ("both IPv4 and IPv6 addresses specified");
13606       return -99;
13607     }
13608
13609   if (vni_set == 0)
13610     {
13611       errmsg ("vni not specified");
13612       return -99;
13613     }
13614
13615   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13616
13617
13618   if (ipv6_set)
13619     {
13620       clib_memcpy (&mp->local, &local6, sizeof (local6));
13621       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13622     }
13623   else
13624     {
13625       clib_memcpy (&mp->local, &local4, sizeof (local4));
13626       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13627     }
13628
13629   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13630   mp->encap_vrf_id = ntohl (encap_vrf_id);
13631   mp->decap_vrf_id = ntohl (decap_vrf_id);
13632   mp->protocol = protocol;
13633   mp->vni = ntohl (vni);
13634   mp->is_add = is_add;
13635   mp->is_ipv6 = ipv6_set;
13636
13637   S (mp);
13638   W (ret);
13639   return ret;
13640 }
13641
13642 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13643   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13644 {
13645   vat_main_t *vam = &vat_main;
13646   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13647   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13648
13649   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13650          ntohl (mp->sw_if_index),
13651          format_ip46_address, &local, IP46_TYPE_ANY,
13652          format_ip46_address, &remote, IP46_TYPE_ANY,
13653          ntohl (mp->vni), mp->protocol,
13654          ntohl (mp->mcast_sw_if_index),
13655          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13656 }
13657
13658
13659 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13660   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13661 {
13662   vat_main_t *vam = &vat_main;
13663   vat_json_node_t *node = NULL;
13664   struct in_addr ip4;
13665   struct in6_addr ip6;
13666
13667   if (VAT_JSON_ARRAY != vam->json_tree.type)
13668     {
13669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13670       vat_json_init_array (&vam->json_tree);
13671     }
13672   node = vat_json_array_add (&vam->json_tree);
13673
13674   vat_json_init_object (node);
13675   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13676   if (mp->is_ipv6)
13677     {
13678       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13679       vat_json_object_add_ip6 (node, "local", ip6);
13680       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13681       vat_json_object_add_ip6 (node, "remote", ip6);
13682     }
13683   else
13684     {
13685       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13686       vat_json_object_add_ip4 (node, "local", ip4);
13687       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13688       vat_json_object_add_ip4 (node, "remote", ip4);
13689     }
13690   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13691   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13692   vat_json_object_add_uint (node, "mcast_sw_if_index",
13693                             ntohl (mp->mcast_sw_if_index));
13694   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13695   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13696   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13697 }
13698
13699 static int
13700 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13701 {
13702   unformat_input_t *i = vam->input;
13703   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13704   vl_api_control_ping_t *mp_ping;
13705   u32 sw_if_index;
13706   u8 sw_if_index_set = 0;
13707   int ret;
13708
13709   /* Parse args required to build the message */
13710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13711     {
13712       if (unformat (i, "sw_if_index %d", &sw_if_index))
13713         sw_if_index_set = 1;
13714       else
13715         break;
13716     }
13717
13718   if (sw_if_index_set == 0)
13719     {
13720       sw_if_index = ~0;
13721     }
13722
13723   if (!vam->json_output)
13724     {
13725       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13726              "sw_if_index", "local", "remote", "vni",
13727              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13728     }
13729
13730   /* Get list of vxlan-tunnel interfaces */
13731   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13732
13733   mp->sw_if_index = htonl (sw_if_index);
13734
13735   S (mp);
13736
13737   /* Use a control ping for synchronization */
13738   MPING (CONTROL_PING, mp_ping);
13739   S (mp_ping);
13740
13741   W (ret);
13742   return ret;
13743 }
13744
13745 static void vl_api_l2_fib_table_details_t_handler
13746   (vl_api_l2_fib_table_details_t * mp)
13747 {
13748   vat_main_t *vam = &vat_main;
13749
13750   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13751          "       %d       %d     %d",
13752          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13753          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13754          mp->bvi_mac);
13755 }
13756
13757 static void vl_api_l2_fib_table_details_t_handler_json
13758   (vl_api_l2_fib_table_details_t * mp)
13759 {
13760   vat_main_t *vam = &vat_main;
13761   vat_json_node_t *node = NULL;
13762
13763   if (VAT_JSON_ARRAY != vam->json_tree.type)
13764     {
13765       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13766       vat_json_init_array (&vam->json_tree);
13767     }
13768   node = vat_json_array_add (&vam->json_tree);
13769
13770   vat_json_init_object (node);
13771   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13772   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13773   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13774   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13775   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13776   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13777 }
13778
13779 static int
13780 api_l2_fib_table_dump (vat_main_t * vam)
13781 {
13782   unformat_input_t *i = vam->input;
13783   vl_api_l2_fib_table_dump_t *mp;
13784   vl_api_control_ping_t *mp_ping;
13785   u32 bd_id;
13786   u8 bd_id_set = 0;
13787   int ret;
13788
13789   /* Parse args required to build the message */
13790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13791     {
13792       if (unformat (i, "bd_id %d", &bd_id))
13793         bd_id_set = 1;
13794       else
13795         break;
13796     }
13797
13798   if (bd_id_set == 0)
13799     {
13800       errmsg ("missing bridge domain");
13801       return -99;
13802     }
13803
13804   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13805
13806   /* Get list of l2 fib entries */
13807   M (L2_FIB_TABLE_DUMP, mp);
13808
13809   mp->bd_id = ntohl (bd_id);
13810   S (mp);
13811
13812   /* Use a control ping for synchronization */
13813   MPING (CONTROL_PING, mp_ping);
13814   S (mp_ping);
13815
13816   W (ret);
13817   return ret;
13818 }
13819
13820
13821 static int
13822 api_interface_name_renumber (vat_main_t * vam)
13823 {
13824   unformat_input_t *line_input = vam->input;
13825   vl_api_interface_name_renumber_t *mp;
13826   u32 sw_if_index = ~0;
13827   u32 new_show_dev_instance = ~0;
13828   int ret;
13829
13830   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13831     {
13832       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13833                     &sw_if_index))
13834         ;
13835       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13836         ;
13837       else if (unformat (line_input, "new_show_dev_instance %d",
13838                          &new_show_dev_instance))
13839         ;
13840       else
13841         break;
13842     }
13843
13844   if (sw_if_index == ~0)
13845     {
13846       errmsg ("missing interface name or sw_if_index");
13847       return -99;
13848     }
13849
13850   if (new_show_dev_instance == ~0)
13851     {
13852       errmsg ("missing new_show_dev_instance");
13853       return -99;
13854     }
13855
13856   M (INTERFACE_NAME_RENUMBER, mp);
13857
13858   mp->sw_if_index = ntohl (sw_if_index);
13859   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13860
13861   S (mp);
13862   W (ret);
13863   return ret;
13864 }
13865
13866 static int
13867 api_ip_probe_neighbor (vat_main_t * vam)
13868 {
13869   unformat_input_t *i = vam->input;
13870   vl_api_ip_probe_neighbor_t *mp;
13871   vl_api_address_t dst_adr = { };
13872   u8 int_set = 0;
13873   u8 adr_set = 0;
13874   u32 sw_if_index;
13875   int ret;
13876
13877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13878     {
13879       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13880         int_set = 1;
13881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13882         int_set = 1;
13883       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13884         adr_set = 1;
13885       else
13886         break;
13887     }
13888
13889   if (int_set == 0)
13890     {
13891       errmsg ("missing interface");
13892       return -99;
13893     }
13894
13895   if (adr_set == 0)
13896     {
13897       errmsg ("missing addresses");
13898       return -99;
13899     }
13900
13901   M (IP_PROBE_NEIGHBOR, mp);
13902
13903   mp->sw_if_index = ntohl (sw_if_index);
13904   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13905
13906   S (mp);
13907   W (ret);
13908   return ret;
13909 }
13910
13911 static int
13912 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13913 {
13914   unformat_input_t *i = vam->input;
13915   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13916   u8 mode = IP_SCAN_V46_NEIGHBORS;
13917   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13918   int ret;
13919
13920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13921     {
13922       if (unformat (i, "ip4"))
13923         mode = IP_SCAN_V4_NEIGHBORS;
13924       else if (unformat (i, "ip6"))
13925         mode = IP_SCAN_V6_NEIGHBORS;
13926       if (unformat (i, "both"))
13927         mode = IP_SCAN_V46_NEIGHBORS;
13928       else if (unformat (i, "disable"))
13929         mode = IP_SCAN_DISABLED;
13930       else if (unformat (i, "interval %d", &interval))
13931         ;
13932       else if (unformat (i, "max-time %d", &time))
13933         ;
13934       else if (unformat (i, "max-update %d", &update))
13935         ;
13936       else if (unformat (i, "delay %d", &delay))
13937         ;
13938       else if (unformat (i, "stale %d", &stale))
13939         ;
13940       else
13941         break;
13942     }
13943
13944   if (interval > 255)
13945     {
13946       errmsg ("interval cannot exceed 255 minutes.");
13947       return -99;
13948     }
13949   if (time > 255)
13950     {
13951       errmsg ("max-time cannot exceed 255 usec.");
13952       return -99;
13953     }
13954   if (update > 255)
13955     {
13956       errmsg ("max-update cannot exceed 255.");
13957       return -99;
13958     }
13959   if (delay > 255)
13960     {
13961       errmsg ("delay cannot exceed 255 msec.");
13962       return -99;
13963     }
13964   if (stale > 255)
13965     {
13966       errmsg ("stale cannot exceed 255 minutes.");
13967       return -99;
13968     }
13969
13970   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13971   mp->mode = mode;
13972   mp->scan_interval = interval;
13973   mp->max_proc_time = time;
13974   mp->max_update = update;
13975   mp->scan_int_delay = delay;
13976   mp->stale_threshold = stale;
13977
13978   S (mp);
13979   W (ret);
13980   return ret;
13981 }
13982
13983 static int
13984 api_want_ip4_arp_events (vat_main_t * vam)
13985 {
13986   unformat_input_t *line_input = vam->input;
13987   vl_api_want_ip4_arp_events_t *mp;
13988   ip4_address_t address;
13989   int address_set = 0;
13990   u32 enable_disable = 1;
13991   int ret;
13992
13993   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13994     {
13995       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13996         address_set = 1;
13997       else if (unformat (line_input, "del"))
13998         enable_disable = 0;
13999       else
14000         break;
14001     }
14002
14003   if (address_set == 0)
14004     {
14005       errmsg ("missing addresses");
14006       return -99;
14007     }
14008
14009   M (WANT_IP4_ARP_EVENTS, mp);
14010   mp->enable_disable = enable_disable;
14011   mp->pid = htonl (getpid ());
14012   clib_memcpy (mp->ip, &address, sizeof (address));
14013
14014   S (mp);
14015   W (ret);
14016   return ret;
14017 }
14018
14019 static int
14020 api_want_ip6_nd_events (vat_main_t * vam)
14021 {
14022   unformat_input_t *line_input = vam->input;
14023   vl_api_want_ip6_nd_events_t *mp;
14024   vl_api_ip6_address_t address;
14025   int address_set = 0;
14026   u32 enable_disable = 1;
14027   int ret;
14028
14029   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14030     {
14031       if (unformat
14032           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14033         address_set = 1;
14034       else if (unformat (line_input, "del"))
14035         enable_disable = 0;
14036       else
14037         break;
14038     }
14039
14040   if (address_set == 0)
14041     {
14042       errmsg ("missing addresses");
14043       return -99;
14044     }
14045
14046   M (WANT_IP6_ND_EVENTS, mp);
14047   mp->enable_disable = enable_disable;
14048   mp->pid = htonl (getpid ());
14049   clib_memcpy (&mp->ip, &address, sizeof (address));
14050
14051   S (mp);
14052   W (ret);
14053   return ret;
14054 }
14055
14056 static int
14057 api_want_l2_macs_events (vat_main_t * vam)
14058 {
14059   unformat_input_t *line_input = vam->input;
14060   vl_api_want_l2_macs_events_t *mp;
14061   u8 enable_disable = 1;
14062   u32 scan_delay = 0;
14063   u32 max_macs_in_event = 0;
14064   u32 learn_limit = 0;
14065   int ret;
14066
14067   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14068     {
14069       if (unformat (line_input, "learn-limit %d", &learn_limit))
14070         ;
14071       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14072         ;
14073       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14074         ;
14075       else if (unformat (line_input, "disable"))
14076         enable_disable = 0;
14077       else
14078         break;
14079     }
14080
14081   M (WANT_L2_MACS_EVENTS, mp);
14082   mp->enable_disable = enable_disable;
14083   mp->pid = htonl (getpid ());
14084   mp->learn_limit = htonl (learn_limit);
14085   mp->scan_delay = (u8) scan_delay;
14086   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14087   S (mp);
14088   W (ret);
14089   return ret;
14090 }
14091
14092 static int
14093 api_input_acl_set_interface (vat_main_t * vam)
14094 {
14095   unformat_input_t *i = vam->input;
14096   vl_api_input_acl_set_interface_t *mp;
14097   u32 sw_if_index;
14098   int sw_if_index_set;
14099   u32 ip4_table_index = ~0;
14100   u32 ip6_table_index = ~0;
14101   u32 l2_table_index = ~0;
14102   u8 is_add = 1;
14103   int ret;
14104
14105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14106     {
14107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14108         sw_if_index_set = 1;
14109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14110         sw_if_index_set = 1;
14111       else if (unformat (i, "del"))
14112         is_add = 0;
14113       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14114         ;
14115       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14116         ;
14117       else if (unformat (i, "l2-table %d", &l2_table_index))
14118         ;
14119       else
14120         {
14121           clib_warning ("parse error '%U'", format_unformat_error, i);
14122           return -99;
14123         }
14124     }
14125
14126   if (sw_if_index_set == 0)
14127     {
14128       errmsg ("missing interface name or sw_if_index");
14129       return -99;
14130     }
14131
14132   M (INPUT_ACL_SET_INTERFACE, mp);
14133
14134   mp->sw_if_index = ntohl (sw_if_index);
14135   mp->ip4_table_index = ntohl (ip4_table_index);
14136   mp->ip6_table_index = ntohl (ip6_table_index);
14137   mp->l2_table_index = ntohl (l2_table_index);
14138   mp->is_add = is_add;
14139
14140   S (mp);
14141   W (ret);
14142   return ret;
14143 }
14144
14145 static int
14146 api_output_acl_set_interface (vat_main_t * vam)
14147 {
14148   unformat_input_t *i = vam->input;
14149   vl_api_output_acl_set_interface_t *mp;
14150   u32 sw_if_index;
14151   int sw_if_index_set;
14152   u32 ip4_table_index = ~0;
14153   u32 ip6_table_index = ~0;
14154   u32 l2_table_index = ~0;
14155   u8 is_add = 1;
14156   int ret;
14157
14158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14159     {
14160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14161         sw_if_index_set = 1;
14162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14163         sw_if_index_set = 1;
14164       else if (unformat (i, "del"))
14165         is_add = 0;
14166       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14167         ;
14168       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14169         ;
14170       else if (unformat (i, "l2-table %d", &l2_table_index))
14171         ;
14172       else
14173         {
14174           clib_warning ("parse error '%U'", format_unformat_error, i);
14175           return -99;
14176         }
14177     }
14178
14179   if (sw_if_index_set == 0)
14180     {
14181       errmsg ("missing interface name or sw_if_index");
14182       return -99;
14183     }
14184
14185   M (OUTPUT_ACL_SET_INTERFACE, mp);
14186
14187   mp->sw_if_index = ntohl (sw_if_index);
14188   mp->ip4_table_index = ntohl (ip4_table_index);
14189   mp->ip6_table_index = ntohl (ip6_table_index);
14190   mp->l2_table_index = ntohl (l2_table_index);
14191   mp->is_add = is_add;
14192
14193   S (mp);
14194   W (ret);
14195   return ret;
14196 }
14197
14198 static int
14199 api_ip_address_dump (vat_main_t * vam)
14200 {
14201   unformat_input_t *i = vam->input;
14202   vl_api_ip_address_dump_t *mp;
14203   vl_api_control_ping_t *mp_ping;
14204   u32 sw_if_index = ~0;
14205   u8 sw_if_index_set = 0;
14206   u8 ipv4_set = 0;
14207   u8 ipv6_set = 0;
14208   int ret;
14209
14210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14211     {
14212       if (unformat (i, "sw_if_index %d", &sw_if_index))
14213         sw_if_index_set = 1;
14214       else
14215         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14216         sw_if_index_set = 1;
14217       else if (unformat (i, "ipv4"))
14218         ipv4_set = 1;
14219       else if (unformat (i, "ipv6"))
14220         ipv6_set = 1;
14221       else
14222         break;
14223     }
14224
14225   if (ipv4_set && ipv6_set)
14226     {
14227       errmsg ("ipv4 and ipv6 flags cannot be both set");
14228       return -99;
14229     }
14230
14231   if ((!ipv4_set) && (!ipv6_set))
14232     {
14233       errmsg ("no ipv4 nor ipv6 flag set");
14234       return -99;
14235     }
14236
14237   if (sw_if_index_set == 0)
14238     {
14239       errmsg ("missing interface name or sw_if_index");
14240       return -99;
14241     }
14242
14243   vam->current_sw_if_index = sw_if_index;
14244   vam->is_ipv6 = ipv6_set;
14245
14246   M (IP_ADDRESS_DUMP, mp);
14247   mp->sw_if_index = ntohl (sw_if_index);
14248   mp->is_ipv6 = ipv6_set;
14249   S (mp);
14250
14251   /* Use a control ping for synchronization */
14252   MPING (CONTROL_PING, mp_ping);
14253   S (mp_ping);
14254
14255   W (ret);
14256   return ret;
14257 }
14258
14259 static int
14260 api_ip_dump (vat_main_t * vam)
14261 {
14262   vl_api_ip_dump_t *mp;
14263   vl_api_control_ping_t *mp_ping;
14264   unformat_input_t *in = vam->input;
14265   int ipv4_set = 0;
14266   int ipv6_set = 0;
14267   int is_ipv6;
14268   int i;
14269   int ret;
14270
14271   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14272     {
14273       if (unformat (in, "ipv4"))
14274         ipv4_set = 1;
14275       else if (unformat (in, "ipv6"))
14276         ipv6_set = 1;
14277       else
14278         break;
14279     }
14280
14281   if (ipv4_set && ipv6_set)
14282     {
14283       errmsg ("ipv4 and ipv6 flags cannot be both set");
14284       return -99;
14285     }
14286
14287   if ((!ipv4_set) && (!ipv6_set))
14288     {
14289       errmsg ("no ipv4 nor ipv6 flag set");
14290       return -99;
14291     }
14292
14293   is_ipv6 = ipv6_set;
14294   vam->is_ipv6 = is_ipv6;
14295
14296   /* free old data */
14297   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14298     {
14299       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14300     }
14301   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14302
14303   M (IP_DUMP, mp);
14304   mp->is_ipv6 = ipv6_set;
14305   S (mp);
14306
14307   /* Use a control ping for synchronization */
14308   MPING (CONTROL_PING, mp_ping);
14309   S (mp_ping);
14310
14311   W (ret);
14312   return ret;
14313 }
14314
14315 static int
14316 api_ipsec_spd_add_del (vat_main_t * vam)
14317 {
14318   unformat_input_t *i = vam->input;
14319   vl_api_ipsec_spd_add_del_t *mp;
14320   u32 spd_id = ~0;
14321   u8 is_add = 1;
14322   int ret;
14323
14324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14325     {
14326       if (unformat (i, "spd_id %d", &spd_id))
14327         ;
14328       else if (unformat (i, "del"))
14329         is_add = 0;
14330       else
14331         {
14332           clib_warning ("parse error '%U'", format_unformat_error, i);
14333           return -99;
14334         }
14335     }
14336   if (spd_id == ~0)
14337     {
14338       errmsg ("spd_id must be set");
14339       return -99;
14340     }
14341
14342   M (IPSEC_SPD_ADD_DEL, mp);
14343
14344   mp->spd_id = ntohl (spd_id);
14345   mp->is_add = is_add;
14346
14347   S (mp);
14348   W (ret);
14349   return ret;
14350 }
14351
14352 static int
14353 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14354 {
14355   unformat_input_t *i = vam->input;
14356   vl_api_ipsec_interface_add_del_spd_t *mp;
14357   u32 sw_if_index;
14358   u8 sw_if_index_set = 0;
14359   u32 spd_id = (u32) ~ 0;
14360   u8 is_add = 1;
14361   int ret;
14362
14363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14364     {
14365       if (unformat (i, "del"))
14366         is_add = 0;
14367       else if (unformat (i, "spd_id %d", &spd_id))
14368         ;
14369       else
14370         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14371         sw_if_index_set = 1;
14372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14373         sw_if_index_set = 1;
14374       else
14375         {
14376           clib_warning ("parse error '%U'", format_unformat_error, i);
14377           return -99;
14378         }
14379
14380     }
14381
14382   if (spd_id == (u32) ~ 0)
14383     {
14384       errmsg ("spd_id must be set");
14385       return -99;
14386     }
14387
14388   if (sw_if_index_set == 0)
14389     {
14390       errmsg ("missing interface name or sw_if_index");
14391       return -99;
14392     }
14393
14394   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14395
14396   mp->spd_id = ntohl (spd_id);
14397   mp->sw_if_index = ntohl (sw_if_index);
14398   mp->is_add = is_add;
14399
14400   S (mp);
14401   W (ret);
14402   return ret;
14403 }
14404
14405 static int
14406 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14407 {
14408   unformat_input_t *i = vam->input;
14409   vl_api_ipsec_spd_entry_add_del_t *mp;
14410   u8 is_add = 1, is_outbound = 0;
14411   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14412   i32 priority = 0;
14413   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14414   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14415   vl_api_address_t laddr_start = { }, laddr_stop =
14416   {
14417   }, raddr_start =
14418   {
14419   }, raddr_stop =
14420   {
14421   };
14422   int ret;
14423
14424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14425     {
14426       if (unformat (i, "del"))
14427         is_add = 0;
14428       if (unformat (i, "outbound"))
14429         is_outbound = 1;
14430       if (unformat (i, "inbound"))
14431         is_outbound = 0;
14432       else if (unformat (i, "spd_id %d", &spd_id))
14433         ;
14434       else if (unformat (i, "sa_id %d", &sa_id))
14435         ;
14436       else if (unformat (i, "priority %d", &priority))
14437         ;
14438       else if (unformat (i, "protocol %d", &protocol))
14439         ;
14440       else if (unformat (i, "lport_start %d", &lport_start))
14441         ;
14442       else if (unformat (i, "lport_stop %d", &lport_stop))
14443         ;
14444       else if (unformat (i, "rport_start %d", &rport_start))
14445         ;
14446       else if (unformat (i, "rport_stop %d", &rport_stop))
14447         ;
14448       else if (unformat (i, "laddr_start %U",
14449                          unformat_vl_api_address, &laddr_start))
14450         ;
14451       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14452                          &laddr_stop))
14453         ;
14454       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14455                          &raddr_start))
14456         ;
14457       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14458                          &raddr_stop))
14459         ;
14460       else
14461         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14462         {
14463           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14464             {
14465               clib_warning ("unsupported action: 'resolve'");
14466               return -99;
14467             }
14468         }
14469       else
14470         {
14471           clib_warning ("parse error '%U'", format_unformat_error, i);
14472           return -99;
14473         }
14474
14475     }
14476
14477   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14478
14479   mp->is_add = is_add;
14480
14481   mp->entry.spd_id = ntohl (spd_id);
14482   mp->entry.priority = ntohl (priority);
14483   mp->entry.is_outbound = is_outbound;
14484
14485   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14486                sizeof (vl_api_address_t));
14487   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14488                sizeof (vl_api_address_t));
14489   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14490                sizeof (vl_api_address_t));
14491   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14492                sizeof (vl_api_address_t));
14493
14494   mp->entry.protocol = (u8) protocol;
14495   mp->entry.local_port_start = ntohs ((u16) lport_start);
14496   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14497   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14498   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14499   mp->entry.policy = (u8) policy;
14500   mp->entry.sa_id = ntohl (sa_id);
14501
14502   S (mp);
14503   W (ret);
14504   return ret;
14505 }
14506
14507 static int
14508 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14509 {
14510   unformat_input_t *i = vam->input;
14511   vl_api_ipsec_sad_entry_add_del_t *mp;
14512   u32 sad_id = 0, spi = 0;
14513   u8 *ck = 0, *ik = 0;
14514   u8 is_add = 1;
14515
14516   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14517   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14518   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14519   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14520   vl_api_address_t tun_src, tun_dst;
14521   int ret;
14522
14523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14524     {
14525       if (unformat (i, "del"))
14526         is_add = 0;
14527       else if (unformat (i, "sad_id %d", &sad_id))
14528         ;
14529       else if (unformat (i, "spi %d", &spi))
14530         ;
14531       else if (unformat (i, "esp"))
14532         protocol = IPSEC_API_PROTO_ESP;
14533       else
14534         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14535         {
14536           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14537           if (ADDRESS_IP6 == tun_src.af)
14538             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14539         }
14540       else
14541         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14542         {
14543           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14544           if (ADDRESS_IP6 == tun_src.af)
14545             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14546         }
14547       else
14548         if (unformat (i, "crypto_alg %U",
14549                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14550         ;
14551       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14552         ;
14553       else if (unformat (i, "integ_alg %U",
14554                          unformat_ipsec_api_integ_alg, &integ_alg))
14555         ;
14556       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14557         ;
14558       else
14559         {
14560           clib_warning ("parse error '%U'", format_unformat_error, i);
14561           return -99;
14562         }
14563
14564     }
14565
14566   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14567
14568   mp->is_add = is_add;
14569   mp->entry.sad_id = ntohl (sad_id);
14570   mp->entry.protocol = protocol;
14571   mp->entry.spi = ntohl (spi);
14572   mp->entry.flags = flags;
14573
14574   mp->entry.crypto_algorithm = crypto_alg;
14575   mp->entry.integrity_algorithm = integ_alg;
14576   mp->entry.crypto_key.length = vec_len (ck);
14577   mp->entry.integrity_key.length = vec_len (ik);
14578
14579   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14580     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14581
14582   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14583     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14584
14585   if (ck)
14586     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14587   if (ik)
14588     clib_memcpy (mp->entry.integrity_key.data, ik,
14589                  mp->entry.integrity_key.length);
14590
14591   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14592     {
14593       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14594                    sizeof (mp->entry.tunnel_src));
14595       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14596                    sizeof (mp->entry.tunnel_dst));
14597     }
14598
14599   S (mp);
14600   W (ret);
14601   return ret;
14602 }
14603
14604 static int
14605 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14606 {
14607   unformat_input_t *i = vam->input;
14608   vl_api_ipsec_tunnel_if_add_del_t *mp;
14609   u32 local_spi = 0, remote_spi = 0;
14610   u32 crypto_alg = 0, integ_alg = 0;
14611   u8 *lck = NULL, *rck = NULL;
14612   u8 *lik = NULL, *rik = NULL;
14613   vl_api_address_t local_ip = { 0 };
14614   vl_api_address_t remote_ip = { 0 };
14615   f64 before = 0;
14616   u8 is_add = 1;
14617   u8 esn = 0;
14618   u8 anti_replay = 0;
14619   u8 renumber = 0;
14620   u32 instance = ~0;
14621   u32 count = 1, jj;
14622   int ret = -1;
14623
14624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14625     {
14626       if (unformat (i, "del"))
14627         is_add = 0;
14628       else if (unformat (i, "esn"))
14629         esn = 1;
14630       else if (unformat (i, "anti-replay"))
14631         anti_replay = 1;
14632       else if (unformat (i, "count %d", &count))
14633         ;
14634       else if (unformat (i, "local_spi %d", &local_spi))
14635         ;
14636       else if (unformat (i, "remote_spi %d", &remote_spi))
14637         ;
14638       else
14639         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14640         ;
14641       else
14642         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14643         ;
14644       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14645         ;
14646       else
14647         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14648         ;
14649       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14650         ;
14651       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14652         ;
14653       else
14654         if (unformat
14655             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14656         {
14657           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14658             {
14659               errmsg ("unsupported crypto-alg: '%U'\n",
14660                       format_ipsec_crypto_alg, crypto_alg);
14661               return -99;
14662             }
14663         }
14664       else
14665         if (unformat
14666             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14667         {
14668           if (integ_alg >= IPSEC_INTEG_N_ALG)
14669             {
14670               errmsg ("unsupported integ-alg: '%U'\n",
14671                       format_ipsec_integ_alg, integ_alg);
14672               return -99;
14673             }
14674         }
14675       else if (unformat (i, "instance %u", &instance))
14676         renumber = 1;
14677       else
14678         {
14679           errmsg ("parse error '%U'\n", format_unformat_error, i);
14680           return -99;
14681         }
14682     }
14683
14684   if (count > 1)
14685     {
14686       /* Turn on async mode */
14687       vam->async_mode = 1;
14688       vam->async_errors = 0;
14689       before = vat_time_now (vam);
14690     }
14691
14692   for (jj = 0; jj < count; jj++)
14693     {
14694       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14695
14696       mp->is_add = is_add;
14697       mp->esn = esn;
14698       mp->anti_replay = anti_replay;
14699
14700       if (jj > 0)
14701         increment_address (&remote_ip);
14702
14703       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14704       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14705
14706       mp->local_spi = htonl (local_spi + jj);
14707       mp->remote_spi = htonl (remote_spi + jj);
14708       mp->crypto_alg = (u8) crypto_alg;
14709
14710       mp->local_crypto_key_len = 0;
14711       if (lck)
14712         {
14713           mp->local_crypto_key_len = vec_len (lck);
14714           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14715             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14716           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14717         }
14718
14719       mp->remote_crypto_key_len = 0;
14720       if (rck)
14721         {
14722           mp->remote_crypto_key_len = vec_len (rck);
14723           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14724             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14725           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14726         }
14727
14728       mp->integ_alg = (u8) integ_alg;
14729
14730       mp->local_integ_key_len = 0;
14731       if (lik)
14732         {
14733           mp->local_integ_key_len = vec_len (lik);
14734           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14735             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14736           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14737         }
14738
14739       mp->remote_integ_key_len = 0;
14740       if (rik)
14741         {
14742           mp->remote_integ_key_len = vec_len (rik);
14743           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14744             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14745           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14746         }
14747
14748       if (renumber)
14749         {
14750           mp->renumber = renumber;
14751           mp->show_instance = ntohl (instance);
14752         }
14753       S (mp);
14754     }
14755
14756   /* When testing multiple add/del ops, use a control-ping to sync */
14757   if (count > 1)
14758     {
14759       vl_api_control_ping_t *mp_ping;
14760       f64 after;
14761       f64 timeout;
14762
14763       /* Shut off async mode */
14764       vam->async_mode = 0;
14765
14766       MPING (CONTROL_PING, mp_ping);
14767       S (mp_ping);
14768
14769       timeout = vat_time_now (vam) + 1.0;
14770       while (vat_time_now (vam) < timeout)
14771         if (vam->result_ready == 1)
14772           goto out;
14773       vam->retval = -99;
14774
14775     out:
14776       if (vam->retval == -99)
14777         errmsg ("timeout");
14778
14779       if (vam->async_errors > 0)
14780         {
14781           errmsg ("%d asynchronous errors", vam->async_errors);
14782           vam->retval = -98;
14783         }
14784       vam->async_errors = 0;
14785       after = vat_time_now (vam);
14786
14787       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14788       if (jj > 0)
14789         count = jj;
14790
14791       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14792              count, after - before, count / (after - before));
14793     }
14794   else
14795     {
14796       /* Wait for a reply... */
14797       W (ret);
14798       return ret;
14799     }
14800
14801   return ret;
14802 }
14803
14804 static void
14805 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14806 {
14807   vat_main_t *vam = &vat_main;
14808
14809   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14810          "crypto_key %U integ_alg %u integ_key %U flags %x "
14811          "tunnel_src_addr %U tunnel_dst_addr %U "
14812          "salt %u seq_outbound %lu last_seq_inbound %lu "
14813          "replay_window %lu\n",
14814          ntohl (mp->entry.sad_id),
14815          ntohl (mp->sw_if_index),
14816          ntohl (mp->entry.spi),
14817          ntohl (mp->entry.protocol),
14818          ntohl (mp->entry.crypto_algorithm),
14819          format_hex_bytes, mp->entry.crypto_key.data,
14820          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14821          format_hex_bytes, mp->entry.integrity_key.data,
14822          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14823          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14824          &mp->entry.tunnel_dst, ntohl (mp->salt),
14825          clib_net_to_host_u64 (mp->seq_outbound),
14826          clib_net_to_host_u64 (mp->last_seq_inbound),
14827          clib_net_to_host_u64 (mp->replay_window));
14828 }
14829
14830 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14831 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14832
14833 static void vl_api_ipsec_sa_details_t_handler_json
14834   (vl_api_ipsec_sa_details_t * mp)
14835 {
14836   vat_main_t *vam = &vat_main;
14837   vat_json_node_t *node = NULL;
14838   vl_api_ipsec_sad_flags_t flags;
14839
14840   if (VAT_JSON_ARRAY != vam->json_tree.type)
14841     {
14842       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14843       vat_json_init_array (&vam->json_tree);
14844     }
14845   node = vat_json_array_add (&vam->json_tree);
14846
14847   vat_json_init_object (node);
14848   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14849   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14850   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14851   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14852   vat_json_object_add_uint (node, "crypto_alg",
14853                             ntohl (mp->entry.crypto_algorithm));
14854   vat_json_object_add_uint (node, "integ_alg",
14855                             ntohl (mp->entry.integrity_algorithm));
14856   flags = ntohl (mp->entry.flags);
14857   vat_json_object_add_uint (node, "use_esn",
14858                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14859   vat_json_object_add_uint (node, "use_anti_replay",
14860                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14861   vat_json_object_add_uint (node, "is_tunnel",
14862                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14863   vat_json_object_add_uint (node, "is_tunnel_ip6",
14864                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14865   vat_json_object_add_uint (node, "udp_encap",
14866                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14867   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14868                              mp->entry.crypto_key.length);
14869   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14870                              mp->entry.integrity_key.length);
14871   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14872   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14873   vat_json_object_add_uint (node, "replay_window",
14874                             clib_net_to_host_u64 (mp->replay_window));
14875 }
14876
14877 static int
14878 api_ipsec_sa_dump (vat_main_t * vam)
14879 {
14880   unformat_input_t *i = vam->input;
14881   vl_api_ipsec_sa_dump_t *mp;
14882   vl_api_control_ping_t *mp_ping;
14883   u32 sa_id = ~0;
14884   int ret;
14885
14886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14887     {
14888       if (unformat (i, "sa_id %d", &sa_id))
14889         ;
14890       else
14891         {
14892           clib_warning ("parse error '%U'", format_unformat_error, i);
14893           return -99;
14894         }
14895     }
14896
14897   M (IPSEC_SA_DUMP, mp);
14898
14899   mp->sa_id = ntohl (sa_id);
14900
14901   S (mp);
14902
14903   /* Use a control ping for synchronization */
14904   M (CONTROL_PING, mp_ping);
14905   S (mp_ping);
14906
14907   W (ret);
14908   return ret;
14909 }
14910
14911 static int
14912 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14913 {
14914   unformat_input_t *i = vam->input;
14915   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14916   u32 sw_if_index = ~0;
14917   u32 sa_id = ~0;
14918   u8 is_outbound = (u8) ~ 0;
14919   int ret;
14920
14921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14922     {
14923       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14924         ;
14925       else if (unformat (i, "sa_id %d", &sa_id))
14926         ;
14927       else if (unformat (i, "outbound"))
14928         is_outbound = 1;
14929       else if (unformat (i, "inbound"))
14930         is_outbound = 0;
14931       else
14932         {
14933           clib_warning ("parse error '%U'", format_unformat_error, i);
14934           return -99;
14935         }
14936     }
14937
14938   if (sw_if_index == ~0)
14939     {
14940       errmsg ("interface must be specified");
14941       return -99;
14942     }
14943
14944   if (sa_id == ~0)
14945     {
14946       errmsg ("SA ID must be specified");
14947       return -99;
14948     }
14949
14950   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14951
14952   mp->sw_if_index = htonl (sw_if_index);
14953   mp->sa_id = htonl (sa_id);
14954   mp->is_outbound = is_outbound;
14955
14956   S (mp);
14957   W (ret);
14958
14959   return ret;
14960 }
14961
14962 static int
14963 api_get_first_msg_id (vat_main_t * vam)
14964 {
14965   vl_api_get_first_msg_id_t *mp;
14966   unformat_input_t *i = vam->input;
14967   u8 *name;
14968   u8 name_set = 0;
14969   int ret;
14970
14971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14972     {
14973       if (unformat (i, "client %s", &name))
14974         name_set = 1;
14975       else
14976         break;
14977     }
14978
14979   if (name_set == 0)
14980     {
14981       errmsg ("missing client name");
14982       return -99;
14983     }
14984   vec_add1 (name, 0);
14985
14986   if (vec_len (name) > 63)
14987     {
14988       errmsg ("client name too long");
14989       return -99;
14990     }
14991
14992   M (GET_FIRST_MSG_ID, mp);
14993   clib_memcpy (mp->name, name, vec_len (name));
14994   S (mp);
14995   W (ret);
14996   return ret;
14997 }
14998
14999 static int
15000 api_cop_interface_enable_disable (vat_main_t * vam)
15001 {
15002   unformat_input_t *line_input = vam->input;
15003   vl_api_cop_interface_enable_disable_t *mp;
15004   u32 sw_if_index = ~0;
15005   u8 enable_disable = 1;
15006   int ret;
15007
15008   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15009     {
15010       if (unformat (line_input, "disable"))
15011         enable_disable = 0;
15012       if (unformat (line_input, "enable"))
15013         enable_disable = 1;
15014       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15015                          vam, &sw_if_index))
15016         ;
15017       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15018         ;
15019       else
15020         break;
15021     }
15022
15023   if (sw_if_index == ~0)
15024     {
15025       errmsg ("missing interface name or sw_if_index");
15026       return -99;
15027     }
15028
15029   /* Construct the API message */
15030   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15031   mp->sw_if_index = ntohl (sw_if_index);
15032   mp->enable_disable = enable_disable;
15033
15034   /* send it... */
15035   S (mp);
15036   /* Wait for the reply */
15037   W (ret);
15038   return ret;
15039 }
15040
15041 static int
15042 api_cop_whitelist_enable_disable (vat_main_t * vam)
15043 {
15044   unformat_input_t *line_input = vam->input;
15045   vl_api_cop_whitelist_enable_disable_t *mp;
15046   u32 sw_if_index = ~0;
15047   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15048   u32 fib_id = 0;
15049   int ret;
15050
15051   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15052     {
15053       if (unformat (line_input, "ip4"))
15054         ip4 = 1;
15055       else if (unformat (line_input, "ip6"))
15056         ip6 = 1;
15057       else if (unformat (line_input, "default"))
15058         default_cop = 1;
15059       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15060                          vam, &sw_if_index))
15061         ;
15062       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15063         ;
15064       else if (unformat (line_input, "fib-id %d", &fib_id))
15065         ;
15066       else
15067         break;
15068     }
15069
15070   if (sw_if_index == ~0)
15071     {
15072       errmsg ("missing interface name or sw_if_index");
15073       return -99;
15074     }
15075
15076   /* Construct the API message */
15077   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15078   mp->sw_if_index = ntohl (sw_if_index);
15079   mp->fib_id = ntohl (fib_id);
15080   mp->ip4 = ip4;
15081   mp->ip6 = ip6;
15082   mp->default_cop = default_cop;
15083
15084   /* send it... */
15085   S (mp);
15086   /* Wait for the reply */
15087   W (ret);
15088   return ret;
15089 }
15090
15091 static int
15092 api_get_node_graph (vat_main_t * vam)
15093 {
15094   vl_api_get_node_graph_t *mp;
15095   int ret;
15096
15097   M (GET_NODE_GRAPH, mp);
15098
15099   /* send it... */
15100   S (mp);
15101   /* Wait for the reply */
15102   W (ret);
15103   return ret;
15104 }
15105
15106 /* *INDENT-OFF* */
15107 /** Used for parsing LISP eids */
15108 typedef CLIB_PACKED(struct{
15109   u8 addr[16];   /**< eid address */
15110   u32 len;       /**< prefix length if IP */
15111   u8 type;      /**< type of eid */
15112 }) lisp_eid_vat_t;
15113 /* *INDENT-ON* */
15114
15115 static uword
15116 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15117 {
15118   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15119
15120   clib_memset (a, 0, sizeof (a[0]));
15121
15122   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15123     {
15124       a->type = 0;              /* ipv4 type */
15125     }
15126   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15127     {
15128       a->type = 1;              /* ipv6 type */
15129     }
15130   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15131     {
15132       a->type = 2;              /* mac type */
15133     }
15134   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15135     {
15136       a->type = 3;              /* NSH type */
15137       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15138       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15139     }
15140   else
15141     {
15142       return 0;
15143     }
15144
15145   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15146     {
15147       return 0;
15148     }
15149
15150   return 1;
15151 }
15152
15153 static int
15154 lisp_eid_size_vat (u8 type)
15155 {
15156   switch (type)
15157     {
15158     case 0:
15159       return 4;
15160     case 1:
15161       return 16;
15162     case 2:
15163       return 6;
15164     case 3:
15165       return 5;
15166     }
15167   return 0;
15168 }
15169
15170 static void
15171 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15172 {
15173   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15174 }
15175
15176 static int
15177 api_one_add_del_locator_set (vat_main_t * vam)
15178 {
15179   unformat_input_t *input = vam->input;
15180   vl_api_one_add_del_locator_set_t *mp;
15181   u8 is_add = 1;
15182   u8 *locator_set_name = NULL;
15183   u8 locator_set_name_set = 0;
15184   vl_api_local_locator_t locator, *locators = 0;
15185   u32 sw_if_index, priority, weight;
15186   u32 data_len = 0;
15187
15188   int ret;
15189   /* Parse args required to build the message */
15190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15191     {
15192       if (unformat (input, "del"))
15193         {
15194           is_add = 0;
15195         }
15196       else if (unformat (input, "locator-set %s", &locator_set_name))
15197         {
15198           locator_set_name_set = 1;
15199         }
15200       else if (unformat (input, "sw_if_index %u p %u w %u",
15201                          &sw_if_index, &priority, &weight))
15202         {
15203           locator.sw_if_index = htonl (sw_if_index);
15204           locator.priority = priority;
15205           locator.weight = weight;
15206           vec_add1 (locators, locator);
15207         }
15208       else
15209         if (unformat
15210             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15211              &sw_if_index, &priority, &weight))
15212         {
15213           locator.sw_if_index = htonl (sw_if_index);
15214           locator.priority = priority;
15215           locator.weight = weight;
15216           vec_add1 (locators, locator);
15217         }
15218       else
15219         break;
15220     }
15221
15222   if (locator_set_name_set == 0)
15223     {
15224       errmsg ("missing locator-set name");
15225       vec_free (locators);
15226       return -99;
15227     }
15228
15229   if (vec_len (locator_set_name) > 64)
15230     {
15231       errmsg ("locator-set name too long");
15232       vec_free (locator_set_name);
15233       vec_free (locators);
15234       return -99;
15235     }
15236   vec_add1 (locator_set_name, 0);
15237
15238   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15239
15240   /* Construct the API message */
15241   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15242
15243   mp->is_add = is_add;
15244   clib_memcpy (mp->locator_set_name, locator_set_name,
15245                vec_len (locator_set_name));
15246   vec_free (locator_set_name);
15247
15248   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15249   if (locators)
15250     clib_memcpy (mp->locators, locators, data_len);
15251   vec_free (locators);
15252
15253   /* send it... */
15254   S (mp);
15255
15256   /* Wait for a reply... */
15257   W (ret);
15258   return ret;
15259 }
15260
15261 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15262
15263 static int
15264 api_one_add_del_locator (vat_main_t * vam)
15265 {
15266   unformat_input_t *input = vam->input;
15267   vl_api_one_add_del_locator_t *mp;
15268   u32 tmp_if_index = ~0;
15269   u32 sw_if_index = ~0;
15270   u8 sw_if_index_set = 0;
15271   u8 sw_if_index_if_name_set = 0;
15272   u32 priority = ~0;
15273   u8 priority_set = 0;
15274   u32 weight = ~0;
15275   u8 weight_set = 0;
15276   u8 is_add = 1;
15277   u8 *locator_set_name = NULL;
15278   u8 locator_set_name_set = 0;
15279   int ret;
15280
15281   /* Parse args required to build the message */
15282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15283     {
15284       if (unformat (input, "del"))
15285         {
15286           is_add = 0;
15287         }
15288       else if (unformat (input, "locator-set %s", &locator_set_name))
15289         {
15290           locator_set_name_set = 1;
15291         }
15292       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15293                          &tmp_if_index))
15294         {
15295           sw_if_index_if_name_set = 1;
15296           sw_if_index = tmp_if_index;
15297         }
15298       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15299         {
15300           sw_if_index_set = 1;
15301           sw_if_index = tmp_if_index;
15302         }
15303       else if (unformat (input, "p %d", &priority))
15304         {
15305           priority_set = 1;
15306         }
15307       else if (unformat (input, "w %d", &weight))
15308         {
15309           weight_set = 1;
15310         }
15311       else
15312         break;
15313     }
15314
15315   if (locator_set_name_set == 0)
15316     {
15317       errmsg ("missing locator-set name");
15318       return -99;
15319     }
15320
15321   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15322     {
15323       errmsg ("missing sw_if_index");
15324       vec_free (locator_set_name);
15325       return -99;
15326     }
15327
15328   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15329     {
15330       errmsg ("cannot use both params interface name and sw_if_index");
15331       vec_free (locator_set_name);
15332       return -99;
15333     }
15334
15335   if (priority_set == 0)
15336     {
15337       errmsg ("missing locator-set priority");
15338       vec_free (locator_set_name);
15339       return -99;
15340     }
15341
15342   if (weight_set == 0)
15343     {
15344       errmsg ("missing locator-set weight");
15345       vec_free (locator_set_name);
15346       return -99;
15347     }
15348
15349   if (vec_len (locator_set_name) > 64)
15350     {
15351       errmsg ("locator-set name too long");
15352       vec_free (locator_set_name);
15353       return -99;
15354     }
15355   vec_add1 (locator_set_name, 0);
15356
15357   /* Construct the API message */
15358   M (ONE_ADD_DEL_LOCATOR, mp);
15359
15360   mp->is_add = is_add;
15361   mp->sw_if_index = ntohl (sw_if_index);
15362   mp->priority = priority;
15363   mp->weight = weight;
15364   clib_memcpy (mp->locator_set_name, locator_set_name,
15365                vec_len (locator_set_name));
15366   vec_free (locator_set_name);
15367
15368   /* send it... */
15369   S (mp);
15370
15371   /* Wait for a reply... */
15372   W (ret);
15373   return ret;
15374 }
15375
15376 #define api_lisp_add_del_locator api_one_add_del_locator
15377
15378 uword
15379 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15380 {
15381   u32 *key_id = va_arg (*args, u32 *);
15382   u8 *s = 0;
15383
15384   if (unformat (input, "%s", &s))
15385     {
15386       if (!strcmp ((char *) s, "sha1"))
15387         key_id[0] = HMAC_SHA_1_96;
15388       else if (!strcmp ((char *) s, "sha256"))
15389         key_id[0] = HMAC_SHA_256_128;
15390       else
15391         {
15392           clib_warning ("invalid key_id: '%s'", s);
15393           key_id[0] = HMAC_NO_KEY;
15394         }
15395     }
15396   else
15397     return 0;
15398
15399   vec_free (s);
15400   return 1;
15401 }
15402
15403 static int
15404 api_one_add_del_local_eid (vat_main_t * vam)
15405 {
15406   unformat_input_t *input = vam->input;
15407   vl_api_one_add_del_local_eid_t *mp;
15408   u8 is_add = 1;
15409   u8 eid_set = 0;
15410   lisp_eid_vat_t _eid, *eid = &_eid;
15411   u8 *locator_set_name = 0;
15412   u8 locator_set_name_set = 0;
15413   u32 vni = 0;
15414   u16 key_id = 0;
15415   u8 *key = 0;
15416   int ret;
15417
15418   /* Parse args required to build the message */
15419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15420     {
15421       if (unformat (input, "del"))
15422         {
15423           is_add = 0;
15424         }
15425       else if (unformat (input, "vni %d", &vni))
15426         {
15427           ;
15428         }
15429       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15430         {
15431           eid_set = 1;
15432         }
15433       else if (unformat (input, "locator-set %s", &locator_set_name))
15434         {
15435           locator_set_name_set = 1;
15436         }
15437       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15438         ;
15439       else if (unformat (input, "secret-key %_%v%_", &key))
15440         ;
15441       else
15442         break;
15443     }
15444
15445   if (locator_set_name_set == 0)
15446     {
15447       errmsg ("missing locator-set name");
15448       return -99;
15449     }
15450
15451   if (0 == eid_set)
15452     {
15453       errmsg ("EID address not set!");
15454       vec_free (locator_set_name);
15455       return -99;
15456     }
15457
15458   if (key && (0 == key_id))
15459     {
15460       errmsg ("invalid key_id!");
15461       return -99;
15462     }
15463
15464   if (vec_len (key) > 64)
15465     {
15466       errmsg ("key too long");
15467       vec_free (key);
15468       return -99;
15469     }
15470
15471   if (vec_len (locator_set_name) > 64)
15472     {
15473       errmsg ("locator-set name too long");
15474       vec_free (locator_set_name);
15475       return -99;
15476     }
15477   vec_add1 (locator_set_name, 0);
15478
15479   /* Construct the API message */
15480   M (ONE_ADD_DEL_LOCAL_EID, mp);
15481
15482   mp->is_add = is_add;
15483   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15484   mp->eid_type = eid->type;
15485   mp->prefix_len = eid->len;
15486   mp->vni = clib_host_to_net_u32 (vni);
15487   mp->key_id = clib_host_to_net_u16 (key_id);
15488   clib_memcpy (mp->locator_set_name, locator_set_name,
15489                vec_len (locator_set_name));
15490   clib_memcpy (mp->key, key, vec_len (key));
15491
15492   vec_free (locator_set_name);
15493   vec_free (key);
15494
15495   /* send it... */
15496   S (mp);
15497
15498   /* Wait for a reply... */
15499   W (ret);
15500   return ret;
15501 }
15502
15503 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15504
15505 static int
15506 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15507 {
15508   u32 dp_table = 0, vni = 0;;
15509   unformat_input_t *input = vam->input;
15510   vl_api_gpe_add_del_fwd_entry_t *mp;
15511   u8 is_add = 1;
15512   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15513   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15514   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15515   u32 action = ~0, w;
15516   ip4_address_t rmt_rloc4, lcl_rloc4;
15517   ip6_address_t rmt_rloc6, lcl_rloc6;
15518   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15519   int ret;
15520
15521   clib_memset (&rloc, 0, sizeof (rloc));
15522
15523   /* Parse args required to build the message */
15524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15525     {
15526       if (unformat (input, "del"))
15527         is_add = 0;
15528       else if (unformat (input, "add"))
15529         is_add = 1;
15530       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15531         {
15532           rmt_eid_set = 1;
15533         }
15534       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15535         {
15536           lcl_eid_set = 1;
15537         }
15538       else if (unformat (input, "vrf %d", &dp_table))
15539         ;
15540       else if (unformat (input, "bd %d", &dp_table))
15541         ;
15542       else if (unformat (input, "vni %d", &vni))
15543         ;
15544       else if (unformat (input, "w %d", &w))
15545         {
15546           if (!curr_rloc)
15547             {
15548               errmsg ("No RLOC configured for setting priority/weight!");
15549               return -99;
15550             }
15551           curr_rloc->weight = w;
15552         }
15553       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15554                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15555         {
15556           rloc.is_ip4 = 1;
15557
15558           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15559           rloc.weight = 0;
15560           vec_add1 (lcl_locs, rloc);
15561
15562           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15563           vec_add1 (rmt_locs, rloc);
15564           /* weight saved in rmt loc */
15565           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15566         }
15567       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15568                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15569         {
15570           rloc.is_ip4 = 0;
15571           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15572           rloc.weight = 0;
15573           vec_add1 (lcl_locs, rloc);
15574
15575           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15576           vec_add1 (rmt_locs, rloc);
15577           /* weight saved in rmt loc */
15578           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15579         }
15580       else if (unformat (input, "action %d", &action))
15581         {
15582           ;
15583         }
15584       else
15585         {
15586           clib_warning ("parse error '%U'", format_unformat_error, input);
15587           return -99;
15588         }
15589     }
15590
15591   if (!rmt_eid_set)
15592     {
15593       errmsg ("remote eid addresses not set");
15594       return -99;
15595     }
15596
15597   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15598     {
15599       errmsg ("eid types don't match");
15600       return -99;
15601     }
15602
15603   if (0 == rmt_locs && (u32) ~ 0 == action)
15604     {
15605       errmsg ("action not set for negative mapping");
15606       return -99;
15607     }
15608
15609   /* Construct the API message */
15610   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15611       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15612
15613   mp->is_add = is_add;
15614   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15615   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15616   mp->eid_type = rmt_eid->type;
15617   mp->dp_table = clib_host_to_net_u32 (dp_table);
15618   mp->vni = clib_host_to_net_u32 (vni);
15619   mp->rmt_len = rmt_eid->len;
15620   mp->lcl_len = lcl_eid->len;
15621   mp->action = action;
15622
15623   if (0 != rmt_locs && 0 != lcl_locs)
15624     {
15625       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15626       clib_memcpy (mp->locs, lcl_locs,
15627                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15628
15629       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15630       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15631                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15632     }
15633   vec_free (lcl_locs);
15634   vec_free (rmt_locs);
15635
15636   /* send it... */
15637   S (mp);
15638
15639   /* Wait for a reply... */
15640   W (ret);
15641   return ret;
15642 }
15643
15644 static int
15645 api_one_add_del_map_server (vat_main_t * vam)
15646 {
15647   unformat_input_t *input = vam->input;
15648   vl_api_one_add_del_map_server_t *mp;
15649   u8 is_add = 1;
15650   u8 ipv4_set = 0;
15651   u8 ipv6_set = 0;
15652   ip4_address_t ipv4;
15653   ip6_address_t ipv6;
15654   int ret;
15655
15656   /* Parse args required to build the message */
15657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15658     {
15659       if (unformat (input, "del"))
15660         {
15661           is_add = 0;
15662         }
15663       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15664         {
15665           ipv4_set = 1;
15666         }
15667       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15668         {
15669           ipv6_set = 1;
15670         }
15671       else
15672         break;
15673     }
15674
15675   if (ipv4_set && ipv6_set)
15676     {
15677       errmsg ("both eid v4 and v6 addresses set");
15678       return -99;
15679     }
15680
15681   if (!ipv4_set && !ipv6_set)
15682     {
15683       errmsg ("eid addresses not set");
15684       return -99;
15685     }
15686
15687   /* Construct the API message */
15688   M (ONE_ADD_DEL_MAP_SERVER, mp);
15689
15690   mp->is_add = is_add;
15691   if (ipv6_set)
15692     {
15693       mp->is_ipv6 = 1;
15694       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15695     }
15696   else
15697     {
15698       mp->is_ipv6 = 0;
15699       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15700     }
15701
15702   /* send it... */
15703   S (mp);
15704
15705   /* Wait for a reply... */
15706   W (ret);
15707   return ret;
15708 }
15709
15710 #define api_lisp_add_del_map_server api_one_add_del_map_server
15711
15712 static int
15713 api_one_add_del_map_resolver (vat_main_t * vam)
15714 {
15715   unformat_input_t *input = vam->input;
15716   vl_api_one_add_del_map_resolver_t *mp;
15717   u8 is_add = 1;
15718   u8 ipv4_set = 0;
15719   u8 ipv6_set = 0;
15720   ip4_address_t ipv4;
15721   ip6_address_t ipv6;
15722   int ret;
15723
15724   /* Parse args required to build the message */
15725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15726     {
15727       if (unformat (input, "del"))
15728         {
15729           is_add = 0;
15730         }
15731       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15732         {
15733           ipv4_set = 1;
15734         }
15735       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15736         {
15737           ipv6_set = 1;
15738         }
15739       else
15740         break;
15741     }
15742
15743   if (ipv4_set && ipv6_set)
15744     {
15745       errmsg ("both eid v4 and v6 addresses set");
15746       return -99;
15747     }
15748
15749   if (!ipv4_set && !ipv6_set)
15750     {
15751       errmsg ("eid addresses not set");
15752       return -99;
15753     }
15754
15755   /* Construct the API message */
15756   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15757
15758   mp->is_add = is_add;
15759   if (ipv6_set)
15760     {
15761       mp->is_ipv6 = 1;
15762       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15763     }
15764   else
15765     {
15766       mp->is_ipv6 = 0;
15767       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15768     }
15769
15770   /* send it... */
15771   S (mp);
15772
15773   /* Wait for a reply... */
15774   W (ret);
15775   return ret;
15776 }
15777
15778 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15779
15780 static int
15781 api_lisp_gpe_enable_disable (vat_main_t * vam)
15782 {
15783   unformat_input_t *input = vam->input;
15784   vl_api_gpe_enable_disable_t *mp;
15785   u8 is_set = 0;
15786   u8 is_en = 1;
15787   int ret;
15788
15789   /* Parse args required to build the message */
15790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15791     {
15792       if (unformat (input, "enable"))
15793         {
15794           is_set = 1;
15795           is_en = 1;
15796         }
15797       else if (unformat (input, "disable"))
15798         {
15799           is_set = 1;
15800           is_en = 0;
15801         }
15802       else
15803         break;
15804     }
15805
15806   if (is_set == 0)
15807     {
15808       errmsg ("Value not set");
15809       return -99;
15810     }
15811
15812   /* Construct the API message */
15813   M (GPE_ENABLE_DISABLE, mp);
15814
15815   mp->is_en = is_en;
15816
15817   /* send it... */
15818   S (mp);
15819
15820   /* Wait for a reply... */
15821   W (ret);
15822   return ret;
15823 }
15824
15825 static int
15826 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15827 {
15828   unformat_input_t *input = vam->input;
15829   vl_api_one_rloc_probe_enable_disable_t *mp;
15830   u8 is_set = 0;
15831   u8 is_en = 0;
15832   int ret;
15833
15834   /* Parse args required to build the message */
15835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15836     {
15837       if (unformat (input, "enable"))
15838         {
15839           is_set = 1;
15840           is_en = 1;
15841         }
15842       else if (unformat (input, "disable"))
15843         is_set = 1;
15844       else
15845         break;
15846     }
15847
15848   if (!is_set)
15849     {
15850       errmsg ("Value not set");
15851       return -99;
15852     }
15853
15854   /* Construct the API message */
15855   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15856
15857   mp->is_enabled = is_en;
15858
15859   /* send it... */
15860   S (mp);
15861
15862   /* Wait for a reply... */
15863   W (ret);
15864   return ret;
15865 }
15866
15867 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15868
15869 static int
15870 api_one_map_register_enable_disable (vat_main_t * vam)
15871 {
15872   unformat_input_t *input = vam->input;
15873   vl_api_one_map_register_enable_disable_t *mp;
15874   u8 is_set = 0;
15875   u8 is_en = 0;
15876   int ret;
15877
15878   /* Parse args required to build the message */
15879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15880     {
15881       if (unformat (input, "enable"))
15882         {
15883           is_set = 1;
15884           is_en = 1;
15885         }
15886       else if (unformat (input, "disable"))
15887         is_set = 1;
15888       else
15889         break;
15890     }
15891
15892   if (!is_set)
15893     {
15894       errmsg ("Value not set");
15895       return -99;
15896     }
15897
15898   /* Construct the API message */
15899   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15900
15901   mp->is_enabled = is_en;
15902
15903   /* send it... */
15904   S (mp);
15905
15906   /* Wait for a reply... */
15907   W (ret);
15908   return ret;
15909 }
15910
15911 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15912
15913 static int
15914 api_one_enable_disable (vat_main_t * vam)
15915 {
15916   unformat_input_t *input = vam->input;
15917   vl_api_one_enable_disable_t *mp;
15918   u8 is_set = 0;
15919   u8 is_en = 0;
15920   int ret;
15921
15922   /* Parse args required to build the message */
15923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15924     {
15925       if (unformat (input, "enable"))
15926         {
15927           is_set = 1;
15928           is_en = 1;
15929         }
15930       else if (unformat (input, "disable"))
15931         {
15932           is_set = 1;
15933         }
15934       else
15935         break;
15936     }
15937
15938   if (!is_set)
15939     {
15940       errmsg ("Value not set");
15941       return -99;
15942     }
15943
15944   /* Construct the API message */
15945   M (ONE_ENABLE_DISABLE, mp);
15946
15947   mp->is_en = is_en;
15948
15949   /* send it... */
15950   S (mp);
15951
15952   /* Wait for a reply... */
15953   W (ret);
15954   return ret;
15955 }
15956
15957 #define api_lisp_enable_disable api_one_enable_disable
15958
15959 static int
15960 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15961 {
15962   unformat_input_t *input = vam->input;
15963   vl_api_one_enable_disable_xtr_mode_t *mp;
15964   u8 is_set = 0;
15965   u8 is_en = 0;
15966   int ret;
15967
15968   /* Parse args required to build the message */
15969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15970     {
15971       if (unformat (input, "enable"))
15972         {
15973           is_set = 1;
15974           is_en = 1;
15975         }
15976       else if (unformat (input, "disable"))
15977         {
15978           is_set = 1;
15979         }
15980       else
15981         break;
15982     }
15983
15984   if (!is_set)
15985     {
15986       errmsg ("Value not set");
15987       return -99;
15988     }
15989
15990   /* Construct the API message */
15991   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15992
15993   mp->is_en = is_en;
15994
15995   /* send it... */
15996   S (mp);
15997
15998   /* Wait for a reply... */
15999   W (ret);
16000   return ret;
16001 }
16002
16003 static int
16004 api_one_show_xtr_mode (vat_main_t * vam)
16005 {
16006   vl_api_one_show_xtr_mode_t *mp;
16007   int ret;
16008
16009   /* Construct the API message */
16010   M (ONE_SHOW_XTR_MODE, mp);
16011
16012   /* send it... */
16013   S (mp);
16014
16015   /* Wait for a reply... */
16016   W (ret);
16017   return ret;
16018 }
16019
16020 static int
16021 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16022 {
16023   unformat_input_t *input = vam->input;
16024   vl_api_one_enable_disable_pitr_mode_t *mp;
16025   u8 is_set = 0;
16026   u8 is_en = 0;
16027   int ret;
16028
16029   /* Parse args required to build the message */
16030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16031     {
16032       if (unformat (input, "enable"))
16033         {
16034           is_set = 1;
16035           is_en = 1;
16036         }
16037       else if (unformat (input, "disable"))
16038         {
16039           is_set = 1;
16040         }
16041       else
16042         break;
16043     }
16044
16045   if (!is_set)
16046     {
16047       errmsg ("Value not set");
16048       return -99;
16049     }
16050
16051   /* Construct the API message */
16052   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16053
16054   mp->is_en = is_en;
16055
16056   /* send it... */
16057   S (mp);
16058
16059   /* Wait for a reply... */
16060   W (ret);
16061   return ret;
16062 }
16063
16064 static int
16065 api_one_show_pitr_mode (vat_main_t * vam)
16066 {
16067   vl_api_one_show_pitr_mode_t *mp;
16068   int ret;
16069
16070   /* Construct the API message */
16071   M (ONE_SHOW_PITR_MODE, mp);
16072
16073   /* send it... */
16074   S (mp);
16075
16076   /* Wait for a reply... */
16077   W (ret);
16078   return ret;
16079 }
16080
16081 static int
16082 api_one_enable_disable_petr_mode (vat_main_t * vam)
16083 {
16084   unformat_input_t *input = vam->input;
16085   vl_api_one_enable_disable_petr_mode_t *mp;
16086   u8 is_set = 0;
16087   u8 is_en = 0;
16088   int ret;
16089
16090   /* Parse args required to build the message */
16091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16092     {
16093       if (unformat (input, "enable"))
16094         {
16095           is_set = 1;
16096           is_en = 1;
16097         }
16098       else if (unformat (input, "disable"))
16099         {
16100           is_set = 1;
16101         }
16102       else
16103         break;
16104     }
16105
16106   if (!is_set)
16107     {
16108       errmsg ("Value not set");
16109       return -99;
16110     }
16111
16112   /* Construct the API message */
16113   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16114
16115   mp->is_en = is_en;
16116
16117   /* send it... */
16118   S (mp);
16119
16120   /* Wait for a reply... */
16121   W (ret);
16122   return ret;
16123 }
16124
16125 static int
16126 api_one_show_petr_mode (vat_main_t * vam)
16127 {
16128   vl_api_one_show_petr_mode_t *mp;
16129   int ret;
16130
16131   /* Construct the API message */
16132   M (ONE_SHOW_PETR_MODE, mp);
16133
16134   /* send it... */
16135   S (mp);
16136
16137   /* Wait for a reply... */
16138   W (ret);
16139   return ret;
16140 }
16141
16142 static int
16143 api_show_one_map_register_state (vat_main_t * vam)
16144 {
16145   vl_api_show_one_map_register_state_t *mp;
16146   int ret;
16147
16148   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16149
16150   /* send */
16151   S (mp);
16152
16153   /* wait for reply */
16154   W (ret);
16155   return ret;
16156 }
16157
16158 #define api_show_lisp_map_register_state api_show_one_map_register_state
16159
16160 static int
16161 api_show_one_rloc_probe_state (vat_main_t * vam)
16162 {
16163   vl_api_show_one_rloc_probe_state_t *mp;
16164   int ret;
16165
16166   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16167
16168   /* send */
16169   S (mp);
16170
16171   /* wait for reply */
16172   W (ret);
16173   return ret;
16174 }
16175
16176 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16177
16178 static int
16179 api_one_add_del_ndp_entry (vat_main_t * vam)
16180 {
16181   vl_api_one_add_del_ndp_entry_t *mp;
16182   unformat_input_t *input = vam->input;
16183   u8 is_add = 1;
16184   u8 mac_set = 0;
16185   u8 bd_set = 0;
16186   u8 ip_set = 0;
16187   u8 mac[6] = { 0, };
16188   u8 ip6[16] = { 0, };
16189   u32 bd = ~0;
16190   int ret;
16191
16192   /* Parse args required to build the message */
16193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16194     {
16195       if (unformat (input, "del"))
16196         is_add = 0;
16197       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16198         mac_set = 1;
16199       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16200         ip_set = 1;
16201       else if (unformat (input, "bd %d", &bd))
16202         bd_set = 1;
16203       else
16204         {
16205           errmsg ("parse error '%U'", format_unformat_error, input);
16206           return -99;
16207         }
16208     }
16209
16210   if (!bd_set || !ip_set || (!mac_set && is_add))
16211     {
16212       errmsg ("Missing BD, IP or MAC!");
16213       return -99;
16214     }
16215
16216   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16217   mp->is_add = is_add;
16218   clib_memcpy (mp->mac, mac, 6);
16219   mp->bd = clib_host_to_net_u32 (bd);
16220   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16221
16222   /* send */
16223   S (mp);
16224
16225   /* wait for reply */
16226   W (ret);
16227   return ret;
16228 }
16229
16230 static int
16231 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16232 {
16233   vl_api_one_add_del_l2_arp_entry_t *mp;
16234   unformat_input_t *input = vam->input;
16235   u8 is_add = 1;
16236   u8 mac_set = 0;
16237   u8 bd_set = 0;
16238   u8 ip_set = 0;
16239   u8 mac[6] = { 0, };
16240   u32 ip4 = 0, bd = ~0;
16241   int ret;
16242
16243   /* Parse args required to build the message */
16244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (input, "del"))
16247         is_add = 0;
16248       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16249         mac_set = 1;
16250       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16251         ip_set = 1;
16252       else if (unformat (input, "bd %d", &bd))
16253         bd_set = 1;
16254       else
16255         {
16256           errmsg ("parse error '%U'", format_unformat_error, input);
16257           return -99;
16258         }
16259     }
16260
16261   if (!bd_set || !ip_set || (!mac_set && is_add))
16262     {
16263       errmsg ("Missing BD, IP or MAC!");
16264       return -99;
16265     }
16266
16267   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16268   mp->is_add = is_add;
16269   clib_memcpy (mp->mac, mac, 6);
16270   mp->bd = clib_host_to_net_u32 (bd);
16271   mp->ip4 = ip4;
16272
16273   /* send */
16274   S (mp);
16275
16276   /* wait for reply */
16277   W (ret);
16278   return ret;
16279 }
16280
16281 static int
16282 api_one_ndp_bd_get (vat_main_t * vam)
16283 {
16284   vl_api_one_ndp_bd_get_t *mp;
16285   int ret;
16286
16287   M (ONE_NDP_BD_GET, mp);
16288
16289   /* send */
16290   S (mp);
16291
16292   /* wait for reply */
16293   W (ret);
16294   return ret;
16295 }
16296
16297 static int
16298 api_one_ndp_entries_get (vat_main_t * vam)
16299 {
16300   vl_api_one_ndp_entries_get_t *mp;
16301   unformat_input_t *input = vam->input;
16302   u8 bd_set = 0;
16303   u32 bd = ~0;
16304   int ret;
16305
16306   /* Parse args required to build the message */
16307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16308     {
16309       if (unformat (input, "bd %d", &bd))
16310         bd_set = 1;
16311       else
16312         {
16313           errmsg ("parse error '%U'", format_unformat_error, input);
16314           return -99;
16315         }
16316     }
16317
16318   if (!bd_set)
16319     {
16320       errmsg ("Expected bridge domain!");
16321       return -99;
16322     }
16323
16324   M (ONE_NDP_ENTRIES_GET, mp);
16325   mp->bd = clib_host_to_net_u32 (bd);
16326
16327   /* send */
16328   S (mp);
16329
16330   /* wait for reply */
16331   W (ret);
16332   return ret;
16333 }
16334
16335 static int
16336 api_one_l2_arp_bd_get (vat_main_t * vam)
16337 {
16338   vl_api_one_l2_arp_bd_get_t *mp;
16339   int ret;
16340
16341   M (ONE_L2_ARP_BD_GET, mp);
16342
16343   /* send */
16344   S (mp);
16345
16346   /* wait for reply */
16347   W (ret);
16348   return ret;
16349 }
16350
16351 static int
16352 api_one_l2_arp_entries_get (vat_main_t * vam)
16353 {
16354   vl_api_one_l2_arp_entries_get_t *mp;
16355   unformat_input_t *input = vam->input;
16356   u8 bd_set = 0;
16357   u32 bd = ~0;
16358   int ret;
16359
16360   /* Parse args required to build the message */
16361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16362     {
16363       if (unformat (input, "bd %d", &bd))
16364         bd_set = 1;
16365       else
16366         {
16367           errmsg ("parse error '%U'", format_unformat_error, input);
16368           return -99;
16369         }
16370     }
16371
16372   if (!bd_set)
16373     {
16374       errmsg ("Expected bridge domain!");
16375       return -99;
16376     }
16377
16378   M (ONE_L2_ARP_ENTRIES_GET, mp);
16379   mp->bd = clib_host_to_net_u32 (bd);
16380
16381   /* send */
16382   S (mp);
16383
16384   /* wait for reply */
16385   W (ret);
16386   return ret;
16387 }
16388
16389 static int
16390 api_one_stats_enable_disable (vat_main_t * vam)
16391 {
16392   vl_api_one_stats_enable_disable_t *mp;
16393   unformat_input_t *input = vam->input;
16394   u8 is_set = 0;
16395   u8 is_en = 0;
16396   int ret;
16397
16398   /* Parse args required to build the message */
16399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16400     {
16401       if (unformat (input, "enable"))
16402         {
16403           is_set = 1;
16404           is_en = 1;
16405         }
16406       else if (unformat (input, "disable"))
16407         {
16408           is_set = 1;
16409         }
16410       else
16411         break;
16412     }
16413
16414   if (!is_set)
16415     {
16416       errmsg ("Value not set");
16417       return -99;
16418     }
16419
16420   M (ONE_STATS_ENABLE_DISABLE, mp);
16421   mp->is_en = is_en;
16422
16423   /* send */
16424   S (mp);
16425
16426   /* wait for reply */
16427   W (ret);
16428   return ret;
16429 }
16430
16431 static int
16432 api_show_one_stats_enable_disable (vat_main_t * vam)
16433 {
16434   vl_api_show_one_stats_enable_disable_t *mp;
16435   int ret;
16436
16437   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16438
16439   /* send */
16440   S (mp);
16441
16442   /* wait for reply */
16443   W (ret);
16444   return ret;
16445 }
16446
16447 static int
16448 api_show_one_map_request_mode (vat_main_t * vam)
16449 {
16450   vl_api_show_one_map_request_mode_t *mp;
16451   int ret;
16452
16453   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16454
16455   /* send */
16456   S (mp);
16457
16458   /* wait for reply */
16459   W (ret);
16460   return ret;
16461 }
16462
16463 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16464
16465 static int
16466 api_one_map_request_mode (vat_main_t * vam)
16467 {
16468   unformat_input_t *input = vam->input;
16469   vl_api_one_map_request_mode_t *mp;
16470   u8 mode = 0;
16471   int ret;
16472
16473   /* Parse args required to build the message */
16474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16475     {
16476       if (unformat (input, "dst-only"))
16477         mode = 0;
16478       else if (unformat (input, "src-dst"))
16479         mode = 1;
16480       else
16481         {
16482           errmsg ("parse error '%U'", format_unformat_error, input);
16483           return -99;
16484         }
16485     }
16486
16487   M (ONE_MAP_REQUEST_MODE, mp);
16488
16489   mp->mode = mode;
16490
16491   /* send */
16492   S (mp);
16493
16494   /* wait for reply */
16495   W (ret);
16496   return ret;
16497 }
16498
16499 #define api_lisp_map_request_mode api_one_map_request_mode
16500
16501 /**
16502  * Enable/disable ONE proxy ITR.
16503  *
16504  * @param vam vpp API test context
16505  * @return return code
16506  */
16507 static int
16508 api_one_pitr_set_locator_set (vat_main_t * vam)
16509 {
16510   u8 ls_name_set = 0;
16511   unformat_input_t *input = vam->input;
16512   vl_api_one_pitr_set_locator_set_t *mp;
16513   u8 is_add = 1;
16514   u8 *ls_name = 0;
16515   int ret;
16516
16517   /* Parse args required to build the message */
16518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16519     {
16520       if (unformat (input, "del"))
16521         is_add = 0;
16522       else if (unformat (input, "locator-set %s", &ls_name))
16523         ls_name_set = 1;
16524       else
16525         {
16526           errmsg ("parse error '%U'", format_unformat_error, input);
16527           return -99;
16528         }
16529     }
16530
16531   if (!ls_name_set)
16532     {
16533       errmsg ("locator-set name not set!");
16534       return -99;
16535     }
16536
16537   M (ONE_PITR_SET_LOCATOR_SET, mp);
16538
16539   mp->is_add = is_add;
16540   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16541   vec_free (ls_name);
16542
16543   /* send */
16544   S (mp);
16545
16546   /* wait for reply */
16547   W (ret);
16548   return ret;
16549 }
16550
16551 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16552
16553 static int
16554 api_one_nsh_set_locator_set (vat_main_t * vam)
16555 {
16556   u8 ls_name_set = 0;
16557   unformat_input_t *input = vam->input;
16558   vl_api_one_nsh_set_locator_set_t *mp;
16559   u8 is_add = 1;
16560   u8 *ls_name = 0;
16561   int ret;
16562
16563   /* Parse args required to build the message */
16564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16565     {
16566       if (unformat (input, "del"))
16567         is_add = 0;
16568       else if (unformat (input, "ls %s", &ls_name))
16569         ls_name_set = 1;
16570       else
16571         {
16572           errmsg ("parse error '%U'", format_unformat_error, input);
16573           return -99;
16574         }
16575     }
16576
16577   if (!ls_name_set && is_add)
16578     {
16579       errmsg ("locator-set name not set!");
16580       return -99;
16581     }
16582
16583   M (ONE_NSH_SET_LOCATOR_SET, mp);
16584
16585   mp->is_add = is_add;
16586   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16587   vec_free (ls_name);
16588
16589   /* send */
16590   S (mp);
16591
16592   /* wait for reply */
16593   W (ret);
16594   return ret;
16595 }
16596
16597 static int
16598 api_show_one_pitr (vat_main_t * vam)
16599 {
16600   vl_api_show_one_pitr_t *mp;
16601   int ret;
16602
16603   if (!vam->json_output)
16604     {
16605       print (vam->ofp, "%=20s", "lisp status:");
16606     }
16607
16608   M (SHOW_ONE_PITR, mp);
16609   /* send it... */
16610   S (mp);
16611
16612   /* Wait for a reply... */
16613   W (ret);
16614   return ret;
16615 }
16616
16617 #define api_show_lisp_pitr api_show_one_pitr
16618
16619 static int
16620 api_one_use_petr (vat_main_t * vam)
16621 {
16622   unformat_input_t *input = vam->input;
16623   vl_api_one_use_petr_t *mp;
16624   u8 is_add = 0;
16625   ip_address_t ip;
16626   int ret;
16627
16628   clib_memset (&ip, 0, sizeof (ip));
16629
16630   /* Parse args required to build the message */
16631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16632     {
16633       if (unformat (input, "disable"))
16634         is_add = 0;
16635       else
16636         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16637         {
16638           is_add = 1;
16639           ip_addr_version (&ip) = IP4;
16640         }
16641       else
16642         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16643         {
16644           is_add = 1;
16645           ip_addr_version (&ip) = IP6;
16646         }
16647       else
16648         {
16649           errmsg ("parse error '%U'", format_unformat_error, input);
16650           return -99;
16651         }
16652     }
16653
16654   M (ONE_USE_PETR, mp);
16655
16656   mp->is_add = is_add;
16657   if (is_add)
16658     {
16659       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16660       if (mp->is_ip4)
16661         clib_memcpy (mp->address, &ip, 4);
16662       else
16663         clib_memcpy (mp->address, &ip, 16);
16664     }
16665
16666   /* send */
16667   S (mp);
16668
16669   /* wait for reply */
16670   W (ret);
16671   return ret;
16672 }
16673
16674 #define api_lisp_use_petr api_one_use_petr
16675
16676 static int
16677 api_show_one_nsh_mapping (vat_main_t * vam)
16678 {
16679   vl_api_show_one_use_petr_t *mp;
16680   int ret;
16681
16682   if (!vam->json_output)
16683     {
16684       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16685     }
16686
16687   M (SHOW_ONE_NSH_MAPPING, mp);
16688   /* send it... */
16689   S (mp);
16690
16691   /* Wait for a reply... */
16692   W (ret);
16693   return ret;
16694 }
16695
16696 static int
16697 api_show_one_use_petr (vat_main_t * vam)
16698 {
16699   vl_api_show_one_use_petr_t *mp;
16700   int ret;
16701
16702   if (!vam->json_output)
16703     {
16704       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16705     }
16706
16707   M (SHOW_ONE_USE_PETR, mp);
16708   /* send it... */
16709   S (mp);
16710
16711   /* Wait for a reply... */
16712   W (ret);
16713   return ret;
16714 }
16715
16716 #define api_show_lisp_use_petr api_show_one_use_petr
16717
16718 /**
16719  * Add/delete mapping between vni and vrf
16720  */
16721 static int
16722 api_one_eid_table_add_del_map (vat_main_t * vam)
16723 {
16724   unformat_input_t *input = vam->input;
16725   vl_api_one_eid_table_add_del_map_t *mp;
16726   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16727   u32 vni, vrf, bd_index;
16728   int ret;
16729
16730   /* Parse args required to build the message */
16731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16732     {
16733       if (unformat (input, "del"))
16734         is_add = 0;
16735       else if (unformat (input, "vrf %d", &vrf))
16736         vrf_set = 1;
16737       else if (unformat (input, "bd_index %d", &bd_index))
16738         bd_index_set = 1;
16739       else if (unformat (input, "vni %d", &vni))
16740         vni_set = 1;
16741       else
16742         break;
16743     }
16744
16745   if (!vni_set || (!vrf_set && !bd_index_set))
16746     {
16747       errmsg ("missing arguments!");
16748       return -99;
16749     }
16750
16751   if (vrf_set && bd_index_set)
16752     {
16753       errmsg ("error: both vrf and bd entered!");
16754       return -99;
16755     }
16756
16757   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16758
16759   mp->is_add = is_add;
16760   mp->vni = htonl (vni);
16761   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16762   mp->is_l2 = bd_index_set;
16763
16764   /* send */
16765   S (mp);
16766
16767   /* wait for reply */
16768   W (ret);
16769   return ret;
16770 }
16771
16772 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16773
16774 uword
16775 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16776 {
16777   u32 *action = va_arg (*args, u32 *);
16778   u8 *s = 0;
16779
16780   if (unformat (input, "%s", &s))
16781     {
16782       if (!strcmp ((char *) s, "no-action"))
16783         action[0] = 0;
16784       else if (!strcmp ((char *) s, "natively-forward"))
16785         action[0] = 1;
16786       else if (!strcmp ((char *) s, "send-map-request"))
16787         action[0] = 2;
16788       else if (!strcmp ((char *) s, "drop"))
16789         action[0] = 3;
16790       else
16791         {
16792           clib_warning ("invalid action: '%s'", s);
16793           action[0] = 3;
16794         }
16795     }
16796   else
16797     return 0;
16798
16799   vec_free (s);
16800   return 1;
16801 }
16802
16803 /**
16804  * Add/del remote mapping to/from ONE control plane
16805  *
16806  * @param vam vpp API test context
16807  * @return return code
16808  */
16809 static int
16810 api_one_add_del_remote_mapping (vat_main_t * vam)
16811 {
16812   unformat_input_t *input = vam->input;
16813   vl_api_one_add_del_remote_mapping_t *mp;
16814   u32 vni = 0;
16815   lisp_eid_vat_t _eid, *eid = &_eid;
16816   lisp_eid_vat_t _seid, *seid = &_seid;
16817   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16818   u32 action = ~0, p, w, data_len;
16819   ip4_address_t rloc4;
16820   ip6_address_t rloc6;
16821   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16822   int ret;
16823
16824   clib_memset (&rloc, 0, sizeof (rloc));
16825
16826   /* Parse args required to build the message */
16827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16828     {
16829       if (unformat (input, "del-all"))
16830         {
16831           del_all = 1;
16832         }
16833       else if (unformat (input, "del"))
16834         {
16835           is_add = 0;
16836         }
16837       else if (unformat (input, "add"))
16838         {
16839           is_add = 1;
16840         }
16841       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16842         {
16843           eid_set = 1;
16844         }
16845       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16846         {
16847           seid_set = 1;
16848         }
16849       else if (unformat (input, "vni %d", &vni))
16850         {
16851           ;
16852         }
16853       else if (unformat (input, "p %d w %d", &p, &w))
16854         {
16855           if (!curr_rloc)
16856             {
16857               errmsg ("No RLOC configured for setting priority/weight!");
16858               return -99;
16859             }
16860           curr_rloc->priority = p;
16861           curr_rloc->weight = w;
16862         }
16863       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16864         {
16865           rloc.is_ip4 = 1;
16866           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16867           vec_add1 (rlocs, rloc);
16868           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16869         }
16870       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16871         {
16872           rloc.is_ip4 = 0;
16873           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16874           vec_add1 (rlocs, rloc);
16875           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16876         }
16877       else if (unformat (input, "action %U",
16878                          unformat_negative_mapping_action, &action))
16879         {
16880           ;
16881         }
16882       else
16883         {
16884           clib_warning ("parse error '%U'", format_unformat_error, input);
16885           return -99;
16886         }
16887     }
16888
16889   if (0 == eid_set)
16890     {
16891       errmsg ("missing params!");
16892       return -99;
16893     }
16894
16895   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16896     {
16897       errmsg ("no action set for negative map-reply!");
16898       return -99;
16899     }
16900
16901   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16902
16903   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16904   mp->is_add = is_add;
16905   mp->vni = htonl (vni);
16906   mp->action = (u8) action;
16907   mp->is_src_dst = seid_set;
16908   mp->eid_len = eid->len;
16909   mp->seid_len = seid->len;
16910   mp->del_all = del_all;
16911   mp->eid_type = eid->type;
16912   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16913   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16914
16915   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16916   clib_memcpy (mp->rlocs, rlocs, data_len);
16917   vec_free (rlocs);
16918
16919   /* send it... */
16920   S (mp);
16921
16922   /* Wait for a reply... */
16923   W (ret);
16924   return ret;
16925 }
16926
16927 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16928
16929 /**
16930  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16931  * forwarding entries in data-plane accordingly.
16932  *
16933  * @param vam vpp API test context
16934  * @return return code
16935  */
16936 static int
16937 api_one_add_del_adjacency (vat_main_t * vam)
16938 {
16939   unformat_input_t *input = vam->input;
16940   vl_api_one_add_del_adjacency_t *mp;
16941   u32 vni = 0;
16942   ip4_address_t leid4, reid4;
16943   ip6_address_t leid6, reid6;
16944   u8 reid_mac[6] = { 0 };
16945   u8 leid_mac[6] = { 0 };
16946   u8 reid_type, leid_type;
16947   u32 leid_len = 0, reid_len = 0, len;
16948   u8 is_add = 1;
16949   int ret;
16950
16951   leid_type = reid_type = (u8) ~ 0;
16952
16953   /* Parse args required to build the message */
16954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16955     {
16956       if (unformat (input, "del"))
16957         {
16958           is_add = 0;
16959         }
16960       else if (unformat (input, "add"))
16961         {
16962           is_add = 1;
16963         }
16964       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16965                          &reid4, &len))
16966         {
16967           reid_type = 0;        /* ipv4 */
16968           reid_len = len;
16969         }
16970       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16971                          &reid6, &len))
16972         {
16973           reid_type = 1;        /* ipv6 */
16974           reid_len = len;
16975         }
16976       else if (unformat (input, "reid %U", unformat_ethernet_address,
16977                          reid_mac))
16978         {
16979           reid_type = 2;        /* mac */
16980         }
16981       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16982                          &leid4, &len))
16983         {
16984           leid_type = 0;        /* ipv4 */
16985           leid_len = len;
16986         }
16987       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16988                          &leid6, &len))
16989         {
16990           leid_type = 1;        /* ipv6 */
16991           leid_len = len;
16992         }
16993       else if (unformat (input, "leid %U", unformat_ethernet_address,
16994                          leid_mac))
16995         {
16996           leid_type = 2;        /* mac */
16997         }
16998       else if (unformat (input, "vni %d", &vni))
16999         {
17000           ;
17001         }
17002       else
17003         {
17004           errmsg ("parse error '%U'", format_unformat_error, input);
17005           return -99;
17006         }
17007     }
17008
17009   if ((u8) ~ 0 == reid_type)
17010     {
17011       errmsg ("missing params!");
17012       return -99;
17013     }
17014
17015   if (leid_type != reid_type)
17016     {
17017       errmsg ("remote and local EIDs are of different types!");
17018       return -99;
17019     }
17020
17021   M (ONE_ADD_DEL_ADJACENCY, mp);
17022   mp->is_add = is_add;
17023   mp->vni = htonl (vni);
17024   mp->leid_len = leid_len;
17025   mp->reid_len = reid_len;
17026   mp->eid_type = reid_type;
17027
17028   switch (mp->eid_type)
17029     {
17030     case 0:
17031       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17032       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17033       break;
17034     case 1:
17035       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17036       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17037       break;
17038     case 2:
17039       clib_memcpy (mp->leid, leid_mac, 6);
17040       clib_memcpy (mp->reid, reid_mac, 6);
17041       break;
17042     default:
17043       errmsg ("unknown EID type %d!", mp->eid_type);
17044       return 0;
17045     }
17046
17047   /* send it... */
17048   S (mp);
17049
17050   /* Wait for a reply... */
17051   W (ret);
17052   return ret;
17053 }
17054
17055 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17056
17057 uword
17058 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17059 {
17060   u32 *mode = va_arg (*args, u32 *);
17061
17062   if (unformat (input, "lisp"))
17063     *mode = 0;
17064   else if (unformat (input, "vxlan"))
17065     *mode = 1;
17066   else
17067     return 0;
17068
17069   return 1;
17070 }
17071
17072 static int
17073 api_gpe_get_encap_mode (vat_main_t * vam)
17074 {
17075   vl_api_gpe_get_encap_mode_t *mp;
17076   int ret;
17077
17078   /* Construct the API message */
17079   M (GPE_GET_ENCAP_MODE, mp);
17080
17081   /* send it... */
17082   S (mp);
17083
17084   /* Wait for a reply... */
17085   W (ret);
17086   return ret;
17087 }
17088
17089 static int
17090 api_gpe_set_encap_mode (vat_main_t * vam)
17091 {
17092   unformat_input_t *input = vam->input;
17093   vl_api_gpe_set_encap_mode_t *mp;
17094   int ret;
17095   u32 mode = 0;
17096
17097   /* Parse args required to build the message */
17098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17099     {
17100       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17101         ;
17102       else
17103         break;
17104     }
17105
17106   /* Construct the API message */
17107   M (GPE_SET_ENCAP_MODE, mp);
17108
17109   mp->mode = mode;
17110
17111   /* send it... */
17112   S (mp);
17113
17114   /* Wait for a reply... */
17115   W (ret);
17116   return ret;
17117 }
17118
17119 static int
17120 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17121 {
17122   unformat_input_t *input = vam->input;
17123   vl_api_gpe_add_del_iface_t *mp;
17124   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17125   u32 dp_table = 0, vni = 0;
17126   int ret;
17127
17128   /* Parse args required to build the message */
17129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17130     {
17131       if (unformat (input, "up"))
17132         {
17133           action_set = 1;
17134           is_add = 1;
17135         }
17136       else if (unformat (input, "down"))
17137         {
17138           action_set = 1;
17139           is_add = 0;
17140         }
17141       else if (unformat (input, "table_id %d", &dp_table))
17142         {
17143           dp_table_set = 1;
17144         }
17145       else if (unformat (input, "bd_id %d", &dp_table))
17146         {
17147           dp_table_set = 1;
17148           is_l2 = 1;
17149         }
17150       else if (unformat (input, "vni %d", &vni))
17151         {
17152           vni_set = 1;
17153         }
17154       else
17155         break;
17156     }
17157
17158   if (action_set == 0)
17159     {
17160       errmsg ("Action not set");
17161       return -99;
17162     }
17163   if (dp_table_set == 0 || vni_set == 0)
17164     {
17165       errmsg ("vni and dp_table must be set");
17166       return -99;
17167     }
17168
17169   /* Construct the API message */
17170   M (GPE_ADD_DEL_IFACE, mp);
17171
17172   mp->is_add = is_add;
17173   mp->dp_table = clib_host_to_net_u32 (dp_table);
17174   mp->is_l2 = is_l2;
17175   mp->vni = clib_host_to_net_u32 (vni);
17176
17177   /* send it... */
17178   S (mp);
17179
17180   /* Wait for a reply... */
17181   W (ret);
17182   return ret;
17183 }
17184
17185 static int
17186 api_one_map_register_fallback_threshold (vat_main_t * vam)
17187 {
17188   unformat_input_t *input = vam->input;
17189   vl_api_one_map_register_fallback_threshold_t *mp;
17190   u32 value = 0;
17191   u8 is_set = 0;
17192   int ret;
17193
17194   /* Parse args required to build the message */
17195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17196     {
17197       if (unformat (input, "%u", &value))
17198         is_set = 1;
17199       else
17200         {
17201           clib_warning ("parse error '%U'", format_unformat_error, input);
17202           return -99;
17203         }
17204     }
17205
17206   if (!is_set)
17207     {
17208       errmsg ("fallback threshold value is missing!");
17209       return -99;
17210     }
17211
17212   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17213   mp->value = clib_host_to_net_u32 (value);
17214
17215   /* send it... */
17216   S (mp);
17217
17218   /* Wait for a reply... */
17219   W (ret);
17220   return ret;
17221 }
17222
17223 static int
17224 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17225 {
17226   vl_api_show_one_map_register_fallback_threshold_t *mp;
17227   int ret;
17228
17229   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17230
17231   /* send it... */
17232   S (mp);
17233
17234   /* Wait for a reply... */
17235   W (ret);
17236   return ret;
17237 }
17238
17239 uword
17240 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17241 {
17242   u32 *proto = va_arg (*args, u32 *);
17243
17244   if (unformat (input, "udp"))
17245     *proto = 1;
17246   else if (unformat (input, "api"))
17247     *proto = 2;
17248   else
17249     return 0;
17250
17251   return 1;
17252 }
17253
17254 static int
17255 api_one_set_transport_protocol (vat_main_t * vam)
17256 {
17257   unformat_input_t *input = vam->input;
17258   vl_api_one_set_transport_protocol_t *mp;
17259   u8 is_set = 0;
17260   u32 protocol = 0;
17261   int ret;
17262
17263   /* Parse args required to build the message */
17264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17265     {
17266       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17267         is_set = 1;
17268       else
17269         {
17270           clib_warning ("parse error '%U'", format_unformat_error, input);
17271           return -99;
17272         }
17273     }
17274
17275   if (!is_set)
17276     {
17277       errmsg ("Transport protocol missing!");
17278       return -99;
17279     }
17280
17281   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17282   mp->protocol = (u8) protocol;
17283
17284   /* send it... */
17285   S (mp);
17286
17287   /* Wait for a reply... */
17288   W (ret);
17289   return ret;
17290 }
17291
17292 static int
17293 api_one_get_transport_protocol (vat_main_t * vam)
17294 {
17295   vl_api_one_get_transport_protocol_t *mp;
17296   int ret;
17297
17298   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17299
17300   /* send it... */
17301   S (mp);
17302
17303   /* Wait for a reply... */
17304   W (ret);
17305   return ret;
17306 }
17307
17308 static int
17309 api_one_map_register_set_ttl (vat_main_t * vam)
17310 {
17311   unformat_input_t *input = vam->input;
17312   vl_api_one_map_register_set_ttl_t *mp;
17313   u32 ttl = 0;
17314   u8 is_set = 0;
17315   int ret;
17316
17317   /* Parse args required to build the message */
17318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17319     {
17320       if (unformat (input, "%u", &ttl))
17321         is_set = 1;
17322       else
17323         {
17324           clib_warning ("parse error '%U'", format_unformat_error, input);
17325           return -99;
17326         }
17327     }
17328
17329   if (!is_set)
17330     {
17331       errmsg ("TTL value missing!");
17332       return -99;
17333     }
17334
17335   M (ONE_MAP_REGISTER_SET_TTL, mp);
17336   mp->ttl = clib_host_to_net_u32 (ttl);
17337
17338   /* send it... */
17339   S (mp);
17340
17341   /* Wait for a reply... */
17342   W (ret);
17343   return ret;
17344 }
17345
17346 static int
17347 api_show_one_map_register_ttl (vat_main_t * vam)
17348 {
17349   vl_api_show_one_map_register_ttl_t *mp;
17350   int ret;
17351
17352   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17353
17354   /* send it... */
17355   S (mp);
17356
17357   /* Wait for a reply... */
17358   W (ret);
17359   return ret;
17360 }
17361
17362 /**
17363  * Add/del map request itr rlocs from ONE control plane and updates
17364  *
17365  * @param vam vpp API test context
17366  * @return return code
17367  */
17368 static int
17369 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17370 {
17371   unformat_input_t *input = vam->input;
17372   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17373   u8 *locator_set_name = 0;
17374   u8 locator_set_name_set = 0;
17375   u8 is_add = 1;
17376   int ret;
17377
17378   /* Parse args required to build the message */
17379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17380     {
17381       if (unformat (input, "del"))
17382         {
17383           is_add = 0;
17384         }
17385       else if (unformat (input, "%_%v%_", &locator_set_name))
17386         {
17387           locator_set_name_set = 1;
17388         }
17389       else
17390         {
17391           clib_warning ("parse error '%U'", format_unformat_error, input);
17392           return -99;
17393         }
17394     }
17395
17396   if (is_add && !locator_set_name_set)
17397     {
17398       errmsg ("itr-rloc is not set!");
17399       return -99;
17400     }
17401
17402   if (is_add && vec_len (locator_set_name) > 64)
17403     {
17404       errmsg ("itr-rloc locator-set name too long");
17405       vec_free (locator_set_name);
17406       return -99;
17407     }
17408
17409   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17410   mp->is_add = is_add;
17411   if (is_add)
17412     {
17413       clib_memcpy (mp->locator_set_name, locator_set_name,
17414                    vec_len (locator_set_name));
17415     }
17416   else
17417     {
17418       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17419     }
17420   vec_free (locator_set_name);
17421
17422   /* send it... */
17423   S (mp);
17424
17425   /* Wait for a reply... */
17426   W (ret);
17427   return ret;
17428 }
17429
17430 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17431
17432 static int
17433 api_one_locator_dump (vat_main_t * vam)
17434 {
17435   unformat_input_t *input = vam->input;
17436   vl_api_one_locator_dump_t *mp;
17437   vl_api_control_ping_t *mp_ping;
17438   u8 is_index_set = 0, is_name_set = 0;
17439   u8 *ls_name = 0;
17440   u32 ls_index = ~0;
17441   int ret;
17442
17443   /* Parse args required to build the message */
17444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17445     {
17446       if (unformat (input, "ls_name %_%v%_", &ls_name))
17447         {
17448           is_name_set = 1;
17449         }
17450       else if (unformat (input, "ls_index %d", &ls_index))
17451         {
17452           is_index_set = 1;
17453         }
17454       else
17455         {
17456           errmsg ("parse error '%U'", format_unformat_error, input);
17457           return -99;
17458         }
17459     }
17460
17461   if (!is_index_set && !is_name_set)
17462     {
17463       errmsg ("error: expected one of index or name!");
17464       return -99;
17465     }
17466
17467   if (is_index_set && is_name_set)
17468     {
17469       errmsg ("error: only one param expected!");
17470       return -99;
17471     }
17472
17473   if (vec_len (ls_name) > 62)
17474     {
17475       errmsg ("error: locator set name too long!");
17476       return -99;
17477     }
17478
17479   if (!vam->json_output)
17480     {
17481       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17482     }
17483
17484   M (ONE_LOCATOR_DUMP, mp);
17485   mp->is_index_set = is_index_set;
17486
17487   if (is_index_set)
17488     mp->ls_index = clib_host_to_net_u32 (ls_index);
17489   else
17490     {
17491       vec_add1 (ls_name, 0);
17492       strncpy ((char *) mp->ls_name, (char *) ls_name,
17493                sizeof (mp->ls_name) - 1);
17494     }
17495
17496   /* send it... */
17497   S (mp);
17498
17499   /* Use a control ping for synchronization */
17500   MPING (CONTROL_PING, mp_ping);
17501   S (mp_ping);
17502
17503   /* Wait for a reply... */
17504   W (ret);
17505   return ret;
17506 }
17507
17508 #define api_lisp_locator_dump api_one_locator_dump
17509
17510 static int
17511 api_one_locator_set_dump (vat_main_t * vam)
17512 {
17513   vl_api_one_locator_set_dump_t *mp;
17514   vl_api_control_ping_t *mp_ping;
17515   unformat_input_t *input = vam->input;
17516   u8 filter = 0;
17517   int ret;
17518
17519   /* Parse args required to build the message */
17520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17521     {
17522       if (unformat (input, "local"))
17523         {
17524           filter = 1;
17525         }
17526       else if (unformat (input, "remote"))
17527         {
17528           filter = 2;
17529         }
17530       else
17531         {
17532           errmsg ("parse error '%U'", format_unformat_error, input);
17533           return -99;
17534         }
17535     }
17536
17537   if (!vam->json_output)
17538     {
17539       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17540     }
17541
17542   M (ONE_LOCATOR_SET_DUMP, mp);
17543
17544   mp->filter = filter;
17545
17546   /* send it... */
17547   S (mp);
17548
17549   /* Use a control ping for synchronization */
17550   MPING (CONTROL_PING, mp_ping);
17551   S (mp_ping);
17552
17553   /* Wait for a reply... */
17554   W (ret);
17555   return ret;
17556 }
17557
17558 #define api_lisp_locator_set_dump api_one_locator_set_dump
17559
17560 static int
17561 api_one_eid_table_map_dump (vat_main_t * vam)
17562 {
17563   u8 is_l2 = 0;
17564   u8 mode_set = 0;
17565   unformat_input_t *input = vam->input;
17566   vl_api_one_eid_table_map_dump_t *mp;
17567   vl_api_control_ping_t *mp_ping;
17568   int ret;
17569
17570   /* Parse args required to build the message */
17571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17572     {
17573       if (unformat (input, "l2"))
17574         {
17575           is_l2 = 1;
17576           mode_set = 1;
17577         }
17578       else if (unformat (input, "l3"))
17579         {
17580           is_l2 = 0;
17581           mode_set = 1;
17582         }
17583       else
17584         {
17585           errmsg ("parse error '%U'", format_unformat_error, input);
17586           return -99;
17587         }
17588     }
17589
17590   if (!mode_set)
17591     {
17592       errmsg ("expected one of 'l2' or 'l3' parameter!");
17593       return -99;
17594     }
17595
17596   if (!vam->json_output)
17597     {
17598       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17599     }
17600
17601   M (ONE_EID_TABLE_MAP_DUMP, mp);
17602   mp->is_l2 = is_l2;
17603
17604   /* send it... */
17605   S (mp);
17606
17607   /* Use a control ping for synchronization */
17608   MPING (CONTROL_PING, mp_ping);
17609   S (mp_ping);
17610
17611   /* Wait for a reply... */
17612   W (ret);
17613   return ret;
17614 }
17615
17616 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17617
17618 static int
17619 api_one_eid_table_vni_dump (vat_main_t * vam)
17620 {
17621   vl_api_one_eid_table_vni_dump_t *mp;
17622   vl_api_control_ping_t *mp_ping;
17623   int ret;
17624
17625   if (!vam->json_output)
17626     {
17627       print (vam->ofp, "VNI");
17628     }
17629
17630   M (ONE_EID_TABLE_VNI_DUMP, mp);
17631
17632   /* send it... */
17633   S (mp);
17634
17635   /* Use a control ping for synchronization */
17636   MPING (CONTROL_PING, mp_ping);
17637   S (mp_ping);
17638
17639   /* Wait for a reply... */
17640   W (ret);
17641   return ret;
17642 }
17643
17644 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17645
17646 static int
17647 api_one_eid_table_dump (vat_main_t * vam)
17648 {
17649   unformat_input_t *i = vam->input;
17650   vl_api_one_eid_table_dump_t *mp;
17651   vl_api_control_ping_t *mp_ping;
17652   struct in_addr ip4;
17653   struct in6_addr ip6;
17654   u8 mac[6];
17655   u8 eid_type = ~0, eid_set = 0;
17656   u32 prefix_length = ~0, t, vni = 0;
17657   u8 filter = 0;
17658   int ret;
17659   lisp_nsh_api_t nsh;
17660
17661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17662     {
17663       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17664         {
17665           eid_set = 1;
17666           eid_type = 0;
17667           prefix_length = t;
17668         }
17669       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17670         {
17671           eid_set = 1;
17672           eid_type = 1;
17673           prefix_length = t;
17674         }
17675       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17676         {
17677           eid_set = 1;
17678           eid_type = 2;
17679         }
17680       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17681         {
17682           eid_set = 1;
17683           eid_type = 3;
17684         }
17685       else if (unformat (i, "vni %d", &t))
17686         {
17687           vni = t;
17688         }
17689       else if (unformat (i, "local"))
17690         {
17691           filter = 1;
17692         }
17693       else if (unformat (i, "remote"))
17694         {
17695           filter = 2;
17696         }
17697       else
17698         {
17699           errmsg ("parse error '%U'", format_unformat_error, i);
17700           return -99;
17701         }
17702     }
17703
17704   if (!vam->json_output)
17705     {
17706       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17707              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17708     }
17709
17710   M (ONE_EID_TABLE_DUMP, mp);
17711
17712   mp->filter = filter;
17713   if (eid_set)
17714     {
17715       mp->eid_set = 1;
17716       mp->vni = htonl (vni);
17717       mp->eid_type = eid_type;
17718       switch (eid_type)
17719         {
17720         case 0:
17721           mp->prefix_length = prefix_length;
17722           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17723           break;
17724         case 1:
17725           mp->prefix_length = prefix_length;
17726           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17727           break;
17728         case 2:
17729           clib_memcpy (mp->eid, mac, sizeof (mac));
17730           break;
17731         case 3:
17732           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17733           break;
17734         default:
17735           errmsg ("unknown EID type %d!", eid_type);
17736           return -99;
17737         }
17738     }
17739
17740   /* send it... */
17741   S (mp);
17742
17743   /* Use a control ping for synchronization */
17744   MPING (CONTROL_PING, mp_ping);
17745   S (mp_ping);
17746
17747   /* Wait for a reply... */
17748   W (ret);
17749   return ret;
17750 }
17751
17752 #define api_lisp_eid_table_dump api_one_eid_table_dump
17753
17754 static int
17755 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17756 {
17757   unformat_input_t *i = vam->input;
17758   vl_api_gpe_fwd_entries_get_t *mp;
17759   u8 vni_set = 0;
17760   u32 vni = ~0;
17761   int ret;
17762
17763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17764     {
17765       if (unformat (i, "vni %d", &vni))
17766         {
17767           vni_set = 1;
17768         }
17769       else
17770         {
17771           errmsg ("parse error '%U'", format_unformat_error, i);
17772           return -99;
17773         }
17774     }
17775
17776   if (!vni_set)
17777     {
17778       errmsg ("vni not set!");
17779       return -99;
17780     }
17781
17782   if (!vam->json_output)
17783     {
17784       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17785              "leid", "reid");
17786     }
17787
17788   M (GPE_FWD_ENTRIES_GET, mp);
17789   mp->vni = clib_host_to_net_u32 (vni);
17790
17791   /* send it... */
17792   S (mp);
17793
17794   /* Wait for a reply... */
17795   W (ret);
17796   return ret;
17797 }
17798
17799 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17800 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17801 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17802 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17803 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17804 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17805 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17806 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17807
17808 static int
17809 api_one_adjacencies_get (vat_main_t * vam)
17810 {
17811   unformat_input_t *i = vam->input;
17812   vl_api_one_adjacencies_get_t *mp;
17813   u8 vni_set = 0;
17814   u32 vni = ~0;
17815   int ret;
17816
17817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17818     {
17819       if (unformat (i, "vni %d", &vni))
17820         {
17821           vni_set = 1;
17822         }
17823       else
17824         {
17825           errmsg ("parse error '%U'", format_unformat_error, i);
17826           return -99;
17827         }
17828     }
17829
17830   if (!vni_set)
17831     {
17832       errmsg ("vni not set!");
17833       return -99;
17834     }
17835
17836   if (!vam->json_output)
17837     {
17838       print (vam->ofp, "%s %40s", "leid", "reid");
17839     }
17840
17841   M (ONE_ADJACENCIES_GET, mp);
17842   mp->vni = clib_host_to_net_u32 (vni);
17843
17844   /* send it... */
17845   S (mp);
17846
17847   /* Wait for a reply... */
17848   W (ret);
17849   return ret;
17850 }
17851
17852 #define api_lisp_adjacencies_get api_one_adjacencies_get
17853
17854 static int
17855 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17856 {
17857   unformat_input_t *i = vam->input;
17858   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17859   int ret;
17860   u8 ip_family_set = 0, is_ip4 = 1;
17861
17862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17863     {
17864       if (unformat (i, "ip4"))
17865         {
17866           ip_family_set = 1;
17867           is_ip4 = 1;
17868         }
17869       else if (unformat (i, "ip6"))
17870         {
17871           ip_family_set = 1;
17872           is_ip4 = 0;
17873         }
17874       else
17875         {
17876           errmsg ("parse error '%U'", format_unformat_error, i);
17877           return -99;
17878         }
17879     }
17880
17881   if (!ip_family_set)
17882     {
17883       errmsg ("ip family not set!");
17884       return -99;
17885     }
17886
17887   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17888   mp->is_ip4 = is_ip4;
17889
17890   /* send it... */
17891   S (mp);
17892
17893   /* Wait for a reply... */
17894   W (ret);
17895   return ret;
17896 }
17897
17898 static int
17899 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17900 {
17901   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17902   int ret;
17903
17904   if (!vam->json_output)
17905     {
17906       print (vam->ofp, "VNIs");
17907     }
17908
17909   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17910
17911   /* send it... */
17912   S (mp);
17913
17914   /* Wait for a reply... */
17915   W (ret);
17916   return ret;
17917 }
17918
17919 static int
17920 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17921 {
17922   unformat_input_t *i = vam->input;
17923   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17924   int ret = 0;
17925   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17926   struct in_addr ip4;
17927   struct in6_addr ip6;
17928   u32 table_id = 0, nh_sw_if_index = ~0;
17929
17930   clib_memset (&ip4, 0, sizeof (ip4));
17931   clib_memset (&ip6, 0, sizeof (ip6));
17932
17933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17934     {
17935       if (unformat (i, "del"))
17936         is_add = 0;
17937       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17938                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17939         {
17940           ip_set = 1;
17941           is_ip4 = 1;
17942         }
17943       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17944                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17945         {
17946           ip_set = 1;
17947           is_ip4 = 0;
17948         }
17949       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17950         {
17951           ip_set = 1;
17952           is_ip4 = 1;
17953           nh_sw_if_index = ~0;
17954         }
17955       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17956         {
17957           ip_set = 1;
17958           is_ip4 = 0;
17959           nh_sw_if_index = ~0;
17960         }
17961       else if (unformat (i, "table %d", &table_id))
17962         ;
17963       else
17964         {
17965           errmsg ("parse error '%U'", format_unformat_error, i);
17966           return -99;
17967         }
17968     }
17969
17970   if (!ip_set)
17971     {
17972       errmsg ("nh addr not set!");
17973       return -99;
17974     }
17975
17976   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17977   mp->is_add = is_add;
17978   mp->table_id = clib_host_to_net_u32 (table_id);
17979   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17980   mp->is_ip4 = is_ip4;
17981   if (is_ip4)
17982     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17983   else
17984     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17985
17986   /* send it... */
17987   S (mp);
17988
17989   /* Wait for a reply... */
17990   W (ret);
17991   return ret;
17992 }
17993
17994 static int
17995 api_one_map_server_dump (vat_main_t * vam)
17996 {
17997   vl_api_one_map_server_dump_t *mp;
17998   vl_api_control_ping_t *mp_ping;
17999   int ret;
18000
18001   if (!vam->json_output)
18002     {
18003       print (vam->ofp, "%=20s", "Map server");
18004     }
18005
18006   M (ONE_MAP_SERVER_DUMP, mp);
18007   /* send it... */
18008   S (mp);
18009
18010   /* Use a control ping for synchronization */
18011   MPING (CONTROL_PING, mp_ping);
18012   S (mp_ping);
18013
18014   /* Wait for a reply... */
18015   W (ret);
18016   return ret;
18017 }
18018
18019 #define api_lisp_map_server_dump api_one_map_server_dump
18020
18021 static int
18022 api_one_map_resolver_dump (vat_main_t * vam)
18023 {
18024   vl_api_one_map_resolver_dump_t *mp;
18025   vl_api_control_ping_t *mp_ping;
18026   int ret;
18027
18028   if (!vam->json_output)
18029     {
18030       print (vam->ofp, "%=20s", "Map resolver");
18031     }
18032
18033   M (ONE_MAP_RESOLVER_DUMP, mp);
18034   /* send it... */
18035   S (mp);
18036
18037   /* Use a control ping for synchronization */
18038   MPING (CONTROL_PING, mp_ping);
18039   S (mp_ping);
18040
18041   /* Wait for a reply... */
18042   W (ret);
18043   return ret;
18044 }
18045
18046 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18047
18048 static int
18049 api_one_stats_flush (vat_main_t * vam)
18050 {
18051   vl_api_one_stats_flush_t *mp;
18052   int ret = 0;
18053
18054   M (ONE_STATS_FLUSH, mp);
18055   S (mp);
18056   W (ret);
18057   return ret;
18058 }
18059
18060 static int
18061 api_one_stats_dump (vat_main_t * vam)
18062 {
18063   vl_api_one_stats_dump_t *mp;
18064   vl_api_control_ping_t *mp_ping;
18065   int ret;
18066
18067   M (ONE_STATS_DUMP, mp);
18068   /* send it... */
18069   S (mp);
18070
18071   /* Use a control ping for synchronization */
18072   MPING (CONTROL_PING, mp_ping);
18073   S (mp_ping);
18074
18075   /* Wait for a reply... */
18076   W (ret);
18077   return ret;
18078 }
18079
18080 static int
18081 api_show_one_status (vat_main_t * vam)
18082 {
18083   vl_api_show_one_status_t *mp;
18084   int ret;
18085
18086   if (!vam->json_output)
18087     {
18088       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18089     }
18090
18091   M (SHOW_ONE_STATUS, mp);
18092   /* send it... */
18093   S (mp);
18094   /* Wait for a reply... */
18095   W (ret);
18096   return ret;
18097 }
18098
18099 #define api_show_lisp_status api_show_one_status
18100
18101 static int
18102 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18103 {
18104   vl_api_gpe_fwd_entry_path_dump_t *mp;
18105   vl_api_control_ping_t *mp_ping;
18106   unformat_input_t *i = vam->input;
18107   u32 fwd_entry_index = ~0;
18108   int ret;
18109
18110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18111     {
18112       if (unformat (i, "index %d", &fwd_entry_index))
18113         ;
18114       else
18115         break;
18116     }
18117
18118   if (~0 == fwd_entry_index)
18119     {
18120       errmsg ("no index specified!");
18121       return -99;
18122     }
18123
18124   if (!vam->json_output)
18125     {
18126       print (vam->ofp, "first line");
18127     }
18128
18129   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18130
18131   /* send it... */
18132   S (mp);
18133   /* Use a control ping for synchronization */
18134   MPING (CONTROL_PING, mp_ping);
18135   S (mp_ping);
18136
18137   /* Wait for a reply... */
18138   W (ret);
18139   return ret;
18140 }
18141
18142 static int
18143 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18144 {
18145   vl_api_one_get_map_request_itr_rlocs_t *mp;
18146   int ret;
18147
18148   if (!vam->json_output)
18149     {
18150       print (vam->ofp, "%=20s", "itr-rlocs:");
18151     }
18152
18153   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18154   /* send it... */
18155   S (mp);
18156   /* Wait for a reply... */
18157   W (ret);
18158   return ret;
18159 }
18160
18161 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18162
18163 static int
18164 api_af_packet_create (vat_main_t * vam)
18165 {
18166   unformat_input_t *i = vam->input;
18167   vl_api_af_packet_create_t *mp;
18168   u8 *host_if_name = 0;
18169   u8 hw_addr[6];
18170   u8 random_hw_addr = 1;
18171   int ret;
18172
18173   clib_memset (hw_addr, 0, sizeof (hw_addr));
18174
18175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18176     {
18177       if (unformat (i, "name %s", &host_if_name))
18178         vec_add1 (host_if_name, 0);
18179       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18180         random_hw_addr = 0;
18181       else
18182         break;
18183     }
18184
18185   if (!vec_len (host_if_name))
18186     {
18187       errmsg ("host-interface name must be specified");
18188       return -99;
18189     }
18190
18191   if (vec_len (host_if_name) > 64)
18192     {
18193       errmsg ("host-interface name too long");
18194       return -99;
18195     }
18196
18197   M (AF_PACKET_CREATE, mp);
18198
18199   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18200   clib_memcpy (mp->hw_addr, hw_addr, 6);
18201   mp->use_random_hw_addr = random_hw_addr;
18202   vec_free (host_if_name);
18203
18204   S (mp);
18205
18206   /* *INDENT-OFF* */
18207   W2 (ret,
18208       ({
18209         if (ret == 0)
18210           fprintf (vam->ofp ? vam->ofp : stderr,
18211                    " new sw_if_index = %d\n", vam->sw_if_index);
18212       }));
18213   /* *INDENT-ON* */
18214   return ret;
18215 }
18216
18217 static int
18218 api_af_packet_delete (vat_main_t * vam)
18219 {
18220   unformat_input_t *i = vam->input;
18221   vl_api_af_packet_delete_t *mp;
18222   u8 *host_if_name = 0;
18223   int ret;
18224
18225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18226     {
18227       if (unformat (i, "name %s", &host_if_name))
18228         vec_add1 (host_if_name, 0);
18229       else
18230         break;
18231     }
18232
18233   if (!vec_len (host_if_name))
18234     {
18235       errmsg ("host-interface name must be specified");
18236       return -99;
18237     }
18238
18239   if (vec_len (host_if_name) > 64)
18240     {
18241       errmsg ("host-interface name too long");
18242       return -99;
18243     }
18244
18245   M (AF_PACKET_DELETE, mp);
18246
18247   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18248   vec_free (host_if_name);
18249
18250   S (mp);
18251   W (ret);
18252   return ret;
18253 }
18254
18255 static void vl_api_af_packet_details_t_handler
18256   (vl_api_af_packet_details_t * mp)
18257 {
18258   vat_main_t *vam = &vat_main;
18259
18260   print (vam->ofp, "%-16s %d",
18261          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18262 }
18263
18264 static void vl_api_af_packet_details_t_handler_json
18265   (vl_api_af_packet_details_t * mp)
18266 {
18267   vat_main_t *vam = &vat_main;
18268   vat_json_node_t *node = NULL;
18269
18270   if (VAT_JSON_ARRAY != vam->json_tree.type)
18271     {
18272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18273       vat_json_init_array (&vam->json_tree);
18274     }
18275   node = vat_json_array_add (&vam->json_tree);
18276
18277   vat_json_init_object (node);
18278   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18279   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18280 }
18281
18282 static int
18283 api_af_packet_dump (vat_main_t * vam)
18284 {
18285   vl_api_af_packet_dump_t *mp;
18286   vl_api_control_ping_t *mp_ping;
18287   int ret;
18288
18289   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18290   /* Get list of tap interfaces */
18291   M (AF_PACKET_DUMP, mp);
18292   S (mp);
18293
18294   /* Use a control ping for synchronization */
18295   MPING (CONTROL_PING, mp_ping);
18296   S (mp_ping);
18297
18298   W (ret);
18299   return ret;
18300 }
18301
18302 static int
18303 api_policer_add_del (vat_main_t * vam)
18304 {
18305   unformat_input_t *i = vam->input;
18306   vl_api_policer_add_del_t *mp;
18307   u8 is_add = 1;
18308   u8 *name = 0;
18309   u32 cir = 0;
18310   u32 eir = 0;
18311   u64 cb = 0;
18312   u64 eb = 0;
18313   u8 rate_type = 0;
18314   u8 round_type = 0;
18315   u8 type = 0;
18316   u8 color_aware = 0;
18317   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18318   int ret;
18319
18320   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18321   conform_action.dscp = 0;
18322   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18323   exceed_action.dscp = 0;
18324   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18325   violate_action.dscp = 0;
18326
18327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18328     {
18329       if (unformat (i, "del"))
18330         is_add = 0;
18331       else if (unformat (i, "name %s", &name))
18332         vec_add1 (name, 0);
18333       else if (unformat (i, "cir %u", &cir))
18334         ;
18335       else if (unformat (i, "eir %u", &eir))
18336         ;
18337       else if (unformat (i, "cb %u", &cb))
18338         ;
18339       else if (unformat (i, "eb %u", &eb))
18340         ;
18341       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18342                          &rate_type))
18343         ;
18344       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18345                          &round_type))
18346         ;
18347       else if (unformat (i, "type %U", unformat_policer_type, &type))
18348         ;
18349       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18350                          &conform_action))
18351         ;
18352       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18353                          &exceed_action))
18354         ;
18355       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18356                          &violate_action))
18357         ;
18358       else if (unformat (i, "color-aware"))
18359         color_aware = 1;
18360       else
18361         break;
18362     }
18363
18364   if (!vec_len (name))
18365     {
18366       errmsg ("policer name must be specified");
18367       return -99;
18368     }
18369
18370   if (vec_len (name) > 64)
18371     {
18372       errmsg ("policer name too long");
18373       return -99;
18374     }
18375
18376   M (POLICER_ADD_DEL, mp);
18377
18378   clib_memcpy (mp->name, name, vec_len (name));
18379   vec_free (name);
18380   mp->is_add = is_add;
18381   mp->cir = ntohl (cir);
18382   mp->eir = ntohl (eir);
18383   mp->cb = clib_net_to_host_u64 (cb);
18384   mp->eb = clib_net_to_host_u64 (eb);
18385   mp->rate_type = rate_type;
18386   mp->round_type = round_type;
18387   mp->type = type;
18388   mp->conform_action_type = conform_action.action_type;
18389   mp->conform_dscp = conform_action.dscp;
18390   mp->exceed_action_type = exceed_action.action_type;
18391   mp->exceed_dscp = exceed_action.dscp;
18392   mp->violate_action_type = violate_action.action_type;
18393   mp->violate_dscp = violate_action.dscp;
18394   mp->color_aware = color_aware;
18395
18396   S (mp);
18397   W (ret);
18398   return ret;
18399 }
18400
18401 static int
18402 api_policer_dump (vat_main_t * vam)
18403 {
18404   unformat_input_t *i = vam->input;
18405   vl_api_policer_dump_t *mp;
18406   vl_api_control_ping_t *mp_ping;
18407   u8 *match_name = 0;
18408   u8 match_name_valid = 0;
18409   int ret;
18410
18411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18412     {
18413       if (unformat (i, "name %s", &match_name))
18414         {
18415           vec_add1 (match_name, 0);
18416           match_name_valid = 1;
18417         }
18418       else
18419         break;
18420     }
18421
18422   M (POLICER_DUMP, mp);
18423   mp->match_name_valid = match_name_valid;
18424   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18425   vec_free (match_name);
18426   /* send it... */
18427   S (mp);
18428
18429   /* Use a control ping for synchronization */
18430   MPING (CONTROL_PING, mp_ping);
18431   S (mp_ping);
18432
18433   /* Wait for a reply... */
18434   W (ret);
18435   return ret;
18436 }
18437
18438 static int
18439 api_policer_classify_set_interface (vat_main_t * vam)
18440 {
18441   unformat_input_t *i = vam->input;
18442   vl_api_policer_classify_set_interface_t *mp;
18443   u32 sw_if_index;
18444   int sw_if_index_set;
18445   u32 ip4_table_index = ~0;
18446   u32 ip6_table_index = ~0;
18447   u32 l2_table_index = ~0;
18448   u8 is_add = 1;
18449   int ret;
18450
18451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18452     {
18453       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18454         sw_if_index_set = 1;
18455       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18456         sw_if_index_set = 1;
18457       else if (unformat (i, "del"))
18458         is_add = 0;
18459       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18460         ;
18461       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18462         ;
18463       else if (unformat (i, "l2-table %d", &l2_table_index))
18464         ;
18465       else
18466         {
18467           clib_warning ("parse error '%U'", format_unformat_error, i);
18468           return -99;
18469         }
18470     }
18471
18472   if (sw_if_index_set == 0)
18473     {
18474       errmsg ("missing interface name or sw_if_index");
18475       return -99;
18476     }
18477
18478   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18479
18480   mp->sw_if_index = ntohl (sw_if_index);
18481   mp->ip4_table_index = ntohl (ip4_table_index);
18482   mp->ip6_table_index = ntohl (ip6_table_index);
18483   mp->l2_table_index = ntohl (l2_table_index);
18484   mp->is_add = is_add;
18485
18486   S (mp);
18487   W (ret);
18488   return ret;
18489 }
18490
18491 static int
18492 api_policer_classify_dump (vat_main_t * vam)
18493 {
18494   unformat_input_t *i = vam->input;
18495   vl_api_policer_classify_dump_t *mp;
18496   vl_api_control_ping_t *mp_ping;
18497   u8 type = POLICER_CLASSIFY_N_TABLES;
18498   int ret;
18499
18500   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18501     ;
18502   else
18503     {
18504       errmsg ("classify table type must be specified");
18505       return -99;
18506     }
18507
18508   if (!vam->json_output)
18509     {
18510       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18511     }
18512
18513   M (POLICER_CLASSIFY_DUMP, mp);
18514   mp->type = type;
18515   /* send it... */
18516   S (mp);
18517
18518   /* Use a control ping for synchronization */
18519   MPING (CONTROL_PING, mp_ping);
18520   S (mp_ping);
18521
18522   /* Wait for a reply... */
18523   W (ret);
18524   return ret;
18525 }
18526
18527 static int
18528 api_netmap_create (vat_main_t * vam)
18529 {
18530   unformat_input_t *i = vam->input;
18531   vl_api_netmap_create_t *mp;
18532   u8 *if_name = 0;
18533   u8 hw_addr[6];
18534   u8 random_hw_addr = 1;
18535   u8 is_pipe = 0;
18536   u8 is_master = 0;
18537   int ret;
18538
18539   clib_memset (hw_addr, 0, sizeof (hw_addr));
18540
18541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18542     {
18543       if (unformat (i, "name %s", &if_name))
18544         vec_add1 (if_name, 0);
18545       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18546         random_hw_addr = 0;
18547       else if (unformat (i, "pipe"))
18548         is_pipe = 1;
18549       else if (unformat (i, "master"))
18550         is_master = 1;
18551       else if (unformat (i, "slave"))
18552         is_master = 0;
18553       else
18554         break;
18555     }
18556
18557   if (!vec_len (if_name))
18558     {
18559       errmsg ("interface name must be specified");
18560       return -99;
18561     }
18562
18563   if (vec_len (if_name) > 64)
18564     {
18565       errmsg ("interface name too long");
18566       return -99;
18567     }
18568
18569   M (NETMAP_CREATE, mp);
18570
18571   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18572   clib_memcpy (mp->hw_addr, hw_addr, 6);
18573   mp->use_random_hw_addr = random_hw_addr;
18574   mp->is_pipe = is_pipe;
18575   mp->is_master = is_master;
18576   vec_free (if_name);
18577
18578   S (mp);
18579   W (ret);
18580   return ret;
18581 }
18582
18583 static int
18584 api_netmap_delete (vat_main_t * vam)
18585 {
18586   unformat_input_t *i = vam->input;
18587   vl_api_netmap_delete_t *mp;
18588   u8 *if_name = 0;
18589   int ret;
18590
18591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18592     {
18593       if (unformat (i, "name %s", &if_name))
18594         vec_add1 (if_name, 0);
18595       else
18596         break;
18597     }
18598
18599   if (!vec_len (if_name))
18600     {
18601       errmsg ("interface name must be specified");
18602       return -99;
18603     }
18604
18605   if (vec_len (if_name) > 64)
18606     {
18607       errmsg ("interface name too long");
18608       return -99;
18609     }
18610
18611   M (NETMAP_DELETE, mp);
18612
18613   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18614   vec_free (if_name);
18615
18616   S (mp);
18617   W (ret);
18618   return ret;
18619 }
18620
18621 static u8 *
18622 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18623 {
18624   vl_api_fib_path_nh_proto_t proto =
18625     va_arg (*args, vl_api_fib_path_nh_proto_t);
18626
18627   switch (proto)
18628     {
18629     case FIB_API_PATH_NH_PROTO_IP4:
18630       s = format (s, "ip4");
18631       break;
18632     case FIB_API_PATH_NH_PROTO_IP6:
18633       s = format (s, "ip6");
18634       break;
18635     case FIB_API_PATH_NH_PROTO_MPLS:
18636       s = format (s, "mpls");
18637       break;
18638     case FIB_API_PATH_NH_PROTO_BIER:
18639       s = format (s, "bier");
18640       break;
18641     case FIB_API_PATH_NH_PROTO_ETHERNET:
18642       s = format (s, "ethernet");
18643       break;
18644     }
18645
18646   return (s);
18647 }
18648
18649 static u8 *
18650 format_vl_api_ip_address_union (u8 * s, va_list * args)
18651 {
18652   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18653   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18654
18655   switch (af)
18656     {
18657     case ADDRESS_IP4:
18658       s = format (s, "%U", format_ip4_address, u->ip4);
18659       break;
18660     case ADDRESS_IP6:
18661       s = format (s, "%U", format_ip6_address, u->ip6);
18662       break;
18663     }
18664   return (s);
18665 }
18666
18667 static u8 *
18668 format_vl_api_fib_path_type (u8 * s, va_list * args)
18669 {
18670   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18671
18672   switch (t)
18673     {
18674     case FIB_API_PATH_TYPE_NORMAL:
18675       s = format (s, "normal");
18676       break;
18677     case FIB_API_PATH_TYPE_LOCAL:
18678       s = format (s, "local");
18679       break;
18680     case FIB_API_PATH_TYPE_DROP:
18681       s = format (s, "drop");
18682       break;
18683     case FIB_API_PATH_TYPE_UDP_ENCAP:
18684       s = format (s, "udp-encap");
18685       break;
18686     case FIB_API_PATH_TYPE_BIER_IMP:
18687       s = format (s, "bier-imp");
18688       break;
18689     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18690       s = format (s, "unreach");
18691       break;
18692     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18693       s = format (s, "prohibit");
18694       break;
18695     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18696       s = format (s, "src-lookup");
18697       break;
18698     case FIB_API_PATH_TYPE_DVR:
18699       s = format (s, "dvr");
18700       break;
18701     case FIB_API_PATH_TYPE_INTERFACE_RX:
18702       s = format (s, "interface-rx");
18703       break;
18704     case FIB_API_PATH_TYPE_CLASSIFY:
18705       s = format (s, "classify");
18706       break;
18707     }
18708
18709   return (s);
18710 }
18711
18712 static void
18713 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18714 {
18715   print (vam->ofp,
18716          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18717          ntohl (fp->weight), ntohl (fp->sw_if_index),
18718          format_vl_api_fib_path_type, fp->type,
18719          format_fib_api_path_nh_proto, fp->proto,
18720          format_vl_api_ip_address_union, &fp->nh.address);
18721 }
18722
18723 static void
18724 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18725                                  vl_api_fib_path_t * fp)
18726 {
18727   struct in_addr ip4;
18728   struct in6_addr ip6;
18729
18730   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18731   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18732   vat_json_object_add_uint (node, "type", fp->type);
18733   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18734   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18735     {
18736       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18737       vat_json_object_add_ip4 (node, "next_hop", ip4);
18738     }
18739   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18740     {
18741       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18742       vat_json_object_add_ip6 (node, "next_hop", ip6);
18743     }
18744 }
18745
18746 static void
18747 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18748 {
18749   vat_main_t *vam = &vat_main;
18750   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18751   vl_api_fib_path_t *fp;
18752   i32 i;
18753
18754   print (vam->ofp, "sw_if_index %d via:",
18755          ntohl (mp->mt_tunnel.mt_sw_if_index));
18756   fp = mp->mt_tunnel.mt_paths;
18757   for (i = 0; i < count; i++)
18758     {
18759       vl_api_fib_path_print (vam, fp);
18760       fp++;
18761     }
18762
18763   print (vam->ofp, "");
18764 }
18765
18766 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18767 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18768
18769 static void
18770 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18771 {
18772   vat_main_t *vam = &vat_main;
18773   vat_json_node_t *node = NULL;
18774   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18775   vl_api_fib_path_t *fp;
18776   i32 i;
18777
18778   if (VAT_JSON_ARRAY != vam->json_tree.type)
18779     {
18780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18781       vat_json_init_array (&vam->json_tree);
18782     }
18783   node = vat_json_array_add (&vam->json_tree);
18784
18785   vat_json_init_object (node);
18786   vat_json_object_add_uint (node, "sw_if_index",
18787                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18788
18789   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18790
18791   fp = mp->mt_tunnel.mt_paths;
18792   for (i = 0; i < count; i++)
18793     {
18794       vl_api_mpls_fib_path_json_print (node, fp);
18795       fp++;
18796     }
18797 }
18798
18799 static int
18800 api_mpls_tunnel_dump (vat_main_t * vam)
18801 {
18802   vl_api_mpls_tunnel_dump_t *mp;
18803   vl_api_control_ping_t *mp_ping;
18804   int ret;
18805
18806   M (MPLS_TUNNEL_DUMP, mp);
18807
18808   S (mp);
18809
18810   /* Use a control ping for synchronization */
18811   MPING (CONTROL_PING, mp_ping);
18812   S (mp_ping);
18813
18814   W (ret);
18815   return ret;
18816 }
18817
18818 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18819 #define vl_api_mpls_table_details_t_print vl_noop_handler
18820
18821
18822 static void
18823 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18824 {
18825   vat_main_t *vam = &vat_main;
18826
18827   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18828 }
18829
18830 static void vl_api_mpls_table_details_t_handler_json
18831   (vl_api_mpls_table_details_t * mp)
18832 {
18833   vat_main_t *vam = &vat_main;
18834   vat_json_node_t *node = NULL;
18835
18836   if (VAT_JSON_ARRAY != vam->json_tree.type)
18837     {
18838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18839       vat_json_init_array (&vam->json_tree);
18840     }
18841   node = vat_json_array_add (&vam->json_tree);
18842
18843   vat_json_init_object (node);
18844   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18845 }
18846
18847 static int
18848 api_mpls_table_dump (vat_main_t * vam)
18849 {
18850   vl_api_mpls_table_dump_t *mp;
18851   vl_api_control_ping_t *mp_ping;
18852   int ret;
18853
18854   M (MPLS_TABLE_DUMP, mp);
18855   S (mp);
18856
18857   /* Use a control ping for synchronization */
18858   MPING (CONTROL_PING, mp_ping);
18859   S (mp_ping);
18860
18861   W (ret);
18862   return ret;
18863 }
18864
18865 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18866 #define vl_api_mpls_route_details_t_print vl_noop_handler
18867
18868 static void
18869 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18870 {
18871   vat_main_t *vam = &vat_main;
18872   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18873   vl_api_fib_path_t *fp;
18874   int i;
18875
18876   print (vam->ofp,
18877          "table-id %d, label %u, ess_bit %u",
18878          ntohl (mp->mr_route.mr_table_id),
18879          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18880   fp = mp->mr_route.mr_paths;
18881   for (i = 0; i < count; i++)
18882     {
18883       vl_api_fib_path_print (vam, fp);
18884       fp++;
18885     }
18886 }
18887
18888 static void vl_api_mpls_route_details_t_handler_json
18889   (vl_api_mpls_route_details_t * mp)
18890 {
18891   vat_main_t *vam = &vat_main;
18892   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18893   vat_json_node_t *node = NULL;
18894   vl_api_fib_path_t *fp;
18895   int i;
18896
18897   if (VAT_JSON_ARRAY != vam->json_tree.type)
18898     {
18899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18900       vat_json_init_array (&vam->json_tree);
18901     }
18902   node = vat_json_array_add (&vam->json_tree);
18903
18904   vat_json_init_object (node);
18905   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18906   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18907   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18908   vat_json_object_add_uint (node, "path_count", count);
18909   fp = mp->mr_route.mr_paths;
18910   for (i = 0; i < count; i++)
18911     {
18912       vl_api_mpls_fib_path_json_print (node, fp);
18913       fp++;
18914     }
18915 }
18916
18917 static int
18918 api_mpls_route_dump (vat_main_t * vam)
18919 {
18920   unformat_input_t *input = vam->input;
18921   vl_api_mpls_route_dump_t *mp;
18922   vl_api_control_ping_t *mp_ping;
18923   u32 table_id;
18924   int ret;
18925
18926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18927     {
18928       if (unformat (input, "table_id %d", &table_id))
18929         ;
18930       else
18931         break;
18932     }
18933   if (table_id == ~0)
18934     {
18935       errmsg ("missing table id");
18936       return -99;
18937     }
18938
18939   M (MPLS_ROUTE_DUMP, mp);
18940
18941   mp->table.mt_table_id = ntohl (table_id);
18942   S (mp);
18943
18944   /* Use a control ping for synchronization */
18945   MPING (CONTROL_PING, mp_ping);
18946   S (mp_ping);
18947
18948   W (ret);
18949   return ret;
18950 }
18951
18952 #define vl_api_ip_table_details_t_endian vl_noop_handler
18953 #define vl_api_ip_table_details_t_print vl_noop_handler
18954
18955 static void
18956 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18957 {
18958   vat_main_t *vam = &vat_main;
18959
18960   print (vam->ofp,
18961          "%s; table-id %d, prefix %U/%d",
18962          mp->table.name, ntohl (mp->table.table_id));
18963 }
18964
18965
18966 static void vl_api_ip_table_details_t_handler_json
18967   (vl_api_ip_table_details_t * mp)
18968 {
18969   vat_main_t *vam = &vat_main;
18970   vat_json_node_t *node = NULL;
18971
18972   if (VAT_JSON_ARRAY != vam->json_tree.type)
18973     {
18974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18975       vat_json_init_array (&vam->json_tree);
18976     }
18977   node = vat_json_array_add (&vam->json_tree);
18978
18979   vat_json_init_object (node);
18980   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18981 }
18982
18983 static int
18984 api_ip_table_dump (vat_main_t * vam)
18985 {
18986   vl_api_ip_table_dump_t *mp;
18987   vl_api_control_ping_t *mp_ping;
18988   int ret;
18989
18990   M (IP_TABLE_DUMP, mp);
18991   S (mp);
18992
18993   /* Use a control ping for synchronization */
18994   MPING (CONTROL_PING, mp_ping);
18995   S (mp_ping);
18996
18997   W (ret);
18998   return ret;
18999 }
19000
19001 static int
19002 api_ip_mtable_dump (vat_main_t * vam)
19003 {
19004   vl_api_ip_mtable_dump_t *mp;
19005   vl_api_control_ping_t *mp_ping;
19006   int ret;
19007
19008   M (IP_MTABLE_DUMP, mp);
19009   S (mp);
19010
19011   /* Use a control ping for synchronization */
19012   MPING (CONTROL_PING, mp_ping);
19013   S (mp_ping);
19014
19015   W (ret);
19016   return ret;
19017 }
19018
19019 static int
19020 api_ip_mroute_dump (vat_main_t * vam)
19021 {
19022   unformat_input_t *input = vam->input;
19023   vl_api_control_ping_t *mp_ping;
19024   vl_api_ip_mroute_dump_t *mp;
19025   int ret, is_ip6;
19026   u32 table_id;
19027
19028   is_ip6 = 0;
19029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19030     {
19031       if (unformat (input, "table_id %d", &table_id))
19032         ;
19033       else if (unformat (input, "ip6"))
19034         is_ip6 = 1;
19035       else if (unformat (input, "ip4"))
19036         is_ip6 = 0;
19037       else
19038         break;
19039     }
19040   if (table_id == ~0)
19041     {
19042       errmsg ("missing table id");
19043       return -99;
19044     }
19045
19046   M (IP_MROUTE_DUMP, mp);
19047   mp->table.table_id = table_id;
19048   mp->table.is_ip6 = is_ip6;
19049   S (mp);
19050
19051   /* Use a control ping for synchronization */
19052   MPING (CONTROL_PING, mp_ping);
19053   S (mp_ping);
19054
19055   W (ret);
19056   return ret;
19057 }
19058
19059 static void vl_api_ip_neighbor_details_t_handler
19060   (vl_api_ip_neighbor_details_t * mp)
19061 {
19062   vat_main_t *vam = &vat_main;
19063
19064   print (vam->ofp, "%c %U %U",
19065          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19066          format_vl_api_mac_address, &mp->neighbor.mac_address,
19067          format_vl_api_address, &mp->neighbor.ip_address);
19068 }
19069
19070 static void vl_api_ip_neighbor_details_t_handler_json
19071   (vl_api_ip_neighbor_details_t * mp)
19072 {
19073
19074   vat_main_t *vam = &vat_main;
19075   vat_json_node_t *node;
19076
19077   if (VAT_JSON_ARRAY != vam->json_tree.type)
19078     {
19079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19080       vat_json_init_array (&vam->json_tree);
19081     }
19082   node = vat_json_array_add (&vam->json_tree);
19083
19084   vat_json_init_object (node);
19085   vat_json_object_add_string_copy
19086     (node, "flag",
19087      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19088       (u8 *) "static" : (u8 *) "dynamic"));
19089
19090   vat_json_object_add_string_copy (node, "link_layer",
19091                                    format (0, "%U", format_vl_api_mac_address,
19092                                            &mp->neighbor.mac_address));
19093   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19094 }
19095
19096 static int
19097 api_ip_neighbor_dump (vat_main_t * vam)
19098 {
19099   unformat_input_t *i = vam->input;
19100   vl_api_ip_neighbor_dump_t *mp;
19101   vl_api_control_ping_t *mp_ping;
19102   u8 is_ipv6 = 0;
19103   u32 sw_if_index = ~0;
19104   int ret;
19105
19106   /* Parse args required to build the message */
19107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19108     {
19109       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19110         ;
19111       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19112         ;
19113       else if (unformat (i, "ip6"))
19114         is_ipv6 = 1;
19115       else
19116         break;
19117     }
19118
19119   if (sw_if_index == ~0)
19120     {
19121       errmsg ("missing interface name or sw_if_index");
19122       return -99;
19123     }
19124
19125   M (IP_NEIGHBOR_DUMP, mp);
19126   mp->is_ipv6 = (u8) is_ipv6;
19127   mp->sw_if_index = ntohl (sw_if_index);
19128   S (mp);
19129
19130   /* Use a control ping for synchronization */
19131   MPING (CONTROL_PING, mp_ping);
19132   S (mp_ping);
19133
19134   W (ret);
19135   return ret;
19136 }
19137
19138 #define vl_api_ip_route_details_t_endian vl_noop_handler
19139 #define vl_api_ip_route_details_t_print vl_noop_handler
19140
19141 static void
19142 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19143 {
19144   vat_main_t *vam = &vat_main;
19145   u8 count = mp->route.n_paths;
19146   vl_api_fib_path_t *fp;
19147   int i;
19148
19149   print (vam->ofp,
19150          "table-id %d, prefix %U/%d",
19151          ntohl (mp->route.table_id),
19152          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19153   for (i = 0; i < count; i++)
19154     {
19155       fp = &mp->route.paths[i];
19156
19157       vl_api_fib_path_print (vam, fp);
19158       fp++;
19159     }
19160 }
19161
19162 static void vl_api_ip_route_details_t_handler_json
19163   (vl_api_ip_route_details_t * mp)
19164 {
19165   vat_main_t *vam = &vat_main;
19166   u8 count = mp->route.n_paths;
19167   vat_json_node_t *node = NULL;
19168   struct in_addr ip4;
19169   struct in6_addr ip6;
19170   vl_api_fib_path_t *fp;
19171   int i;
19172
19173   if (VAT_JSON_ARRAY != vam->json_tree.type)
19174     {
19175       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19176       vat_json_init_array (&vam->json_tree);
19177     }
19178   node = vat_json_array_add (&vam->json_tree);
19179
19180   vat_json_init_object (node);
19181   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19182   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19183     {
19184       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19185       vat_json_object_add_ip6 (node, "prefix", ip6);
19186     }
19187   else
19188     {
19189       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19190       vat_json_object_add_ip4 (node, "prefix", ip4);
19191     }
19192   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19193   vat_json_object_add_uint (node, "path_count", count);
19194   for (i = 0; i < count; i++)
19195     {
19196       fp = &mp->route.paths[i];
19197       vl_api_mpls_fib_path_json_print (node, fp);
19198     }
19199 }
19200
19201 static int
19202 api_ip_route_dump (vat_main_t * vam)
19203 {
19204   unformat_input_t *input = vam->input;
19205   vl_api_ip_route_dump_t *mp;
19206   vl_api_control_ping_t *mp_ping;
19207   u32 table_id;
19208   u8 is_ip6;
19209   int ret;
19210
19211   is_ip6 = 0;
19212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19213     {
19214       if (unformat (input, "table_id %d", &table_id))
19215         ;
19216       else if (unformat (input, "ip6"))
19217         is_ip6 = 1;
19218       else if (unformat (input, "ip4"))
19219         is_ip6 = 0;
19220       else
19221         break;
19222     }
19223   if (table_id == ~0)
19224     {
19225       errmsg ("missing table id");
19226       return -99;
19227     }
19228
19229   M (IP_ROUTE_DUMP, mp);
19230
19231   mp->table.table_id = table_id;
19232   mp->table.is_ip6 = is_ip6;
19233
19234   S (mp);
19235
19236   /* Use a control ping for synchronization */
19237   MPING (CONTROL_PING, mp_ping);
19238   S (mp_ping);
19239
19240   W (ret);
19241   return ret;
19242 }
19243
19244 int
19245 api_classify_table_ids (vat_main_t * vam)
19246 {
19247   vl_api_classify_table_ids_t *mp;
19248   int ret;
19249
19250   /* Construct the API message */
19251   M (CLASSIFY_TABLE_IDS, mp);
19252   mp->context = 0;
19253
19254   S (mp);
19255   W (ret);
19256   return ret;
19257 }
19258
19259 int
19260 api_classify_table_by_interface (vat_main_t * vam)
19261 {
19262   unformat_input_t *input = vam->input;
19263   vl_api_classify_table_by_interface_t *mp;
19264
19265   u32 sw_if_index = ~0;
19266   int ret;
19267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19268     {
19269       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19270         ;
19271       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19272         ;
19273       else
19274         break;
19275     }
19276   if (sw_if_index == ~0)
19277     {
19278       errmsg ("missing interface name or sw_if_index");
19279       return -99;
19280     }
19281
19282   /* Construct the API message */
19283   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19284   mp->context = 0;
19285   mp->sw_if_index = ntohl (sw_if_index);
19286
19287   S (mp);
19288   W (ret);
19289   return ret;
19290 }
19291
19292 int
19293 api_classify_table_info (vat_main_t * vam)
19294 {
19295   unformat_input_t *input = vam->input;
19296   vl_api_classify_table_info_t *mp;
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_TABLE_INFO, mp);
19315   mp->context = 0;
19316   mp->table_id = ntohl (table_id);
19317
19318   S (mp);
19319   W (ret);
19320   return ret;
19321 }
19322
19323 int
19324 api_classify_session_dump (vat_main_t * vam)
19325 {
19326   unformat_input_t *input = vam->input;
19327   vl_api_classify_session_dump_t *mp;
19328   vl_api_control_ping_t *mp_ping;
19329
19330   u32 table_id = ~0;
19331   int ret;
19332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19333     {
19334       if (unformat (input, "table_id %d", &table_id))
19335         ;
19336       else
19337         break;
19338     }
19339   if (table_id == ~0)
19340     {
19341       errmsg ("missing table id");
19342       return -99;
19343     }
19344
19345   /* Construct the API message */
19346   M (CLASSIFY_SESSION_DUMP, mp);
19347   mp->context = 0;
19348   mp->table_id = ntohl (table_id);
19349   S (mp);
19350
19351   /* Use a control ping for synchronization */
19352   MPING (CONTROL_PING, mp_ping);
19353   S (mp_ping);
19354
19355   W (ret);
19356   return ret;
19357 }
19358
19359 static void
19360 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19361 {
19362   vat_main_t *vam = &vat_main;
19363
19364   print (vam->ofp, "collector_address %U, collector_port %d, "
19365          "src_address %U, vrf_id %d, path_mtu %u, "
19366          "template_interval %u, udp_checksum %d",
19367          format_ip4_address, mp->collector_address,
19368          ntohs (mp->collector_port),
19369          format_ip4_address, mp->src_address,
19370          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19371          ntohl (mp->template_interval), mp->udp_checksum);
19372
19373   vam->retval = 0;
19374   vam->result_ready = 1;
19375 }
19376
19377 static void
19378   vl_api_ipfix_exporter_details_t_handler_json
19379   (vl_api_ipfix_exporter_details_t * mp)
19380 {
19381   vat_main_t *vam = &vat_main;
19382   vat_json_node_t node;
19383   struct in_addr collector_address;
19384   struct in_addr src_address;
19385
19386   vat_json_init_object (&node);
19387   clib_memcpy (&collector_address, &mp->collector_address,
19388                sizeof (collector_address));
19389   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19390   vat_json_object_add_uint (&node, "collector_port",
19391                             ntohs (mp->collector_port));
19392   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19393   vat_json_object_add_ip4 (&node, "src_address", src_address);
19394   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19395   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19396   vat_json_object_add_uint (&node, "template_interval",
19397                             ntohl (mp->template_interval));
19398   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19399
19400   vat_json_print (vam->ofp, &node);
19401   vat_json_free (&node);
19402   vam->retval = 0;
19403   vam->result_ready = 1;
19404 }
19405
19406 int
19407 api_ipfix_exporter_dump (vat_main_t * vam)
19408 {
19409   vl_api_ipfix_exporter_dump_t *mp;
19410   int ret;
19411
19412   /* Construct the API message */
19413   M (IPFIX_EXPORTER_DUMP, mp);
19414   mp->context = 0;
19415
19416   S (mp);
19417   W (ret);
19418   return ret;
19419 }
19420
19421 static int
19422 api_ipfix_classify_stream_dump (vat_main_t * vam)
19423 {
19424   vl_api_ipfix_classify_stream_dump_t *mp;
19425   int ret;
19426
19427   /* Construct the API message */
19428   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19429   mp->context = 0;
19430
19431   S (mp);
19432   W (ret);
19433   return ret;
19434   /* NOTREACHED */
19435   return 0;
19436 }
19437
19438 static void
19439   vl_api_ipfix_classify_stream_details_t_handler
19440   (vl_api_ipfix_classify_stream_details_t * mp)
19441 {
19442   vat_main_t *vam = &vat_main;
19443   print (vam->ofp, "domain_id %d, src_port %d",
19444          ntohl (mp->domain_id), ntohs (mp->src_port));
19445   vam->retval = 0;
19446   vam->result_ready = 1;
19447 }
19448
19449 static void
19450   vl_api_ipfix_classify_stream_details_t_handler_json
19451   (vl_api_ipfix_classify_stream_details_t * mp)
19452 {
19453   vat_main_t *vam = &vat_main;
19454   vat_json_node_t node;
19455
19456   vat_json_init_object (&node);
19457   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19458   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19459
19460   vat_json_print (vam->ofp, &node);
19461   vat_json_free (&node);
19462   vam->retval = 0;
19463   vam->result_ready = 1;
19464 }
19465
19466 static int
19467 api_ipfix_classify_table_dump (vat_main_t * vam)
19468 {
19469   vl_api_ipfix_classify_table_dump_t *mp;
19470   vl_api_control_ping_t *mp_ping;
19471   int ret;
19472
19473   if (!vam->json_output)
19474     {
19475       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19476              "transport_protocol");
19477     }
19478
19479   /* Construct the API message */
19480   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19481
19482   /* send it... */
19483   S (mp);
19484
19485   /* Use a control ping for synchronization */
19486   MPING (CONTROL_PING, mp_ping);
19487   S (mp_ping);
19488
19489   W (ret);
19490   return ret;
19491 }
19492
19493 static void
19494   vl_api_ipfix_classify_table_details_t_handler
19495   (vl_api_ipfix_classify_table_details_t * mp)
19496 {
19497   vat_main_t *vam = &vat_main;
19498   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19499          mp->transport_protocol);
19500 }
19501
19502 static void
19503   vl_api_ipfix_classify_table_details_t_handler_json
19504   (vl_api_ipfix_classify_table_details_t * mp)
19505 {
19506   vat_json_node_t *node = NULL;
19507   vat_main_t *vam = &vat_main;
19508
19509   if (VAT_JSON_ARRAY != vam->json_tree.type)
19510     {
19511       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19512       vat_json_init_array (&vam->json_tree);
19513     }
19514
19515   node = vat_json_array_add (&vam->json_tree);
19516   vat_json_init_object (node);
19517
19518   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19519   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19520   vat_json_object_add_uint (node, "transport_protocol",
19521                             mp->transport_protocol);
19522 }
19523
19524 static int
19525 api_sw_interface_span_enable_disable (vat_main_t * vam)
19526 {
19527   unformat_input_t *i = vam->input;
19528   vl_api_sw_interface_span_enable_disable_t *mp;
19529   u32 src_sw_if_index = ~0;
19530   u32 dst_sw_if_index = ~0;
19531   u8 state = 3;
19532   int ret;
19533   u8 is_l2 = 0;
19534
19535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19536     {
19537       if (unformat
19538           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19539         ;
19540       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19541         ;
19542       else
19543         if (unformat
19544             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19545         ;
19546       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19547         ;
19548       else if (unformat (i, "disable"))
19549         state = 0;
19550       else if (unformat (i, "rx"))
19551         state = 1;
19552       else if (unformat (i, "tx"))
19553         state = 2;
19554       else if (unformat (i, "both"))
19555         state = 3;
19556       else if (unformat (i, "l2"))
19557         is_l2 = 1;
19558       else
19559         break;
19560     }
19561
19562   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19563
19564   mp->sw_if_index_from = htonl (src_sw_if_index);
19565   mp->sw_if_index_to = htonl (dst_sw_if_index);
19566   mp->state = state;
19567   mp->is_l2 = is_l2;
19568
19569   S (mp);
19570   W (ret);
19571   return ret;
19572 }
19573
19574 static void
19575 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19576                                             * mp)
19577 {
19578   vat_main_t *vam = &vat_main;
19579   u8 *sw_if_from_name = 0;
19580   u8 *sw_if_to_name = 0;
19581   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19582   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19583   char *states[] = { "none", "rx", "tx", "both" };
19584   hash_pair_t *p;
19585
19586   /* *INDENT-OFF* */
19587   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19588   ({
19589     if ((u32) p->value[0] == sw_if_index_from)
19590       {
19591         sw_if_from_name = (u8 *)(p->key);
19592         if (sw_if_to_name)
19593           break;
19594       }
19595     if ((u32) p->value[0] == sw_if_index_to)
19596       {
19597         sw_if_to_name = (u8 *)(p->key);
19598         if (sw_if_from_name)
19599           break;
19600       }
19601   }));
19602   /* *INDENT-ON* */
19603   print (vam->ofp, "%20s => %20s (%s) %s",
19604          sw_if_from_name, sw_if_to_name, states[mp->state],
19605          mp->is_l2 ? "l2" : "device");
19606 }
19607
19608 static void
19609   vl_api_sw_interface_span_details_t_handler_json
19610   (vl_api_sw_interface_span_details_t * mp)
19611 {
19612   vat_main_t *vam = &vat_main;
19613   vat_json_node_t *node = NULL;
19614   u8 *sw_if_from_name = 0;
19615   u8 *sw_if_to_name = 0;
19616   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19617   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19618   hash_pair_t *p;
19619
19620   /* *INDENT-OFF* */
19621   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19622   ({
19623     if ((u32) p->value[0] == sw_if_index_from)
19624       {
19625         sw_if_from_name = (u8 *)(p->key);
19626         if (sw_if_to_name)
19627           break;
19628       }
19629     if ((u32) p->value[0] == sw_if_index_to)
19630       {
19631         sw_if_to_name = (u8 *)(p->key);
19632         if (sw_if_from_name)
19633           break;
19634       }
19635   }));
19636   /* *INDENT-ON* */
19637
19638   if (VAT_JSON_ARRAY != vam->json_tree.type)
19639     {
19640       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19641       vat_json_init_array (&vam->json_tree);
19642     }
19643   node = vat_json_array_add (&vam->json_tree);
19644
19645   vat_json_init_object (node);
19646   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19647   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19648   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19649   if (0 != sw_if_to_name)
19650     {
19651       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19652     }
19653   vat_json_object_add_uint (node, "state", mp->state);
19654   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19655 }
19656
19657 static int
19658 api_sw_interface_span_dump (vat_main_t * vam)
19659 {
19660   unformat_input_t *input = vam->input;
19661   vl_api_sw_interface_span_dump_t *mp;
19662   vl_api_control_ping_t *mp_ping;
19663   u8 is_l2 = 0;
19664   int ret;
19665
19666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19667     {
19668       if (unformat (input, "l2"))
19669         is_l2 = 1;
19670       else
19671         break;
19672     }
19673
19674   M (SW_INTERFACE_SPAN_DUMP, mp);
19675   mp->is_l2 = is_l2;
19676   S (mp);
19677
19678   /* Use a control ping for synchronization */
19679   MPING (CONTROL_PING, mp_ping);
19680   S (mp_ping);
19681
19682   W (ret);
19683   return ret;
19684 }
19685
19686 int
19687 api_pg_create_interface (vat_main_t * vam)
19688 {
19689   unformat_input_t *input = vam->input;
19690   vl_api_pg_create_interface_t *mp;
19691
19692   u32 if_id = ~0, gso_size = 0;
19693   u8 gso_enabled = 0;
19694   int ret;
19695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19696     {
19697       if (unformat (input, "if_id %d", &if_id))
19698         ;
19699       else if (unformat (input, "gso-enabled"))
19700         {
19701           gso_enabled = 1;
19702           if (unformat (input, "gso-size %u", &gso_size))
19703             ;
19704           else
19705             {
19706               errmsg ("missing gso-size");
19707               return -99;
19708             }
19709         }
19710       else
19711         break;
19712     }
19713   if (if_id == ~0)
19714     {
19715       errmsg ("missing pg interface index");
19716       return -99;
19717     }
19718
19719   /* Construct the API message */
19720   M (PG_CREATE_INTERFACE, mp);
19721   mp->context = 0;
19722   mp->interface_id = ntohl (if_id);
19723   mp->gso_enabled = gso_enabled;
19724
19725   S (mp);
19726   W (ret);
19727   return ret;
19728 }
19729
19730 int
19731 api_pg_capture (vat_main_t * vam)
19732 {
19733   unformat_input_t *input = vam->input;
19734   vl_api_pg_capture_t *mp;
19735
19736   u32 if_id = ~0;
19737   u8 enable = 1;
19738   u32 count = 1;
19739   u8 pcap_file_set = 0;
19740   u8 *pcap_file = 0;
19741   int ret;
19742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19743     {
19744       if (unformat (input, "if_id %d", &if_id))
19745         ;
19746       else if (unformat (input, "pcap %s", &pcap_file))
19747         pcap_file_set = 1;
19748       else if (unformat (input, "count %d", &count))
19749         ;
19750       else if (unformat (input, "disable"))
19751         enable = 0;
19752       else
19753         break;
19754     }
19755   if (if_id == ~0)
19756     {
19757       errmsg ("missing pg interface index");
19758       return -99;
19759     }
19760   if (pcap_file_set > 0)
19761     {
19762       if (vec_len (pcap_file) > 255)
19763         {
19764           errmsg ("pcap file name is too long");
19765           return -99;
19766         }
19767     }
19768
19769   u32 name_len = vec_len (pcap_file);
19770   /* Construct the API message */
19771   M (PG_CAPTURE, mp);
19772   mp->context = 0;
19773   mp->interface_id = ntohl (if_id);
19774   mp->is_enabled = enable;
19775   mp->count = ntohl (count);
19776   mp->pcap_name_length = ntohl (name_len);
19777   if (pcap_file_set != 0)
19778     {
19779       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19780     }
19781   vec_free (pcap_file);
19782
19783   S (mp);
19784   W (ret);
19785   return ret;
19786 }
19787
19788 int
19789 api_pg_enable_disable (vat_main_t * vam)
19790 {
19791   unformat_input_t *input = vam->input;
19792   vl_api_pg_enable_disable_t *mp;
19793
19794   u8 enable = 1;
19795   u8 stream_name_set = 0;
19796   u8 *stream_name = 0;
19797   int ret;
19798   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19799     {
19800       if (unformat (input, "stream %s", &stream_name))
19801         stream_name_set = 1;
19802       else if (unformat (input, "disable"))
19803         enable = 0;
19804       else
19805         break;
19806     }
19807
19808   if (stream_name_set > 0)
19809     {
19810       if (vec_len (stream_name) > 255)
19811         {
19812           errmsg ("stream name too long");
19813           return -99;
19814         }
19815     }
19816
19817   u32 name_len = vec_len (stream_name);
19818   /* Construct the API message */
19819   M (PG_ENABLE_DISABLE, mp);
19820   mp->context = 0;
19821   mp->is_enabled = enable;
19822   if (stream_name_set != 0)
19823     {
19824       mp->stream_name_length = ntohl (name_len);
19825       clib_memcpy (mp->stream_name, stream_name, name_len);
19826     }
19827   vec_free (stream_name);
19828
19829   S (mp);
19830   W (ret);
19831   return ret;
19832 }
19833
19834 int
19835 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19836 {
19837   unformat_input_t *input = vam->input;
19838   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19839
19840   u16 *low_ports = 0;
19841   u16 *high_ports = 0;
19842   u16 this_low;
19843   u16 this_hi;
19844   vl_api_prefix_t prefix;
19845   u32 tmp, tmp2;
19846   u8 prefix_set = 0;
19847   u32 vrf_id = ~0;
19848   u8 is_add = 1;
19849   int ret;
19850
19851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19852     {
19853       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19854         prefix_set = 1;
19855       else if (unformat (input, "vrf %d", &vrf_id))
19856         ;
19857       else if (unformat (input, "del"))
19858         is_add = 0;
19859       else if (unformat (input, "port %d", &tmp))
19860         {
19861           if (tmp == 0 || tmp > 65535)
19862             {
19863               errmsg ("port %d out of range", tmp);
19864               return -99;
19865             }
19866           this_low = tmp;
19867           this_hi = this_low + 1;
19868           vec_add1 (low_ports, this_low);
19869           vec_add1 (high_ports, this_hi);
19870         }
19871       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19872         {
19873           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19874             {
19875               errmsg ("incorrect range parameters");
19876               return -99;
19877             }
19878           this_low = tmp;
19879           /* Note: in debug CLI +1 is added to high before
19880              passing to real fn that does "the work"
19881              (ip_source_and_port_range_check_add_del).
19882              This fn is a wrapper around the binary API fn a
19883              control plane will call, which expects this increment
19884              to have occurred. Hence letting the binary API control
19885              plane fn do the increment for consistency between VAT
19886              and other control planes.
19887            */
19888           this_hi = tmp2;
19889           vec_add1 (low_ports, this_low);
19890           vec_add1 (high_ports, this_hi);
19891         }
19892       else
19893         break;
19894     }
19895
19896   if (prefix_set == 0)
19897     {
19898       errmsg ("<address>/<mask> not specified");
19899       return -99;
19900     }
19901
19902   if (vrf_id == ~0)
19903     {
19904       errmsg ("VRF ID required, not specified");
19905       return -99;
19906     }
19907
19908   if (vrf_id == 0)
19909     {
19910       errmsg
19911         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19912       return -99;
19913     }
19914
19915   if (vec_len (low_ports) == 0)
19916     {
19917       errmsg ("At least one port or port range required");
19918       return -99;
19919     }
19920
19921   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19922
19923   mp->is_add = is_add;
19924
19925   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19926
19927   mp->number_of_ranges = vec_len (low_ports);
19928
19929   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19930   vec_free (low_ports);
19931
19932   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19933   vec_free (high_ports);
19934
19935   mp->vrf_id = ntohl (vrf_id);
19936
19937   S (mp);
19938   W (ret);
19939   return ret;
19940 }
19941
19942 int
19943 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19944 {
19945   unformat_input_t *input = vam->input;
19946   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19947   u32 sw_if_index = ~0;
19948   int vrf_set = 0;
19949   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19950   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19951   u8 is_add = 1;
19952   int ret;
19953
19954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19955     {
19956       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19957         ;
19958       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19959         ;
19960       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19961         vrf_set = 1;
19962       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19963         vrf_set = 1;
19964       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19965         vrf_set = 1;
19966       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19967         vrf_set = 1;
19968       else if (unformat (input, "del"))
19969         is_add = 0;
19970       else
19971         break;
19972     }
19973
19974   if (sw_if_index == ~0)
19975     {
19976       errmsg ("Interface required but not specified");
19977       return -99;
19978     }
19979
19980   if (vrf_set == 0)
19981     {
19982       errmsg ("VRF ID required but not specified");
19983       return -99;
19984     }
19985
19986   if (tcp_out_vrf_id == 0
19987       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19988     {
19989       errmsg
19990         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19991       return -99;
19992     }
19993
19994   /* Construct the API message */
19995   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19996
19997   mp->sw_if_index = ntohl (sw_if_index);
19998   mp->is_add = is_add;
19999   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20000   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20001   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20002   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20003
20004   /* send it... */
20005   S (mp);
20006
20007   /* Wait for a reply... */
20008   W (ret);
20009   return ret;
20010 }
20011
20012 static int
20013 api_set_punt (vat_main_t * vam)
20014 {
20015   unformat_input_t *i = vam->input;
20016   vl_api_address_family_t af;
20017   vl_api_set_punt_t *mp;
20018   u32 protocol = ~0;
20019   u32 port = ~0;
20020   int is_add = 1;
20021   int ret;
20022
20023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20024     {
20025       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20026         ;
20027       else if (unformat (i, "protocol %d", &protocol))
20028         ;
20029       else if (unformat (i, "port %d", &port))
20030         ;
20031       else if (unformat (i, "del"))
20032         is_add = 0;
20033       else
20034         {
20035           clib_warning ("parse error '%U'", format_unformat_error, i);
20036           return -99;
20037         }
20038     }
20039
20040   M (SET_PUNT, mp);
20041
20042   mp->is_add = (u8) is_add;
20043   mp->punt.type = PUNT_API_TYPE_L4;
20044   mp->punt.punt.l4.af = af;
20045   mp->punt.punt.l4.protocol = (u8) protocol;
20046   mp->punt.punt.l4.port = htons ((u16) port);
20047
20048   S (mp);
20049   W (ret);
20050   return ret;
20051 }
20052
20053 static int
20054 api_delete_subif (vat_main_t * vam)
20055 {
20056   unformat_input_t *i = vam->input;
20057   vl_api_delete_subif_t *mp;
20058   u32 sw_if_index = ~0;
20059   int ret;
20060
20061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20062     {
20063       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20064         ;
20065       if (unformat (i, "sw_if_index %d", &sw_if_index))
20066         ;
20067       else
20068         break;
20069     }
20070
20071   if (sw_if_index == ~0)
20072     {
20073       errmsg ("missing sw_if_index");
20074       return -99;
20075     }
20076
20077   /* Construct the API message */
20078   M (DELETE_SUBIF, mp);
20079   mp->sw_if_index = ntohl (sw_if_index);
20080
20081   S (mp);
20082   W (ret);
20083   return ret;
20084 }
20085
20086 #define foreach_pbb_vtr_op      \
20087 _("disable",  L2_VTR_DISABLED)  \
20088 _("pop",  L2_VTR_POP_2)         \
20089 _("push",  L2_VTR_PUSH_2)
20090
20091 static int
20092 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20093 {
20094   unformat_input_t *i = vam->input;
20095   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20096   u32 sw_if_index = ~0, vtr_op = ~0;
20097   u16 outer_tag = ~0;
20098   u8 dmac[6], smac[6];
20099   u8 dmac_set = 0, smac_set = 0;
20100   u16 vlanid = 0;
20101   u32 sid = ~0;
20102   u32 tmp;
20103   int ret;
20104
20105   /* Shut up coverity */
20106   clib_memset (dmac, 0, sizeof (dmac));
20107   clib_memset (smac, 0, sizeof (smac));
20108
20109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20110     {
20111       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20112         ;
20113       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20114         ;
20115       else if (unformat (i, "vtr_op %d", &vtr_op))
20116         ;
20117 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20118       foreach_pbb_vtr_op
20119 #undef _
20120         else if (unformat (i, "translate_pbb_stag"))
20121         {
20122           if (unformat (i, "%d", &tmp))
20123             {
20124               vtr_op = L2_VTR_TRANSLATE_2_1;
20125               outer_tag = tmp;
20126             }
20127           else
20128             {
20129               errmsg
20130                 ("translate_pbb_stag operation requires outer tag definition");
20131               return -99;
20132             }
20133         }
20134       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20135         dmac_set++;
20136       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20137         smac_set++;
20138       else if (unformat (i, "sid %d", &sid))
20139         ;
20140       else if (unformat (i, "vlanid %d", &tmp))
20141         vlanid = tmp;
20142       else
20143         {
20144           clib_warning ("parse error '%U'", format_unformat_error, i);
20145           return -99;
20146         }
20147     }
20148
20149   if ((sw_if_index == ~0) || (vtr_op == ~0))
20150     {
20151       errmsg ("missing sw_if_index or vtr operation");
20152       return -99;
20153     }
20154   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20155       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20156     {
20157       errmsg
20158         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20159       return -99;
20160     }
20161
20162   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20163   mp->sw_if_index = ntohl (sw_if_index);
20164   mp->vtr_op = ntohl (vtr_op);
20165   mp->outer_tag = ntohs (outer_tag);
20166   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20167   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20168   mp->b_vlanid = ntohs (vlanid);
20169   mp->i_sid = ntohl (sid);
20170
20171   S (mp);
20172   W (ret);
20173   return ret;
20174 }
20175
20176 static int
20177 api_flow_classify_set_interface (vat_main_t * vam)
20178 {
20179   unformat_input_t *i = vam->input;
20180   vl_api_flow_classify_set_interface_t *mp;
20181   u32 sw_if_index;
20182   int sw_if_index_set;
20183   u32 ip4_table_index = ~0;
20184   u32 ip6_table_index = ~0;
20185   u8 is_add = 1;
20186   int ret;
20187
20188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20189     {
20190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20191         sw_if_index_set = 1;
20192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20193         sw_if_index_set = 1;
20194       else if (unformat (i, "del"))
20195         is_add = 0;
20196       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20197         ;
20198       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20199         ;
20200       else
20201         {
20202           clib_warning ("parse error '%U'", format_unformat_error, i);
20203           return -99;
20204         }
20205     }
20206
20207   if (sw_if_index_set == 0)
20208     {
20209       errmsg ("missing interface name or sw_if_index");
20210       return -99;
20211     }
20212
20213   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20214
20215   mp->sw_if_index = ntohl (sw_if_index);
20216   mp->ip4_table_index = ntohl (ip4_table_index);
20217   mp->ip6_table_index = ntohl (ip6_table_index);
20218   mp->is_add = is_add;
20219
20220   S (mp);
20221   W (ret);
20222   return ret;
20223 }
20224
20225 static int
20226 api_flow_classify_dump (vat_main_t * vam)
20227 {
20228   unformat_input_t *i = vam->input;
20229   vl_api_flow_classify_dump_t *mp;
20230   vl_api_control_ping_t *mp_ping;
20231   u8 type = FLOW_CLASSIFY_N_TABLES;
20232   int ret;
20233
20234   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20235     ;
20236   else
20237     {
20238       errmsg ("classify table type must be specified");
20239       return -99;
20240     }
20241
20242   if (!vam->json_output)
20243     {
20244       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20245     }
20246
20247   M (FLOW_CLASSIFY_DUMP, mp);
20248   mp->type = type;
20249   /* send it... */
20250   S (mp);
20251
20252   /* Use a control ping for synchronization */
20253   MPING (CONTROL_PING, mp_ping);
20254   S (mp_ping);
20255
20256   /* Wait for a reply... */
20257   W (ret);
20258   return ret;
20259 }
20260
20261 static int
20262 api_feature_enable_disable (vat_main_t * vam)
20263 {
20264   unformat_input_t *i = vam->input;
20265   vl_api_feature_enable_disable_t *mp;
20266   u8 *arc_name = 0;
20267   u8 *feature_name = 0;
20268   u32 sw_if_index = ~0;
20269   u8 enable = 1;
20270   int ret;
20271
20272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20273     {
20274       if (unformat (i, "arc_name %s", &arc_name))
20275         ;
20276       else if (unformat (i, "feature_name %s", &feature_name))
20277         ;
20278       else
20279         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20280         ;
20281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20282         ;
20283       else if (unformat (i, "disable"))
20284         enable = 0;
20285       else
20286         break;
20287     }
20288
20289   if (arc_name == 0)
20290     {
20291       errmsg ("missing arc name");
20292       return -99;
20293     }
20294   if (vec_len (arc_name) > 63)
20295     {
20296       errmsg ("arc name too long");
20297     }
20298
20299   if (feature_name == 0)
20300     {
20301       errmsg ("missing feature name");
20302       return -99;
20303     }
20304   if (vec_len (feature_name) > 63)
20305     {
20306       errmsg ("feature name too long");
20307     }
20308
20309   if (sw_if_index == ~0)
20310     {
20311       errmsg ("missing interface name or sw_if_index");
20312       return -99;
20313     }
20314
20315   /* Construct the API message */
20316   M (FEATURE_ENABLE_DISABLE, mp);
20317   mp->sw_if_index = ntohl (sw_if_index);
20318   mp->enable = enable;
20319   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20320   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20321   vec_free (arc_name);
20322   vec_free (feature_name);
20323
20324   S (mp);
20325   W (ret);
20326   return ret;
20327 }
20328
20329 static int
20330 api_sw_interface_tag_add_del (vat_main_t * vam)
20331 {
20332   unformat_input_t *i = vam->input;
20333   vl_api_sw_interface_tag_add_del_t *mp;
20334   u32 sw_if_index = ~0;
20335   u8 *tag = 0;
20336   u8 enable = 1;
20337   int ret;
20338
20339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20340     {
20341       if (unformat (i, "tag %s", &tag))
20342         ;
20343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20344         ;
20345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20346         ;
20347       else if (unformat (i, "del"))
20348         enable = 0;
20349       else
20350         break;
20351     }
20352
20353   if (sw_if_index == ~0)
20354     {
20355       errmsg ("missing interface name or sw_if_index");
20356       return -99;
20357     }
20358
20359   if (enable && (tag == 0))
20360     {
20361       errmsg ("no tag specified");
20362       return -99;
20363     }
20364
20365   /* Construct the API message */
20366   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20367   mp->sw_if_index = ntohl (sw_if_index);
20368   mp->is_add = enable;
20369   if (enable)
20370     vl_api_to_api_string (strlen ((char *) tag), (char *) tag, &mp->tag);
20371   vec_free (tag);
20372
20373   S (mp);
20374   W (ret);
20375   return ret;
20376 }
20377
20378 static void vl_api_l2_xconnect_details_t_handler
20379   (vl_api_l2_xconnect_details_t * mp)
20380 {
20381   vat_main_t *vam = &vat_main;
20382
20383   print (vam->ofp, "%15d%15d",
20384          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20385 }
20386
20387 static void vl_api_l2_xconnect_details_t_handler_json
20388   (vl_api_l2_xconnect_details_t * mp)
20389 {
20390   vat_main_t *vam = &vat_main;
20391   vat_json_node_t *node = NULL;
20392
20393   if (VAT_JSON_ARRAY != vam->json_tree.type)
20394     {
20395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20396       vat_json_init_array (&vam->json_tree);
20397     }
20398   node = vat_json_array_add (&vam->json_tree);
20399
20400   vat_json_init_object (node);
20401   vat_json_object_add_uint (node, "rx_sw_if_index",
20402                             ntohl (mp->rx_sw_if_index));
20403   vat_json_object_add_uint (node, "tx_sw_if_index",
20404                             ntohl (mp->tx_sw_if_index));
20405 }
20406
20407 static int
20408 api_l2_xconnect_dump (vat_main_t * vam)
20409 {
20410   vl_api_l2_xconnect_dump_t *mp;
20411   vl_api_control_ping_t *mp_ping;
20412   int ret;
20413
20414   if (!vam->json_output)
20415     {
20416       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20417     }
20418
20419   M (L2_XCONNECT_DUMP, mp);
20420
20421   S (mp);
20422
20423   /* Use a control ping for synchronization */
20424   MPING (CONTROL_PING, mp_ping);
20425   S (mp_ping);
20426
20427   W (ret);
20428   return ret;
20429 }
20430
20431 static int
20432 api_hw_interface_set_mtu (vat_main_t * vam)
20433 {
20434   unformat_input_t *i = vam->input;
20435   vl_api_hw_interface_set_mtu_t *mp;
20436   u32 sw_if_index = ~0;
20437   u32 mtu = 0;
20438   int ret;
20439
20440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20441     {
20442       if (unformat (i, "mtu %d", &mtu))
20443         ;
20444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20445         ;
20446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20447         ;
20448       else
20449         break;
20450     }
20451
20452   if (sw_if_index == ~0)
20453     {
20454       errmsg ("missing interface name or sw_if_index");
20455       return -99;
20456     }
20457
20458   if (mtu == 0)
20459     {
20460       errmsg ("no mtu specified");
20461       return -99;
20462     }
20463
20464   /* Construct the API message */
20465   M (HW_INTERFACE_SET_MTU, mp);
20466   mp->sw_if_index = ntohl (sw_if_index);
20467   mp->mtu = ntohs ((u16) mtu);
20468
20469   S (mp);
20470   W (ret);
20471   return ret;
20472 }
20473
20474 static int
20475 api_p2p_ethernet_add (vat_main_t * vam)
20476 {
20477   unformat_input_t *i = vam->input;
20478   vl_api_p2p_ethernet_add_t *mp;
20479   u32 parent_if_index = ~0;
20480   u32 sub_id = ~0;
20481   u8 remote_mac[6];
20482   u8 mac_set = 0;
20483   int ret;
20484
20485   clib_memset (remote_mac, 0, sizeof (remote_mac));
20486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20487     {
20488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20489         ;
20490       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20491         ;
20492       else
20493         if (unformat
20494             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20495         mac_set++;
20496       else if (unformat (i, "sub_id %d", &sub_id))
20497         ;
20498       else
20499         {
20500           clib_warning ("parse error '%U'", format_unformat_error, i);
20501           return -99;
20502         }
20503     }
20504
20505   if (parent_if_index == ~0)
20506     {
20507       errmsg ("missing interface name or sw_if_index");
20508       return -99;
20509     }
20510   if (mac_set == 0)
20511     {
20512       errmsg ("missing remote mac address");
20513       return -99;
20514     }
20515   if (sub_id == ~0)
20516     {
20517       errmsg ("missing sub-interface id");
20518       return -99;
20519     }
20520
20521   M (P2P_ETHERNET_ADD, mp);
20522   mp->parent_if_index = ntohl (parent_if_index);
20523   mp->subif_id = ntohl (sub_id);
20524   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20525
20526   S (mp);
20527   W (ret);
20528   return ret;
20529 }
20530
20531 static int
20532 api_p2p_ethernet_del (vat_main_t * vam)
20533 {
20534   unformat_input_t *i = vam->input;
20535   vl_api_p2p_ethernet_del_t *mp;
20536   u32 parent_if_index = ~0;
20537   u8 remote_mac[6];
20538   u8 mac_set = 0;
20539   int ret;
20540
20541   clib_memset (remote_mac, 0, sizeof (remote_mac));
20542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20543     {
20544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20545         ;
20546       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20547         ;
20548       else
20549         if (unformat
20550             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20551         mac_set++;
20552       else
20553         {
20554           clib_warning ("parse error '%U'", format_unformat_error, i);
20555           return -99;
20556         }
20557     }
20558
20559   if (parent_if_index == ~0)
20560     {
20561       errmsg ("missing interface name or sw_if_index");
20562       return -99;
20563     }
20564   if (mac_set == 0)
20565     {
20566       errmsg ("missing remote mac address");
20567       return -99;
20568     }
20569
20570   M (P2P_ETHERNET_DEL, mp);
20571   mp->parent_if_index = ntohl (parent_if_index);
20572   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20573
20574   S (mp);
20575   W (ret);
20576   return ret;
20577 }
20578
20579 static int
20580 api_lldp_config (vat_main_t * vam)
20581 {
20582   unformat_input_t *i = vam->input;
20583   vl_api_lldp_config_t *mp;
20584   int tx_hold = 0;
20585   int tx_interval = 0;
20586   u8 *sys_name = NULL;
20587   int ret;
20588
20589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20590     {
20591       if (unformat (i, "system-name %s", &sys_name))
20592         ;
20593       else if (unformat (i, "tx-hold %d", &tx_hold))
20594         ;
20595       else if (unformat (i, "tx-interval %d", &tx_interval))
20596         ;
20597       else
20598         {
20599           clib_warning ("parse error '%U'", format_unformat_error, i);
20600           return -99;
20601         }
20602     }
20603
20604   vec_add1 (sys_name, 0);
20605
20606   M (LLDP_CONFIG, mp);
20607   mp->tx_hold = htonl (tx_hold);
20608   mp->tx_interval = htonl (tx_interval);
20609   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20610   vec_free (sys_name);
20611
20612   S (mp);
20613   W (ret);
20614   return ret;
20615 }
20616
20617 static int
20618 api_sw_interface_set_lldp (vat_main_t * vam)
20619 {
20620   unformat_input_t *i = vam->input;
20621   vl_api_sw_interface_set_lldp_t *mp;
20622   u32 sw_if_index = ~0;
20623   u32 enable = 1;
20624   u8 *port_desc = NULL, *mgmt_oid = NULL;
20625   ip4_address_t ip4_addr;
20626   ip6_address_t ip6_addr;
20627   int ret;
20628
20629   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20630   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20631
20632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20633     {
20634       if (unformat (i, "disable"))
20635         enable = 0;
20636       else
20637         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20638         ;
20639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20640         ;
20641       else if (unformat (i, "port-desc %s", &port_desc))
20642         ;
20643       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20644         ;
20645       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20646         ;
20647       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20648         ;
20649       else
20650         break;
20651     }
20652
20653   if (sw_if_index == ~0)
20654     {
20655       errmsg ("missing interface name or sw_if_index");
20656       return -99;
20657     }
20658
20659   /* Construct the API message */
20660   vec_add1 (port_desc, 0);
20661   vec_add1 (mgmt_oid, 0);
20662   M (SW_INTERFACE_SET_LLDP, mp);
20663   mp->sw_if_index = ntohl (sw_if_index);
20664   mp->enable = enable;
20665   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20666   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20667   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20668   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20669   vec_free (port_desc);
20670   vec_free (mgmt_oid);
20671
20672   S (mp);
20673   W (ret);
20674   return ret;
20675 }
20676
20677 static int
20678 api_tcp_configure_src_addresses (vat_main_t * vam)
20679 {
20680   vl_api_tcp_configure_src_addresses_t *mp;
20681   unformat_input_t *i = vam->input;
20682   ip4_address_t v4first, v4last;
20683   ip6_address_t v6first, v6last;
20684   u8 range_set = 0;
20685   u32 vrf_id = 0;
20686   int ret;
20687
20688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20689     {
20690       if (unformat (i, "%U - %U",
20691                     unformat_ip4_address, &v4first,
20692                     unformat_ip4_address, &v4last))
20693         {
20694           if (range_set)
20695             {
20696               errmsg ("one range per message (range already set)");
20697               return -99;
20698             }
20699           range_set = 1;
20700         }
20701       else if (unformat (i, "%U - %U",
20702                          unformat_ip6_address, &v6first,
20703                          unformat_ip6_address, &v6last))
20704         {
20705           if (range_set)
20706             {
20707               errmsg ("one range per message (range already set)");
20708               return -99;
20709             }
20710           range_set = 2;
20711         }
20712       else if (unformat (i, "vrf %d", &vrf_id))
20713         ;
20714       else
20715         break;
20716     }
20717
20718   if (range_set == 0)
20719     {
20720       errmsg ("address range not set");
20721       return -99;
20722     }
20723
20724   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20725   mp->vrf_id = ntohl (vrf_id);
20726   /* ipv6? */
20727   if (range_set == 2)
20728     {
20729       mp->is_ipv6 = 1;
20730       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20731       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20732     }
20733   else
20734     {
20735       mp->is_ipv6 = 0;
20736       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20737       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20738     }
20739   S (mp);
20740   W (ret);
20741   return ret;
20742 }
20743
20744 static void vl_api_app_namespace_add_del_reply_t_handler
20745   (vl_api_app_namespace_add_del_reply_t * mp)
20746 {
20747   vat_main_t *vam = &vat_main;
20748   i32 retval = ntohl (mp->retval);
20749   if (vam->async_mode)
20750     {
20751       vam->async_errors += (retval < 0);
20752     }
20753   else
20754     {
20755       vam->retval = retval;
20756       if (retval == 0)
20757         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20758       vam->result_ready = 1;
20759     }
20760 }
20761
20762 static void vl_api_app_namespace_add_del_reply_t_handler_json
20763   (vl_api_app_namespace_add_del_reply_t * mp)
20764 {
20765   vat_main_t *vam = &vat_main;
20766   vat_json_node_t node;
20767
20768   vat_json_init_object (&node);
20769   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20770   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20771
20772   vat_json_print (vam->ofp, &node);
20773   vat_json_free (&node);
20774
20775   vam->retval = ntohl (mp->retval);
20776   vam->result_ready = 1;
20777 }
20778
20779 static int
20780 api_app_namespace_add_del (vat_main_t * vam)
20781 {
20782   vl_api_app_namespace_add_del_t *mp;
20783   unformat_input_t *i = vam->input;
20784   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20785   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20786   u64 secret;
20787   int ret;
20788
20789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20790     {
20791       if (unformat (i, "id %_%v%_", &ns_id))
20792         ;
20793       else if (unformat (i, "secret %lu", &secret))
20794         secret_set = 1;
20795       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20796         sw_if_index_set = 1;
20797       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20798         ;
20799       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20800         ;
20801       else
20802         break;
20803     }
20804   if (!ns_id || !secret_set || !sw_if_index_set)
20805     {
20806       errmsg ("namespace id, secret and sw_if_index must be set");
20807       return -99;
20808     }
20809   if (vec_len (ns_id) > 64)
20810     {
20811       errmsg ("namespace id too long");
20812       return -99;
20813     }
20814   M (APP_NAMESPACE_ADD_DEL, mp);
20815
20816   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20817   mp->namespace_id_len = vec_len (ns_id);
20818   mp->secret = clib_host_to_net_u64 (secret);
20819   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20820   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20821   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20822   vec_free (ns_id);
20823   S (mp);
20824   W (ret);
20825   return ret;
20826 }
20827
20828 static int
20829 api_sock_init_shm (vat_main_t * vam)
20830 {
20831 #if VPP_API_TEST_BUILTIN == 0
20832   unformat_input_t *i = vam->input;
20833   vl_api_shm_elem_config_t *config = 0;
20834   u64 size = 64 << 20;
20835   int rv;
20836
20837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20838     {
20839       if (unformat (i, "size %U", unformat_memory_size, &size))
20840         ;
20841       else
20842         break;
20843     }
20844
20845   /*
20846    * Canned custom ring allocator config.
20847    * Should probably parse all of this
20848    */
20849   vec_validate (config, 6);
20850   config[0].type = VL_API_VLIB_RING;
20851   config[0].size = 256;
20852   config[0].count = 32;
20853
20854   config[1].type = VL_API_VLIB_RING;
20855   config[1].size = 1024;
20856   config[1].count = 16;
20857
20858   config[2].type = VL_API_VLIB_RING;
20859   config[2].size = 4096;
20860   config[2].count = 2;
20861
20862   config[3].type = VL_API_CLIENT_RING;
20863   config[3].size = 256;
20864   config[3].count = 32;
20865
20866   config[4].type = VL_API_CLIENT_RING;
20867   config[4].size = 1024;
20868   config[4].count = 16;
20869
20870   config[5].type = VL_API_CLIENT_RING;
20871   config[5].size = 4096;
20872   config[5].count = 2;
20873
20874   config[6].type = VL_API_QUEUE;
20875   config[6].count = 128;
20876   config[6].size = sizeof (uword);
20877
20878   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20879   if (!rv)
20880     vam->client_index_invalid = 1;
20881   return rv;
20882 #else
20883   return -99;
20884 #endif
20885 }
20886
20887 static void
20888 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20889 {
20890   vat_main_t *vam = &vat_main;
20891
20892   if (mp->is_ip4)
20893     {
20894       print (vam->ofp,
20895              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20896              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20897              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20898              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20899              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20900              clib_net_to_host_u32 (mp->action_index), mp->tag);
20901     }
20902   else
20903     {
20904       print (vam->ofp,
20905              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20906              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20907              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20908              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20909              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20910              clib_net_to_host_u32 (mp->action_index), mp->tag);
20911     }
20912 }
20913
20914 static void
20915 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20916                                              mp)
20917 {
20918   vat_main_t *vam = &vat_main;
20919   vat_json_node_t *node = NULL;
20920   struct in6_addr ip6;
20921   struct in_addr ip4;
20922
20923   if (VAT_JSON_ARRAY != vam->json_tree.type)
20924     {
20925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20926       vat_json_init_array (&vam->json_tree);
20927     }
20928   node = vat_json_array_add (&vam->json_tree);
20929   vat_json_init_object (node);
20930
20931   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20932   vat_json_object_add_uint (node, "appns_index",
20933                             clib_net_to_host_u32 (mp->appns_index));
20934   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20935   vat_json_object_add_uint (node, "scope", mp->scope);
20936   vat_json_object_add_uint (node, "action_index",
20937                             clib_net_to_host_u32 (mp->action_index));
20938   vat_json_object_add_uint (node, "lcl_port",
20939                             clib_net_to_host_u16 (mp->lcl_port));
20940   vat_json_object_add_uint (node, "rmt_port",
20941                             clib_net_to_host_u16 (mp->rmt_port));
20942   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20943   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20944   vat_json_object_add_string_copy (node, "tag", mp->tag);
20945   if (mp->is_ip4)
20946     {
20947       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20948       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20949       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20950       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20951     }
20952   else
20953     {
20954       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20955       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20956       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20957       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20958     }
20959 }
20960
20961 static int
20962 api_session_rule_add_del (vat_main_t * vam)
20963 {
20964   vl_api_session_rule_add_del_t *mp;
20965   unformat_input_t *i = vam->input;
20966   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20967   u32 appns_index = 0, scope = 0;
20968   ip4_address_t lcl_ip4, rmt_ip4;
20969   ip6_address_t lcl_ip6, rmt_ip6;
20970   u8 is_ip4 = 1, conn_set = 0;
20971   u8 is_add = 1, *tag = 0;
20972   int ret;
20973
20974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20975     {
20976       if (unformat (i, "del"))
20977         is_add = 0;
20978       else if (unformat (i, "add"))
20979         ;
20980       else if (unformat (i, "proto tcp"))
20981         proto = 0;
20982       else if (unformat (i, "proto udp"))
20983         proto = 1;
20984       else if (unformat (i, "appns %d", &appns_index))
20985         ;
20986       else if (unformat (i, "scope %d", &scope))
20987         ;
20988       else if (unformat (i, "tag %_%v%_", &tag))
20989         ;
20990       else
20991         if (unformat
20992             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20993              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20994              &rmt_port))
20995         {
20996           is_ip4 = 1;
20997           conn_set = 1;
20998         }
20999       else
21000         if (unformat
21001             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21002              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21003              &rmt_port))
21004         {
21005           is_ip4 = 0;
21006           conn_set = 1;
21007         }
21008       else if (unformat (i, "action %d", &action))
21009         ;
21010       else
21011         break;
21012     }
21013   if (proto == ~0 || !conn_set || action == ~0)
21014     {
21015       errmsg ("transport proto, connection and action must be set");
21016       return -99;
21017     }
21018
21019   if (scope > 3)
21020     {
21021       errmsg ("scope should be 0-3");
21022       return -99;
21023     }
21024
21025   M (SESSION_RULE_ADD_DEL, mp);
21026
21027   mp->is_ip4 = is_ip4;
21028   mp->transport_proto = proto;
21029   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21030   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21031   mp->lcl_plen = lcl_plen;
21032   mp->rmt_plen = rmt_plen;
21033   mp->action_index = clib_host_to_net_u32 (action);
21034   mp->appns_index = clib_host_to_net_u32 (appns_index);
21035   mp->scope = scope;
21036   mp->is_add = is_add;
21037   if (is_ip4)
21038     {
21039       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21040       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21041     }
21042   else
21043     {
21044       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21045       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21046     }
21047   if (tag)
21048     {
21049       clib_memcpy (mp->tag, tag, vec_len (tag));
21050       vec_free (tag);
21051     }
21052
21053   S (mp);
21054   W (ret);
21055   return ret;
21056 }
21057
21058 static int
21059 api_session_rules_dump (vat_main_t * vam)
21060 {
21061   vl_api_session_rules_dump_t *mp;
21062   vl_api_control_ping_t *mp_ping;
21063   int ret;
21064
21065   if (!vam->json_output)
21066     {
21067       print (vam->ofp, "%=20s", "Session Rules");
21068     }
21069
21070   M (SESSION_RULES_DUMP, mp);
21071   /* send it... */
21072   S (mp);
21073
21074   /* Use a control ping for synchronization */
21075   MPING (CONTROL_PING, mp_ping);
21076   S (mp_ping);
21077
21078   /* Wait for a reply... */
21079   W (ret);
21080   return ret;
21081 }
21082
21083 static int
21084 api_ip_container_proxy_add_del (vat_main_t * vam)
21085 {
21086   vl_api_ip_container_proxy_add_del_t *mp;
21087   unformat_input_t *i = vam->input;
21088   u32 sw_if_index = ~0;
21089   vl_api_prefix_t pfx = { };
21090   u8 is_add = 1;
21091   int ret;
21092
21093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21094     {
21095       if (unformat (i, "del"))
21096         is_add = 0;
21097       else if (unformat (i, "add"))
21098         ;
21099       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21100         ;
21101       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21102         ;
21103       else
21104         break;
21105     }
21106   if (sw_if_index == ~0 || pfx.len == 0)
21107     {
21108       errmsg ("address and sw_if_index must be set");
21109       return -99;
21110     }
21111
21112   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21113
21114   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21115   mp->is_add = is_add;
21116   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21117
21118   S (mp);
21119   W (ret);
21120   return ret;
21121 }
21122
21123 static int
21124 api_qos_record_enable_disable (vat_main_t * vam)
21125 {
21126   unformat_input_t *i = vam->input;
21127   vl_api_qos_record_enable_disable_t *mp;
21128   u32 sw_if_index, qs = 0xff;
21129   u8 sw_if_index_set = 0;
21130   u8 enable = 1;
21131   int ret;
21132
21133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21134     {
21135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21136         sw_if_index_set = 1;
21137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21138         sw_if_index_set = 1;
21139       else if (unformat (i, "%U", unformat_qos_source, &qs))
21140         ;
21141       else if (unformat (i, "disable"))
21142         enable = 0;
21143       else
21144         {
21145           clib_warning ("parse error '%U'", format_unformat_error, i);
21146           return -99;
21147         }
21148     }
21149
21150   if (sw_if_index_set == 0)
21151     {
21152       errmsg ("missing interface name or sw_if_index");
21153       return -99;
21154     }
21155   if (qs == 0xff)
21156     {
21157       errmsg ("input location must be specified");
21158       return -99;
21159     }
21160
21161   M (QOS_RECORD_ENABLE_DISABLE, mp);
21162
21163   mp->record.sw_if_index = ntohl (sw_if_index);
21164   mp->record.input_source = qs;
21165   mp->enable = enable;
21166
21167   S (mp);
21168   W (ret);
21169   return ret;
21170 }
21171
21172
21173 static int
21174 q_or_quit (vat_main_t * vam)
21175 {
21176 #if VPP_API_TEST_BUILTIN == 0
21177   longjmp (vam->jump_buf, 1);
21178 #endif
21179   return 0;                     /* not so much */
21180 }
21181
21182 static int
21183 q (vat_main_t * vam)
21184 {
21185   return q_or_quit (vam);
21186 }
21187
21188 static int
21189 quit (vat_main_t * vam)
21190 {
21191   return q_or_quit (vam);
21192 }
21193
21194 static int
21195 comment (vat_main_t * vam)
21196 {
21197   return 0;
21198 }
21199
21200 static int
21201 elog_save (vat_main_t * vam)
21202 {
21203 #if VPP_API_TEST_BUILTIN == 0
21204   elog_main_t *em = &vam->elog_main;
21205   unformat_input_t *i = vam->input;
21206   char *file, *chroot_file;
21207   clib_error_t *error;
21208
21209   if (!unformat (i, "%s", &file))
21210     {
21211       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21212       return 0;
21213     }
21214
21215   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21216   if (strstr (file, "..") || index (file, '/'))
21217     {
21218       errmsg ("illegal characters in filename '%s'", file);
21219       return 0;
21220     }
21221
21222   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21223
21224   vec_free (file);
21225
21226   errmsg ("Saving %wd of %wd events to %s",
21227           elog_n_events_in_buffer (em),
21228           elog_buffer_capacity (em), chroot_file);
21229
21230   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21231   vec_free (chroot_file);
21232
21233   if (error)
21234     clib_error_report (error);
21235 #else
21236   errmsg ("Use the vpp event loger...");
21237 #endif
21238
21239   return 0;
21240 }
21241
21242 static int
21243 elog_setup (vat_main_t * vam)
21244 {
21245 #if VPP_API_TEST_BUILTIN == 0
21246   elog_main_t *em = &vam->elog_main;
21247   unformat_input_t *i = vam->input;
21248   u32 nevents = 128 << 10;
21249
21250   (void) unformat (i, "nevents %d", &nevents);
21251
21252   elog_init (em, nevents);
21253   vl_api_set_elog_main (em);
21254   vl_api_set_elog_trace_api_messages (1);
21255   errmsg ("Event logger initialized with %u events", nevents);
21256 #else
21257   errmsg ("Use the vpp event loger...");
21258 #endif
21259   return 0;
21260 }
21261
21262 static int
21263 elog_enable (vat_main_t * vam)
21264 {
21265 #if VPP_API_TEST_BUILTIN == 0
21266   elog_main_t *em = &vam->elog_main;
21267
21268   elog_enable_disable (em, 1 /* enable */ );
21269   vl_api_set_elog_trace_api_messages (1);
21270   errmsg ("Event logger enabled...");
21271 #else
21272   errmsg ("Use the vpp event loger...");
21273 #endif
21274   return 0;
21275 }
21276
21277 static int
21278 elog_disable (vat_main_t * vam)
21279 {
21280 #if VPP_API_TEST_BUILTIN == 0
21281   elog_main_t *em = &vam->elog_main;
21282
21283   elog_enable_disable (em, 0 /* enable */ );
21284   vl_api_set_elog_trace_api_messages (1);
21285   errmsg ("Event logger disabled...");
21286 #else
21287   errmsg ("Use the vpp event loger...");
21288 #endif
21289   return 0;
21290 }
21291
21292 static int
21293 statseg (vat_main_t * vam)
21294 {
21295   ssvm_private_t *ssvmp = &vam->stat_segment;
21296   ssvm_shared_header_t *shared_header = ssvmp->sh;
21297   vlib_counter_t **counters;
21298   u64 thread0_index1_packets;
21299   u64 thread0_index1_bytes;
21300   f64 vector_rate, input_rate;
21301   uword *p;
21302
21303   uword *counter_vector_by_name;
21304   if (vam->stat_segment_lockp == 0)
21305     {
21306       errmsg ("Stat segment not mapped...");
21307       return -99;
21308     }
21309
21310   /* look up "/if/rx for sw_if_index 1 as a test */
21311
21312   clib_spinlock_lock (vam->stat_segment_lockp);
21313
21314   counter_vector_by_name = (uword *) shared_header->opaque[1];
21315
21316   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21317   if (p == 0)
21318     {
21319       clib_spinlock_unlock (vam->stat_segment_lockp);
21320       errmsg ("/if/tx not found?");
21321       return -99;
21322     }
21323
21324   /* Fish per-thread vector of combined counters from shared memory */
21325   counters = (vlib_counter_t **) p[0];
21326
21327   if (vec_len (counters[0]) < 2)
21328     {
21329       clib_spinlock_unlock (vam->stat_segment_lockp);
21330       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21331       return -99;
21332     }
21333
21334   /* Read thread 0 sw_if_index 1 counter */
21335   thread0_index1_packets = counters[0][1].packets;
21336   thread0_index1_bytes = counters[0][1].bytes;
21337
21338   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21339   if (p == 0)
21340     {
21341       clib_spinlock_unlock (vam->stat_segment_lockp);
21342       errmsg ("vector_rate not found?");
21343       return -99;
21344     }
21345
21346   vector_rate = *(f64 *) (p[0]);
21347   p = hash_get_mem (counter_vector_by_name, "input_rate");
21348   if (p == 0)
21349     {
21350       clib_spinlock_unlock (vam->stat_segment_lockp);
21351       errmsg ("input_rate not found?");
21352       return -99;
21353     }
21354   input_rate = *(f64 *) (p[0]);
21355
21356   clib_spinlock_unlock (vam->stat_segment_lockp);
21357
21358   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21359          vector_rate, input_rate);
21360   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21361          thread0_index1_packets, thread0_index1_bytes);
21362
21363   return 0;
21364 }
21365
21366 static int
21367 cmd_cmp (void *a1, void *a2)
21368 {
21369   u8 **c1 = a1;
21370   u8 **c2 = a2;
21371
21372   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21373 }
21374
21375 static int
21376 help (vat_main_t * vam)
21377 {
21378   u8 **cmds = 0;
21379   u8 *name = 0;
21380   hash_pair_t *p;
21381   unformat_input_t *i = vam->input;
21382   int j;
21383
21384   if (unformat (i, "%s", &name))
21385     {
21386       uword *hs;
21387
21388       vec_add1 (name, 0);
21389
21390       hs = hash_get_mem (vam->help_by_name, name);
21391       if (hs)
21392         print (vam->ofp, "usage: %s %s", name, hs[0]);
21393       else
21394         print (vam->ofp, "No such msg / command '%s'", name);
21395       vec_free (name);
21396       return 0;
21397     }
21398
21399   print (vam->ofp, "Help is available for the following:");
21400
21401     /* *INDENT-OFF* */
21402     hash_foreach_pair (p, vam->function_by_name,
21403     ({
21404       vec_add1 (cmds, (u8 *)(p->key));
21405     }));
21406     /* *INDENT-ON* */
21407
21408   vec_sort_with_function (cmds, cmd_cmp);
21409
21410   for (j = 0; j < vec_len (cmds); j++)
21411     print (vam->ofp, "%s", cmds[j]);
21412
21413   vec_free (cmds);
21414   return 0;
21415 }
21416
21417 static int
21418 set (vat_main_t * vam)
21419 {
21420   u8 *name = 0, *value = 0;
21421   unformat_input_t *i = vam->input;
21422
21423   if (unformat (i, "%s", &name))
21424     {
21425       /* The input buffer is a vector, not a string. */
21426       value = vec_dup (i->buffer);
21427       vec_delete (value, i->index, 0);
21428       /* Almost certainly has a trailing newline */
21429       if (value[vec_len (value) - 1] == '\n')
21430         value[vec_len (value) - 1] = 0;
21431       /* Make sure it's a proper string, one way or the other */
21432       vec_add1 (value, 0);
21433       (void) clib_macro_set_value (&vam->macro_main,
21434                                    (char *) name, (char *) value);
21435     }
21436   else
21437     errmsg ("usage: set <name> <value>");
21438
21439   vec_free (name);
21440   vec_free (value);
21441   return 0;
21442 }
21443
21444 static int
21445 unset (vat_main_t * vam)
21446 {
21447   u8 *name = 0;
21448
21449   if (unformat (vam->input, "%s", &name))
21450     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21451       errmsg ("unset: %s wasn't set", name);
21452   vec_free (name);
21453   return 0;
21454 }
21455
21456 typedef struct
21457 {
21458   u8 *name;
21459   u8 *value;
21460 } macro_sort_t;
21461
21462
21463 static int
21464 macro_sort_cmp (void *a1, void *a2)
21465 {
21466   macro_sort_t *s1 = a1;
21467   macro_sort_t *s2 = a2;
21468
21469   return strcmp ((char *) (s1->name), (char *) (s2->name));
21470 }
21471
21472 static int
21473 dump_macro_table (vat_main_t * vam)
21474 {
21475   macro_sort_t *sort_me = 0, *sm;
21476   int i;
21477   hash_pair_t *p;
21478
21479     /* *INDENT-OFF* */
21480     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21481     ({
21482       vec_add2 (sort_me, sm, 1);
21483       sm->name = (u8 *)(p->key);
21484       sm->value = (u8 *) (p->value[0]);
21485     }));
21486     /* *INDENT-ON* */
21487
21488   vec_sort_with_function (sort_me, macro_sort_cmp);
21489
21490   if (vec_len (sort_me))
21491     print (vam->ofp, "%-15s%s", "Name", "Value");
21492   else
21493     print (vam->ofp, "The macro table is empty...");
21494
21495   for (i = 0; i < vec_len (sort_me); i++)
21496     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21497   return 0;
21498 }
21499
21500 static int
21501 dump_node_table (vat_main_t * vam)
21502 {
21503   int i, j;
21504   vlib_node_t *node, *next_node;
21505
21506   if (vec_len (vam->graph_nodes) == 0)
21507     {
21508       print (vam->ofp, "Node table empty, issue get_node_graph...");
21509       return 0;
21510     }
21511
21512   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21513     {
21514       node = vam->graph_nodes[0][i];
21515       print (vam->ofp, "[%d] %s", i, node->name);
21516       for (j = 0; j < vec_len (node->next_nodes); j++)
21517         {
21518           if (node->next_nodes[j] != ~0)
21519             {
21520               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21521               print (vam->ofp, "  [%d] %s", j, next_node->name);
21522             }
21523         }
21524     }
21525   return 0;
21526 }
21527
21528 static int
21529 value_sort_cmp (void *a1, void *a2)
21530 {
21531   name_sort_t *n1 = a1;
21532   name_sort_t *n2 = a2;
21533
21534   if (n1->value < n2->value)
21535     return -1;
21536   if (n1->value > n2->value)
21537     return 1;
21538   return 0;
21539 }
21540
21541
21542 static int
21543 dump_msg_api_table (vat_main_t * vam)
21544 {
21545   api_main_t *am = &api_main;
21546   name_sort_t *nses = 0, *ns;
21547   hash_pair_t *hp;
21548   int i;
21549
21550   /* *INDENT-OFF* */
21551   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21552   ({
21553     vec_add2 (nses, ns, 1);
21554     ns->name = (u8 *)(hp->key);
21555     ns->value = (u32) hp->value[0];
21556   }));
21557   /* *INDENT-ON* */
21558
21559   vec_sort_with_function (nses, value_sort_cmp);
21560
21561   for (i = 0; i < vec_len (nses); i++)
21562     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21563   vec_free (nses);
21564   return 0;
21565 }
21566
21567 static int
21568 get_msg_id (vat_main_t * vam)
21569 {
21570   u8 *name_and_crc;
21571   u32 message_index;
21572
21573   if (unformat (vam->input, "%s", &name_and_crc))
21574     {
21575       message_index = vl_msg_api_get_msg_index (name_and_crc);
21576       if (message_index == ~0)
21577         {
21578           print (vam->ofp, " '%s' not found", name_and_crc);
21579           return 0;
21580         }
21581       print (vam->ofp, " '%s' has message index %d",
21582              name_and_crc, message_index);
21583       return 0;
21584     }
21585   errmsg ("name_and_crc required...");
21586   return 0;
21587 }
21588
21589 static int
21590 search_node_table (vat_main_t * vam)
21591 {
21592   unformat_input_t *line_input = vam->input;
21593   u8 *node_to_find;
21594   int j;
21595   vlib_node_t *node, *next_node;
21596   uword *p;
21597
21598   if (vam->graph_node_index_by_name == 0)
21599     {
21600       print (vam->ofp, "Node table empty, issue get_node_graph...");
21601       return 0;
21602     }
21603
21604   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21605     {
21606       if (unformat (line_input, "%s", &node_to_find))
21607         {
21608           vec_add1 (node_to_find, 0);
21609           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21610           if (p == 0)
21611             {
21612               print (vam->ofp, "%s not found...", node_to_find);
21613               goto out;
21614             }
21615           node = vam->graph_nodes[0][p[0]];
21616           print (vam->ofp, "[%d] %s", p[0], node->name);
21617           for (j = 0; j < vec_len (node->next_nodes); j++)
21618             {
21619               if (node->next_nodes[j] != ~0)
21620                 {
21621                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21622                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21623                 }
21624             }
21625         }
21626
21627       else
21628         {
21629           clib_warning ("parse error '%U'", format_unformat_error,
21630                         line_input);
21631           return -99;
21632         }
21633
21634     out:
21635       vec_free (node_to_find);
21636
21637     }
21638
21639   return 0;
21640 }
21641
21642
21643 static int
21644 script (vat_main_t * vam)
21645 {
21646 #if (VPP_API_TEST_BUILTIN==0)
21647   u8 *s = 0;
21648   char *save_current_file;
21649   unformat_input_t save_input;
21650   jmp_buf save_jump_buf;
21651   u32 save_line_number;
21652
21653   FILE *new_fp, *save_ifp;
21654
21655   if (unformat (vam->input, "%s", &s))
21656     {
21657       new_fp = fopen ((char *) s, "r");
21658       if (new_fp == 0)
21659         {
21660           errmsg ("Couldn't open script file %s", s);
21661           vec_free (s);
21662           return -99;
21663         }
21664     }
21665   else
21666     {
21667       errmsg ("Missing script name");
21668       return -99;
21669     }
21670
21671   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21672   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21673   save_ifp = vam->ifp;
21674   save_line_number = vam->input_line_number;
21675   save_current_file = (char *) vam->current_file;
21676
21677   vam->input_line_number = 0;
21678   vam->ifp = new_fp;
21679   vam->current_file = s;
21680   do_one_file (vam);
21681
21682   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21683   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21684   vam->ifp = save_ifp;
21685   vam->input_line_number = save_line_number;
21686   vam->current_file = (u8 *) save_current_file;
21687   vec_free (s);
21688
21689   return 0;
21690 #else
21691   clib_warning ("use the exec command...");
21692   return -99;
21693 #endif
21694 }
21695
21696 static int
21697 echo (vat_main_t * vam)
21698 {
21699   print (vam->ofp, "%v", vam->input->buffer);
21700   return 0;
21701 }
21702
21703 /* List of API message constructors, CLI names map to api_xxx */
21704 #define foreach_vpe_api_msg                                             \
21705 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21706 _(sw_interface_dump,"")                                                 \
21707 _(sw_interface_set_flags,                                               \
21708   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21709 _(sw_interface_add_del_address,                                         \
21710   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21711 _(sw_interface_set_rx_mode,                                             \
21712   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21713 _(sw_interface_set_rx_placement,                                        \
21714   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21715 _(sw_interface_rx_placement_dump,                                       \
21716   "[<intfc> | sw_if_index <id>]")                                         \
21717 _(sw_interface_set_table,                                               \
21718   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21719 _(sw_interface_set_mpls_enable,                                         \
21720   "<intfc> | sw_if_index [disable | dis]")                              \
21721 _(sw_interface_set_vpath,                                               \
21722   "<intfc> | sw_if_index <id> enable | disable")                        \
21723 _(sw_interface_set_vxlan_bypass,                                        \
21724   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21725 _(sw_interface_set_geneve_bypass,                                       \
21726   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21727 _(sw_interface_set_l2_xconnect,                                         \
21728   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21729   "enable | disable")                                                   \
21730 _(sw_interface_set_l2_bridge,                                           \
21731   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21732   "[shg <split-horizon-group>] [bvi]\n"                                 \
21733   "enable | disable")                                                   \
21734 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21735 _(bridge_domain_add_del,                                                \
21736   "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") \
21737 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21738 _(l2fib_add_del,                                                        \
21739   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21740 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21741 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21742 _(l2_flags,                                                             \
21743   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21744 _(bridge_flags,                                                         \
21745   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21746 _(tap_create_v2,                                                        \
21747   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21748 _(tap_delete_v2,                                                        \
21749   "<vpp-if-name> | sw_if_index <id>")                                   \
21750 _(sw_interface_tap_v2_dump, "")                                         \
21751 _(virtio_pci_create,                                                    \
21752   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21753 _(virtio_pci_delete,                                                    \
21754   "<vpp-if-name> | sw_if_index <id>")                                   \
21755 _(sw_interface_virtio_pci_dump, "")                                     \
21756 _(bond_create,                                                          \
21757   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21758   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21759   "[id <if-id>]")                                                       \
21760 _(bond_delete,                                                          \
21761   "<vpp-if-name> | sw_if_index <id>")                                   \
21762 _(bond_enslave,                                                         \
21763   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21764 _(bond_detach_slave,                                                    \
21765   "sw_if_index <n>")                                                    \
21766 _(sw_interface_bond_dump, "")                                           \
21767 _(sw_interface_slave_dump,                                              \
21768   "<vpp-if-name> | sw_if_index <id>")                                   \
21769 _(ip_table_add_del,                                                     \
21770   "table <n> [ipv6] [add | del]\n")                                     \
21771 _(ip_route_add_del,                                                     \
21772   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21773   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21774   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21775   "[multipath] [count <n>] [del]")                                      \
21776 _(ip_mroute_add_del,                                                    \
21777   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21778   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21779 _(mpls_table_add_del,                                                   \
21780   "table <n> [add | del]\n")                                            \
21781 _(mpls_route_add_del,                                                   \
21782   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21783   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21784   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21785   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21786   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21787   "[count <n>] [del]")                                                  \
21788 _(mpls_ip_bind_unbind,                                                  \
21789   "<label> <addr/len>")                                                 \
21790 _(mpls_tunnel_add_del,                                                  \
21791   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21792   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21793   "[l2-only]  [out-label <n>]")                                         \
21794 _(sr_mpls_policy_add,                                                   \
21795   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21796 _(sr_mpls_policy_del,                                                   \
21797   "bsid <id>")                                                          \
21798 _(bier_table_add_del,                                                   \
21799   "<label> <sub-domain> <set> <bsl> [del]")                             \
21800 _(bier_route_add_del,                                                   \
21801   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21802   "[<intfc> | sw_if_index <id>]"                                        \
21803   "[weight <n>] [del] [multipath]")                                     \
21804 _(proxy_arp_add_del,                                                    \
21805   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21806 _(proxy_arp_intfc_enable_disable,                                       \
21807   "<intfc> | sw_if_index <id> enable | disable")                        \
21808 _(sw_interface_set_unnumbered,                                          \
21809   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21810 _(ip_neighbor_add_del,                                                  \
21811   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21812   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21813 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21814 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21815   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21816   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21817   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21818 _(reset_fib, "vrf <n> [ipv6]")                                          \
21819 _(dhcp_proxy_config,                                                    \
21820   "svr <v46-address> src <v46-address>\n"                               \
21821    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21822 _(dhcp_proxy_set_vss,                                                   \
21823   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21824 _(dhcp_proxy_dump, "ip6")                                               \
21825 _(dhcp_client_config,                                                   \
21826   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21827 _(set_ip_flow_hash,                                                     \
21828   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21829 _(sw_interface_ip6_enable_disable,                                      \
21830   "<intfc> | sw_if_index <id> enable | disable")                        \
21831 _(ip6nd_proxy_add_del,                                                  \
21832   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21833 _(ip6nd_proxy_dump, "")                                                 \
21834 _(sw_interface_ip6nd_ra_prefix,                                         \
21835   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21836   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21837   "[nolink] [isno]")                                                    \
21838 _(sw_interface_ip6nd_ra_config,                                         \
21839   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21840   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21841   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21842 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21843 _(l2_patch_add_del,                                                     \
21844   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21845   "enable | disable")                                                   \
21846 _(sr_localsid_add_del,                                                  \
21847   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21848   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21849 _(classify_add_del_table,                                               \
21850   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21851   " [del] [del-chain] mask <mask-value>\n"                              \
21852   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21853   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21854 _(classify_add_del_session,                                             \
21855   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21856   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21857   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21858   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21859 _(classify_set_interface_ip_table,                                      \
21860   "<intfc> | sw_if_index <nn> table <nn>")                              \
21861 _(classify_set_interface_l2_tables,                                     \
21862   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21863   "  [other-table <nn>]")                                               \
21864 _(get_node_index, "node <node-name")                                    \
21865 _(add_node_next, "node <node-name> next <next-node-name>")              \
21866 _(l2tpv3_create_tunnel,                                                 \
21867   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21868   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21869   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21870 _(l2tpv3_set_tunnel_cookies,                                            \
21871   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21872   "[new_remote_cookie <nn>]\n")                                         \
21873 _(l2tpv3_interface_enable_disable,                                      \
21874   "<intfc> | sw_if_index <nn> enable | disable")                        \
21875 _(l2tpv3_set_lookup_key,                                                \
21876   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21877 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21878 _(vxlan_offload_rx,                                                     \
21879   "hw { <interface name> | hw_if_index <nn>} "                          \
21880   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21881 _(vxlan_add_del_tunnel,                                                 \
21882   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21883   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21884   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21885 _(geneve_add_del_tunnel,                                                \
21886   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21887   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21888   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21889 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21890 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21891 _(gre_tunnel_add_del,                                                   \
21892   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21893   "[teb | erspan <session-id>] [del]")                                  \
21894 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21895 _(l2_fib_clear_table, "")                                               \
21896 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21897 _(l2_interface_vlan_tag_rewrite,                                        \
21898   "<intfc> | sw_if_index <nn> \n"                                       \
21899   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21900   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21901 _(create_vhost_user_if,                                                 \
21902         "socket <filename> [server] [renumber <dev_instance>] "         \
21903         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21904         "[mac <mac_address>]")                                          \
21905 _(modify_vhost_user_if,                                                 \
21906         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21907         "[server] [renumber <dev_instance>] [gso]")                     \
21908 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21909 _(sw_interface_vhost_user_dump, "")                                     \
21910 _(show_version, "")                                                     \
21911 _(show_threads, "")                                                     \
21912 _(vxlan_gpe_add_del_tunnel,                                             \
21913   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21914   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21915   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21916   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21917 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21918 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21919 _(interface_name_renumber,                                              \
21920   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21921 _(input_acl_set_interface,                                              \
21922   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21923   "  [l2-table <nn>] [del]")                                            \
21924 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21925 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21926   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21927 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21928 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21929 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21930 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21931 _(ip_dump, "ipv4 | ipv6")                                               \
21932 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21933 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21934   "  spid_id <n> ")                                                     \
21935 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21936   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21937   "  integ_alg <alg> integ_key <hex>")                                  \
21938 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21939   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21940   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21941   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21942 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21943   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21944   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21945   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21946   "  [instance <n>]")     \
21947 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21948 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21949 _(delete_loopback,"sw_if_index <nn>")                                   \
21950 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21951 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21952 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21953 _(want_interface_events,  "enable|disable")                             \
21954 _(get_first_msg_id, "client <name>")                                    \
21955 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21956 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21957   "fib-id <nn> [ip4][ip6][default]")                                    \
21958 _(get_node_graph, " ")                                                  \
21959 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21960 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21961 _(ioam_disable, "")                                                     \
21962 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21963                             " sw_if_index <sw_if_index> p <priority> "  \
21964                             "w <weight>] [del]")                        \
21965 _(one_add_del_locator, "locator-set <locator_name> "                    \
21966                         "iface <intf> | sw_if_index <sw_if_index> "     \
21967                         "p <priority> w <weight> [del]")                \
21968 _(one_add_del_local_eid,"vni <vni> eid "                                \
21969                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21970                          "locator-set <locator_name> [del]"             \
21971                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21972 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21973 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21974 _(one_enable_disable, "enable|disable")                                 \
21975 _(one_map_register_enable_disable, "enable|disable")                    \
21976 _(one_map_register_fallback_threshold, "<value>")                       \
21977 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21978 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21979                                "[seid <seid>] "                         \
21980                                "rloc <locator> p <prio> "               \
21981                                "w <weight> [rloc <loc> ... ] "          \
21982                                "action <action> [del-all]")             \
21983 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21984                           "<local-eid>")                                \
21985 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21986 _(one_use_petr, "ip-address> | disable")                                \
21987 _(one_map_request_mode, "src-dst|dst-only")                             \
21988 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21989 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21990 _(one_locator_set_dump, "[local | remote]")                             \
21991 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21992 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21993                        "[local] | [remote]")                            \
21994 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21995 _(one_ndp_bd_get, "")                                                   \
21996 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21997 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21998 _(one_l2_arp_bd_get, "")                                                \
21999 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22000 _(one_stats_enable_disable, "enable|disable")                           \
22001 _(show_one_stats_enable_disable, "")                                    \
22002 _(one_eid_table_vni_dump, "")                                           \
22003 _(one_eid_table_map_dump, "l2|l3")                                      \
22004 _(one_map_resolver_dump, "")                                            \
22005 _(one_map_server_dump, "")                                              \
22006 _(one_adjacencies_get, "vni <vni>")                                     \
22007 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22008 _(show_one_rloc_probe_state, "")                                        \
22009 _(show_one_map_register_state, "")                                      \
22010 _(show_one_status, "")                                                  \
22011 _(one_stats_dump, "")                                                   \
22012 _(one_stats_flush, "")                                                  \
22013 _(one_get_map_request_itr_rlocs, "")                                    \
22014 _(one_map_register_set_ttl, "<ttl>")                                    \
22015 _(one_set_transport_protocol, "udp|api")                                \
22016 _(one_get_transport_protocol, "")                                       \
22017 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22018 _(one_show_xtr_mode, "")                                                \
22019 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22020 _(one_show_pitr_mode, "")                                               \
22021 _(one_enable_disable_petr_mode, "enable|disable")                       \
22022 _(one_show_petr_mode, "")                                               \
22023 _(show_one_nsh_mapping, "")                                             \
22024 _(show_one_pitr, "")                                                    \
22025 _(show_one_use_petr, "")                                                \
22026 _(show_one_map_request_mode, "")                                        \
22027 _(show_one_map_register_ttl, "")                                        \
22028 _(show_one_map_register_fallback_threshold, "")                         \
22029 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22030                             " sw_if_index <sw_if_index> p <priority> "  \
22031                             "w <weight>] [del]")                        \
22032 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22033                         "iface <intf> | sw_if_index <sw_if_index> "     \
22034                         "p <priority> w <weight> [del]")                \
22035 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22036                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22037                          "locator-set <locator_name> [del]"             \
22038                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22039 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22040 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22041 _(lisp_enable_disable, "enable|disable")                                \
22042 _(lisp_map_register_enable_disable, "enable|disable")                   \
22043 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22044 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22045                                "[seid <seid>] "                         \
22046                                "rloc <locator> p <prio> "               \
22047                                "w <weight> [rloc <loc> ... ] "          \
22048                                "action <action> [del-all]")             \
22049 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22050                           "<local-eid>")                                \
22051 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22052 _(lisp_use_petr, "<ip-address> | disable")                              \
22053 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22054 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22055 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22056 _(lisp_locator_set_dump, "[local | remote]")                            \
22057 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22058 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22059                        "[local] | [remote]")                            \
22060 _(lisp_eid_table_vni_dump, "")                                          \
22061 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22062 _(lisp_map_resolver_dump, "")                                           \
22063 _(lisp_map_server_dump, "")                                             \
22064 _(lisp_adjacencies_get, "vni <vni>")                                    \
22065 _(gpe_fwd_entry_vnis_get, "")                                           \
22066 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22067 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22068                                 "[table <table-id>]")                   \
22069 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22070 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22071 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22072 _(gpe_get_encap_mode, "")                                               \
22073 _(lisp_gpe_add_del_iface, "up|down")                                    \
22074 _(lisp_gpe_enable_disable, "enable|disable")                            \
22075 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22076   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22077 _(show_lisp_rloc_probe_state, "")                                       \
22078 _(show_lisp_map_register_state, "")                                     \
22079 _(show_lisp_status, "")                                                 \
22080 _(lisp_get_map_request_itr_rlocs, "")                                   \
22081 _(show_lisp_pitr, "")                                                   \
22082 _(show_lisp_use_petr, "")                                               \
22083 _(show_lisp_map_request_mode, "")                                       \
22084 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22085 _(af_packet_delete, "name <host interface name>")                       \
22086 _(af_packet_dump, "")                                                   \
22087 _(policer_add_del, "name <policer name> <params> [del]")                \
22088 _(policer_dump, "[name <policer name>]")                                \
22089 _(policer_classify_set_interface,                                       \
22090   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22091   "  [l2-table <nn>] [del]")                                            \
22092 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22093 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22094     "[master|slave]")                                                   \
22095 _(netmap_delete, "name <interface name>")                               \
22096 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22097 _(mpls_table_dump, "")                                                  \
22098 _(mpls_route_dump, "table-id <ID>")                                     \
22099 _(classify_table_ids, "")                                               \
22100 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22101 _(classify_table_info, "table_id <nn>")                                 \
22102 _(classify_session_dump, "table_id <nn>")                               \
22103 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22104     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22105     "[template_interval <nn>] [udp_checksum]")                          \
22106 _(ipfix_exporter_dump, "")                                              \
22107 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22108 _(ipfix_classify_stream_dump, "")                                       \
22109 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22110 _(ipfix_classify_table_dump, "")                                        \
22111 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22112 _(sw_interface_span_dump, "[l2]")                                           \
22113 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22114 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22115 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22116 _(pg_enable_disable, "[stream <id>] disable")                           \
22117 _(ip_source_and_port_range_check_add_del,                               \
22118   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22119 _(ip_source_and_port_range_check_interface_add_del,                     \
22120   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22121   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22122 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22123 _(l2_interface_pbb_tag_rewrite,                                         \
22124   "<intfc> | sw_if_index <nn> \n"                                       \
22125   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22126   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22127 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22128 _(flow_classify_set_interface,                                          \
22129   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22130 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22131 _(ip_table_dump, "")                                                    \
22132 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22133 _(ip_mtable_dump, "")                                                   \
22134 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22135 _(feature_enable_disable, "arc_name <arc_name> "                        \
22136   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22137 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22138 "[disable]")                                                            \
22139 _(l2_xconnect_dump, "")                                                 \
22140 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22141 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22142 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22143 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22144 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22145 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22146 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22147   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22148 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22149 _(sock_init_shm, "size <nnn>")                                          \
22150 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22151 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22152   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22153 _(session_rules_dump, "")                                               \
22154 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22155 _(output_acl_set_interface,                                             \
22156   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22157   "  [l2-table <nn>] [del]")                                            \
22158 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22159
22160 /* List of command functions, CLI names map directly to functions */
22161 #define foreach_cli_function                                    \
22162 _(comment, "usage: comment <ignore-rest-of-line>")              \
22163 _(dump_interface_table, "usage: dump_interface_table")          \
22164 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22165 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22166 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22167 _(dump_macro_table, "usage: dump_macro_table ")                 \
22168 _(dump_node_table, "usage: dump_node_table")                    \
22169 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22170 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22171 _(elog_disable, "usage: elog_disable")                          \
22172 _(elog_enable, "usage: elog_enable")                            \
22173 _(elog_save, "usage: elog_save <filename>")                     \
22174 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22175 _(echo, "usage: echo <message>")                                \
22176 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22177 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22178 _(help, "usage: help")                                          \
22179 _(q, "usage: quit")                                             \
22180 _(quit, "usage: quit")                                          \
22181 _(search_node_table, "usage: search_node_table <name>...")      \
22182 _(set, "usage: set <variable-name> <value>")                    \
22183 _(script, "usage: script <file-name>")                          \
22184 _(statseg, "usage: statseg")                                    \
22185 _(unset, "usage: unset <variable-name>")
22186
22187 #define _(N,n)                                  \
22188     static void vl_api_##n##_t_handler_uni      \
22189     (vl_api_##n##_t * mp)                       \
22190     {                                           \
22191         vat_main_t * vam = &vat_main;           \
22192         if (vam->json_output) {                 \
22193             vl_api_##n##_t_handler_json(mp);    \
22194         } else {                                \
22195             vl_api_##n##_t_handler(mp);         \
22196         }                                       \
22197     }
22198 foreach_vpe_api_reply_msg;
22199 #if VPP_API_TEST_BUILTIN == 0
22200 foreach_standalone_reply_msg;
22201 #endif
22202 #undef _
22203
22204 void
22205 vat_api_hookup (vat_main_t * vam)
22206 {
22207 #define _(N,n)                                                  \
22208     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22209                            vl_api_##n##_t_handler_uni,          \
22210                            vl_noop_handler,                     \
22211                            vl_api_##n##_t_endian,               \
22212                            vl_api_##n##_t_print,                \
22213                            sizeof(vl_api_##n##_t), 1);
22214   foreach_vpe_api_reply_msg;
22215 #if VPP_API_TEST_BUILTIN == 0
22216   foreach_standalone_reply_msg;
22217 #endif
22218 #undef _
22219
22220 #if (VPP_API_TEST_BUILTIN==0)
22221   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22222
22223   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22224
22225   vam->function_by_name = hash_create_string (0, sizeof (uword));
22226
22227   vam->help_by_name = hash_create_string (0, sizeof (uword));
22228 #endif
22229
22230   /* API messages we can send */
22231 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22232   foreach_vpe_api_msg;
22233 #undef _
22234
22235   /* Help strings */
22236 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22237   foreach_vpe_api_msg;
22238 #undef _
22239
22240   /* CLI functions */
22241 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22242   foreach_cli_function;
22243 #undef _
22244
22245   /* Help strings */
22246 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22247   foreach_cli_function;
22248 #undef _
22249 }
22250
22251 #if VPP_API_TEST_BUILTIN
22252 static clib_error_t *
22253 vat_api_hookup_shim (vlib_main_t * vm)
22254 {
22255   vat_api_hookup (&vat_main);
22256   return 0;
22257 }
22258
22259 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22260 #endif
22261
22262 /*
22263  * fd.io coding-style-patch-verification: ON
22264  *
22265  * Local Variables:
22266  * eval: (c-set-style "gnu")
22267  * End:
22268  */