devices interface tests: vhosst GSO support
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 void vl_api_set_elog_main (elog_main_t * m);
89 int vl_api_set_elog_trace_api_messages (int enable);
90
91 #if VPP_API_TEST_BUILTIN == 0
92 #include <netdb.h>
93
94 u32
95 vl (void *p)
96 {
97   return vec_len (p);
98 }
99
100 int
101 vat_socket_connect (vat_main_t * vam)
102 {
103   int rv;
104   vam->socket_client_main = &socket_client_main;
105   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
106                                       "vpp_api_test",
107                                       0 /* default socket rx, tx buffer */ )))
108     return rv;
109   /* vpp expects the client index in network order */
110   vam->my_client_index = htonl (socket_client_main.client_index);
111   return 0;
112 }
113 #else /* vpp built-in case, we don't do sockets... */
114 int
115 vat_socket_connect (vat_main_t * vam)
116 {
117   return 0;
118 }
119
120 int
121 vl_socket_client_read (int wait)
122 {
123   return -1;
124 };
125
126 int
127 vl_socket_client_write ()
128 {
129   return -1;
130 };
131
132 void *
133 vl_socket_client_msg_alloc (int nbytes)
134 {
135   return 0;
136 }
137 #endif
138
139
140 f64
141 vat_time_now (vat_main_t * vam)
142 {
143 #if VPP_API_TEST_BUILTIN
144   return vlib_time_now (vam->vlib_main);
145 #else
146   return clib_time_now (&vam->clib_time);
147 #endif
148 }
149
150 void
151 errmsg (char *fmt, ...)
152 {
153   vat_main_t *vam = &vat_main;
154   va_list va;
155   u8 *s;
156
157   va_start (va, fmt);
158   s = va_format (0, fmt, &va);
159   va_end (va);
160
161   vec_add1 (s, 0);
162
163 #if VPP_API_TEST_BUILTIN
164   vlib_cli_output (vam->vlib_main, (char *) s);
165 #else
166   {
167     if (vam->ifp != stdin)
168       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
169                vam->input_line_number);
170     else
171       fformat (vam->ofp, "%s\n", (char *) s);
172     fflush (vam->ofp);
173   }
174 #endif
175
176   vec_free (s);
177 }
178
179 #if VPP_API_TEST_BUILTIN == 0
180 static uword
181 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
182 {
183   vat_main_t *vam = va_arg (*args, vat_main_t *);
184   u32 *result = va_arg (*args, u32 *);
185   u8 *if_name;
186   uword *p;
187
188   if (!unformat (input, "%s", &if_name))
189     return 0;
190
191   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
192   if (p == 0)
193     return 0;
194   *result = p[0];
195   return 1;
196 }
197
198 static uword
199 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
200 {
201   return 0;
202 }
203
204 /* Parse an IP4 address %d.%d.%d.%d. */
205 uword
206 unformat_ip4_address (unformat_input_t * input, va_list * args)
207 {
208   u8 *result = va_arg (*args, u8 *);
209   unsigned a[4];
210
211   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
212     return 0;
213
214   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
215     return 0;
216
217   result[0] = a[0];
218   result[1] = a[1];
219   result[2] = a[2];
220   result[3] = a[3];
221
222   return 1;
223 }
224
225 uword
226 unformat_ethernet_address (unformat_input_t * input, va_list * args)
227 {
228   u8 *result = va_arg (*args, u8 *);
229   u32 i, a[6];
230
231   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
232                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
233     return 0;
234
235   /* Check range. */
236   for (i = 0; i < 6; i++)
237     if (a[i] >= (1 << 8))
238       return 0;
239
240   for (i = 0; i < 6; i++)
241     result[i] = a[i];
242
243   return 1;
244 }
245
246 /* Returns ethernet type as an int in host byte order. */
247 uword
248 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
249                                         va_list * args)
250 {
251   u16 *result = va_arg (*args, u16 *);
252   int type;
253
254   /* Numeric type. */
255   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
256     {
257       if (type >= (1 << 16))
258         return 0;
259       *result = type;
260       return 1;
261     }
262   return 0;
263 }
264
265 /* Parse an IP6 address. */
266 uword
267 unformat_ip6_address (unformat_input_t * input, va_list * args)
268 {
269   ip6_address_t *result = va_arg (*args, ip6_address_t *);
270   u16 hex_quads[8];
271   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
272   uword c, n_colon, double_colon_index;
273
274   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
275   double_colon_index = ARRAY_LEN (hex_quads);
276   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
277     {
278       hex_digit = 16;
279       if (c >= '0' && c <= '9')
280         hex_digit = c - '0';
281       else if (c >= 'a' && c <= 'f')
282         hex_digit = c + 10 - 'a';
283       else if (c >= 'A' && c <= 'F')
284         hex_digit = c + 10 - 'A';
285       else if (c == ':' && n_colon < 2)
286         n_colon++;
287       else
288         {
289           unformat_put_input (input);
290           break;
291         }
292
293       /* Too many hex quads. */
294       if (n_hex_quads >= ARRAY_LEN (hex_quads))
295         return 0;
296
297       if (hex_digit < 16)
298         {
299           hex_quad = (hex_quad << 4) | hex_digit;
300
301           /* Hex quad must fit in 16 bits. */
302           if (n_hex_digits >= 4)
303             return 0;
304
305           n_colon = 0;
306           n_hex_digits++;
307         }
308
309       /* Save position of :: */
310       if (n_colon == 2)
311         {
312           /* More than one :: ? */
313           if (double_colon_index < ARRAY_LEN (hex_quads))
314             return 0;
315           double_colon_index = n_hex_quads;
316         }
317
318       if (n_colon > 0 && n_hex_digits > 0)
319         {
320           hex_quads[n_hex_quads++] = hex_quad;
321           hex_quad = 0;
322           n_hex_digits = 0;
323         }
324     }
325
326   if (n_hex_digits > 0)
327     hex_quads[n_hex_quads++] = hex_quad;
328
329   {
330     word i;
331
332     /* Expand :: to appropriate number of zero hex quads. */
333     if (double_colon_index < ARRAY_LEN (hex_quads))
334       {
335         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
336
337         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
338           hex_quads[n_zero + i] = hex_quads[i];
339
340         for (i = 0; i < n_zero; i++)
341           hex_quads[double_colon_index + i] = 0;
342
343         n_hex_quads = ARRAY_LEN (hex_quads);
344       }
345
346     /* Too few hex quads given. */
347     if (n_hex_quads < ARRAY_LEN (hex_quads))
348       return 0;
349
350     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
351       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
352
353     return 1;
354   }
355 }
356
357 uword
358 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
359 {
360   u32 *r = va_arg (*args, u32 *);
361
362   if (0);
363 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
364   foreach_ipsec_policy_action
365 #undef _
366     else
367     return 0;
368   return 1;
369 }
370
371 u8 *
372 format_ipsec_crypto_alg (u8 * s, va_list * args)
373 {
374   u32 i = va_arg (*args, u32);
375   u8 *t = 0;
376
377   switch (i)
378     {
379 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
380       foreach_ipsec_crypto_alg
381 #undef _
382     default:
383       return format (s, "unknown");
384     }
385   return format (s, "%s", t);
386 }
387
388 u8 *
389 format_ipsec_integ_alg (u8 * s, va_list * args)
390 {
391   u32 i = va_arg (*args, u32);
392   u8 *t = 0;
393
394   switch (i)
395     {
396 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
397       foreach_ipsec_integ_alg
398 #undef _
399     default:
400       return format (s, "unknown");
401     }
402   return format (s, "%s", t);
403 }
404
405 #else /* VPP_API_TEST_BUILTIN == 1 */
406 static uword
407 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
408 {
409   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
410   vnet_main_t *vnm = vnet_get_main ();
411   u32 *result = va_arg (*args, u32 *);
412
413   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
414 }
415
416 static uword
417 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
418 {
419   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
420   vnet_main_t *vnm = vnet_get_main ();
421   u32 *result = va_arg (*args, u32 *);
422
423   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
424 }
425
426 #endif /* VPP_API_TEST_BUILTIN */
427
428 uword
429 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
435   foreach_ipsec_crypto_alg
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
444 {
445   u32 *r = va_arg (*args, u32 *);
446
447   if (0);
448 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
449   foreach_ipsec_integ_alg
450 #undef _
451     else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
458 {
459   u8 *r = va_arg (*args, u8 *);
460
461   if (unformat (input, "kbps"))
462     *r = SSE2_QOS_RATE_KBPS;
463   else if (unformat (input, "pps"))
464     *r = SSE2_QOS_RATE_PPS;
465   else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_round_type (unformat_input_t * input, va_list * args)
472 {
473   u8 *r = va_arg (*args, u8 *);
474
475   if (unformat (input, "closest"))
476     *r = SSE2_QOS_ROUND_TO_CLOSEST;
477   else if (unformat (input, "up"))
478     *r = SSE2_QOS_ROUND_TO_UP;
479   else if (unformat (input, "down"))
480     *r = SSE2_QOS_ROUND_TO_DOWN;
481   else
482     return 0;
483   return 1;
484 }
485
486 static uword
487 unformat_policer_type (unformat_input_t * input, va_list * args)
488 {
489   u8 *r = va_arg (*args, u8 *);
490
491   if (unformat (input, "1r2c"))
492     *r = SSE2_QOS_POLICER_TYPE_1R2C;
493   else if (unformat (input, "1r3c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
495   else if (unformat (input, "2r3c-2698"))
496     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
497   else if (unformat (input, "2r3c-4115"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
499   else if (unformat (input, "2r3c-mef5cf1"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
501   else
502     return 0;
503   return 1;
504 }
505
506 static uword
507 unformat_dscp (unformat_input_t * input, va_list * va)
508 {
509   u8 *r = va_arg (*va, u8 *);
510
511   if (0);
512 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
513   foreach_vnet_dscp
514 #undef _
515     else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_action_type (unformat_input_t * input, va_list * va)
522 {
523   sse2_qos_pol_action_params_st *a
524     = va_arg (*va, sse2_qos_pol_action_params_st *);
525
526   if (unformat (input, "drop"))
527     a->action_type = SSE2_QOS_ACTION_DROP;
528   else if (unformat (input, "transmit"))
529     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
530   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
531     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
532   else
533     return 0;
534   return 1;
535 }
536
537 static uword
538 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
539 {
540   u32 *r = va_arg (*va, u32 *);
541   u32 tid;
542
543   if (unformat (input, "ip4"))
544     tid = POLICER_CLASSIFY_TABLE_IP4;
545   else if (unformat (input, "ip6"))
546     tid = POLICER_CLASSIFY_TABLE_IP6;
547   else if (unformat (input, "l2"))
548     tid = POLICER_CLASSIFY_TABLE_L2;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static uword
557 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
558 {
559   u32 *r = va_arg (*va, u32 *);
560   u32 tid;
561
562   if (unformat (input, "ip4"))
563     tid = FLOW_CLASSIFY_TABLE_IP4;
564   else if (unformat (input, "ip6"))
565     tid = FLOW_CLASSIFY_TABLE_IP6;
566   else
567     return 0;
568
569   *r = tid;
570   return 1;
571 }
572
573 #if (VPP_API_TEST_BUILTIN==0)
574
575 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
576 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
577 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
578 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
579
580 uword
581 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
582 {
583   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
584   mfib_itf_attribute_t attr;
585
586   old = *iflags;
587   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
588   {
589     if (unformat (input, mfib_itf_flag_long_names[attr]))
590       *iflags |= (1 << attr);
591   }
592   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
593   {
594     if (unformat (input, mfib_itf_flag_names[attr]))
595       *iflags |= (1 << attr);
596   }
597
598   return (old == *iflags ? 0 : 1);
599 }
600
601 uword
602 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
603 {
604   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
605   mfib_entry_attribute_t attr;
606
607   old = *eflags;
608   FOR_EACH_MFIB_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_flag_long_names[attr]))
611       *eflags |= (1 << attr);
612   }
613   FOR_EACH_MFIB_ATTRIBUTE (attr)
614   {
615     if (unformat (input, mfib_flag_names[attr]))
616       *eflags |= (1 << attr);
617   }
618
619   return (old == *eflags ? 0 : 1);
620 }
621
622 u8 *
623 format_ip4_address (u8 * s, va_list * args)
624 {
625   u8 *a = va_arg (*args, u8 *);
626   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
627 }
628
629 u8 *
630 format_ip6_address (u8 * s, va_list * args)
631 {
632   ip6_address_t *a = va_arg (*args, ip6_address_t *);
633   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
634
635   i_max_n_zero = ARRAY_LEN (a->as_u16);
636   max_n_zeros = 0;
637   i_first_zero = i_max_n_zero;
638   n_zeros = 0;
639   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
640     {
641       u32 is_zero = a->as_u16[i] == 0;
642       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
643         {
644           i_first_zero = i;
645           n_zeros = 0;
646         }
647       n_zeros += is_zero;
648       if ((!is_zero && n_zeros > max_n_zeros)
649           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
650         {
651           i_max_n_zero = i_first_zero;
652           max_n_zeros = n_zeros;
653           i_first_zero = ARRAY_LEN (a->as_u16);
654           n_zeros = 0;
655         }
656     }
657
658   last_double_colon = 0;
659   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
660     {
661       if (i == i_max_n_zero && max_n_zeros > 1)
662         {
663           s = format (s, "::");
664           i += max_n_zeros - 1;
665           last_double_colon = 1;
666         }
667       else
668         {
669           s = format (s, "%s%x",
670                       (last_double_colon || i == 0) ? "" : ":",
671                       clib_net_to_host_u16 (a->as_u16[i]));
672           last_double_colon = 0;
673         }
674     }
675
676   return s;
677 }
678
679 /* Format an IP46 address. */
680 u8 *
681 format_ip46_address (u8 * s, va_list * args)
682 {
683   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
684   ip46_type_t type = va_arg (*args, ip46_type_t);
685   int is_ip4 = 1;
686
687   switch (type)
688     {
689     case IP46_TYPE_ANY:
690       is_ip4 = ip46_address_is_ip4 (ip46);
691       break;
692     case IP46_TYPE_IP4:
693       is_ip4 = 1;
694       break;
695     case IP46_TYPE_IP6:
696       is_ip4 = 0;
697       break;
698     }
699
700   return is_ip4 ?
701     format (s, "%U", format_ip4_address, &ip46->ip4) :
702     format (s, "%U", format_ip6_address, &ip46->ip6);
703 }
704
705 u8 *
706 format_ethernet_address (u8 * s, va_list * args)
707 {
708   u8 *a = va_arg (*args, u8 *);
709
710   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
711                  a[0], a[1], a[2], a[3], a[4], a[5]);
712 }
713 #endif
714
715 static void
716 increment_v4_address (vl_api_ip4_address_t * i)
717 {
718   ip4_address_t *a = (ip4_address_t *) i;
719   u32 v;
720
721   v = ntohl (a->as_u32) + 1;
722   a->as_u32 = ntohl (v);
723 }
724
725 static void
726 increment_v6_address (vl_api_ip6_address_t * i)
727 {
728   ip6_address_t *a = (ip6_address_t *) i;
729   u64 v0, v1;
730
731   v0 = clib_net_to_host_u64 (a->as_u64[0]);
732   v1 = clib_net_to_host_u64 (a->as_u64[1]);
733
734   v1 += 1;
735   if (v1 == 0)
736     v0 += 1;
737   a->as_u64[0] = clib_net_to_host_u64 (v0);
738   a->as_u64[1] = clib_net_to_host_u64 (v1);
739 }
740
741 static void
742 increment_address (vl_api_address_t * a)
743 {
744   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
745     increment_v4_address (&a->un.ip4);
746   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
747     increment_v6_address (&a->un.ip6);
748 }
749
750 static void
751 set_ip4_address (vl_api_address_t * a, u32 v)
752 {
753   if (a->af == ADDRESS_IP4)
754     {
755       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
756       i->as_u32 = v;
757     }
758 }
759
760 static void
761 increment_mac_address (u8 * mac)
762 {
763   u64 tmp = *((u64 *) mac);
764   tmp = clib_net_to_host_u64 (tmp);
765   tmp += 1 << 16;               /* skip unused (least significant) octets */
766   tmp = clib_host_to_net_u64 (tmp);
767
768   clib_memcpy (mac, &tmp, 6);
769 }
770
771 static void
772 vat_json_object_add_address (vat_json_node_t * node,
773                              const char *str, const vl_api_address_t * addr)
774 {
775   if (ADDRESS_IP6 == addr->af)
776     {
777       struct in6_addr ip6;
778
779       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
780       vat_json_object_add_ip6 (node, str, ip6);
781     }
782   else
783     {
784       struct in_addr ip4;
785
786       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
787       vat_json_object_add_ip4 (node, str, ip4);
788     }
789 }
790
791 static void
792 vat_json_object_add_prefix (vat_json_node_t * node,
793                             const vl_api_prefix_t * prefix)
794 {
795   vat_json_object_add_uint (node, "len", prefix->len);
796   vat_json_object_add_address (node, "address", &prefix->address);
797 }
798
799 static void vl_api_create_loopback_reply_t_handler
800   (vl_api_create_loopback_reply_t * mp)
801 {
802   vat_main_t *vam = &vat_main;
803   i32 retval = ntohl (mp->retval);
804
805   vam->retval = retval;
806   vam->regenerate_interface_table = 1;
807   vam->sw_if_index = ntohl (mp->sw_if_index);
808   vam->result_ready = 1;
809 }
810
811 static void vl_api_create_loopback_reply_t_handler_json
812   (vl_api_create_loopback_reply_t * mp)
813 {
814   vat_main_t *vam = &vat_main;
815   vat_json_node_t node;
816
817   vat_json_init_object (&node);
818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
820
821   vat_json_print (vam->ofp, &node);
822   vat_json_free (&node);
823   vam->retval = ntohl (mp->retval);
824   vam->result_ready = 1;
825 }
826
827 static void vl_api_create_loopback_instance_reply_t_handler
828   (vl_api_create_loopback_instance_reply_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   i32 retval = ntohl (mp->retval);
832
833   vam->retval = retval;
834   vam->regenerate_interface_table = 1;
835   vam->sw_if_index = ntohl (mp->sw_if_index);
836   vam->result_ready = 1;
837 }
838
839 static void vl_api_create_loopback_instance_reply_t_handler_json
840   (vl_api_create_loopback_instance_reply_t * mp)
841 {
842   vat_main_t *vam = &vat_main;
843   vat_json_node_t node;
844
845   vat_json_init_object (&node);
846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
848
849   vat_json_print (vam->ofp, &node);
850   vat_json_free (&node);
851   vam->retval = ntohl (mp->retval);
852   vam->result_ready = 1;
853 }
854
855 static void vl_api_af_packet_create_reply_t_handler
856   (vl_api_af_packet_create_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->regenerate_interface_table = 1;
863   vam->sw_if_index = ntohl (mp->sw_if_index);
864   vam->result_ready = 1;
865 }
866
867 static void vl_api_af_packet_create_reply_t_handler_json
868   (vl_api_af_packet_create_reply_t * mp)
869 {
870   vat_main_t *vam = &vat_main;
871   vat_json_node_t node;
872
873   vat_json_init_object (&node);
874   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
875   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
876
877   vat_json_print (vam->ofp, &node);
878   vat_json_free (&node);
879
880   vam->retval = ntohl (mp->retval);
881   vam->result_ready = 1;
882 }
883
884 static void vl_api_create_vlan_subif_reply_t_handler
885   (vl_api_create_vlan_subif_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   i32 retval = ntohl (mp->retval);
889
890   vam->retval = retval;
891   vam->regenerate_interface_table = 1;
892   vam->sw_if_index = ntohl (mp->sw_if_index);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_create_vlan_subif_reply_t_handler_json
897   (vl_api_create_vlan_subif_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_create_subif_reply_t_handler
914   (vl_api_create_subif_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918
919   vam->retval = retval;
920   vam->regenerate_interface_table = 1;
921   vam->sw_if_index = ntohl (mp->sw_if_index);
922   vam->result_ready = 1;
923 }
924
925 static void vl_api_create_subif_reply_t_handler_json
926   (vl_api_create_subif_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_interface_name_renumber_reply_t_handler
943   (vl_api_interface_name_renumber_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947
948   vam->retval = retval;
949   vam->regenerate_interface_table = 1;
950   vam->result_ready = 1;
951 }
952
953 static void vl_api_interface_name_renumber_reply_t_handler_json
954   (vl_api_interface_name_renumber_reply_t * mp)
955 {
956   vat_main_t *vam = &vat_main;
957   vat_json_node_t node;
958
959   vat_json_init_object (&node);
960   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
961
962   vat_json_print (vam->ofp, &node);
963   vat_json_free (&node);
964
965   vam->retval = ntohl (mp->retval);
966   vam->result_ready = 1;
967 }
968
969 /*
970  * Special-case: build the interface table, maintain
971  * the next loopback sw_if_index vbl.
972  */
973 static void vl_api_sw_interface_details_t_handler
974   (vl_api_sw_interface_details_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   u8 *s = format (0, "%s%c", mp->interface_name, 0);
978
979   hash_set_mem (vam->sw_if_index_by_interface_name, s,
980                 ntohl (mp->sw_if_index));
981
982   /* In sub interface case, fill the sub interface table entry */
983   if (mp->sw_if_index != mp->sup_sw_if_index)
984     {
985       sw_interface_subif_t *sub = NULL;
986
987       vec_add2 (vam->sw_if_subif_table, sub, 1);
988
989       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
990       strncpy ((char *) sub->interface_name, (char *) s,
991                vec_len (sub->interface_name));
992       sub->sw_if_index = ntohl (mp->sw_if_index);
993       sub->sub_id = ntohl (mp->sub_id);
994
995       sub->sub_dot1ad = mp->sub_dot1ad;
996       sub->sub_number_of_tags = mp->sub_number_of_tags;
997       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
998       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
999       sub->sub_exact_match = mp->sub_exact_match;
1000       sub->sub_default = mp->sub_default;
1001       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
1002       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
1003
1004       /* vlan tag rewrite */
1005       sub->vtr_op = ntohl (mp->vtr_op);
1006       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1007       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1008       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1009     }
1010 }
1011
1012 static void vl_api_sw_interface_details_t_handler_json
1013   (vl_api_sw_interface_details_t * mp)
1014 {
1015   vat_main_t *vam = &vat_main;
1016   vat_json_node_t *node = NULL;
1017
1018   if (VAT_JSON_ARRAY != vam->json_tree.type)
1019     {
1020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1021       vat_json_init_array (&vam->json_tree);
1022     }
1023   node = vat_json_array_add (&vam->json_tree);
1024
1025   vat_json_init_object (node);
1026   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1027   vat_json_object_add_uint (node, "sup_sw_if_index",
1028                             ntohl (mp->sup_sw_if_index));
1029   vat_json_object_add_uint (node, "l2_address_length",
1030                             ntohl (mp->l2_address_length));
1031   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1032                              sizeof (mp->l2_address));
1033   vat_json_object_add_string_copy (node, "interface_name",
1034                                    mp->interface_name);
1035   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1036   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1037   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1038   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1039   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1040   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1041   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1042   vat_json_object_add_uint (node, "sub_number_of_tags",
1043                             mp->sub_number_of_tags);
1044   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1045                             ntohs (mp->sub_outer_vlan_id));
1046   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1047                             ntohs (mp->sub_inner_vlan_id));
1048   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1049   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1050   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1051                             mp->sub_outer_vlan_id_any);
1052   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1053                             mp->sub_inner_vlan_id_any);
1054   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1055   vat_json_object_add_uint (node, "vtr_push_dot1q",
1056                             ntohl (mp->vtr_push_dot1q));
1057   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1058   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1059   if (mp->sub_dot1ah)
1060     {
1061       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1062                                        format (0, "%U",
1063                                                format_ethernet_address,
1064                                                &mp->b_dmac));
1065       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1066                                        format (0, "%U",
1067                                                format_ethernet_address,
1068                                                &mp->b_smac));
1069       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1070       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1071     }
1072 }
1073
1074 #if VPP_API_TEST_BUILTIN == 0
1075 static void vl_api_sw_interface_event_t_handler
1076   (vl_api_sw_interface_event_t * mp)
1077 {
1078   vat_main_t *vam = &vat_main;
1079   if (vam->interface_event_display)
1080     errmsg ("interface flags: sw_if_index %d %s %s",
1081             ntohl (mp->sw_if_index),
1082             mp->admin_up_down ? "admin-up" : "admin-down",
1083             mp->link_up_down ? "link-up" : "link-down");
1084 }
1085 #endif
1086
1087 __clib_unused static void
1088 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1089 {
1090   /* JSON output not supported */
1091 }
1092
1093 static void
1094 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   i32 retval = ntohl (mp->retval);
1098
1099   vam->retval = retval;
1100   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1101   vam->result_ready = 1;
1102 }
1103
1104 static void
1105 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1106 {
1107   vat_main_t *vam = &vat_main;
1108   vat_json_node_t node;
1109   api_main_t *am = &api_main;
1110   void *oldheap;
1111   u8 *reply;
1112
1113   vat_json_init_object (&node);
1114   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1115   vat_json_object_add_uint (&node, "reply_in_shmem",
1116                             ntohl (mp->reply_in_shmem));
1117   /* Toss the shared-memory original... */
1118   pthread_mutex_lock (&am->vlib_rp->mutex);
1119   oldheap = svm_push_data_heap (am->vlib_rp);
1120
1121   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1122   vec_free (reply);
1123
1124   svm_pop_heap (oldheap);
1125   pthread_mutex_unlock (&am->vlib_rp->mutex);
1126
1127   vat_json_print (vam->ofp, &node);
1128   vat_json_free (&node);
1129
1130   vam->retval = ntohl (mp->retval);
1131   vam->result_ready = 1;
1132 }
1133
1134 static void
1135 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1136 {
1137   vat_main_t *vam = &vat_main;
1138   i32 retval = ntohl (mp->retval);
1139   u32 length = vl_api_string_len (&mp->reply);
1140
1141   vec_reset_length (vam->cmd_reply);
1142
1143   vam->retval = retval;
1144   if (retval == 0)
1145     {
1146       vec_validate (vam->cmd_reply, length);
1147       clib_memcpy ((char *) (vam->cmd_reply),
1148                    vl_api_from_api_string (&mp->reply), length);
1149       vam->cmd_reply[length] = 0;
1150     }
1151   vam->result_ready = 1;
1152 }
1153
1154 static void
1155 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   vat_json_node_t node;
1159
1160   vec_reset_length (vam->cmd_reply);
1161
1162   vat_json_init_object (&node);
1163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1164   vat_json_object_add_string_copy (&node, "reply",
1165                                    vl_api_from_api_string (&mp->reply));
1166
1167   vat_json_print (vam->ofp, &node);
1168   vat_json_free (&node);
1169
1170   vam->retval = ntohl (mp->retval);
1171   vam->result_ready = 1;
1172 }
1173
1174 static void vl_api_classify_add_del_table_reply_t_handler
1175   (vl_api_classify_add_del_table_reply_t * mp)
1176 {
1177   vat_main_t *vam = &vat_main;
1178   i32 retval = ntohl (mp->retval);
1179   if (vam->async_mode)
1180     {
1181       vam->async_errors += (retval < 0);
1182     }
1183   else
1184     {
1185       vam->retval = retval;
1186       if (retval == 0 &&
1187           ((mp->new_table_index != 0xFFFFFFFF) ||
1188            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1189            (mp->match_n_vectors != 0xFFFFFFFF)))
1190         /*
1191          * Note: this is just barely thread-safe, depends on
1192          * the main thread spinning waiting for an answer...
1193          */
1194         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1195                 ntohl (mp->new_table_index),
1196                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1197       vam->result_ready = 1;
1198     }
1199 }
1200
1201 static void vl_api_classify_add_del_table_reply_t_handler_json
1202   (vl_api_classify_add_del_table_reply_t * mp)
1203 {
1204   vat_main_t *vam = &vat_main;
1205   vat_json_node_t node;
1206
1207   vat_json_init_object (&node);
1208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1209   vat_json_object_add_uint (&node, "new_table_index",
1210                             ntohl (mp->new_table_index));
1211   vat_json_object_add_uint (&node, "skip_n_vectors",
1212                             ntohl (mp->skip_n_vectors));
1213   vat_json_object_add_uint (&node, "match_n_vectors",
1214                             ntohl (mp->match_n_vectors));
1215
1216   vat_json_print (vam->ofp, &node);
1217   vat_json_free (&node);
1218
1219   vam->retval = ntohl (mp->retval);
1220   vam->result_ready = 1;
1221 }
1222
1223 static void vl_api_get_node_index_reply_t_handler
1224   (vl_api_get_node_index_reply_t * mp)
1225 {
1226   vat_main_t *vam = &vat_main;
1227   i32 retval = ntohl (mp->retval);
1228   if (vam->async_mode)
1229     {
1230       vam->async_errors += (retval < 0);
1231     }
1232   else
1233     {
1234       vam->retval = retval;
1235       if (retval == 0)
1236         errmsg ("node index %d", ntohl (mp->node_index));
1237       vam->result_ready = 1;
1238     }
1239 }
1240
1241 static void vl_api_get_node_index_reply_t_handler_json
1242   (vl_api_get_node_index_reply_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t node;
1246
1247   vat_json_init_object (&node);
1248   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1249   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1250
1251   vat_json_print (vam->ofp, &node);
1252   vat_json_free (&node);
1253
1254   vam->retval = ntohl (mp->retval);
1255   vam->result_ready = 1;
1256 }
1257
1258 static void vl_api_get_next_index_reply_t_handler
1259   (vl_api_get_next_index_reply_t * mp)
1260 {
1261   vat_main_t *vam = &vat_main;
1262   i32 retval = ntohl (mp->retval);
1263   if (vam->async_mode)
1264     {
1265       vam->async_errors += (retval < 0);
1266     }
1267   else
1268     {
1269       vam->retval = retval;
1270       if (retval == 0)
1271         errmsg ("next node index %d", ntohl (mp->next_index));
1272       vam->result_ready = 1;
1273     }
1274 }
1275
1276 static void vl_api_get_next_index_reply_t_handler_json
1277   (vl_api_get_next_index_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t node;
1281
1282   vat_json_init_object (&node);
1283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1284   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1285
1286   vat_json_print (vam->ofp, &node);
1287   vat_json_free (&node);
1288
1289   vam->retval = ntohl (mp->retval);
1290   vam->result_ready = 1;
1291 }
1292
1293 static void vl_api_add_node_next_reply_t_handler
1294   (vl_api_add_node_next_reply_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   i32 retval = ntohl (mp->retval);
1298   if (vam->async_mode)
1299     {
1300       vam->async_errors += (retval < 0);
1301     }
1302   else
1303     {
1304       vam->retval = retval;
1305       if (retval == 0)
1306         errmsg ("next index %d", ntohl (mp->next_index));
1307       vam->result_ready = 1;
1308     }
1309 }
1310
1311 static void vl_api_add_node_next_reply_t_handler_json
1312   (vl_api_add_node_next_reply_t * mp)
1313 {
1314   vat_main_t *vam = &vat_main;
1315   vat_json_node_t node;
1316
1317   vat_json_init_object (&node);
1318   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1319   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1320
1321   vat_json_print (vam->ofp, &node);
1322   vat_json_free (&node);
1323
1324   vam->retval = ntohl (mp->retval);
1325   vam->result_ready = 1;
1326 }
1327
1328 static void vl_api_show_version_reply_t_handler
1329   (vl_api_show_version_reply_t * mp)
1330 {
1331   vat_main_t *vam = &vat_main;
1332   i32 retval = ntohl (mp->retval);
1333
1334   if (retval >= 0)
1335     {
1336       u8 *s = 0;
1337       char *p = (char *) &mp->program;
1338
1339       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1340       errmsg ("        program: %v\n", s);
1341       vec_free (s);
1342
1343       p +=
1344         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1345       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1346       errmsg ("        version: %v\n", s);
1347       vec_free (s);
1348
1349       p +=
1350         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1351       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1352       errmsg ("     build date: %v\n", s);
1353       vec_free (s);
1354
1355       p +=
1356         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1357       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1358       errmsg ("build directory: %v\n", s);
1359       vec_free (s);
1360     }
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void vl_api_show_version_reply_t_handler_json
1366   (vl_api_show_version_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t node;
1370
1371   vat_json_init_object (&node);
1372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1373   char *p = (char *) &mp->program;
1374   vat_json_object_add_string_copy (&node, "program",
1375                                    vl_api_from_api_string ((vl_api_string_t *)
1376                                                            p));
1377   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1378   vat_json_object_add_string_copy (&node, "version",
1379                                    vl_api_from_api_string ((vl_api_string_t *)
1380                                                            p));
1381   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1382   vat_json_object_add_string_copy (&node, "build_date",
1383                                    vl_api_from_api_string ((vl_api_string_t *)
1384                                                            p));
1385   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1386   vat_json_object_add_string_copy (&node, "build_directory",
1387                                    vl_api_from_api_string ((vl_api_string_t *)
1388                                                            p));
1389
1390   vat_json_print (vam->ofp, &node);
1391   vat_json_free (&node);
1392
1393   vam->retval = ntohl (mp->retval);
1394   vam->result_ready = 1;
1395 }
1396
1397 static void vl_api_show_threads_reply_t_handler
1398   (vl_api_show_threads_reply_t * mp)
1399 {
1400   vat_main_t *vam = &vat_main;
1401   i32 retval = ntohl (mp->retval);
1402   int i, count = 0;
1403
1404   if (retval >= 0)
1405     count = ntohl (mp->count);
1406
1407   for (i = 0; i < count; i++)
1408     print (vam->ofp,
1409            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1410            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1411            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1412            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1413            ntohl (mp->thread_data[i].cpu_socket));
1414
1415   vam->retval = retval;
1416   vam->result_ready = 1;
1417 }
1418
1419 static void vl_api_show_threads_reply_t_handler_json
1420   (vl_api_show_threads_reply_t * mp)
1421 {
1422   vat_main_t *vam = &vat_main;
1423   vat_json_node_t node;
1424   vl_api_thread_data_t *td;
1425   i32 retval = ntohl (mp->retval);
1426   int i, count = 0;
1427
1428   if (retval >= 0)
1429     count = ntohl (mp->count);
1430
1431   vat_json_init_object (&node);
1432   vat_json_object_add_int (&node, "retval", retval);
1433   vat_json_object_add_uint (&node, "count", count);
1434
1435   for (i = 0; i < count; i++)
1436     {
1437       td = &mp->thread_data[i];
1438       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1439       vat_json_object_add_string_copy (&node, "name", td->name);
1440       vat_json_object_add_string_copy (&node, "type", td->type);
1441       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1442       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1443       vat_json_object_add_int (&node, "core", ntohl (td->id));
1444       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1445     }
1446
1447   vat_json_print (vam->ofp, &node);
1448   vat_json_free (&node);
1449
1450   vam->retval = retval;
1451   vam->result_ready = 1;
1452 }
1453
1454 static int
1455 api_show_threads (vat_main_t * vam)
1456 {
1457   vl_api_show_threads_t *mp;
1458   int ret;
1459
1460   print (vam->ofp,
1461          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1462          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1463
1464   M (SHOW_THREADS, mp);
1465
1466   S (mp);
1467   W (ret);
1468   return ret;
1469 }
1470
1471 static void
1472 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1473 {
1474   u32 sw_if_index = ntohl (mp->sw_if_index);
1475   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1476           mp->mac_ip ? "mac/ip binding" : "address resolution",
1477           ntohl (mp->pid), format_ip4_address, mp->ip,
1478           format_vl_api_mac_address, &mp->mac, sw_if_index);
1479 }
1480
1481 static void
1482 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1483 {
1484   /* JSON output not supported */
1485 }
1486
1487 static void
1488 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1489 {
1490   u32 sw_if_index = ntohl (mp->sw_if_index);
1491   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1492           mp->mac_ip ? "mac/ip binding" : "address resolution",
1493           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1494           format_vl_api_mac_address, mp->mac, sw_if_index);
1495 }
1496
1497 static void
1498 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1499 {
1500   /* JSON output not supported */
1501 }
1502
1503 static void
1504 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1505 {
1506   u32 n_macs = ntohl (mp->n_macs);
1507   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1508           ntohl (mp->pid), mp->client_index, n_macs);
1509   int i;
1510   for (i = 0; i < n_macs; i++)
1511     {
1512       vl_api_mac_entry_t *mac = &mp->mac[i];
1513       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1514               i + 1, ntohl (mac->sw_if_index),
1515               format_ethernet_address, mac->mac_addr, mac->action);
1516       if (i == 1000)
1517         break;
1518     }
1519 }
1520
1521 static void
1522 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1523 {
1524   /* JSON output not supported */
1525 }
1526
1527 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1528 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1529
1530 /*
1531  * Special-case: build the bridge domain table, maintain
1532  * the next bd id vbl.
1533  */
1534 static void vl_api_bridge_domain_details_t_handler
1535   (vl_api_bridge_domain_details_t * mp)
1536 {
1537   vat_main_t *vam = &vat_main;
1538   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1539   int i;
1540
1541   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1542          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1543
1544   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1545          ntohl (mp->bd_id), mp->learn, mp->forward,
1546          mp->flood, ntohl (mp->bvi_sw_if_index),
1547          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1548
1549   if (n_sw_ifs)
1550     {
1551       vl_api_bridge_domain_sw_if_t *sw_ifs;
1552       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1553              "Interface Name");
1554
1555       sw_ifs = mp->sw_if_details;
1556       for (i = 0; i < n_sw_ifs; i++)
1557         {
1558           u8 *sw_if_name = 0;
1559           u32 sw_if_index;
1560           hash_pair_t *p;
1561
1562           sw_if_index = ntohl (sw_ifs->sw_if_index);
1563
1564           /* *INDENT-OFF* */
1565           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1566                              ({
1567                                if ((u32) p->value[0] == sw_if_index)
1568                                  {
1569                                    sw_if_name = (u8 *)(p->key);
1570                                    break;
1571                                  }
1572                              }));
1573           /* *INDENT-ON* */
1574           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1575                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1576                  "sw_if_index not found!");
1577
1578           sw_ifs++;
1579         }
1580     }
1581 }
1582
1583 static void vl_api_bridge_domain_details_t_handler_json
1584   (vl_api_bridge_domain_details_t * mp)
1585 {
1586   vat_main_t *vam = &vat_main;
1587   vat_json_node_t *node, *array = NULL;
1588   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1589
1590   if (VAT_JSON_ARRAY != vam->json_tree.type)
1591     {
1592       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1593       vat_json_init_array (&vam->json_tree);
1594     }
1595   node = vat_json_array_add (&vam->json_tree);
1596
1597   vat_json_init_object (node);
1598   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1599   vat_json_object_add_uint (node, "flood", mp->flood);
1600   vat_json_object_add_uint (node, "forward", mp->forward);
1601   vat_json_object_add_uint (node, "learn", mp->learn);
1602   vat_json_object_add_uint (node, "bvi_sw_if_index",
1603                             ntohl (mp->bvi_sw_if_index));
1604   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1605   array = vat_json_object_add (node, "sw_if");
1606   vat_json_init_array (array);
1607
1608
1609
1610   if (n_sw_ifs)
1611     {
1612       vl_api_bridge_domain_sw_if_t *sw_ifs;
1613       int i;
1614
1615       sw_ifs = mp->sw_if_details;
1616       for (i = 0; i < n_sw_ifs; i++)
1617         {
1618           node = vat_json_array_add (array);
1619           vat_json_init_object (node);
1620           vat_json_object_add_uint (node, "sw_if_index",
1621                                     ntohl (sw_ifs->sw_if_index));
1622           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1623           sw_ifs++;
1624         }
1625     }
1626 }
1627
1628 static void vl_api_control_ping_reply_t_handler
1629   (vl_api_control_ping_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   i32 retval = ntohl (mp->retval);
1633   if (vam->async_mode)
1634     {
1635       vam->async_errors += (retval < 0);
1636     }
1637   else
1638     {
1639       vam->retval = retval;
1640       vam->result_ready = 1;
1641     }
1642   if (vam->socket_client_main)
1643     vam->socket_client_main->control_pings_outstanding--;
1644 }
1645
1646 static void vl_api_control_ping_reply_t_handler_json
1647   (vl_api_control_ping_reply_t * mp)
1648 {
1649   vat_main_t *vam = &vat_main;
1650   i32 retval = ntohl (mp->retval);
1651
1652   if (VAT_JSON_NONE != vam->json_tree.type)
1653     {
1654       vat_json_print (vam->ofp, &vam->json_tree);
1655       vat_json_free (&vam->json_tree);
1656       vam->json_tree.type = VAT_JSON_NONE;
1657     }
1658   else
1659     {
1660       /* just print [] */
1661       vat_json_init_array (&vam->json_tree);
1662       vat_json_print (vam->ofp, &vam->json_tree);
1663       vam->json_tree.type = VAT_JSON_NONE;
1664     }
1665
1666   vam->retval = retval;
1667   vam->result_ready = 1;
1668 }
1669
1670 static void
1671   vl_api_bridge_domain_set_mac_age_reply_t_handler
1672   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1673 {
1674   vat_main_t *vam = &vat_main;
1675   i32 retval = ntohl (mp->retval);
1676   if (vam->async_mode)
1677     {
1678       vam->async_errors += (retval < 0);
1679     }
1680   else
1681     {
1682       vam->retval = retval;
1683       vam->result_ready = 1;
1684     }
1685 }
1686
1687 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1688   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   vat_json_node_t node;
1692
1693   vat_json_init_object (&node);
1694   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1695
1696   vat_json_print (vam->ofp, &node);
1697   vat_json_free (&node);
1698
1699   vam->retval = ntohl (mp->retval);
1700   vam->result_ready = 1;
1701 }
1702
1703 static void
1704 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1705 {
1706   vat_main_t *vam = &vat_main;
1707   i32 retval = ntohl (mp->retval);
1708   if (vam->async_mode)
1709     {
1710       vam->async_errors += (retval < 0);
1711     }
1712   else
1713     {
1714       vam->retval = retval;
1715       vam->result_ready = 1;
1716     }
1717 }
1718
1719 static void vl_api_l2_flags_reply_t_handler_json
1720   (vl_api_l2_flags_reply_t * mp)
1721 {
1722   vat_main_t *vam = &vat_main;
1723   vat_json_node_t node;
1724
1725   vat_json_init_object (&node);
1726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1727   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1728                             ntohl (mp->resulting_feature_bitmap));
1729
1730   vat_json_print (vam->ofp, &node);
1731   vat_json_free (&node);
1732
1733   vam->retval = ntohl (mp->retval);
1734   vam->result_ready = 1;
1735 }
1736
1737 static void vl_api_bridge_flags_reply_t_handler
1738   (vl_api_bridge_flags_reply_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   i32 retval = ntohl (mp->retval);
1742   if (vam->async_mode)
1743     {
1744       vam->async_errors += (retval < 0);
1745     }
1746   else
1747     {
1748       vam->retval = retval;
1749       vam->result_ready = 1;
1750     }
1751 }
1752
1753 static void vl_api_bridge_flags_reply_t_handler_json
1754   (vl_api_bridge_flags_reply_t * mp)
1755 {
1756   vat_main_t *vam = &vat_main;
1757   vat_json_node_t node;
1758
1759   vat_json_init_object (&node);
1760   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1761   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1762                             ntohl (mp->resulting_feature_bitmap));
1763
1764   vat_json_print (vam->ofp, &node);
1765   vat_json_free (&node);
1766
1767   vam->retval = ntohl (mp->retval);
1768   vam->result_ready = 1;
1769 }
1770
1771 static void
1772 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   i32 retval = ntohl (mp->retval);
1776   if (vam->async_mode)
1777     {
1778       vam->async_errors += (retval < 0);
1779     }
1780   else
1781     {
1782       vam->retval = retval;
1783       vam->sw_if_index = ntohl (mp->sw_if_index);
1784       vam->result_ready = 1;
1785     }
1786
1787 }
1788
1789 static void vl_api_tap_create_v2_reply_t_handler_json
1790   (vl_api_tap_create_v2_reply_t * mp)
1791 {
1792   vat_main_t *vam = &vat_main;
1793   vat_json_node_t node;
1794
1795   vat_json_init_object (&node);
1796   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1797   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1798
1799   vat_json_print (vam->ofp, &node);
1800   vat_json_free (&node);
1801
1802   vam->retval = ntohl (mp->retval);
1803   vam->result_ready = 1;
1804
1805 }
1806
1807 static void
1808 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1809 {
1810   vat_main_t *vam = &vat_main;
1811   i32 retval = ntohl (mp->retval);
1812   if (vam->async_mode)
1813     {
1814       vam->async_errors += (retval < 0);
1815     }
1816   else
1817     {
1818       vam->retval = retval;
1819       vam->result_ready = 1;
1820     }
1821 }
1822
1823 static void vl_api_tap_delete_v2_reply_t_handler_json
1824   (vl_api_tap_delete_v2_reply_t * mp)
1825 {
1826   vat_main_t *vam = &vat_main;
1827   vat_json_node_t node;
1828
1829   vat_json_init_object (&node);
1830   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1831
1832   vat_json_print (vam->ofp, &node);
1833   vat_json_free (&node);
1834
1835   vam->retval = ntohl (mp->retval);
1836   vam->result_ready = 1;
1837 }
1838
1839 static void
1840 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1841                                           mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844   i32 retval = ntohl (mp->retval);
1845   if (vam->async_mode)
1846     {
1847       vam->async_errors += (retval < 0);
1848     }
1849   else
1850     {
1851       vam->retval = retval;
1852       vam->sw_if_index = ntohl (mp->sw_if_index);
1853       vam->result_ready = 1;
1854     }
1855 }
1856
1857 static void vl_api_virtio_pci_create_reply_t_handler_json
1858   (vl_api_virtio_pci_create_reply_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   vat_json_node_t node;
1862
1863   vat_json_init_object (&node);
1864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1866
1867   vat_json_print (vam->ofp, &node);
1868   vat_json_free (&node);
1869
1870   vam->retval = ntohl (mp->retval);
1871   vam->result_ready = 1;
1872
1873 }
1874
1875 static void
1876 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1877                                           mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   i32 retval = ntohl (mp->retval);
1881   if (vam->async_mode)
1882     {
1883       vam->async_errors += (retval < 0);
1884     }
1885   else
1886     {
1887       vam->retval = retval;
1888       vam->result_ready = 1;
1889     }
1890 }
1891
1892 static void vl_api_virtio_pci_delete_reply_t_handler_json
1893   (vl_api_virtio_pci_delete_reply_t * mp)
1894 {
1895   vat_main_t *vam = &vat_main;
1896   vat_json_node_t node;
1897
1898   vat_json_init_object (&node);
1899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1900
1901   vat_json_print (vam->ofp, &node);
1902   vat_json_free (&node);
1903
1904   vam->retval = ntohl (mp->retval);
1905   vam->result_ready = 1;
1906 }
1907
1908 static void
1909 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1910 {
1911   vat_main_t *vam = &vat_main;
1912   i32 retval = ntohl (mp->retval);
1913
1914   if (vam->async_mode)
1915     {
1916       vam->async_errors += (retval < 0);
1917     }
1918   else
1919     {
1920       vam->retval = retval;
1921       vam->sw_if_index = ntohl (mp->sw_if_index);
1922       vam->result_ready = 1;
1923     }
1924 }
1925
1926 static void vl_api_bond_create_reply_t_handler_json
1927   (vl_api_bond_create_reply_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930   vat_json_node_t node;
1931
1932   vat_json_init_object (&node);
1933   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1934   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1935
1936   vat_json_print (vam->ofp, &node);
1937   vat_json_free (&node);
1938
1939   vam->retval = ntohl (mp->retval);
1940   vam->result_ready = 1;
1941 }
1942
1943 static void
1944 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1945 {
1946   vat_main_t *vam = &vat_main;
1947   i32 retval = ntohl (mp->retval);
1948
1949   if (vam->async_mode)
1950     {
1951       vam->async_errors += (retval < 0);
1952     }
1953   else
1954     {
1955       vam->retval = retval;
1956       vam->result_ready = 1;
1957     }
1958 }
1959
1960 static void vl_api_bond_delete_reply_t_handler_json
1961   (vl_api_bond_delete_reply_t * mp)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   vat_json_node_t node;
1965
1966   vat_json_init_object (&node);
1967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1968
1969   vat_json_print (vam->ofp, &node);
1970   vat_json_free (&node);
1971
1972   vam->retval = ntohl (mp->retval);
1973   vam->result_ready = 1;
1974 }
1975
1976 static void
1977 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   i32 retval = ntohl (mp->retval);
1981
1982   if (vam->async_mode)
1983     {
1984       vam->async_errors += (retval < 0);
1985     }
1986   else
1987     {
1988       vam->retval = retval;
1989       vam->result_ready = 1;
1990     }
1991 }
1992
1993 static void vl_api_bond_enslave_reply_t_handler_json
1994   (vl_api_bond_enslave_reply_t * mp)
1995 {
1996   vat_main_t *vam = &vat_main;
1997   vat_json_node_t node;
1998
1999   vat_json_init_object (&node);
2000   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2001
2002   vat_json_print (vam->ofp, &node);
2003   vat_json_free (&node);
2004
2005   vam->retval = ntohl (mp->retval);
2006   vam->result_ready = 1;
2007 }
2008
2009 static void
2010 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2011                                           mp)
2012 {
2013   vat_main_t *vam = &vat_main;
2014   i32 retval = ntohl (mp->retval);
2015
2016   if (vam->async_mode)
2017     {
2018       vam->async_errors += (retval < 0);
2019     }
2020   else
2021     {
2022       vam->retval = retval;
2023       vam->result_ready = 1;
2024     }
2025 }
2026
2027 static void vl_api_bond_detach_slave_reply_t_handler_json
2028   (vl_api_bond_detach_slave_reply_t * mp)
2029 {
2030   vat_main_t *vam = &vat_main;
2031   vat_json_node_t node;
2032
2033   vat_json_init_object (&node);
2034   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2035
2036   vat_json_print (vam->ofp, &node);
2037   vat_json_free (&node);
2038
2039   vam->retval = ntohl (mp->retval);
2040   vam->result_ready = 1;
2041 }
2042
2043 static void vl_api_sw_interface_bond_details_t_handler
2044   (vl_api_sw_interface_bond_details_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047
2048   print (vam->ofp,
2049          "%-16s %-12d %-12U %-13U %-14u %-14u",
2050          mp->interface_name, ntohl (mp->sw_if_index),
2051          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2052          ntohl (mp->active_slaves), ntohl (mp->slaves));
2053 }
2054
2055 static void vl_api_sw_interface_bond_details_t_handler_json
2056   (vl_api_sw_interface_bond_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vat_json_node_t *node = NULL;
2060
2061   if (VAT_JSON_ARRAY != vam->json_tree.type)
2062     {
2063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064       vat_json_init_array (&vam->json_tree);
2065     }
2066   node = vat_json_array_add (&vam->json_tree);
2067
2068   vat_json_init_object (node);
2069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070   vat_json_object_add_string_copy (node, "interface_name",
2071                                    mp->interface_name);
2072   vat_json_object_add_uint (node, "mode", mp->mode);
2073   vat_json_object_add_uint (node, "load_balance", mp->lb);
2074   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076 }
2077
2078 static int
2079 api_sw_interface_bond_dump (vat_main_t * vam)
2080 {
2081   vl_api_sw_interface_bond_dump_t *mp;
2082   vl_api_control_ping_t *mp_ping;
2083   int ret;
2084
2085   print (vam->ofp,
2086          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087          "interface name", "sw_if_index", "mode", "load balance",
2088          "active slaves", "slaves");
2089
2090   /* Get list of bond interfaces */
2091   M (SW_INTERFACE_BOND_DUMP, mp);
2092   S (mp);
2093
2094   /* Use a control ping for synchronization */
2095   MPING (CONTROL_PING, mp_ping);
2096   S (mp_ping);
2097
2098   W (ret);
2099   return ret;
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106
2107   print (vam->ofp,
2108          "%-25s %-12d %-12d %d", mp->interface_name,
2109          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2110 }
2111
2112 static void vl_api_sw_interface_slave_details_t_handler_json
2113   (vl_api_sw_interface_slave_details_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116   vat_json_node_t *node = NULL;
2117
2118   if (VAT_JSON_ARRAY != vam->json_tree.type)
2119     {
2120       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2121       vat_json_init_array (&vam->json_tree);
2122     }
2123   node = vat_json_array_add (&vam->json_tree);
2124
2125   vat_json_init_object (node);
2126   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2127   vat_json_object_add_string_copy (node, "interface_name",
2128                                    mp->interface_name);
2129   vat_json_object_add_uint (node, "passive", mp->is_passive);
2130   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2131 }
2132
2133 static int
2134 api_sw_interface_slave_dump (vat_main_t * vam)
2135 {
2136   unformat_input_t *i = vam->input;
2137   vl_api_sw_interface_slave_dump_t *mp;
2138   vl_api_control_ping_t *mp_ping;
2139   u32 sw_if_index = ~0;
2140   u8 sw_if_index_set = 0;
2141   int ret;
2142
2143   /* Parse args required to build the message */
2144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2145     {
2146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2147         sw_if_index_set = 1;
2148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2149         sw_if_index_set = 1;
2150       else
2151         break;
2152     }
2153
2154   if (sw_if_index_set == 0)
2155     {
2156       errmsg ("missing vpp interface name. ");
2157       return -99;
2158     }
2159
2160   print (vam->ofp,
2161          "\n%-25s %-12s %-12s %s",
2162          "slave interface name", "sw_if_index", "passive", "long_timeout");
2163
2164   /* Get list of bond interfaces */
2165   M (SW_INTERFACE_SLAVE_DUMP, mp);
2166   mp->sw_if_index = ntohl (sw_if_index);
2167   S (mp);
2168
2169   /* Use a control ping for synchronization */
2170   MPING (CONTROL_PING, mp_ping);
2171   S (mp_ping);
2172
2173   W (ret);
2174   return ret;
2175 }
2176
2177 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2178   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2179 {
2180   vat_main_t *vam = &vat_main;
2181   i32 retval = ntohl (mp->retval);
2182   if (vam->async_mode)
2183     {
2184       vam->async_errors += (retval < 0);
2185     }
2186   else
2187     {
2188       vam->retval = retval;
2189       vam->sw_if_index = ntohl (mp->sw_if_index);
2190       vam->result_ready = 1;
2191     }
2192   vam->regenerate_interface_table = 1;
2193 }
2194
2195 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2196   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vat_json_node_t node;
2200
2201   vat_json_init_object (&node);
2202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2203   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2204                             ntohl (mp->sw_if_index));
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2214   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   i32 retval = ntohl (mp->retval);
2218   if (vam->async_mode)
2219     {
2220       vam->async_errors += (retval < 0);
2221     }
2222   else
2223     {
2224       vam->retval = retval;
2225       vam->sw_if_index = ntohl (mp->sw_if_index);
2226       vam->result_ready = 1;
2227     }
2228 }
2229
2230 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2231   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   vat_json_node_t node;
2235
2236   vat_json_init_object (&node);
2237   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2238   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2239
2240   vat_json_print (vam->ofp, &node);
2241   vat_json_free (&node);
2242
2243   vam->retval = ntohl (mp->retval);
2244   vam->result_ready = 1;
2245 }
2246
2247 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2248   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   i32 retval = ntohl (mp->retval);
2252   if (vam->async_mode)
2253     {
2254       vam->async_errors += (retval < 0);
2255     }
2256   else
2257     {
2258       vam->retval = retval;
2259       vam->result_ready = 1;
2260     }
2261 }
2262
2263 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2264   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2265 {
2266   vat_main_t *vam = &vat_main;
2267   vat_json_node_t node;
2268
2269   vat_json_init_object (&node);
2270   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2271   vat_json_object_add_uint (&node, "fwd_entry_index",
2272                             clib_net_to_host_u32 (mp->fwd_entry_index));
2273
2274   vat_json_print (vam->ofp, &node);
2275   vat_json_free (&node);
2276
2277   vam->retval = ntohl (mp->retval);
2278   vam->result_ready = 1;
2279 }
2280
2281 u8 *
2282 format_lisp_transport_protocol (u8 * s, va_list * args)
2283 {
2284   u32 proto = va_arg (*args, u32);
2285
2286   switch (proto)
2287     {
2288     case 1:
2289       return format (s, "udp");
2290     case 2:
2291       return format (s, "api");
2292     default:
2293       return 0;
2294     }
2295   return 0;
2296 }
2297
2298 static void vl_api_one_get_transport_protocol_reply_t_handler
2299   (vl_api_one_get_transport_protocol_reply_t * mp)
2300 {
2301   vat_main_t *vam = &vat_main;
2302   i32 retval = ntohl (mp->retval);
2303   if (vam->async_mode)
2304     {
2305       vam->async_errors += (retval < 0);
2306     }
2307   else
2308     {
2309       u32 proto = mp->protocol;
2310       print (vam->ofp, "Transport protocol: %U",
2311              format_lisp_transport_protocol, proto);
2312       vam->retval = retval;
2313       vam->result_ready = 1;
2314     }
2315 }
2316
2317 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2318   (vl_api_one_get_transport_protocol_reply_t * mp)
2319 {
2320   vat_main_t *vam = &vat_main;
2321   vat_json_node_t node;
2322   u8 *s;
2323
2324   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2325   vec_add1 (s, 0);
2326
2327   vat_json_init_object (&node);
2328   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2329   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2330
2331   vec_free (s);
2332   vat_json_print (vam->ofp, &node);
2333   vat_json_free (&node);
2334
2335   vam->retval = ntohl (mp->retval);
2336   vam->result_ready = 1;
2337 }
2338
2339 static void vl_api_one_add_del_locator_set_reply_t_handler
2340   (vl_api_one_add_del_locator_set_reply_t * mp)
2341 {
2342   vat_main_t *vam = &vat_main;
2343   i32 retval = ntohl (mp->retval);
2344   if (vam->async_mode)
2345     {
2346       vam->async_errors += (retval < 0);
2347     }
2348   else
2349     {
2350       vam->retval = retval;
2351       vam->result_ready = 1;
2352     }
2353 }
2354
2355 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2356   (vl_api_one_add_del_locator_set_reply_t * mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   vat_json_node_t node;
2360
2361   vat_json_init_object (&node);
2362   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2363   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2364
2365   vat_json_print (vam->ofp, &node);
2366   vat_json_free (&node);
2367
2368   vam->retval = ntohl (mp->retval);
2369   vam->result_ready = 1;
2370 }
2371
2372 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2373   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   i32 retval = ntohl (mp->retval);
2377   if (vam->async_mode)
2378     {
2379       vam->async_errors += (retval < 0);
2380     }
2381   else
2382     {
2383       vam->retval = retval;
2384       vam->sw_if_index = ntohl (mp->sw_if_index);
2385       vam->result_ready = 1;
2386     }
2387   vam->regenerate_interface_table = 1;
2388 }
2389
2390 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2391   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   vat_json_node_t node;
2395
2396   vat_json_init_object (&node);
2397   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2398   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2399
2400   vat_json_print (vam->ofp, &node);
2401   vat_json_free (&node);
2402
2403   vam->retval = ntohl (mp->retval);
2404   vam->result_ready = 1;
2405 }
2406
2407 static void vl_api_vxlan_offload_rx_reply_t_handler
2408   (vl_api_vxlan_offload_rx_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   i32 retval = ntohl (mp->retval);
2412   if (vam->async_mode)
2413     {
2414       vam->async_errors += (retval < 0);
2415     }
2416   else
2417     {
2418       vam->retval = retval;
2419       vam->result_ready = 1;
2420     }
2421 }
2422
2423 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2424   (vl_api_vxlan_offload_rx_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   vat_json_node_t node;
2428
2429   vat_json_init_object (&node);
2430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2431
2432   vat_json_print (vam->ofp, &node);
2433   vat_json_free (&node);
2434
2435   vam->retval = ntohl (mp->retval);
2436   vam->result_ready = 1;
2437 }
2438
2439 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2440   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2441 {
2442   vat_main_t *vam = &vat_main;
2443   i32 retval = ntohl (mp->retval);
2444   if (vam->async_mode)
2445     {
2446       vam->async_errors += (retval < 0);
2447     }
2448   else
2449     {
2450       vam->retval = retval;
2451       vam->sw_if_index = ntohl (mp->sw_if_index);
2452       vam->result_ready = 1;
2453     }
2454 }
2455
2456 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2457   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t node;
2461
2462   vat_json_init_object (&node);
2463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2464   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2465
2466   vat_json_print (vam->ofp, &node);
2467   vat_json_free (&node);
2468
2469   vam->retval = ntohl (mp->retval);
2470   vam->result_ready = 1;
2471 }
2472
2473 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2474   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477   i32 retval = ntohl (mp->retval);
2478   if (vam->async_mode)
2479     {
2480       vam->async_errors += (retval < 0);
2481     }
2482   else
2483     {
2484       vam->retval = retval;
2485       vam->sw_if_index = ntohl (mp->sw_if_index);
2486       vam->result_ready = 1;
2487     }
2488   vam->regenerate_interface_table = 1;
2489 }
2490
2491 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2492   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2493 {
2494   vat_main_t *vam = &vat_main;
2495   vat_json_node_t node;
2496
2497   vat_json_init_object (&node);
2498   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2499   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2500
2501   vat_json_print (vam->ofp, &node);
2502   vat_json_free (&node);
2503
2504   vam->retval = ntohl (mp->retval);
2505   vam->result_ready = 1;
2506 }
2507
2508 static void vl_api_gre_tunnel_add_del_reply_t_handler
2509   (vl_api_gre_tunnel_add_del_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   i32 retval = ntohl (mp->retval);
2513   if (vam->async_mode)
2514     {
2515       vam->async_errors += (retval < 0);
2516     }
2517   else
2518     {
2519       vam->retval = retval;
2520       vam->sw_if_index = ntohl (mp->sw_if_index);
2521       vam->result_ready = 1;
2522     }
2523 }
2524
2525 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2526   (vl_api_gre_tunnel_add_del_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   vat_json_node_t node;
2530
2531   vat_json_init_object (&node);
2532   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2533   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2534
2535   vat_json_print (vam->ofp, &node);
2536   vat_json_free (&node);
2537
2538   vam->retval = ntohl (mp->retval);
2539   vam->result_ready = 1;
2540 }
2541
2542 static void vl_api_create_vhost_user_if_reply_t_handler
2543   (vl_api_create_vhost_user_if_reply_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   i32 retval = ntohl (mp->retval);
2547   if (vam->async_mode)
2548     {
2549       vam->async_errors += (retval < 0);
2550     }
2551   else
2552     {
2553       vam->retval = retval;
2554       vam->sw_if_index = ntohl (mp->sw_if_index);
2555       vam->result_ready = 1;
2556     }
2557   vam->regenerate_interface_table = 1;
2558 }
2559
2560 static void vl_api_create_vhost_user_if_reply_t_handler_json
2561   (vl_api_create_vhost_user_if_reply_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564   vat_json_node_t node;
2565
2566   vat_json_init_object (&node);
2567   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2568   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2569
2570   vat_json_print (vam->ofp, &node);
2571   vat_json_free (&node);
2572
2573   vam->retval = ntohl (mp->retval);
2574   vam->result_ready = 1;
2575 }
2576
2577 static void vl_api_dns_resolve_name_reply_t_handler
2578   (vl_api_dns_resolve_name_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   i32 retval = ntohl (mp->retval);
2582   if (vam->async_mode)
2583     {
2584       vam->async_errors += (retval < 0);
2585     }
2586   else
2587     {
2588       vam->retval = retval;
2589       vam->result_ready = 1;
2590
2591       if (retval == 0)
2592         {
2593           if (mp->ip4_set)
2594             clib_warning ("ip4 address %U", format_ip4_address,
2595                           (ip4_address_t *) mp->ip4_address);
2596           if (mp->ip6_set)
2597             clib_warning ("ip6 address %U", format_ip6_address,
2598                           (ip6_address_t *) mp->ip6_address);
2599         }
2600       else
2601         clib_warning ("retval %d", retval);
2602     }
2603 }
2604
2605 static void vl_api_dns_resolve_name_reply_t_handler_json
2606   (vl_api_dns_resolve_name_reply_t * mp)
2607 {
2608   clib_warning ("not implemented");
2609 }
2610
2611 static void vl_api_dns_resolve_ip_reply_t_handler
2612   (vl_api_dns_resolve_ip_reply_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   i32 retval = ntohl (mp->retval);
2616   if (vam->async_mode)
2617     {
2618       vam->async_errors += (retval < 0);
2619     }
2620   else
2621     {
2622       vam->retval = retval;
2623       vam->result_ready = 1;
2624
2625       if (retval == 0)
2626         {
2627           clib_warning ("canonical name %s", mp->name);
2628         }
2629       else
2630         clib_warning ("retval %d", retval);
2631     }
2632 }
2633
2634 static void vl_api_dns_resolve_ip_reply_t_handler_json
2635   (vl_api_dns_resolve_ip_reply_t * mp)
2636 {
2637   clib_warning ("not implemented");
2638 }
2639
2640
2641 static void vl_api_ip_address_details_t_handler
2642   (vl_api_ip_address_details_t * mp)
2643 {
2644   vat_main_t *vam = &vat_main;
2645   static ip_address_details_t empty_ip_address_details = { {0} };
2646   ip_address_details_t *address = NULL;
2647   ip_details_t *current_ip_details = NULL;
2648   ip_details_t *details = NULL;
2649
2650   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2651
2652   if (!details || vam->current_sw_if_index >= vec_len (details)
2653       || !details[vam->current_sw_if_index].present)
2654     {
2655       errmsg ("ip address details arrived but not stored");
2656       errmsg ("ip_dump should be called first");
2657       return;
2658     }
2659
2660   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2661
2662 #define addresses (current_ip_details->addr)
2663
2664   vec_validate_init_empty (addresses, vec_len (addresses),
2665                            empty_ip_address_details);
2666
2667   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2668
2669   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2670   address->prefix_length = mp->prefix.len;
2671 #undef addresses
2672 }
2673
2674 static void vl_api_ip_address_details_t_handler_json
2675   (vl_api_ip_address_details_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   vat_json_node_t *node = NULL;
2679
2680   if (VAT_JSON_ARRAY != vam->json_tree.type)
2681     {
2682       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2683       vat_json_init_array (&vam->json_tree);
2684     }
2685   node = vat_json_array_add (&vam->json_tree);
2686
2687   vat_json_init_object (node);
2688   vat_json_object_add_prefix (node, &mp->prefix);
2689 }
2690
2691 static void
2692 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   static ip_details_t empty_ip_details = { 0 };
2696   ip_details_t *ip = NULL;
2697   u32 sw_if_index = ~0;
2698
2699   sw_if_index = ntohl (mp->sw_if_index);
2700
2701   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2702                            sw_if_index, empty_ip_details);
2703
2704   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2705                          sw_if_index);
2706
2707   ip->present = 1;
2708 }
2709
2710 static void
2711 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2712 {
2713   vat_main_t *vam = &vat_main;
2714
2715   if (VAT_JSON_ARRAY != vam->json_tree.type)
2716     {
2717       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2718       vat_json_init_array (&vam->json_tree);
2719     }
2720   vat_json_array_add_uint (&vam->json_tree,
2721                            clib_net_to_host_u32 (mp->sw_if_index));
2722 }
2723
2724 static void
2725 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2726 {
2727   u8 *s, i;
2728
2729   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2730               "host_mac %U router_addr %U",
2731               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2732               mp->lease.hostname,
2733               format_ip4_address, mp->lease.host_address,
2734               format_ethernet_address, mp->lease.host_mac,
2735               format_ip4_address, mp->lease.router_address);
2736
2737   for (i = 0; i < mp->lease.count; i++)
2738     s =
2739       format (s, " domain_server_addr %U", format_ip4_address,
2740               mp->lease.domain_server[i].address);
2741
2742   errmsg ((char *) s);
2743   vec_free (s);
2744 }
2745
2746 static void vl_api_dhcp_compl_event_t_handler_json
2747   (vl_api_dhcp_compl_event_t * mp)
2748 {
2749   /* JSON output not supported */
2750 }
2751
2752 static void vl_api_get_first_msg_id_reply_t_handler
2753   (vl_api_get_first_msg_id_reply_t * mp)
2754 {
2755   vat_main_t *vam = &vat_main;
2756   i32 retval = ntohl (mp->retval);
2757
2758   if (vam->async_mode)
2759     {
2760       vam->async_errors += (retval < 0);
2761     }
2762   else
2763     {
2764       vam->retval = retval;
2765       vam->result_ready = 1;
2766     }
2767   if (retval >= 0)
2768     {
2769       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2770     }
2771 }
2772
2773 static void vl_api_get_first_msg_id_reply_t_handler_json
2774   (vl_api_get_first_msg_id_reply_t * mp)
2775 {
2776   vat_main_t *vam = &vat_main;
2777   vat_json_node_t node;
2778
2779   vat_json_init_object (&node);
2780   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2781   vat_json_object_add_uint (&node, "first_msg_id",
2782                             (uint) ntohs (mp->first_msg_id));
2783
2784   vat_json_print (vam->ofp, &node);
2785   vat_json_free (&node);
2786
2787   vam->retval = ntohl (mp->retval);
2788   vam->result_ready = 1;
2789 }
2790
2791 static void vl_api_get_node_graph_reply_t_handler
2792   (vl_api_get_node_graph_reply_t * mp)
2793 {
2794   vat_main_t *vam = &vat_main;
2795   api_main_t *am = &api_main;
2796   i32 retval = ntohl (mp->retval);
2797   u8 *pvt_copy, *reply;
2798   void *oldheap;
2799   vlib_node_t *node;
2800   int i;
2801
2802   if (vam->async_mode)
2803     {
2804       vam->async_errors += (retval < 0);
2805     }
2806   else
2807     {
2808       vam->retval = retval;
2809       vam->result_ready = 1;
2810     }
2811
2812   /* "Should never happen..." */
2813   if (retval != 0)
2814     return;
2815
2816   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2817   pvt_copy = vec_dup (reply);
2818
2819   /* Toss the shared-memory original... */
2820   pthread_mutex_lock (&am->vlib_rp->mutex);
2821   oldheap = svm_push_data_heap (am->vlib_rp);
2822
2823   vec_free (reply);
2824
2825   svm_pop_heap (oldheap);
2826   pthread_mutex_unlock (&am->vlib_rp->mutex);
2827
2828   if (vam->graph_nodes)
2829     {
2830       hash_free (vam->graph_node_index_by_name);
2831
2832       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2833         {
2834           node = vam->graph_nodes[0][i];
2835           vec_free (node->name);
2836           vec_free (node->next_nodes);
2837           vec_free (node);
2838         }
2839       vec_free (vam->graph_nodes[0]);
2840       vec_free (vam->graph_nodes);
2841     }
2842
2843   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2844   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2845   vec_free (pvt_copy);
2846
2847   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2848     {
2849       node = vam->graph_nodes[0][i];
2850       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2851     }
2852 }
2853
2854 static void vl_api_get_node_graph_reply_t_handler_json
2855   (vl_api_get_node_graph_reply_t * mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   api_main_t *am = &api_main;
2859   void *oldheap;
2860   vat_json_node_t node;
2861   u8 *reply;
2862
2863   /* $$$$ make this real? */
2864   vat_json_init_object (&node);
2865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2866   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2867
2868   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2869
2870   /* Toss the shared-memory original... */
2871   pthread_mutex_lock (&am->vlib_rp->mutex);
2872   oldheap = svm_push_data_heap (am->vlib_rp);
2873
2874   vec_free (reply);
2875
2876   svm_pop_heap (oldheap);
2877   pthread_mutex_unlock (&am->vlib_rp->mutex);
2878
2879   vat_json_print (vam->ofp, &node);
2880   vat_json_free (&node);
2881
2882   vam->retval = ntohl (mp->retval);
2883   vam->result_ready = 1;
2884 }
2885
2886 static void
2887 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   u8 *s = 0;
2891
2892   if (mp->local)
2893     {
2894       s = format (s, "%=16d%=16d%=16d",
2895                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2896     }
2897   else
2898     {
2899       s = format (s, "%=16U%=16d%=16d",
2900                   mp->is_ipv6 ? format_ip6_address :
2901                   format_ip4_address,
2902                   mp->ip_address, mp->priority, mp->weight);
2903     }
2904
2905   print (vam->ofp, "%v", s);
2906   vec_free (s);
2907 }
2908
2909 static void
2910 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2911 {
2912   vat_main_t *vam = &vat_main;
2913   vat_json_node_t *node = NULL;
2914   struct in6_addr ip6;
2915   struct in_addr ip4;
2916
2917   if (VAT_JSON_ARRAY != vam->json_tree.type)
2918     {
2919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2920       vat_json_init_array (&vam->json_tree);
2921     }
2922   node = vat_json_array_add (&vam->json_tree);
2923   vat_json_init_object (node);
2924
2925   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2926   vat_json_object_add_uint (node, "priority", mp->priority);
2927   vat_json_object_add_uint (node, "weight", mp->weight);
2928
2929   if (mp->local)
2930     vat_json_object_add_uint (node, "sw_if_index",
2931                               clib_net_to_host_u32 (mp->sw_if_index));
2932   else
2933     {
2934       if (mp->is_ipv6)
2935         {
2936           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2937           vat_json_object_add_ip6 (node, "address", ip6);
2938         }
2939       else
2940         {
2941           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2942           vat_json_object_add_ip4 (node, "address", ip4);
2943         }
2944     }
2945 }
2946
2947 static void
2948 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2949                                           mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   u8 *ls_name = 0;
2953
2954   ls_name = format (0, "%s", mp->ls_name);
2955
2956   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2957          ls_name);
2958   vec_free (ls_name);
2959 }
2960
2961 static void
2962   vl_api_one_locator_set_details_t_handler_json
2963   (vl_api_one_locator_set_details_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   vat_json_node_t *node = 0;
2967   u8 *ls_name = 0;
2968
2969   ls_name = format (0, "%s", mp->ls_name);
2970   vec_add1 (ls_name, 0);
2971
2972   if (VAT_JSON_ARRAY != vam->json_tree.type)
2973     {
2974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2975       vat_json_init_array (&vam->json_tree);
2976     }
2977   node = vat_json_array_add (&vam->json_tree);
2978
2979   vat_json_init_object (node);
2980   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2981   vat_json_object_add_uint (node, "ls_index",
2982                             clib_net_to_host_u32 (mp->ls_index));
2983   vec_free (ls_name);
2984 }
2985
2986 typedef struct
2987 {
2988   u32 spi;
2989   u8 si;
2990 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2991
2992 uword
2993 unformat_nsh_address (unformat_input_t * input, va_list * args)
2994 {
2995   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2996   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2997 }
2998
2999 u8 *
3000 format_nsh_address_vat (u8 * s, va_list * args)
3001 {
3002   nsh_t *a = va_arg (*args, nsh_t *);
3003   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3004 }
3005
3006 static u8 *
3007 format_lisp_flat_eid (u8 * s, va_list * args)
3008 {
3009   u32 type = va_arg (*args, u32);
3010   u8 *eid = va_arg (*args, u8 *);
3011   u32 eid_len = va_arg (*args, u32);
3012
3013   switch (type)
3014     {
3015     case 0:
3016       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3017     case 1:
3018       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3019     case 2:
3020       return format (s, "%U", format_ethernet_address, eid);
3021     case 3:
3022       return format (s, "%U", format_nsh_address_vat, eid);
3023     }
3024   return 0;
3025 }
3026
3027 static u8 *
3028 format_lisp_eid_vat (u8 * s, va_list * args)
3029 {
3030   u32 type = va_arg (*args, u32);
3031   u8 *eid = va_arg (*args, u8 *);
3032   u32 eid_len = va_arg (*args, u32);
3033   u8 *seid = va_arg (*args, u8 *);
3034   u32 seid_len = va_arg (*args, u32);
3035   u32 is_src_dst = va_arg (*args, u32);
3036
3037   if (is_src_dst)
3038     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3039
3040   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3041
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   u8 *s = 0, *eid = 0;
3050
3051   if (~0 == mp->locator_set_index)
3052     s = format (0, "action: %d", mp->action);
3053   else
3054     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3055
3056   eid = format (0, "%U", format_lisp_eid_vat,
3057                 mp->eid_type,
3058                 mp->eid,
3059                 mp->eid_prefix_len,
3060                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3061   vec_add1 (eid, 0);
3062
3063   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3064          clib_net_to_host_u32 (mp->vni),
3065          eid,
3066          mp->is_local ? "local" : "remote",
3067          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3068          clib_net_to_host_u16 (mp->key_id), mp->key);
3069
3070   vec_free (s);
3071   vec_free (eid);
3072 }
3073
3074 static void
3075 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3076                                              * mp)
3077 {
3078   vat_main_t *vam = &vat_main;
3079   vat_json_node_t *node = 0;
3080   u8 *eid = 0;
3081
3082   if (VAT_JSON_ARRAY != vam->json_tree.type)
3083     {
3084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3085       vat_json_init_array (&vam->json_tree);
3086     }
3087   node = vat_json_array_add (&vam->json_tree);
3088
3089   vat_json_init_object (node);
3090   if (~0 == mp->locator_set_index)
3091     vat_json_object_add_uint (node, "action", mp->action);
3092   else
3093     vat_json_object_add_uint (node, "locator_set_index",
3094                               clib_net_to_host_u32 (mp->locator_set_index));
3095
3096   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3097   if (mp->eid_type == 3)
3098     {
3099       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3100       vat_json_init_object (nsh_json);
3101       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3102       vat_json_object_add_uint (nsh_json, "spi",
3103                                 clib_net_to_host_u32 (nsh->spi));
3104       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3105     }
3106   else
3107     {
3108       eid = format (0, "%U", format_lisp_eid_vat,
3109                     mp->eid_type,
3110                     mp->eid,
3111                     mp->eid_prefix_len,
3112                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3113       vec_add1 (eid, 0);
3114       vat_json_object_add_string_copy (node, "eid", eid);
3115       vec_free (eid);
3116     }
3117   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3118   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3119   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3120
3121   if (mp->key_id)
3122     {
3123       vat_json_object_add_uint (node, "key_id",
3124                                 clib_net_to_host_u16 (mp->key_id));
3125       vat_json_object_add_string_copy (node, "key", mp->key);
3126     }
3127 }
3128
3129 static void
3130 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3131 {
3132   vat_main_t *vam = &vat_main;
3133   u8 *seid = 0, *deid = 0;
3134   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3135
3136   deid = format (0, "%U", format_lisp_eid_vat,
3137                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3138
3139   seid = format (0, "%U", format_lisp_eid_vat,
3140                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3141
3142   vec_add1 (deid, 0);
3143   vec_add1 (seid, 0);
3144
3145   if (mp->is_ip4)
3146     format_ip_address_fcn = format_ip4_address;
3147   else
3148     format_ip_address_fcn = format_ip6_address;
3149
3150
3151   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3152          clib_net_to_host_u32 (mp->vni),
3153          seid, deid,
3154          format_ip_address_fcn, mp->lloc,
3155          format_ip_address_fcn, mp->rloc,
3156          clib_net_to_host_u32 (mp->pkt_count),
3157          clib_net_to_host_u32 (mp->bytes));
3158
3159   vec_free (deid);
3160   vec_free (seid);
3161 }
3162
3163 static void
3164 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3165 {
3166   struct in6_addr ip6;
3167   struct in_addr ip4;
3168   vat_main_t *vam = &vat_main;
3169   vat_json_node_t *node = 0;
3170   u8 *deid = 0, *seid = 0;
3171
3172   if (VAT_JSON_ARRAY != vam->json_tree.type)
3173     {
3174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3175       vat_json_init_array (&vam->json_tree);
3176     }
3177   node = vat_json_array_add (&vam->json_tree);
3178
3179   vat_json_init_object (node);
3180   deid = format (0, "%U", format_lisp_eid_vat,
3181                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3182
3183   seid = format (0, "%U", format_lisp_eid_vat,
3184                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3185
3186   vec_add1 (deid, 0);
3187   vec_add1 (seid, 0);
3188
3189   vat_json_object_add_string_copy (node, "seid", seid);
3190   vat_json_object_add_string_copy (node, "deid", deid);
3191   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3192
3193   if (mp->is_ip4)
3194     {
3195       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3196       vat_json_object_add_ip4 (node, "lloc", ip4);
3197       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3198       vat_json_object_add_ip4 (node, "rloc", ip4);
3199     }
3200   else
3201     {
3202       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3203       vat_json_object_add_ip6 (node, "lloc", ip6);
3204       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3205       vat_json_object_add_ip6 (node, "rloc", ip6);
3206     }
3207   vat_json_object_add_uint (node, "pkt_count",
3208                             clib_net_to_host_u32 (mp->pkt_count));
3209   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3210
3211   vec_free (deid);
3212   vec_free (seid);
3213 }
3214
3215 static void
3216   vl_api_one_eid_table_map_details_t_handler
3217   (vl_api_one_eid_table_map_details_t * mp)
3218 {
3219   vat_main_t *vam = &vat_main;
3220
3221   u8 *line = format (0, "%=10d%=10d",
3222                      clib_net_to_host_u32 (mp->vni),
3223                      clib_net_to_host_u32 (mp->dp_table));
3224   print (vam->ofp, "%v", line);
3225   vec_free (line);
3226 }
3227
3228 static void
3229   vl_api_one_eid_table_map_details_t_handler_json
3230   (vl_api_one_eid_table_map_details_t * mp)
3231 {
3232   vat_main_t *vam = &vat_main;
3233   vat_json_node_t *node = NULL;
3234
3235   if (VAT_JSON_ARRAY != vam->json_tree.type)
3236     {
3237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3238       vat_json_init_array (&vam->json_tree);
3239     }
3240   node = vat_json_array_add (&vam->json_tree);
3241   vat_json_init_object (node);
3242   vat_json_object_add_uint (node, "dp_table",
3243                             clib_net_to_host_u32 (mp->dp_table));
3244   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3245 }
3246
3247 static void
3248   vl_api_one_eid_table_vni_details_t_handler
3249   (vl_api_one_eid_table_vni_details_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252
3253   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3254   print (vam->ofp, "%v", line);
3255   vec_free (line);
3256 }
3257
3258 static void
3259   vl_api_one_eid_table_vni_details_t_handler_json
3260   (vl_api_one_eid_table_vni_details_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   vat_json_node_t *node = NULL;
3264
3265   if (VAT_JSON_ARRAY != vam->json_tree.type)
3266     {
3267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3268       vat_json_init_array (&vam->json_tree);
3269     }
3270   node = vat_json_array_add (&vam->json_tree);
3271   vat_json_init_object (node);
3272   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3273 }
3274
3275 static void
3276   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3277   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3278 {
3279   vat_main_t *vam = &vat_main;
3280   int retval = clib_net_to_host_u32 (mp->retval);
3281
3282   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3283   print (vam->ofp, "fallback threshold value: %d", mp->value);
3284
3285   vam->retval = retval;
3286   vam->result_ready = 1;
3287 }
3288
3289 static void
3290   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3291   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3292 {
3293   vat_main_t *vam = &vat_main;
3294   vat_json_node_t _node, *node = &_node;
3295   int retval = clib_net_to_host_u32 (mp->retval);
3296
3297   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3298   vat_json_init_object (node);
3299   vat_json_object_add_uint (node, "value", mp->value);
3300
3301   vat_json_print (vam->ofp, node);
3302   vat_json_free (node);
3303
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306 }
3307
3308 static void
3309   vl_api_show_one_map_register_state_reply_t_handler
3310   (vl_api_show_one_map_register_state_reply_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   int retval = clib_net_to_host_u32 (mp->retval);
3314
3315   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3316
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319 }
3320
3321 static void
3322   vl_api_show_one_map_register_state_reply_t_handler_json
3323   (vl_api_show_one_map_register_state_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   vat_json_node_t _node, *node = &_node;
3327   int retval = clib_net_to_host_u32 (mp->retval);
3328
3329   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3330
3331   vat_json_init_object (node);
3332   vat_json_object_add_string_copy (node, "state", s);
3333
3334   vat_json_print (vam->ofp, node);
3335   vat_json_free (node);
3336
3337   vam->retval = retval;
3338   vam->result_ready = 1;
3339   vec_free (s);
3340 }
3341
3342 static void
3343   vl_api_show_one_rloc_probe_state_reply_t_handler
3344   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3345 {
3346   vat_main_t *vam = &vat_main;
3347   int retval = clib_net_to_host_u32 (mp->retval);
3348
3349   if (retval)
3350     goto end;
3351
3352   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3353 end:
3354   vam->retval = retval;
3355   vam->result_ready = 1;
3356 }
3357
3358 static void
3359   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3360   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3361 {
3362   vat_main_t *vam = &vat_main;
3363   vat_json_node_t _node, *node = &_node;
3364   int retval = clib_net_to_host_u32 (mp->retval);
3365
3366   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3367   vat_json_init_object (node);
3368   vat_json_object_add_string_copy (node, "state", s);
3369
3370   vat_json_print (vam->ofp, node);
3371   vat_json_free (node);
3372
3373   vam->retval = retval;
3374   vam->result_ready = 1;
3375   vec_free (s);
3376 }
3377
3378 static void
3379   vl_api_show_one_stats_enable_disable_reply_t_handler
3380   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3381 {
3382   vat_main_t *vam = &vat_main;
3383   int retval = clib_net_to_host_u32 (mp->retval);
3384
3385   if (retval)
3386     goto end;
3387
3388   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3389 end:
3390   vam->retval = retval;
3391   vam->result_ready = 1;
3392 }
3393
3394 static void
3395   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3396   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399   vat_json_node_t _node, *node = &_node;
3400   int retval = clib_net_to_host_u32 (mp->retval);
3401
3402   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3403   vat_json_init_object (node);
3404   vat_json_object_add_string_copy (node, "state", s);
3405
3406   vat_json_print (vam->ofp, node);
3407   vat_json_free (node);
3408
3409   vam->retval = retval;
3410   vam->result_ready = 1;
3411   vec_free (s);
3412 }
3413
3414 static void
3415 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3416 {
3417   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3418   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3419   e->vni = clib_net_to_host_u32 (e->vni);
3420 }
3421
3422 static void
3423   gpe_fwd_entries_get_reply_t_net_to_host
3424   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3425 {
3426   u32 i;
3427
3428   mp->count = clib_net_to_host_u32 (mp->count);
3429   for (i = 0; i < mp->count; i++)
3430     {
3431       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3432     }
3433 }
3434
3435 static u8 *
3436 format_gpe_encap_mode (u8 * s, va_list * args)
3437 {
3438   u32 mode = va_arg (*args, u32);
3439
3440   switch (mode)
3441     {
3442     case 0:
3443       return format (s, "lisp");
3444     case 1:
3445       return format (s, "vxlan");
3446     }
3447   return 0;
3448 }
3449
3450 static void
3451   vl_api_gpe_get_encap_mode_reply_t_handler
3452   (vl_api_gpe_get_encap_mode_reply_t * mp)
3453 {
3454   vat_main_t *vam = &vat_main;
3455
3456   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3457   vam->retval = ntohl (mp->retval);
3458   vam->result_ready = 1;
3459 }
3460
3461 static void
3462   vl_api_gpe_get_encap_mode_reply_t_handler_json
3463   (vl_api_gpe_get_encap_mode_reply_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   vat_json_node_t node;
3467
3468   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3469   vec_add1 (encap_mode, 0);
3470
3471   vat_json_init_object (&node);
3472   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3473
3474   vec_free (encap_mode);
3475   vat_json_print (vam->ofp, &node);
3476   vat_json_free (&node);
3477
3478   vam->retval = ntohl (mp->retval);
3479   vam->result_ready = 1;
3480 }
3481
3482 static void
3483   vl_api_gpe_fwd_entry_path_details_t_handler
3484   (vl_api_gpe_fwd_entry_path_details_t * mp)
3485 {
3486   vat_main_t *vam = &vat_main;
3487   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3488
3489   if (mp->lcl_loc.is_ip4)
3490     format_ip_address_fcn = format_ip4_address;
3491   else
3492     format_ip_address_fcn = format_ip6_address;
3493
3494   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3495          format_ip_address_fcn, &mp->lcl_loc,
3496          format_ip_address_fcn, &mp->rmt_loc);
3497 }
3498
3499 static void
3500 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3501 {
3502   struct in6_addr ip6;
3503   struct in_addr ip4;
3504
3505   if (loc->is_ip4)
3506     {
3507       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3508       vat_json_object_add_ip4 (n, "address", ip4);
3509     }
3510   else
3511     {
3512       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3513       vat_json_object_add_ip6 (n, "address", ip6);
3514     }
3515   vat_json_object_add_uint (n, "weight", loc->weight);
3516 }
3517
3518 static void
3519   vl_api_gpe_fwd_entry_path_details_t_handler_json
3520   (vl_api_gpe_fwd_entry_path_details_t * mp)
3521 {
3522   vat_main_t *vam = &vat_main;
3523   vat_json_node_t *node = NULL;
3524   vat_json_node_t *loc_node;
3525
3526   if (VAT_JSON_ARRAY != vam->json_tree.type)
3527     {
3528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3529       vat_json_init_array (&vam->json_tree);
3530     }
3531   node = vat_json_array_add (&vam->json_tree);
3532   vat_json_init_object (node);
3533
3534   loc_node = vat_json_object_add (node, "local_locator");
3535   vat_json_init_object (loc_node);
3536   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3537
3538   loc_node = vat_json_object_add (node, "remote_locator");
3539   vat_json_init_object (loc_node);
3540   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3541 }
3542
3543 static void
3544   vl_api_gpe_fwd_entries_get_reply_t_handler
3545   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   u32 i;
3549   int retval = clib_net_to_host_u32 (mp->retval);
3550   vl_api_gpe_fwd_entry_t *e;
3551
3552   if (retval)
3553     goto end;
3554
3555   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3556
3557   for (i = 0; i < mp->count; i++)
3558     {
3559       e = &mp->entries[i];
3560       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3561              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3562              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3563     }
3564
3565 end:
3566   vam->retval = retval;
3567   vam->result_ready = 1;
3568 }
3569
3570 static void
3571   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3572   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3573 {
3574   u8 *s = 0;
3575   vat_main_t *vam = &vat_main;
3576   vat_json_node_t *e = 0, root;
3577   u32 i;
3578   int retval = clib_net_to_host_u32 (mp->retval);
3579   vl_api_gpe_fwd_entry_t *fwd;
3580
3581   if (retval)
3582     goto end;
3583
3584   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3585   vat_json_init_array (&root);
3586
3587   for (i = 0; i < mp->count; i++)
3588     {
3589       e = vat_json_array_add (&root);
3590       fwd = &mp->entries[i];
3591
3592       vat_json_init_object (e);
3593       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3594       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3595       vat_json_object_add_int (e, "vni", fwd->vni);
3596       vat_json_object_add_int (e, "action", fwd->action);
3597
3598       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3599                   fwd->leid_prefix_len);
3600       vec_add1 (s, 0);
3601       vat_json_object_add_string_copy (e, "leid", s);
3602       vec_free (s);
3603
3604       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3605                   fwd->reid_prefix_len);
3606       vec_add1 (s, 0);
3607       vat_json_object_add_string_copy (e, "reid", s);
3608       vec_free (s);
3609     }
3610
3611   vat_json_print (vam->ofp, &root);
3612   vat_json_free (&root);
3613
3614 end:
3615   vam->retval = retval;
3616   vam->result_ready = 1;
3617 }
3618
3619 static void
3620   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3621   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   u32 i, n;
3625   int retval = clib_net_to_host_u32 (mp->retval);
3626   vl_api_gpe_native_fwd_rpath_t *r;
3627
3628   if (retval)
3629     goto end;
3630
3631   n = clib_net_to_host_u32 (mp->count);
3632
3633   for (i = 0; i < n; i++)
3634     {
3635       r = &mp->entries[i];
3636       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3637              clib_net_to_host_u32 (r->fib_index),
3638              clib_net_to_host_u32 (r->nh_sw_if_index),
3639              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3640     }
3641
3642 end:
3643   vam->retval = retval;
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3649   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   vat_json_node_t root, *e;
3653   u32 i, n;
3654   int retval = clib_net_to_host_u32 (mp->retval);
3655   vl_api_gpe_native_fwd_rpath_t *r;
3656   u8 *s;
3657
3658   if (retval)
3659     goto end;
3660
3661   n = clib_net_to_host_u32 (mp->count);
3662   vat_json_init_array (&root);
3663
3664   for (i = 0; i < n; i++)
3665     {
3666       e = vat_json_array_add (&root);
3667       vat_json_init_object (e);
3668       r = &mp->entries[i];
3669       s =
3670         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3671                 r->nh_addr);
3672       vec_add1 (s, 0);
3673       vat_json_object_add_string_copy (e, "ip4", s);
3674       vec_free (s);
3675
3676       vat_json_object_add_uint (e, "fib_index",
3677                                 clib_net_to_host_u32 (r->fib_index));
3678       vat_json_object_add_uint (e, "nh_sw_if_index",
3679                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3680     }
3681
3682   vat_json_print (vam->ofp, &root);
3683   vat_json_free (&root);
3684
3685 end:
3686   vam->retval = retval;
3687   vam->result_ready = 1;
3688 }
3689
3690 static void
3691   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3692   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695   u32 i, n;
3696   int retval = clib_net_to_host_u32 (mp->retval);
3697
3698   if (retval)
3699     goto end;
3700
3701   n = clib_net_to_host_u32 (mp->count);
3702
3703   for (i = 0; i < n; i++)
3704     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3705
3706 end:
3707   vam->retval = retval;
3708   vam->result_ready = 1;
3709 }
3710
3711 static void
3712   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3713   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3714 {
3715   vat_main_t *vam = &vat_main;
3716   vat_json_node_t root;
3717   u32 i, n;
3718   int retval = clib_net_to_host_u32 (mp->retval);
3719
3720   if (retval)
3721     goto end;
3722
3723   n = clib_net_to_host_u32 (mp->count);
3724   vat_json_init_array (&root);
3725
3726   for (i = 0; i < n; i++)
3727     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3728
3729   vat_json_print (vam->ofp, &root);
3730   vat_json_free (&root);
3731
3732 end:
3733   vam->retval = retval;
3734   vam->result_ready = 1;
3735 }
3736
3737 static void
3738   vl_api_one_ndp_entries_get_reply_t_handler
3739   (vl_api_one_ndp_entries_get_reply_t * mp)
3740 {
3741   vat_main_t *vam = &vat_main;
3742   u32 i, n;
3743   int retval = clib_net_to_host_u32 (mp->retval);
3744
3745   if (retval)
3746     goto end;
3747
3748   n = clib_net_to_host_u32 (mp->count);
3749
3750   for (i = 0; i < n; i++)
3751     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3752            format_ethernet_address, mp->entries[i].mac);
3753
3754 end:
3755   vam->retval = retval;
3756   vam->result_ready = 1;
3757 }
3758
3759 static void
3760   vl_api_one_ndp_entries_get_reply_t_handler_json
3761   (vl_api_one_ndp_entries_get_reply_t * mp)
3762 {
3763   u8 *s = 0;
3764   vat_main_t *vam = &vat_main;
3765   vat_json_node_t *e = 0, root;
3766   u32 i, n;
3767   int retval = clib_net_to_host_u32 (mp->retval);
3768   vl_api_one_ndp_entry_t *arp_entry;
3769
3770   if (retval)
3771     goto end;
3772
3773   n = clib_net_to_host_u32 (mp->count);
3774   vat_json_init_array (&root);
3775
3776   for (i = 0; i < n; i++)
3777     {
3778       e = vat_json_array_add (&root);
3779       arp_entry = &mp->entries[i];
3780
3781       vat_json_init_object (e);
3782       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3783       vec_add1 (s, 0);
3784
3785       vat_json_object_add_string_copy (e, "mac", s);
3786       vec_free (s);
3787
3788       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3789       vec_add1 (s, 0);
3790       vat_json_object_add_string_copy (e, "ip6", s);
3791       vec_free (s);
3792     }
3793
3794   vat_json_print (vam->ofp, &root);
3795   vat_json_free (&root);
3796
3797 end:
3798   vam->retval = retval;
3799   vam->result_ready = 1;
3800 }
3801
3802 static void
3803   vl_api_one_l2_arp_entries_get_reply_t_handler
3804   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3805 {
3806   vat_main_t *vam = &vat_main;
3807   u32 i, n;
3808   int retval = clib_net_to_host_u32 (mp->retval);
3809
3810   if (retval)
3811     goto end;
3812
3813   n = clib_net_to_host_u32 (mp->count);
3814
3815   for (i = 0; i < n; i++)
3816     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3817            format_ethernet_address, mp->entries[i].mac);
3818
3819 end:
3820   vam->retval = retval;
3821   vam->result_ready = 1;
3822 }
3823
3824 static void
3825   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3826   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3827 {
3828   u8 *s = 0;
3829   vat_main_t *vam = &vat_main;
3830   vat_json_node_t *e = 0, root;
3831   u32 i, n;
3832   int retval = clib_net_to_host_u32 (mp->retval);
3833   vl_api_one_l2_arp_entry_t *arp_entry;
3834
3835   if (retval)
3836     goto end;
3837
3838   n = clib_net_to_host_u32 (mp->count);
3839   vat_json_init_array (&root);
3840
3841   for (i = 0; i < n; i++)
3842     {
3843       e = vat_json_array_add (&root);
3844       arp_entry = &mp->entries[i];
3845
3846       vat_json_init_object (e);
3847       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3848       vec_add1 (s, 0);
3849
3850       vat_json_object_add_string_copy (e, "mac", s);
3851       vec_free (s);
3852
3853       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3854       vec_add1 (s, 0);
3855       vat_json_object_add_string_copy (e, "ip4", s);
3856       vec_free (s);
3857     }
3858
3859   vat_json_print (vam->ofp, &root);
3860   vat_json_free (&root);
3861
3862 end:
3863   vam->retval = retval;
3864   vam->result_ready = 1;
3865 }
3866
3867 static void
3868 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3869 {
3870   vat_main_t *vam = &vat_main;
3871   u32 i, n;
3872   int retval = clib_net_to_host_u32 (mp->retval);
3873
3874   if (retval)
3875     goto end;
3876
3877   n = clib_net_to_host_u32 (mp->count);
3878
3879   for (i = 0; i < n; i++)
3880     {
3881       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3882     }
3883
3884 end:
3885   vam->retval = retval;
3886   vam->result_ready = 1;
3887 }
3888
3889 static void
3890   vl_api_one_ndp_bd_get_reply_t_handler_json
3891   (vl_api_one_ndp_bd_get_reply_t * mp)
3892 {
3893   vat_main_t *vam = &vat_main;
3894   vat_json_node_t root;
3895   u32 i, n;
3896   int retval = clib_net_to_host_u32 (mp->retval);
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902   vat_json_init_array (&root);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       vat_json_array_add_uint (&root,
3907                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3908     }
3909
3910   vat_json_print (vam->ofp, &root);
3911   vat_json_free (&root);
3912
3913 end:
3914   vam->retval = retval;
3915   vam->result_ready = 1;
3916 }
3917
3918 static void
3919   vl_api_one_l2_arp_bd_get_reply_t_handler
3920   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3921 {
3922   vat_main_t *vam = &vat_main;
3923   u32 i, n;
3924   int retval = clib_net_to_host_u32 (mp->retval);
3925
3926   if (retval)
3927     goto end;
3928
3929   n = clib_net_to_host_u32 (mp->count);
3930
3931   for (i = 0; i < n; i++)
3932     {
3933       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3934     }
3935
3936 end:
3937   vam->retval = retval;
3938   vam->result_ready = 1;
3939 }
3940
3941 static void
3942   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3943   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3944 {
3945   vat_main_t *vam = &vat_main;
3946   vat_json_node_t root;
3947   u32 i, n;
3948   int retval = clib_net_to_host_u32 (mp->retval);
3949
3950   if (retval)
3951     goto end;
3952
3953   n = clib_net_to_host_u32 (mp->count);
3954   vat_json_init_array (&root);
3955
3956   for (i = 0; i < n; i++)
3957     {
3958       vat_json_array_add_uint (&root,
3959                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3960     }
3961
3962   vat_json_print (vam->ofp, &root);
3963   vat_json_free (&root);
3964
3965 end:
3966   vam->retval = retval;
3967   vam->result_ready = 1;
3968 }
3969
3970 static void
3971   vl_api_one_adjacencies_get_reply_t_handler
3972   (vl_api_one_adjacencies_get_reply_t * mp)
3973 {
3974   vat_main_t *vam = &vat_main;
3975   u32 i, n;
3976   int retval = clib_net_to_host_u32 (mp->retval);
3977   vl_api_one_adjacency_t *a;
3978
3979   if (retval)
3980     goto end;
3981
3982   n = clib_net_to_host_u32 (mp->count);
3983
3984   for (i = 0; i < n; i++)
3985     {
3986       a = &mp->adjacencies[i];
3987       print (vam->ofp, "%U %40U",
3988              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3989              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3990     }
3991
3992 end:
3993   vam->retval = retval;
3994   vam->result_ready = 1;
3995 }
3996
3997 static void
3998   vl_api_one_adjacencies_get_reply_t_handler_json
3999   (vl_api_one_adjacencies_get_reply_t * mp)
4000 {
4001   u8 *s = 0;
4002   vat_main_t *vam = &vat_main;
4003   vat_json_node_t *e = 0, root;
4004   u32 i, n;
4005   int retval = clib_net_to_host_u32 (mp->retval);
4006   vl_api_one_adjacency_t *a;
4007
4008   if (retval)
4009     goto end;
4010
4011   n = clib_net_to_host_u32 (mp->count);
4012   vat_json_init_array (&root);
4013
4014   for (i = 0; i < n; i++)
4015     {
4016       e = vat_json_array_add (&root);
4017       a = &mp->adjacencies[i];
4018
4019       vat_json_init_object (e);
4020       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4021                   a->leid_prefix_len);
4022       vec_add1 (s, 0);
4023       vat_json_object_add_string_copy (e, "leid", s);
4024       vec_free (s);
4025
4026       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4027                   a->reid_prefix_len);
4028       vec_add1 (s, 0);
4029       vat_json_object_add_string_copy (e, "reid", s);
4030       vec_free (s);
4031     }
4032
4033   vat_json_print (vam->ofp, &root);
4034   vat_json_free (&root);
4035
4036 end:
4037   vam->retval = retval;
4038   vam->result_ready = 1;
4039 }
4040
4041 static void
4042 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4043 {
4044   vat_main_t *vam = &vat_main;
4045
4046   print (vam->ofp, "%=20U",
4047          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4048          mp->ip_address);
4049 }
4050
4051 static void
4052   vl_api_one_map_server_details_t_handler_json
4053   (vl_api_one_map_server_details_t * mp)
4054 {
4055   vat_main_t *vam = &vat_main;
4056   vat_json_node_t *node = NULL;
4057   struct in6_addr ip6;
4058   struct in_addr ip4;
4059
4060   if (VAT_JSON_ARRAY != vam->json_tree.type)
4061     {
4062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4063       vat_json_init_array (&vam->json_tree);
4064     }
4065   node = vat_json_array_add (&vam->json_tree);
4066
4067   vat_json_init_object (node);
4068   if (mp->is_ipv6)
4069     {
4070       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4071       vat_json_object_add_ip6 (node, "map-server", ip6);
4072     }
4073   else
4074     {
4075       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4076       vat_json_object_add_ip4 (node, "map-server", ip4);
4077     }
4078 }
4079
4080 static void
4081 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4082                                            * mp)
4083 {
4084   vat_main_t *vam = &vat_main;
4085
4086   print (vam->ofp, "%=20U",
4087          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4088          mp->ip_address);
4089 }
4090
4091 static void
4092   vl_api_one_map_resolver_details_t_handler_json
4093   (vl_api_one_map_resolver_details_t * mp)
4094 {
4095   vat_main_t *vam = &vat_main;
4096   vat_json_node_t *node = NULL;
4097   struct in6_addr ip6;
4098   struct in_addr ip4;
4099
4100   if (VAT_JSON_ARRAY != vam->json_tree.type)
4101     {
4102       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4103       vat_json_init_array (&vam->json_tree);
4104     }
4105   node = vat_json_array_add (&vam->json_tree);
4106
4107   vat_json_init_object (node);
4108   if (mp->is_ipv6)
4109     {
4110       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4111       vat_json_object_add_ip6 (node, "map resolver", ip6);
4112     }
4113   else
4114     {
4115       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4116       vat_json_object_add_ip4 (node, "map resolver", ip4);
4117     }
4118 }
4119
4120 static void
4121 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4122 {
4123   vat_main_t *vam = &vat_main;
4124   i32 retval = ntohl (mp->retval);
4125
4126   if (0 <= retval)
4127     {
4128       print (vam->ofp, "feature: %s\ngpe: %s",
4129              mp->feature_status ? "enabled" : "disabled",
4130              mp->gpe_status ? "enabled" : "disabled");
4131     }
4132
4133   vam->retval = retval;
4134   vam->result_ready = 1;
4135 }
4136
4137 static void
4138   vl_api_show_one_status_reply_t_handler_json
4139   (vl_api_show_one_status_reply_t * mp)
4140 {
4141   vat_main_t *vam = &vat_main;
4142   vat_json_node_t node;
4143   u8 *gpe_status = NULL;
4144   u8 *feature_status = NULL;
4145
4146   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4147   feature_status = format (0, "%s",
4148                            mp->feature_status ? "enabled" : "disabled");
4149   vec_add1 (gpe_status, 0);
4150   vec_add1 (feature_status, 0);
4151
4152   vat_json_init_object (&node);
4153   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4154   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4155
4156   vec_free (gpe_status);
4157   vec_free (feature_status);
4158
4159   vat_json_print (vam->ofp, &node);
4160   vat_json_free (&node);
4161
4162   vam->retval = ntohl (mp->retval);
4163   vam->result_ready = 1;
4164 }
4165
4166 static void
4167   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4168   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4169 {
4170   vat_main_t *vam = &vat_main;
4171   i32 retval = ntohl (mp->retval);
4172
4173   if (retval >= 0)
4174     {
4175       print (vam->ofp, "%=20s", mp->locator_set_name);
4176     }
4177
4178   vam->retval = retval;
4179   vam->result_ready = 1;
4180 }
4181
4182 static void
4183   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4184   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4185 {
4186   vat_main_t *vam = &vat_main;
4187   vat_json_node_t *node = NULL;
4188
4189   if (VAT_JSON_ARRAY != vam->json_tree.type)
4190     {
4191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4192       vat_json_init_array (&vam->json_tree);
4193     }
4194   node = vat_json_array_add (&vam->json_tree);
4195
4196   vat_json_init_object (node);
4197   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4198
4199   vat_json_print (vam->ofp, node);
4200   vat_json_free (node);
4201
4202   vam->retval = ntohl (mp->retval);
4203   vam->result_ready = 1;
4204 }
4205
4206 static u8 *
4207 format_lisp_map_request_mode (u8 * s, va_list * args)
4208 {
4209   u32 mode = va_arg (*args, u32);
4210
4211   switch (mode)
4212     {
4213     case 0:
4214       return format (0, "dst-only");
4215     case 1:
4216       return format (0, "src-dst");
4217     }
4218   return 0;
4219 }
4220
4221 static void
4222   vl_api_show_one_map_request_mode_reply_t_handler
4223   (vl_api_show_one_map_request_mode_reply_t * mp)
4224 {
4225   vat_main_t *vam = &vat_main;
4226   i32 retval = ntohl (mp->retval);
4227
4228   if (0 <= retval)
4229     {
4230       u32 mode = mp->mode;
4231       print (vam->ofp, "map_request_mode: %U",
4232              format_lisp_map_request_mode, mode);
4233     }
4234
4235   vam->retval = retval;
4236   vam->result_ready = 1;
4237 }
4238
4239 static void
4240   vl_api_show_one_map_request_mode_reply_t_handler_json
4241   (vl_api_show_one_map_request_mode_reply_t * mp)
4242 {
4243   vat_main_t *vam = &vat_main;
4244   vat_json_node_t node;
4245   u8 *s = 0;
4246   u32 mode;
4247
4248   mode = mp->mode;
4249   s = format (0, "%U", format_lisp_map_request_mode, mode);
4250   vec_add1 (s, 0);
4251
4252   vat_json_init_object (&node);
4253   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4254   vat_json_print (vam->ofp, &node);
4255   vat_json_free (&node);
4256
4257   vec_free (s);
4258   vam->retval = ntohl (mp->retval);
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_one_show_xtr_mode_reply_t_handler
4264   (vl_api_one_show_xtr_mode_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   i32 retval = ntohl (mp->retval);
4268
4269   if (0 <= retval)
4270     {
4271       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4272     }
4273
4274   vam->retval = retval;
4275   vam->result_ready = 1;
4276 }
4277
4278 static void
4279   vl_api_one_show_xtr_mode_reply_t_handler_json
4280   (vl_api_one_show_xtr_mode_reply_t * mp)
4281 {
4282   vat_main_t *vam = &vat_main;
4283   vat_json_node_t node;
4284   u8 *status = 0;
4285
4286   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4287   vec_add1 (status, 0);
4288
4289   vat_json_init_object (&node);
4290   vat_json_object_add_string_copy (&node, "status", status);
4291
4292   vec_free (status);
4293
4294   vat_json_print (vam->ofp, &node);
4295   vat_json_free (&node);
4296
4297   vam->retval = ntohl (mp->retval);
4298   vam->result_ready = 1;
4299 }
4300
4301 static void
4302   vl_api_one_show_pitr_mode_reply_t_handler
4303   (vl_api_one_show_pitr_mode_reply_t * mp)
4304 {
4305   vat_main_t *vam = &vat_main;
4306   i32 retval = ntohl (mp->retval);
4307
4308   if (0 <= retval)
4309     {
4310       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4311     }
4312
4313   vam->retval = retval;
4314   vam->result_ready = 1;
4315 }
4316
4317 static void
4318   vl_api_one_show_pitr_mode_reply_t_handler_json
4319   (vl_api_one_show_pitr_mode_reply_t * mp)
4320 {
4321   vat_main_t *vam = &vat_main;
4322   vat_json_node_t node;
4323   u8 *status = 0;
4324
4325   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4326   vec_add1 (status, 0);
4327
4328   vat_json_init_object (&node);
4329   vat_json_object_add_string_copy (&node, "status", status);
4330
4331   vec_free (status);
4332
4333   vat_json_print (vam->ofp, &node);
4334   vat_json_free (&node);
4335
4336   vam->retval = ntohl (mp->retval);
4337   vam->result_ready = 1;
4338 }
4339
4340 static void
4341   vl_api_one_show_petr_mode_reply_t_handler
4342   (vl_api_one_show_petr_mode_reply_t * mp)
4343 {
4344   vat_main_t *vam = &vat_main;
4345   i32 retval = ntohl (mp->retval);
4346
4347   if (0 <= retval)
4348     {
4349       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4350     }
4351
4352   vam->retval = retval;
4353   vam->result_ready = 1;
4354 }
4355
4356 static void
4357   vl_api_one_show_petr_mode_reply_t_handler_json
4358   (vl_api_one_show_petr_mode_reply_t * mp)
4359 {
4360   vat_main_t *vam = &vat_main;
4361   vat_json_node_t node;
4362   u8 *status = 0;
4363
4364   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4365   vec_add1 (status, 0);
4366
4367   vat_json_init_object (&node);
4368   vat_json_object_add_string_copy (&node, "status", status);
4369
4370   vec_free (status);
4371
4372   vat_json_print (vam->ofp, &node);
4373   vat_json_free (&node);
4374
4375   vam->retval = ntohl (mp->retval);
4376   vam->result_ready = 1;
4377 }
4378
4379 static void
4380   vl_api_show_one_use_petr_reply_t_handler
4381   (vl_api_show_one_use_petr_reply_t * mp)
4382 {
4383   vat_main_t *vam = &vat_main;
4384   i32 retval = ntohl (mp->retval);
4385
4386   if (0 <= retval)
4387     {
4388       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4389       if (mp->status)
4390         {
4391           print (vam->ofp, "Proxy-ETR address; %U",
4392                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4393                  mp->address);
4394         }
4395     }
4396
4397   vam->retval = retval;
4398   vam->result_ready = 1;
4399 }
4400
4401 static void
4402   vl_api_show_one_use_petr_reply_t_handler_json
4403   (vl_api_show_one_use_petr_reply_t * mp)
4404 {
4405   vat_main_t *vam = &vat_main;
4406   vat_json_node_t node;
4407   u8 *status = 0;
4408   struct in_addr ip4;
4409   struct in6_addr ip6;
4410
4411   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4412   vec_add1 (status, 0);
4413
4414   vat_json_init_object (&node);
4415   vat_json_object_add_string_copy (&node, "status", status);
4416   if (mp->status)
4417     {
4418       if (mp->is_ip4)
4419         {
4420           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4421           vat_json_object_add_ip6 (&node, "address", ip6);
4422         }
4423       else
4424         {
4425           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4426           vat_json_object_add_ip4 (&node, "address", ip4);
4427         }
4428     }
4429
4430   vec_free (status);
4431
4432   vat_json_print (vam->ofp, &node);
4433   vat_json_free (&node);
4434
4435   vam->retval = ntohl (mp->retval);
4436   vam->result_ready = 1;
4437 }
4438
4439 static void
4440   vl_api_show_one_nsh_mapping_reply_t_handler
4441   (vl_api_show_one_nsh_mapping_reply_t * mp)
4442 {
4443   vat_main_t *vam = &vat_main;
4444   i32 retval = ntohl (mp->retval);
4445
4446   if (0 <= retval)
4447     {
4448       print (vam->ofp, "%-20s%-16s",
4449              mp->is_set ? "set" : "not-set",
4450              mp->is_set ? (char *) mp->locator_set_name : "");
4451     }
4452
4453   vam->retval = retval;
4454   vam->result_ready = 1;
4455 }
4456
4457 static void
4458   vl_api_show_one_nsh_mapping_reply_t_handler_json
4459   (vl_api_show_one_nsh_mapping_reply_t * mp)
4460 {
4461   vat_main_t *vam = &vat_main;
4462   vat_json_node_t node;
4463   u8 *status = 0;
4464
4465   status = format (0, "%s", mp->is_set ? "yes" : "no");
4466   vec_add1 (status, 0);
4467
4468   vat_json_init_object (&node);
4469   vat_json_object_add_string_copy (&node, "is_set", status);
4470   if (mp->is_set)
4471     {
4472       vat_json_object_add_string_copy (&node, "locator_set",
4473                                        mp->locator_set_name);
4474     }
4475
4476   vec_free (status);
4477
4478   vat_json_print (vam->ofp, &node);
4479   vat_json_free (&node);
4480
4481   vam->retval = ntohl (mp->retval);
4482   vam->result_ready = 1;
4483 }
4484
4485 static void
4486   vl_api_show_one_map_register_ttl_reply_t_handler
4487   (vl_api_show_one_map_register_ttl_reply_t * mp)
4488 {
4489   vat_main_t *vam = &vat_main;
4490   i32 retval = ntohl (mp->retval);
4491
4492   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4493
4494   if (0 <= retval)
4495     {
4496       print (vam->ofp, "ttl: %u", mp->ttl);
4497     }
4498
4499   vam->retval = retval;
4500   vam->result_ready = 1;
4501 }
4502
4503 static void
4504   vl_api_show_one_map_register_ttl_reply_t_handler_json
4505   (vl_api_show_one_map_register_ttl_reply_t * mp)
4506 {
4507   vat_main_t *vam = &vat_main;
4508   vat_json_node_t node;
4509
4510   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4511   vat_json_init_object (&node);
4512   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4513
4514   vat_json_print (vam->ofp, &node);
4515   vat_json_free (&node);
4516
4517   vam->retval = ntohl (mp->retval);
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4523 {
4524   vat_main_t *vam = &vat_main;
4525   i32 retval = ntohl (mp->retval);
4526
4527   if (0 <= retval)
4528     {
4529       print (vam->ofp, "%-20s%-16s",
4530              mp->status ? "enabled" : "disabled",
4531              mp->status ? (char *) mp->locator_set_name : "");
4532     }
4533
4534   vam->retval = retval;
4535   vam->result_ready = 1;
4536 }
4537
4538 static void
4539 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4540 {
4541   vat_main_t *vam = &vat_main;
4542   vat_json_node_t node;
4543   u8 *status = 0;
4544
4545   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4546   vec_add1 (status, 0);
4547
4548   vat_json_init_object (&node);
4549   vat_json_object_add_string_copy (&node, "status", status);
4550   if (mp->status)
4551     {
4552       vat_json_object_add_string_copy (&node, "locator_set",
4553                                        mp->locator_set_name);
4554     }
4555
4556   vec_free (status);
4557
4558   vat_json_print (vam->ofp, &node);
4559   vat_json_free (&node);
4560
4561   vam->retval = ntohl (mp->retval);
4562   vam->result_ready = 1;
4563 }
4564
4565 static u8 *
4566 format_policer_type (u8 * s, va_list * va)
4567 {
4568   u32 i = va_arg (*va, u32);
4569
4570   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4571     s = format (s, "1r2c");
4572   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4573     s = format (s, "1r3c");
4574   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4575     s = format (s, "2r3c-2698");
4576   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4577     s = format (s, "2r3c-4115");
4578   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4579     s = format (s, "2r3c-mef5cf1");
4580   else
4581     s = format (s, "ILLEGAL");
4582   return s;
4583 }
4584
4585 static u8 *
4586 format_policer_rate_type (u8 * s, va_list * va)
4587 {
4588   u32 i = va_arg (*va, u32);
4589
4590   if (i == SSE2_QOS_RATE_KBPS)
4591     s = format (s, "kbps");
4592   else if (i == SSE2_QOS_RATE_PPS)
4593     s = format (s, "pps");
4594   else
4595     s = format (s, "ILLEGAL");
4596   return s;
4597 }
4598
4599 static u8 *
4600 format_policer_round_type (u8 * s, va_list * va)
4601 {
4602   u32 i = va_arg (*va, u32);
4603
4604   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4605     s = format (s, "closest");
4606   else if (i == SSE2_QOS_ROUND_TO_UP)
4607     s = format (s, "up");
4608   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4609     s = format (s, "down");
4610   else
4611     s = format (s, "ILLEGAL");
4612   return s;
4613 }
4614
4615 static u8 *
4616 format_policer_action_type (u8 * s, va_list * va)
4617 {
4618   u32 i = va_arg (*va, u32);
4619
4620   if (i == SSE2_QOS_ACTION_DROP)
4621     s = format (s, "drop");
4622   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4623     s = format (s, "transmit");
4624   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4625     s = format (s, "mark-and-transmit");
4626   else
4627     s = format (s, "ILLEGAL");
4628   return s;
4629 }
4630
4631 static u8 *
4632 format_dscp (u8 * s, va_list * va)
4633 {
4634   u32 i = va_arg (*va, u32);
4635   char *t = 0;
4636
4637   switch (i)
4638     {
4639 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4640       foreach_vnet_dscp
4641 #undef _
4642     default:
4643       return format (s, "ILLEGAL");
4644     }
4645   s = format (s, "%s", t);
4646   return s;
4647 }
4648
4649 static void
4650 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4651 {
4652   vat_main_t *vam = &vat_main;
4653   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4654
4655   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4656     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4657   else
4658     conform_dscp_str = format (0, "");
4659
4660   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4661     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4662   else
4663     exceed_dscp_str = format (0, "");
4664
4665   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4666     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4667   else
4668     violate_dscp_str = format (0, "");
4669
4670   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4671          "rate type %U, round type %U, %s rate, %s color-aware, "
4672          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4673          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4674          "conform action %U%s, exceed action %U%s, violate action %U%s",
4675          mp->name,
4676          format_policer_type, mp->type,
4677          ntohl (mp->cir),
4678          ntohl (mp->eir),
4679          clib_net_to_host_u64 (mp->cb),
4680          clib_net_to_host_u64 (mp->eb),
4681          format_policer_rate_type, mp->rate_type,
4682          format_policer_round_type, mp->round_type,
4683          mp->single_rate ? "single" : "dual",
4684          mp->color_aware ? "is" : "not",
4685          ntohl (mp->cir_tokens_per_period),
4686          ntohl (mp->pir_tokens_per_period),
4687          ntohl (mp->scale),
4688          ntohl (mp->current_limit),
4689          ntohl (mp->current_bucket),
4690          ntohl (mp->extended_limit),
4691          ntohl (mp->extended_bucket),
4692          clib_net_to_host_u64 (mp->last_update_time),
4693          format_policer_action_type, mp->conform_action_type,
4694          conform_dscp_str,
4695          format_policer_action_type, mp->exceed_action_type,
4696          exceed_dscp_str,
4697          format_policer_action_type, mp->violate_action_type,
4698          violate_dscp_str);
4699
4700   vec_free (conform_dscp_str);
4701   vec_free (exceed_dscp_str);
4702   vec_free (violate_dscp_str);
4703 }
4704
4705 static void vl_api_policer_details_t_handler_json
4706   (vl_api_policer_details_t * mp)
4707 {
4708   vat_main_t *vam = &vat_main;
4709   vat_json_node_t *node;
4710   u8 *rate_type_str, *round_type_str, *type_str;
4711   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4712
4713   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4714   round_type_str =
4715     format (0, "%U", format_policer_round_type, mp->round_type);
4716   type_str = format (0, "%U", format_policer_type, mp->type);
4717   conform_action_str = format (0, "%U", format_policer_action_type,
4718                                mp->conform_action_type);
4719   exceed_action_str = format (0, "%U", format_policer_action_type,
4720                               mp->exceed_action_type);
4721   violate_action_str = format (0, "%U", format_policer_action_type,
4722                                mp->violate_action_type);
4723
4724   if (VAT_JSON_ARRAY != vam->json_tree.type)
4725     {
4726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4727       vat_json_init_array (&vam->json_tree);
4728     }
4729   node = vat_json_array_add (&vam->json_tree);
4730
4731   vat_json_init_object (node);
4732   vat_json_object_add_string_copy (node, "name", mp->name);
4733   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4734   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4735   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4736   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4737   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4738   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4739   vat_json_object_add_string_copy (node, "type", type_str);
4740   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4741   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4742   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4743   vat_json_object_add_uint (node, "cir_tokens_per_period",
4744                             ntohl (mp->cir_tokens_per_period));
4745   vat_json_object_add_uint (node, "eir_tokens_per_period",
4746                             ntohl (mp->pir_tokens_per_period));
4747   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4748   vat_json_object_add_uint (node, "current_bucket",
4749                             ntohl (mp->current_bucket));
4750   vat_json_object_add_uint (node, "extended_limit",
4751                             ntohl (mp->extended_limit));
4752   vat_json_object_add_uint (node, "extended_bucket",
4753                             ntohl (mp->extended_bucket));
4754   vat_json_object_add_uint (node, "last_update_time",
4755                             ntohl (mp->last_update_time));
4756   vat_json_object_add_string_copy (node, "conform_action",
4757                                    conform_action_str);
4758   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4759     {
4760       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4761       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4762       vec_free (dscp_str);
4763     }
4764   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4765   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4766     {
4767       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4768       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4769       vec_free (dscp_str);
4770     }
4771   vat_json_object_add_string_copy (node, "violate_action",
4772                                    violate_action_str);
4773   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4774     {
4775       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4776       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4777       vec_free (dscp_str);
4778     }
4779
4780   vec_free (rate_type_str);
4781   vec_free (round_type_str);
4782   vec_free (type_str);
4783   vec_free (conform_action_str);
4784   vec_free (exceed_action_str);
4785   vec_free (violate_action_str);
4786 }
4787
4788 static void
4789 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4790                                            mp)
4791 {
4792   vat_main_t *vam = &vat_main;
4793   int i, count = ntohl (mp->count);
4794
4795   if (count > 0)
4796     print (vam->ofp, "classify table ids (%d) : ", count);
4797   for (i = 0; i < count; i++)
4798     {
4799       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4800       print (vam->ofp, (i < count - 1) ? "," : "");
4801     }
4802   vam->retval = ntohl (mp->retval);
4803   vam->result_ready = 1;
4804 }
4805
4806 static void
4807   vl_api_classify_table_ids_reply_t_handler_json
4808   (vl_api_classify_table_ids_reply_t * mp)
4809 {
4810   vat_main_t *vam = &vat_main;
4811   int i, count = ntohl (mp->count);
4812
4813   if (count > 0)
4814     {
4815       vat_json_node_t node;
4816
4817       vat_json_init_object (&node);
4818       for (i = 0; i < count; i++)
4819         {
4820           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4821         }
4822       vat_json_print (vam->ofp, &node);
4823       vat_json_free (&node);
4824     }
4825   vam->retval = ntohl (mp->retval);
4826   vam->result_ready = 1;
4827 }
4828
4829 static void
4830   vl_api_classify_table_by_interface_reply_t_handler
4831   (vl_api_classify_table_by_interface_reply_t * mp)
4832 {
4833   vat_main_t *vam = &vat_main;
4834   u32 table_id;
4835
4836   table_id = ntohl (mp->l2_table_id);
4837   if (table_id != ~0)
4838     print (vam->ofp, "l2 table id : %d", table_id);
4839   else
4840     print (vam->ofp, "l2 table id : No input ACL tables configured");
4841   table_id = ntohl (mp->ip4_table_id);
4842   if (table_id != ~0)
4843     print (vam->ofp, "ip4 table id : %d", table_id);
4844   else
4845     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4846   table_id = ntohl (mp->ip6_table_id);
4847   if (table_id != ~0)
4848     print (vam->ofp, "ip6 table id : %d", table_id);
4849   else
4850     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4851   vam->retval = ntohl (mp->retval);
4852   vam->result_ready = 1;
4853 }
4854
4855 static void
4856   vl_api_classify_table_by_interface_reply_t_handler_json
4857   (vl_api_classify_table_by_interface_reply_t * mp)
4858 {
4859   vat_main_t *vam = &vat_main;
4860   vat_json_node_t node;
4861
4862   vat_json_init_object (&node);
4863
4864   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4865   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4866   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4867
4868   vat_json_print (vam->ofp, &node);
4869   vat_json_free (&node);
4870
4871   vam->retval = ntohl (mp->retval);
4872   vam->result_ready = 1;
4873 }
4874
4875 static void vl_api_policer_add_del_reply_t_handler
4876   (vl_api_policer_add_del_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   i32 retval = ntohl (mp->retval);
4880   if (vam->async_mode)
4881     {
4882       vam->async_errors += (retval < 0);
4883     }
4884   else
4885     {
4886       vam->retval = retval;
4887       vam->result_ready = 1;
4888       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4889         /*
4890          * Note: this is just barely thread-safe, depends on
4891          * the main thread spinning waiting for an answer...
4892          */
4893         errmsg ("policer index %d", ntohl (mp->policer_index));
4894     }
4895 }
4896
4897 static void vl_api_policer_add_del_reply_t_handler_json
4898   (vl_api_policer_add_del_reply_t * mp)
4899 {
4900   vat_main_t *vam = &vat_main;
4901   vat_json_node_t node;
4902
4903   vat_json_init_object (&node);
4904   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4905   vat_json_object_add_uint (&node, "policer_index",
4906                             ntohl (mp->policer_index));
4907
4908   vat_json_print (vam->ofp, &node);
4909   vat_json_free (&node);
4910
4911   vam->retval = ntohl (mp->retval);
4912   vam->result_ready = 1;
4913 }
4914
4915 /* Format hex dump. */
4916 u8 *
4917 format_hex_bytes (u8 * s, va_list * va)
4918 {
4919   u8 *bytes = va_arg (*va, u8 *);
4920   int n_bytes = va_arg (*va, int);
4921   uword i;
4922
4923   /* Print short or long form depending on byte count. */
4924   uword short_form = n_bytes <= 32;
4925   u32 indent = format_get_indent (s);
4926
4927   if (n_bytes == 0)
4928     return s;
4929
4930   for (i = 0; i < n_bytes; i++)
4931     {
4932       if (!short_form && (i % 32) == 0)
4933         s = format (s, "%08x: ", i);
4934       s = format (s, "%02x", bytes[i]);
4935       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4936         s = format (s, "\n%U", format_white_space, indent);
4937     }
4938
4939   return s;
4940 }
4941
4942 static void
4943 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4944                                             * mp)
4945 {
4946   vat_main_t *vam = &vat_main;
4947   i32 retval = ntohl (mp->retval);
4948   if (retval == 0)
4949     {
4950       print (vam->ofp, "classify table info :");
4951       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4952              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4953              ntohl (mp->miss_next_index));
4954       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4955              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4956              ntohl (mp->match_n_vectors));
4957       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4958              ntohl (mp->mask_length));
4959     }
4960   vam->retval = retval;
4961   vam->result_ready = 1;
4962 }
4963
4964 static void
4965   vl_api_classify_table_info_reply_t_handler_json
4966   (vl_api_classify_table_info_reply_t * mp)
4967 {
4968   vat_main_t *vam = &vat_main;
4969   vat_json_node_t node;
4970
4971   i32 retval = ntohl (mp->retval);
4972   if (retval == 0)
4973     {
4974       vat_json_init_object (&node);
4975
4976       vat_json_object_add_int (&node, "sessions",
4977                                ntohl (mp->active_sessions));
4978       vat_json_object_add_int (&node, "nexttbl",
4979                                ntohl (mp->next_table_index));
4980       vat_json_object_add_int (&node, "nextnode",
4981                                ntohl (mp->miss_next_index));
4982       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4983       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4984       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4985       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4986                       ntohl (mp->mask_length), 0);
4987       vat_json_object_add_string_copy (&node, "mask", s);
4988
4989       vat_json_print (vam->ofp, &node);
4990       vat_json_free (&node);
4991     }
4992   vam->retval = ntohl (mp->retval);
4993   vam->result_ready = 1;
4994 }
4995
4996 static void
4997 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4998                                            mp)
4999 {
5000   vat_main_t *vam = &vat_main;
5001
5002   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5003          ntohl (mp->hit_next_index), ntohl (mp->advance),
5004          ntohl (mp->opaque_index));
5005   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5006          ntohl (mp->match_length));
5007 }
5008
5009 static void
5010   vl_api_classify_session_details_t_handler_json
5011   (vl_api_classify_session_details_t * mp)
5012 {
5013   vat_main_t *vam = &vat_main;
5014   vat_json_node_t *node = NULL;
5015
5016   if (VAT_JSON_ARRAY != vam->json_tree.type)
5017     {
5018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5019       vat_json_init_array (&vam->json_tree);
5020     }
5021   node = vat_json_array_add (&vam->json_tree);
5022
5023   vat_json_init_object (node);
5024   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5025   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5026   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5027   u8 *s =
5028     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5029             0);
5030   vat_json_object_add_string_copy (node, "match", s);
5031 }
5032
5033 static void vl_api_pg_create_interface_reply_t_handler
5034   (vl_api_pg_create_interface_reply_t * mp)
5035 {
5036   vat_main_t *vam = &vat_main;
5037
5038   vam->retval = ntohl (mp->retval);
5039   vam->result_ready = 1;
5040 }
5041
5042 static void vl_api_pg_create_interface_reply_t_handler_json
5043   (vl_api_pg_create_interface_reply_t * mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046   vat_json_node_t node;
5047
5048   i32 retval = ntohl (mp->retval);
5049   if (retval == 0)
5050     {
5051       vat_json_init_object (&node);
5052
5053       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5054
5055       vat_json_print (vam->ofp, &node);
5056       vat_json_free (&node);
5057     }
5058   vam->retval = ntohl (mp->retval);
5059   vam->result_ready = 1;
5060 }
5061
5062 static void vl_api_policer_classify_details_t_handler
5063   (vl_api_policer_classify_details_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066
5067   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5068          ntohl (mp->table_index));
5069 }
5070
5071 static void vl_api_policer_classify_details_t_handler_json
5072   (vl_api_policer_classify_details_t * mp)
5073 {
5074   vat_main_t *vam = &vat_main;
5075   vat_json_node_t *node;
5076
5077   if (VAT_JSON_ARRAY != vam->json_tree.type)
5078     {
5079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5080       vat_json_init_array (&vam->json_tree);
5081     }
5082   node = vat_json_array_add (&vam->json_tree);
5083
5084   vat_json_init_object (node);
5085   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5086   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5087 }
5088
5089 static void vl_api_flow_classify_details_t_handler
5090   (vl_api_flow_classify_details_t * mp)
5091 {
5092   vat_main_t *vam = &vat_main;
5093
5094   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5095          ntohl (mp->table_index));
5096 }
5097
5098 static void vl_api_flow_classify_details_t_handler_json
5099   (vl_api_flow_classify_details_t * mp)
5100 {
5101   vat_main_t *vam = &vat_main;
5102   vat_json_node_t *node;
5103
5104   if (VAT_JSON_ARRAY != vam->json_tree.type)
5105     {
5106       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5107       vat_json_init_array (&vam->json_tree);
5108     }
5109   node = vat_json_array_add (&vam->json_tree);
5110
5111   vat_json_init_object (node);
5112   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5113   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5114 }
5115
5116 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5117 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5118 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5119 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5120 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5121 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5122 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5123 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5124 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5125 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5126
5127 /*
5128  * Generate boilerplate reply handlers, which
5129  * dig the return value out of the xxx_reply_t API message,
5130  * stick it into vam->retval, and set vam->result_ready
5131  *
5132  * Could also do this by pointing N message decode slots at
5133  * a single function, but that could break in subtle ways.
5134  */
5135
5136 #define foreach_standard_reply_retval_handler           \
5137 _(sw_interface_set_flags_reply)                         \
5138 _(sw_interface_add_del_address_reply)                   \
5139 _(sw_interface_set_rx_mode_reply)                       \
5140 _(sw_interface_set_rx_placement_reply)                  \
5141 _(sw_interface_set_table_reply)                         \
5142 _(sw_interface_set_mpls_enable_reply)                   \
5143 _(sw_interface_set_vpath_reply)                         \
5144 _(sw_interface_set_vxlan_bypass_reply)                  \
5145 _(sw_interface_set_geneve_bypass_reply)                 \
5146 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5147 _(sw_interface_set_l2_bridge_reply)                     \
5148 _(bridge_domain_add_del_reply)                          \
5149 _(sw_interface_set_l2_xconnect_reply)                   \
5150 _(l2fib_add_del_reply)                                  \
5151 _(l2fib_flush_int_reply)                                \
5152 _(l2fib_flush_bd_reply)                                 \
5153 _(ip_route_add_del_reply)                               \
5154 _(ip_table_add_del_reply)                               \
5155 _(ip_mroute_add_del_reply)                              \
5156 _(mpls_route_add_del_reply)                             \
5157 _(mpls_table_add_del_reply)                             \
5158 _(mpls_ip_bind_unbind_reply)                            \
5159 _(bier_route_add_del_reply)                             \
5160 _(bier_table_add_del_reply)                             \
5161 _(proxy_arp_add_del_reply)                              \
5162 _(proxy_arp_intfc_enable_disable_reply)                 \
5163 _(sw_interface_set_unnumbered_reply)                    \
5164 _(ip_neighbor_add_del_reply)                            \
5165 _(reset_fib_reply)                                      \
5166 _(dhcp_proxy_config_reply)                              \
5167 _(dhcp_proxy_set_vss_reply)                             \
5168 _(dhcp_client_config_reply)                             \
5169 _(set_ip_flow_hash_reply)                               \
5170 _(sw_interface_ip6_enable_disable_reply)                \
5171 _(ip6nd_proxy_add_del_reply)                            \
5172 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5173 _(sw_interface_ip6nd_ra_config_reply)                   \
5174 _(set_arp_neighbor_limit_reply)                         \
5175 _(l2_patch_add_del_reply)                               \
5176 _(sr_mpls_policy_add_reply)                             \
5177 _(sr_mpls_policy_mod_reply)                             \
5178 _(sr_mpls_policy_del_reply)                             \
5179 _(sr_policy_add_reply)                                  \
5180 _(sr_policy_mod_reply)                                  \
5181 _(sr_policy_del_reply)                                  \
5182 _(sr_localsid_add_del_reply)                            \
5183 _(sr_steering_add_del_reply)                            \
5184 _(classify_add_del_session_reply)                       \
5185 _(classify_set_interface_ip_table_reply)                \
5186 _(classify_set_interface_l2_tables_reply)               \
5187 _(l2tpv3_set_tunnel_cookies_reply)                      \
5188 _(l2tpv3_interface_enable_disable_reply)                \
5189 _(l2tpv3_set_lookup_key_reply)                          \
5190 _(l2_fib_clear_table_reply)                             \
5191 _(l2_interface_efp_filter_reply)                        \
5192 _(l2_interface_vlan_tag_rewrite_reply)                  \
5193 _(modify_vhost_user_if_reply)                           \
5194 _(delete_vhost_user_if_reply)                           \
5195 _(ip_probe_neighbor_reply)                              \
5196 _(ip_scan_neighbor_enable_disable_reply)                \
5197 _(want_ip4_arp_events_reply)                            \
5198 _(want_ip6_nd_events_reply)                             \
5199 _(want_l2_macs_events_reply)                            \
5200 _(input_acl_set_interface_reply)                        \
5201 _(ipsec_spd_add_del_reply)                              \
5202 _(ipsec_interface_add_del_spd_reply)                    \
5203 _(ipsec_spd_entry_add_del_reply)                        \
5204 _(ipsec_sad_entry_add_del_reply)                        \
5205 _(ipsec_tunnel_if_add_del_reply)                        \
5206 _(ipsec_tunnel_if_set_sa_reply)                         \
5207 _(delete_loopback_reply)                                \
5208 _(bd_ip_mac_add_del_reply)                              \
5209 _(bd_ip_mac_flush_reply)                                \
5210 _(want_interface_events_reply)                          \
5211 _(cop_interface_enable_disable_reply)                   \
5212 _(cop_whitelist_enable_disable_reply)                   \
5213 _(sw_interface_clear_stats_reply)                       \
5214 _(ioam_enable_reply)                                    \
5215 _(ioam_disable_reply)                                   \
5216 _(one_add_del_locator_reply)                            \
5217 _(one_add_del_local_eid_reply)                          \
5218 _(one_add_del_remote_mapping_reply)                     \
5219 _(one_add_del_adjacency_reply)                          \
5220 _(one_add_del_map_resolver_reply)                       \
5221 _(one_add_del_map_server_reply)                         \
5222 _(one_enable_disable_reply)                             \
5223 _(one_rloc_probe_enable_disable_reply)                  \
5224 _(one_map_register_enable_disable_reply)                \
5225 _(one_map_register_set_ttl_reply)                       \
5226 _(one_set_transport_protocol_reply)                     \
5227 _(one_map_register_fallback_threshold_reply)            \
5228 _(one_pitr_set_locator_set_reply)                       \
5229 _(one_map_request_mode_reply)                           \
5230 _(one_add_del_map_request_itr_rlocs_reply)              \
5231 _(one_eid_table_add_del_map_reply)                      \
5232 _(one_use_petr_reply)                                   \
5233 _(one_stats_enable_disable_reply)                       \
5234 _(one_add_del_l2_arp_entry_reply)                       \
5235 _(one_add_del_ndp_entry_reply)                          \
5236 _(one_stats_flush_reply)                                \
5237 _(one_enable_disable_xtr_mode_reply)                    \
5238 _(one_enable_disable_pitr_mode_reply)                   \
5239 _(one_enable_disable_petr_mode_reply)                   \
5240 _(gpe_enable_disable_reply)                             \
5241 _(gpe_set_encap_mode_reply)                             \
5242 _(gpe_add_del_iface_reply)                              \
5243 _(gpe_add_del_native_fwd_rpath_reply)                   \
5244 _(af_packet_delete_reply)                               \
5245 _(policer_classify_set_interface_reply)                 \
5246 _(netmap_create_reply)                                  \
5247 _(netmap_delete_reply)                                  \
5248 _(set_ipfix_exporter_reply)                             \
5249 _(set_ipfix_classify_stream_reply)                      \
5250 _(ipfix_classify_table_add_del_reply)                   \
5251 _(flow_classify_set_interface_reply)                    \
5252 _(sw_interface_span_enable_disable_reply)               \
5253 _(pg_capture_reply)                                     \
5254 _(pg_enable_disable_reply)                              \
5255 _(ip_source_and_port_range_check_add_del_reply)         \
5256 _(ip_source_and_port_range_check_interface_add_del_reply)\
5257 _(delete_subif_reply)                                   \
5258 _(l2_interface_pbb_tag_rewrite_reply)                   \
5259 _(set_punt_reply)                                       \
5260 _(feature_enable_disable_reply)                         \
5261 _(sw_interface_tag_add_del_reply)                       \
5262 _(hw_interface_set_mtu_reply)                           \
5263 _(p2p_ethernet_add_reply)                               \
5264 _(p2p_ethernet_del_reply)                               \
5265 _(lldp_config_reply)                                    \
5266 _(sw_interface_set_lldp_reply)                          \
5267 _(tcp_configure_src_addresses_reply)                    \
5268 _(dns_enable_disable_reply)                             \
5269 _(dns_name_server_add_del_reply)                        \
5270 _(session_rule_add_del_reply)                           \
5271 _(ip_container_proxy_add_del_reply)                     \
5272 _(output_acl_set_interface_reply)                       \
5273 _(qos_record_enable_disable_reply)
5274
5275 #define _(n)                                    \
5276     static void vl_api_##n##_t_handler          \
5277     (vl_api_##n##_t * mp)                       \
5278     {                                           \
5279         vat_main_t * vam = &vat_main;           \
5280         i32 retval = ntohl(mp->retval);         \
5281         if (vam->async_mode) {                  \
5282             vam->async_errors += (retval < 0);  \
5283         } else {                                \
5284             vam->retval = retval;               \
5285             vam->result_ready = 1;              \
5286         }                                       \
5287     }
5288 foreach_standard_reply_retval_handler;
5289 #undef _
5290
5291 #define _(n)                                    \
5292     static void vl_api_##n##_t_handler_json     \
5293     (vl_api_##n##_t * mp)                       \
5294     {                                           \
5295         vat_main_t * vam = &vat_main;           \
5296         vat_json_node_t node;                   \
5297         vat_json_init_object(&node);            \
5298         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5299         vat_json_print(vam->ofp, &node);        \
5300         vam->retval = ntohl(mp->retval);        \
5301         vam->result_ready = 1;                  \
5302     }
5303 foreach_standard_reply_retval_handler;
5304 #undef _
5305
5306 /*
5307  * Table of message reply handlers, must include boilerplate handlers
5308  * we just generated
5309  */
5310
5311 #define foreach_vpe_api_reply_msg                                       \
5312 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5313 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5314 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5315 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5316 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5317 _(CLI_REPLY, cli_reply)                                                 \
5318 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5319 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5320   sw_interface_add_del_address_reply)                                   \
5321 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5322 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5323 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5324 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5325 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5326 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5327 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5328 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5329 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5330 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5331   sw_interface_set_l2_xconnect_reply)                                   \
5332 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5333   sw_interface_set_l2_bridge_reply)                                     \
5334 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5335 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5336 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5337 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5338 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5339 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5340 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5341 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5342 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5343 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5344 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5345 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5346 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5347 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5348 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5349 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5350 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5351 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5352 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5353 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5354 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5355 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5356 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5357 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5358 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5359 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5360 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5361 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5362 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5363 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5364   proxy_arp_intfc_enable_disable_reply)                                 \
5365 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5366 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5367   sw_interface_set_unnumbered_reply)                                    \
5368 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5369 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5370 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5371 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5372 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5373 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5374 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5375 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5376 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5377 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5378   sw_interface_ip6_enable_disable_reply)                                \
5379 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5380 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5381 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5382   sw_interface_ip6nd_ra_prefix_reply)                                   \
5383 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5384   sw_interface_ip6nd_ra_config_reply)                                   \
5385 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5386 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5387 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5388 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5389 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5390 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5391 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5392 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5393 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5394 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5395 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5396 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5397 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5398 classify_set_interface_ip_table_reply)                                  \
5399 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5400   classify_set_interface_l2_tables_reply)                               \
5401 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5402 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5403 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5404 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5405 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5406   l2tpv3_interface_enable_disable_reply)                                \
5407 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5408 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5409 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5410 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5411 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5412 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5413 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5414 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5415 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5416 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5417 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5418 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5419 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5420 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5421 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5422 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5423 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5424 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5425 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5426 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5427 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5428 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5429 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5430 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5431 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5432 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5433 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5434 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5435 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5436 _(L2_MACS_EVENT, l2_macs_event)                                         \
5437 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5438 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5439 _(IP_DETAILS, ip_details)                                               \
5440 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5441 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5442 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5443 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5444 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5445 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5446 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5447 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5448 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5449 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5450 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5451 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5452 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5453 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5454 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5455 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5456 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5457 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5458 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5459 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5460 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5461 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5462 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5463 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5464 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5465 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5466 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5467 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5468 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5469   one_map_register_enable_disable_reply)                                \
5470 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5471 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5472 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5473 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5474   one_map_register_fallback_threshold_reply)                            \
5475 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5476   one_rloc_probe_enable_disable_reply)                                  \
5477 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5478 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5479 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5480 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5481 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5482 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5483 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5484 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5485 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5486 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5487 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5488 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5489 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5490 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5491 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5492 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5493   show_one_stats_enable_disable_reply)                                  \
5494 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5495 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5496 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5497 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5498 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5499 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5500 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5501 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5502   one_enable_disable_pitr_mode_reply)                                   \
5503 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5504   one_enable_disable_petr_mode_reply)                                   \
5505 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5506 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5507 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5508 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5509 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5510 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5511 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5512 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5513 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5514 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5515 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5516 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5517   gpe_add_del_native_fwd_rpath_reply)                                   \
5518 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5519   gpe_fwd_entry_path_details)                                           \
5520 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5521 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5522   one_add_del_map_request_itr_rlocs_reply)                              \
5523 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5524   one_get_map_request_itr_rlocs_reply)                                  \
5525 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5526 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5527 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5528 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5529 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5530 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5531   show_one_map_register_state_reply)                                    \
5532 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5533 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5534   show_one_map_register_fallback_threshold_reply)                       \
5535 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5536 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5537 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5538 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5539 _(POLICER_DETAILS, policer_details)                                     \
5540 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5541 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5542 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5543 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5544 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5545 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5546 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5547 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5548 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5549 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5550 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5551 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5552 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5553 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5554 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5555 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5556 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5557 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5558 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5559 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5560 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5561 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5562 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5563 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5564 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5565 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5566  ip_source_and_port_range_check_add_del_reply)                          \
5567 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5568  ip_source_and_port_range_check_interface_add_del_reply)                \
5569 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5570 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5571 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5572 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5573 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5574 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5575 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5576 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5577 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5578 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5579 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5580 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5581 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5582 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5583 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5584 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5585 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5586 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5587 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5588 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5589 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5590 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5591 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5592 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5593 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5594 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5595
5596 #define foreach_standalone_reply_msg                                    \
5597 _(SW_INTERFACE_EVENT, sw_interface_event)
5598
5599 typedef struct
5600 {
5601   u8 *name;
5602   u32 value;
5603 } name_sort_t;
5604
5605 #define STR_VTR_OP_CASE(op)     \
5606     case L2_VTR_ ## op:         \
5607         return "" # op;
5608
5609 static const char *
5610 str_vtr_op (u32 vtr_op)
5611 {
5612   switch (vtr_op)
5613     {
5614       STR_VTR_OP_CASE (DISABLED);
5615       STR_VTR_OP_CASE (PUSH_1);
5616       STR_VTR_OP_CASE (PUSH_2);
5617       STR_VTR_OP_CASE (POP_1);
5618       STR_VTR_OP_CASE (POP_2);
5619       STR_VTR_OP_CASE (TRANSLATE_1_1);
5620       STR_VTR_OP_CASE (TRANSLATE_1_2);
5621       STR_VTR_OP_CASE (TRANSLATE_2_1);
5622       STR_VTR_OP_CASE (TRANSLATE_2_2);
5623     }
5624
5625   return "UNKNOWN";
5626 }
5627
5628 static int
5629 dump_sub_interface_table (vat_main_t * vam)
5630 {
5631   const sw_interface_subif_t *sub = NULL;
5632
5633   if (vam->json_output)
5634     {
5635       clib_warning
5636         ("JSON output supported only for VPE API calls and dump_stats_table");
5637       return -99;
5638     }
5639
5640   print (vam->ofp,
5641          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5642          "Interface", "sw_if_index",
5643          "sub id", "dot1ad", "tags", "outer id",
5644          "inner id", "exact", "default", "outer any", "inner any");
5645
5646   vec_foreach (sub, vam->sw_if_subif_table)
5647   {
5648     print (vam->ofp,
5649            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5650            sub->interface_name,
5651            sub->sw_if_index,
5652            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5653            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5654            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5655            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5656     if (sub->vtr_op != L2_VTR_DISABLED)
5657       {
5658         print (vam->ofp,
5659                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5660                "tag1: %d tag2: %d ]",
5661                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5662                sub->vtr_tag1, sub->vtr_tag2);
5663       }
5664   }
5665
5666   return 0;
5667 }
5668
5669 static int
5670 name_sort_cmp (void *a1, void *a2)
5671 {
5672   name_sort_t *n1 = a1;
5673   name_sort_t *n2 = a2;
5674
5675   return strcmp ((char *) n1->name, (char *) n2->name);
5676 }
5677
5678 static int
5679 dump_interface_table (vat_main_t * vam)
5680 {
5681   hash_pair_t *p;
5682   name_sort_t *nses = 0, *ns;
5683
5684   if (vam->json_output)
5685     {
5686       clib_warning
5687         ("JSON output supported only for VPE API calls and dump_stats_table");
5688       return -99;
5689     }
5690
5691   /* *INDENT-OFF* */
5692   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5693   ({
5694     vec_add2 (nses, ns, 1);
5695     ns->name = (u8 *)(p->key);
5696     ns->value = (u32) p->value[0];
5697   }));
5698   /* *INDENT-ON* */
5699
5700   vec_sort_with_function (nses, name_sort_cmp);
5701
5702   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5703   vec_foreach (ns, nses)
5704   {
5705     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5706   }
5707   vec_free (nses);
5708   return 0;
5709 }
5710
5711 static int
5712 dump_ip_table (vat_main_t * vam, int is_ipv6)
5713 {
5714   const ip_details_t *det = NULL;
5715   const ip_address_details_t *address = NULL;
5716   u32 i = ~0;
5717
5718   print (vam->ofp, "%-12s", "sw_if_index");
5719
5720   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5721   {
5722     i++;
5723     if (!det->present)
5724       {
5725         continue;
5726       }
5727     print (vam->ofp, "%-12d", i);
5728     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5729     if (!det->addr)
5730       {
5731         continue;
5732       }
5733     vec_foreach (address, det->addr)
5734     {
5735       print (vam->ofp,
5736              "            %-30U%-13d",
5737              is_ipv6 ? format_ip6_address : format_ip4_address,
5738              address->ip, address->prefix_length);
5739     }
5740   }
5741
5742   return 0;
5743 }
5744
5745 static int
5746 dump_ipv4_table (vat_main_t * vam)
5747 {
5748   if (vam->json_output)
5749     {
5750       clib_warning
5751         ("JSON output supported only for VPE API calls and dump_stats_table");
5752       return -99;
5753     }
5754
5755   return dump_ip_table (vam, 0);
5756 }
5757
5758 static int
5759 dump_ipv6_table (vat_main_t * vam)
5760 {
5761   if (vam->json_output)
5762     {
5763       clib_warning
5764         ("JSON output supported only for VPE API calls and dump_stats_table");
5765       return -99;
5766     }
5767
5768   return dump_ip_table (vam, 1);
5769 }
5770
5771 /*
5772  * Pass CLI buffers directly in the CLI_INBAND API message,
5773  * instead of an additional shared memory area.
5774  */
5775 static int
5776 exec_inband (vat_main_t * vam)
5777 {
5778   vl_api_cli_inband_t *mp;
5779   unformat_input_t *i = vam->input;
5780   int ret;
5781
5782   if (vec_len (i->buffer) == 0)
5783     return -1;
5784
5785   if (vam->exec_mode == 0 && unformat (i, "mode"))
5786     {
5787       vam->exec_mode = 1;
5788       return 0;
5789     }
5790   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5791     {
5792       vam->exec_mode = 0;
5793       return 0;
5794     }
5795
5796   /*
5797    * In order for the CLI command to work, it
5798    * must be a vector ending in \n, not a C-string ending
5799    * in \n\0.
5800    */
5801   u32 len = vec_len (vam->input->buffer);
5802   M2 (CLI_INBAND, mp, len);
5803   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5804
5805   S (mp);
5806   W (ret);
5807   /* json responses may or may not include a useful reply... */
5808   if (vec_len (vam->cmd_reply))
5809     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5810   return ret;
5811 }
5812
5813 int
5814 exec (vat_main_t * vam)
5815 {
5816   return exec_inband (vam);
5817 }
5818
5819 static int
5820 api_create_loopback (vat_main_t * vam)
5821 {
5822   unformat_input_t *i = vam->input;
5823   vl_api_create_loopback_t *mp;
5824   vl_api_create_loopback_instance_t *mp_lbi;
5825   u8 mac_address[6];
5826   u8 mac_set = 0;
5827   u8 is_specified = 0;
5828   u32 user_instance = 0;
5829   int ret;
5830
5831   clib_memset (mac_address, 0, sizeof (mac_address));
5832
5833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5834     {
5835       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5836         mac_set = 1;
5837       if (unformat (i, "instance %d", &user_instance))
5838         is_specified = 1;
5839       else
5840         break;
5841     }
5842
5843   if (is_specified)
5844     {
5845       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5846       mp_lbi->is_specified = is_specified;
5847       if (is_specified)
5848         mp_lbi->user_instance = htonl (user_instance);
5849       if (mac_set)
5850         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5851       S (mp_lbi);
5852     }
5853   else
5854     {
5855       /* Construct the API message */
5856       M (CREATE_LOOPBACK, mp);
5857       if (mac_set)
5858         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5859       S (mp);
5860     }
5861
5862   W (ret);
5863   return ret;
5864 }
5865
5866 static int
5867 api_delete_loopback (vat_main_t * vam)
5868 {
5869   unformat_input_t *i = vam->input;
5870   vl_api_delete_loopback_t *mp;
5871   u32 sw_if_index = ~0;
5872   int ret;
5873
5874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5875     {
5876       if (unformat (i, "sw_if_index %d", &sw_if_index))
5877         ;
5878       else
5879         break;
5880     }
5881
5882   if (sw_if_index == ~0)
5883     {
5884       errmsg ("missing sw_if_index");
5885       return -99;
5886     }
5887
5888   /* Construct the API message */
5889   M (DELETE_LOOPBACK, mp);
5890   mp->sw_if_index = ntohl (sw_if_index);
5891
5892   S (mp);
5893   W (ret);
5894   return ret;
5895 }
5896
5897 static int
5898 api_want_interface_events (vat_main_t * vam)
5899 {
5900   unformat_input_t *i = vam->input;
5901   vl_api_want_interface_events_t *mp;
5902   int enable = -1;
5903   int ret;
5904
5905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5906     {
5907       if (unformat (i, "enable"))
5908         enable = 1;
5909       else if (unformat (i, "disable"))
5910         enable = 0;
5911       else
5912         break;
5913     }
5914
5915   if (enable == -1)
5916     {
5917       errmsg ("missing enable|disable");
5918       return -99;
5919     }
5920
5921   M (WANT_INTERFACE_EVENTS, mp);
5922   mp->enable_disable = enable;
5923
5924   vam->interface_event_display = enable;
5925
5926   S (mp);
5927   W (ret);
5928   return ret;
5929 }
5930
5931
5932 /* Note: non-static, called once to set up the initial intfc table */
5933 int
5934 api_sw_interface_dump (vat_main_t * vam)
5935 {
5936   vl_api_sw_interface_dump_t *mp;
5937   vl_api_control_ping_t *mp_ping;
5938   hash_pair_t *p;
5939   name_sort_t *nses = 0, *ns;
5940   sw_interface_subif_t *sub = NULL;
5941   int ret;
5942
5943   /* Toss the old name table */
5944   /* *INDENT-OFF* */
5945   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5946   ({
5947     vec_add2 (nses, ns, 1);
5948     ns->name = (u8 *)(p->key);
5949     ns->value = (u32) p->value[0];
5950   }));
5951   /* *INDENT-ON* */
5952
5953   hash_free (vam->sw_if_index_by_interface_name);
5954
5955   vec_foreach (ns, nses) vec_free (ns->name);
5956
5957   vec_free (nses);
5958
5959   vec_foreach (sub, vam->sw_if_subif_table)
5960   {
5961     vec_free (sub->interface_name);
5962   }
5963   vec_free (vam->sw_if_subif_table);
5964
5965   /* recreate the interface name hash table */
5966   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5967
5968   /*
5969    * Ask for all interface names. Otherwise, the epic catalog of
5970    * name filters becomes ridiculously long, and vat ends up needing
5971    * to be taught about new interface types.
5972    */
5973   M (SW_INTERFACE_DUMP, mp);
5974   S (mp);
5975
5976   /* Use a control ping for synchronization */
5977   MPING (CONTROL_PING, mp_ping);
5978   S (mp_ping);
5979
5980   W (ret);
5981   return ret;
5982 }
5983
5984 static int
5985 api_sw_interface_set_flags (vat_main_t * vam)
5986 {
5987   unformat_input_t *i = vam->input;
5988   vl_api_sw_interface_set_flags_t *mp;
5989   u32 sw_if_index;
5990   u8 sw_if_index_set = 0;
5991   u8 admin_up = 0;
5992   int ret;
5993
5994   /* Parse args required to build the message */
5995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5996     {
5997       if (unformat (i, "admin-up"))
5998         admin_up = 1;
5999       else if (unformat (i, "admin-down"))
6000         admin_up = 0;
6001       else
6002         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6003         sw_if_index_set = 1;
6004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6005         sw_if_index_set = 1;
6006       else
6007         break;
6008     }
6009
6010   if (sw_if_index_set == 0)
6011     {
6012       errmsg ("missing interface name or sw_if_index");
6013       return -99;
6014     }
6015
6016   /* Construct the API message */
6017   M (SW_INTERFACE_SET_FLAGS, mp);
6018   mp->sw_if_index = ntohl (sw_if_index);
6019   mp->admin_up_down = admin_up;
6020
6021   /* send it... */
6022   S (mp);
6023
6024   /* Wait for a reply, return the good/bad news... */
6025   W (ret);
6026   return ret;
6027 }
6028
6029 static int
6030 api_sw_interface_set_rx_mode (vat_main_t * vam)
6031 {
6032   unformat_input_t *i = vam->input;
6033   vl_api_sw_interface_set_rx_mode_t *mp;
6034   u32 sw_if_index;
6035   u8 sw_if_index_set = 0;
6036   int ret;
6037   u8 queue_id_valid = 0;
6038   u32 queue_id;
6039   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6040
6041   /* Parse args required to build the message */
6042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6043     {
6044       if (unformat (i, "queue %d", &queue_id))
6045         queue_id_valid = 1;
6046       else if (unformat (i, "polling"))
6047         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6048       else if (unformat (i, "interrupt"))
6049         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6050       else if (unformat (i, "adaptive"))
6051         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6052       else
6053         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6054         sw_if_index_set = 1;
6055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6056         sw_if_index_set = 1;
6057       else
6058         break;
6059     }
6060
6061   if (sw_if_index_set == 0)
6062     {
6063       errmsg ("missing interface name or sw_if_index");
6064       return -99;
6065     }
6066   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6067     {
6068       errmsg ("missing rx-mode");
6069       return -99;
6070     }
6071
6072   /* Construct the API message */
6073   M (SW_INTERFACE_SET_RX_MODE, mp);
6074   mp->sw_if_index = ntohl (sw_if_index);
6075   mp->mode = mode;
6076   mp->queue_id_valid = queue_id_valid;
6077   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6078
6079   /* send it... */
6080   S (mp);
6081
6082   /* Wait for a reply, return the good/bad news... */
6083   W (ret);
6084   return ret;
6085 }
6086
6087 static int
6088 api_sw_interface_set_rx_placement (vat_main_t * vam)
6089 {
6090   unformat_input_t *i = vam->input;
6091   vl_api_sw_interface_set_rx_placement_t *mp;
6092   u32 sw_if_index;
6093   u8 sw_if_index_set = 0;
6094   int ret;
6095   u8 is_main = 0;
6096   u32 queue_id, thread_index;
6097
6098   /* Parse args required to build the message */
6099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6100     {
6101       if (unformat (i, "queue %d", &queue_id))
6102         ;
6103       else if (unformat (i, "main"))
6104         is_main = 1;
6105       else if (unformat (i, "worker %d", &thread_index))
6106         ;
6107       else
6108         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6109         sw_if_index_set = 1;
6110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6111         sw_if_index_set = 1;
6112       else
6113         break;
6114     }
6115
6116   if (sw_if_index_set == 0)
6117     {
6118       errmsg ("missing interface name or sw_if_index");
6119       return -99;
6120     }
6121
6122   if (is_main)
6123     thread_index = 0;
6124   /* Construct the API message */
6125   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6126   mp->sw_if_index = ntohl (sw_if_index);
6127   mp->worker_id = ntohl (thread_index);
6128   mp->queue_id = ntohl (queue_id);
6129   mp->is_main = is_main;
6130
6131   /* send it... */
6132   S (mp);
6133   /* Wait for a reply, return the good/bad news... */
6134   W (ret);
6135   return ret;
6136 }
6137
6138 static void vl_api_sw_interface_rx_placement_details_t_handler
6139   (vl_api_sw_interface_rx_placement_details_t * mp)
6140 {
6141   vat_main_t *vam = &vat_main;
6142   u32 worker_id = ntohl (mp->worker_id);
6143
6144   print (vam->ofp,
6145          "\n%-11d %-11s %-6d %-5d %-9s",
6146          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6147          worker_id, ntohl (mp->queue_id),
6148          (mp->mode ==
6149           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6150 }
6151
6152 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6153   (vl_api_sw_interface_rx_placement_details_t * mp)
6154 {
6155   vat_main_t *vam = &vat_main;
6156   vat_json_node_t *node = NULL;
6157
6158   if (VAT_JSON_ARRAY != vam->json_tree.type)
6159     {
6160       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6161       vat_json_init_array (&vam->json_tree);
6162     }
6163   node = vat_json_array_add (&vam->json_tree);
6164
6165   vat_json_init_object (node);
6166   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6167   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6168   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6169   vat_json_object_add_uint (node, "mode", mp->mode);
6170 }
6171
6172 static int
6173 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6174 {
6175   unformat_input_t *i = vam->input;
6176   vl_api_sw_interface_rx_placement_dump_t *mp;
6177   vl_api_control_ping_t *mp_ping;
6178   int ret;
6179   u32 sw_if_index;
6180   u8 sw_if_index_set = 0;
6181
6182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6183     {
6184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6185         sw_if_index_set++;
6186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6187         sw_if_index_set++;
6188       else
6189         break;
6190     }
6191
6192   print (vam->ofp,
6193          "\n%-11s %-11s %-6s %-5s %-4s",
6194          "sw_if_index", "main/worker", "thread", "queue", "mode");
6195
6196   /* Dump Interface rx placement */
6197   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6198
6199   if (sw_if_index_set)
6200     mp->sw_if_index = htonl (sw_if_index);
6201   else
6202     mp->sw_if_index = ~0;
6203
6204   S (mp);
6205
6206   /* Use a control ping for synchronization */
6207   MPING (CONTROL_PING, mp_ping);
6208   S (mp_ping);
6209
6210   W (ret);
6211   return ret;
6212 }
6213
6214 static int
6215 api_sw_interface_clear_stats (vat_main_t * vam)
6216 {
6217   unformat_input_t *i = vam->input;
6218   vl_api_sw_interface_clear_stats_t *mp;
6219   u32 sw_if_index;
6220   u8 sw_if_index_set = 0;
6221   int ret;
6222
6223   /* Parse args required to build the message */
6224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6225     {
6226       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6227         sw_if_index_set = 1;
6228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6229         sw_if_index_set = 1;
6230       else
6231         break;
6232     }
6233
6234   /* Construct the API message */
6235   M (SW_INTERFACE_CLEAR_STATS, mp);
6236
6237   if (sw_if_index_set == 1)
6238     mp->sw_if_index = ntohl (sw_if_index);
6239   else
6240     mp->sw_if_index = ~0;
6241
6242   /* send it... */
6243   S (mp);
6244
6245   /* Wait for a reply, return the good/bad news... */
6246   W (ret);
6247   return ret;
6248 }
6249
6250 static int
6251 api_sw_interface_add_del_address (vat_main_t * vam)
6252 {
6253   unformat_input_t *i = vam->input;
6254   vl_api_sw_interface_add_del_address_t *mp;
6255   u32 sw_if_index;
6256   u8 sw_if_index_set = 0;
6257   u8 is_add = 1, del_all = 0;
6258   u32 address_length = 0;
6259   u8 v4_address_set = 0;
6260   u8 v6_address_set = 0;
6261   ip4_address_t v4address;
6262   ip6_address_t v6address;
6263   int ret;
6264
6265   /* Parse args required to build the message */
6266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6267     {
6268       if (unformat (i, "del-all"))
6269         del_all = 1;
6270       else if (unformat (i, "del"))
6271         is_add = 0;
6272       else
6273         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6274         sw_if_index_set = 1;
6275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6276         sw_if_index_set = 1;
6277       else if (unformat (i, "%U/%d",
6278                          unformat_ip4_address, &v4address, &address_length))
6279         v4_address_set = 1;
6280       else if (unformat (i, "%U/%d",
6281                          unformat_ip6_address, &v6address, &address_length))
6282         v6_address_set = 1;
6283       else
6284         break;
6285     }
6286
6287   if (sw_if_index_set == 0)
6288     {
6289       errmsg ("missing interface name or sw_if_index");
6290       return -99;
6291     }
6292   if (v4_address_set && v6_address_set)
6293     {
6294       errmsg ("both v4 and v6 addresses set");
6295       return -99;
6296     }
6297   if (!v4_address_set && !v6_address_set && !del_all)
6298     {
6299       errmsg ("no addresses set");
6300       return -99;
6301     }
6302
6303   /* Construct the API message */
6304   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6305
6306   mp->sw_if_index = ntohl (sw_if_index);
6307   mp->is_add = is_add;
6308   mp->del_all = del_all;
6309   if (v6_address_set)
6310     {
6311       mp->is_ipv6 = 1;
6312       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6313     }
6314   else
6315     {
6316       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6317     }
6318   mp->address_length = address_length;
6319
6320   /* send it... */
6321   S (mp);
6322
6323   /* Wait for a reply, return good/bad news  */
6324   W (ret);
6325   return ret;
6326 }
6327
6328 static int
6329 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6330 {
6331   unformat_input_t *i = vam->input;
6332   vl_api_sw_interface_set_mpls_enable_t *mp;
6333   u32 sw_if_index;
6334   u8 sw_if_index_set = 0;
6335   u8 enable = 1;
6336   int ret;
6337
6338   /* Parse args required to build the message */
6339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6340     {
6341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6342         sw_if_index_set = 1;
6343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6344         sw_if_index_set = 1;
6345       else if (unformat (i, "disable"))
6346         enable = 0;
6347       else if (unformat (i, "dis"))
6348         enable = 0;
6349       else
6350         break;
6351     }
6352
6353   if (sw_if_index_set == 0)
6354     {
6355       errmsg ("missing interface name or sw_if_index");
6356       return -99;
6357     }
6358
6359   /* Construct the API message */
6360   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6361
6362   mp->sw_if_index = ntohl (sw_if_index);
6363   mp->enable = enable;
6364
6365   /* send it... */
6366   S (mp);
6367
6368   /* Wait for a reply... */
6369   W (ret);
6370   return ret;
6371 }
6372
6373 static int
6374 api_sw_interface_set_table (vat_main_t * vam)
6375 {
6376   unformat_input_t *i = vam->input;
6377   vl_api_sw_interface_set_table_t *mp;
6378   u32 sw_if_index, vrf_id = 0;
6379   u8 sw_if_index_set = 0;
6380   u8 is_ipv6 = 0;
6381   int ret;
6382
6383   /* Parse args required to build the message */
6384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6385     {
6386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6387         sw_if_index_set = 1;
6388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6389         sw_if_index_set = 1;
6390       else if (unformat (i, "vrf %d", &vrf_id))
6391         ;
6392       else if (unformat (i, "ipv6"))
6393         is_ipv6 = 1;
6394       else
6395         break;
6396     }
6397
6398   if (sw_if_index_set == 0)
6399     {
6400       errmsg ("missing interface name or sw_if_index");
6401       return -99;
6402     }
6403
6404   /* Construct the API message */
6405   M (SW_INTERFACE_SET_TABLE, mp);
6406
6407   mp->sw_if_index = ntohl (sw_if_index);
6408   mp->is_ipv6 = is_ipv6;
6409   mp->vrf_id = ntohl (vrf_id);
6410
6411   /* send it... */
6412   S (mp);
6413
6414   /* Wait for a reply... */
6415   W (ret);
6416   return ret;
6417 }
6418
6419 static void vl_api_sw_interface_get_table_reply_t_handler
6420   (vl_api_sw_interface_get_table_reply_t * mp)
6421 {
6422   vat_main_t *vam = &vat_main;
6423
6424   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6425
6426   vam->retval = ntohl (mp->retval);
6427   vam->result_ready = 1;
6428
6429 }
6430
6431 static void vl_api_sw_interface_get_table_reply_t_handler_json
6432   (vl_api_sw_interface_get_table_reply_t * mp)
6433 {
6434   vat_main_t *vam = &vat_main;
6435   vat_json_node_t node;
6436
6437   vat_json_init_object (&node);
6438   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6439   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6440
6441   vat_json_print (vam->ofp, &node);
6442   vat_json_free (&node);
6443
6444   vam->retval = ntohl (mp->retval);
6445   vam->result_ready = 1;
6446 }
6447
6448 static int
6449 api_sw_interface_get_table (vat_main_t * vam)
6450 {
6451   unformat_input_t *i = vam->input;
6452   vl_api_sw_interface_get_table_t *mp;
6453   u32 sw_if_index;
6454   u8 sw_if_index_set = 0;
6455   u8 is_ipv6 = 0;
6456   int ret;
6457
6458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6459     {
6460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6461         sw_if_index_set = 1;
6462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6463         sw_if_index_set = 1;
6464       else if (unformat (i, "ipv6"))
6465         is_ipv6 = 1;
6466       else
6467         break;
6468     }
6469
6470   if (sw_if_index_set == 0)
6471     {
6472       errmsg ("missing interface name or sw_if_index");
6473       return -99;
6474     }
6475
6476   M (SW_INTERFACE_GET_TABLE, mp);
6477   mp->sw_if_index = htonl (sw_if_index);
6478   mp->is_ipv6 = is_ipv6;
6479
6480   S (mp);
6481   W (ret);
6482   return ret;
6483 }
6484
6485 static int
6486 api_sw_interface_set_vpath (vat_main_t * vam)
6487 {
6488   unformat_input_t *i = vam->input;
6489   vl_api_sw_interface_set_vpath_t *mp;
6490   u32 sw_if_index = 0;
6491   u8 sw_if_index_set = 0;
6492   u8 is_enable = 0;
6493   int ret;
6494
6495   /* Parse args required to build the message */
6496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6497     {
6498       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6499         sw_if_index_set = 1;
6500       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6501         sw_if_index_set = 1;
6502       else if (unformat (i, "enable"))
6503         is_enable = 1;
6504       else if (unformat (i, "disable"))
6505         is_enable = 0;
6506       else
6507         break;
6508     }
6509
6510   if (sw_if_index_set == 0)
6511     {
6512       errmsg ("missing interface name or sw_if_index");
6513       return -99;
6514     }
6515
6516   /* Construct the API message */
6517   M (SW_INTERFACE_SET_VPATH, mp);
6518
6519   mp->sw_if_index = ntohl (sw_if_index);
6520   mp->enable = is_enable;
6521
6522   /* send it... */
6523   S (mp);
6524
6525   /* Wait for a reply... */
6526   W (ret);
6527   return ret;
6528 }
6529
6530 static int
6531 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6532 {
6533   unformat_input_t *i = vam->input;
6534   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6535   u32 sw_if_index = 0;
6536   u8 sw_if_index_set = 0;
6537   u8 is_enable = 1;
6538   u8 is_ipv6 = 0;
6539   int ret;
6540
6541   /* Parse args required to build the message */
6542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6543     {
6544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6545         sw_if_index_set = 1;
6546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6547         sw_if_index_set = 1;
6548       else if (unformat (i, "enable"))
6549         is_enable = 1;
6550       else if (unformat (i, "disable"))
6551         is_enable = 0;
6552       else if (unformat (i, "ip4"))
6553         is_ipv6 = 0;
6554       else if (unformat (i, "ip6"))
6555         is_ipv6 = 1;
6556       else
6557         break;
6558     }
6559
6560   if (sw_if_index_set == 0)
6561     {
6562       errmsg ("missing interface name or sw_if_index");
6563       return -99;
6564     }
6565
6566   /* Construct the API message */
6567   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6568
6569   mp->sw_if_index = ntohl (sw_if_index);
6570   mp->enable = is_enable;
6571   mp->is_ipv6 = is_ipv6;
6572
6573   /* send it... */
6574   S (mp);
6575
6576   /* Wait for a reply... */
6577   W (ret);
6578   return ret;
6579 }
6580
6581 static int
6582 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6583 {
6584   unformat_input_t *i = vam->input;
6585   vl_api_sw_interface_set_geneve_bypass_t *mp;
6586   u32 sw_if_index = 0;
6587   u8 sw_if_index_set = 0;
6588   u8 is_enable = 1;
6589   u8 is_ipv6 = 0;
6590   int ret;
6591
6592   /* Parse args required to build the message */
6593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6594     {
6595       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6598         sw_if_index_set = 1;
6599       else if (unformat (i, "enable"))
6600         is_enable = 1;
6601       else if (unformat (i, "disable"))
6602         is_enable = 0;
6603       else if (unformat (i, "ip4"))
6604         is_ipv6 = 0;
6605       else if (unformat (i, "ip6"))
6606         is_ipv6 = 1;
6607       else
6608         break;
6609     }
6610
6611   if (sw_if_index_set == 0)
6612     {
6613       errmsg ("missing interface name or sw_if_index");
6614       return -99;
6615     }
6616
6617   /* Construct the API message */
6618   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6619
6620   mp->sw_if_index = ntohl (sw_if_index);
6621   mp->enable = is_enable;
6622   mp->is_ipv6 = is_ipv6;
6623
6624   /* send it... */
6625   S (mp);
6626
6627   /* Wait for a reply... */
6628   W (ret);
6629   return ret;
6630 }
6631
6632 static int
6633 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6634 {
6635   unformat_input_t *i = vam->input;
6636   vl_api_sw_interface_set_l2_xconnect_t *mp;
6637   u32 rx_sw_if_index;
6638   u8 rx_sw_if_index_set = 0;
6639   u32 tx_sw_if_index;
6640   u8 tx_sw_if_index_set = 0;
6641   u8 enable = 1;
6642   int ret;
6643
6644   /* Parse args required to build the message */
6645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6646     {
6647       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6648         rx_sw_if_index_set = 1;
6649       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6650         tx_sw_if_index_set = 1;
6651       else if (unformat (i, "rx"))
6652         {
6653           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6654             {
6655               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6656                             &rx_sw_if_index))
6657                 rx_sw_if_index_set = 1;
6658             }
6659           else
6660             break;
6661         }
6662       else if (unformat (i, "tx"))
6663         {
6664           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665             {
6666               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6667                             &tx_sw_if_index))
6668                 tx_sw_if_index_set = 1;
6669             }
6670           else
6671             break;
6672         }
6673       else if (unformat (i, "enable"))
6674         enable = 1;
6675       else if (unformat (i, "disable"))
6676         enable = 0;
6677       else
6678         break;
6679     }
6680
6681   if (rx_sw_if_index_set == 0)
6682     {
6683       errmsg ("missing rx interface name or rx_sw_if_index");
6684       return -99;
6685     }
6686
6687   if (enable && (tx_sw_if_index_set == 0))
6688     {
6689       errmsg ("missing tx interface name or tx_sw_if_index");
6690       return -99;
6691     }
6692
6693   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6694
6695   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6696   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6697   mp->enable = enable;
6698
6699   S (mp);
6700   W (ret);
6701   return ret;
6702 }
6703
6704 static int
6705 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6706 {
6707   unformat_input_t *i = vam->input;
6708   vl_api_sw_interface_set_l2_bridge_t *mp;
6709   vl_api_l2_port_type_t port_type;
6710   u32 rx_sw_if_index;
6711   u8 rx_sw_if_index_set = 0;
6712   u32 bd_id;
6713   u8 bd_id_set = 0;
6714   u32 shg = 0;
6715   u8 enable = 1;
6716   int ret;
6717
6718   port_type = L2_API_PORT_TYPE_NORMAL;
6719
6720   /* Parse args required to build the message */
6721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6722     {
6723       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6724         rx_sw_if_index_set = 1;
6725       else if (unformat (i, "bd_id %d", &bd_id))
6726         bd_id_set = 1;
6727       else
6728         if (unformat
6729             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6730         rx_sw_if_index_set = 1;
6731       else if (unformat (i, "shg %d", &shg))
6732         ;
6733       else if (unformat (i, "bvi"))
6734         port_type = L2_API_PORT_TYPE_BVI;
6735       else if (unformat (i, "uu-fwd"))
6736         port_type = L2_API_PORT_TYPE_UU_FWD;
6737       else if (unformat (i, "enable"))
6738         enable = 1;
6739       else if (unformat (i, "disable"))
6740         enable = 0;
6741       else
6742         break;
6743     }
6744
6745   if (rx_sw_if_index_set == 0)
6746     {
6747       errmsg ("missing rx interface name or sw_if_index");
6748       return -99;
6749     }
6750
6751   if (enable && (bd_id_set == 0))
6752     {
6753       errmsg ("missing bridge domain");
6754       return -99;
6755     }
6756
6757   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6758
6759   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6760   mp->bd_id = ntohl (bd_id);
6761   mp->shg = (u8) shg;
6762   mp->port_type = ntohl (port_type);
6763   mp->enable = enable;
6764
6765   S (mp);
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_bridge_domain_dump (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_bridge_domain_dump_t *mp;
6775   vl_api_control_ping_t *mp_ping;
6776   u32 bd_id = ~0;
6777   int ret;
6778
6779   /* Parse args required to build the message */
6780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6781     {
6782       if (unformat (i, "bd_id %d", &bd_id))
6783         ;
6784       else
6785         break;
6786     }
6787
6788   M (BRIDGE_DOMAIN_DUMP, mp);
6789   mp->bd_id = ntohl (bd_id);
6790   S (mp);
6791
6792   /* Use a control ping for synchronization */
6793   MPING (CONTROL_PING, mp_ping);
6794   S (mp_ping);
6795
6796   W (ret);
6797   return ret;
6798 }
6799
6800 static int
6801 api_bridge_domain_add_del (vat_main_t * vam)
6802 {
6803   unformat_input_t *i = vam->input;
6804   vl_api_bridge_domain_add_del_t *mp;
6805   u32 bd_id = ~0;
6806   u8 is_add = 1;
6807   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6808   u8 *bd_tag = NULL;
6809   u32 mac_age = 0;
6810   int ret;
6811
6812   /* Parse args required to build the message */
6813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6814     {
6815       if (unformat (i, "bd_id %d", &bd_id))
6816         ;
6817       else if (unformat (i, "flood %d", &flood))
6818         ;
6819       else if (unformat (i, "uu-flood %d", &uu_flood))
6820         ;
6821       else if (unformat (i, "forward %d", &forward))
6822         ;
6823       else if (unformat (i, "learn %d", &learn))
6824         ;
6825       else if (unformat (i, "arp-term %d", &arp_term))
6826         ;
6827       else if (unformat (i, "mac-age %d", &mac_age))
6828         ;
6829       else if (unformat (i, "bd-tag %s", &bd_tag))
6830         ;
6831       else if (unformat (i, "del"))
6832         {
6833           is_add = 0;
6834           flood = uu_flood = forward = learn = 0;
6835         }
6836       else
6837         break;
6838     }
6839
6840   if (bd_id == ~0)
6841     {
6842       errmsg ("missing bridge domain");
6843       ret = -99;
6844       goto done;
6845     }
6846
6847   if (mac_age > 255)
6848     {
6849       errmsg ("mac age must be less than 256 ");
6850       ret = -99;
6851       goto done;
6852     }
6853
6854   if ((bd_tag) && (vec_len (bd_tag) > 63))
6855     {
6856       errmsg ("bd-tag cannot be longer than 63");
6857       ret = -99;
6858       goto done;
6859     }
6860
6861   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6862
6863   mp->bd_id = ntohl (bd_id);
6864   mp->flood = flood;
6865   mp->uu_flood = uu_flood;
6866   mp->forward = forward;
6867   mp->learn = learn;
6868   mp->arp_term = arp_term;
6869   mp->is_add = is_add;
6870   mp->mac_age = (u8) mac_age;
6871   if (bd_tag)
6872     {
6873       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6874       mp->bd_tag[vec_len (bd_tag)] = 0;
6875     }
6876   S (mp);
6877   W (ret);
6878
6879 done:
6880   vec_free (bd_tag);
6881   return ret;
6882 }
6883
6884 static int
6885 api_l2fib_flush_bd (vat_main_t * vam)
6886 {
6887   unformat_input_t *i = vam->input;
6888   vl_api_l2fib_flush_bd_t *mp;
6889   u32 bd_id = ~0;
6890   int ret;
6891
6892   /* Parse args required to build the message */
6893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6894     {
6895       if (unformat (i, "bd_id %d", &bd_id));
6896       else
6897         break;
6898     }
6899
6900   if (bd_id == ~0)
6901     {
6902       errmsg ("missing bridge domain");
6903       return -99;
6904     }
6905
6906   M (L2FIB_FLUSH_BD, mp);
6907
6908   mp->bd_id = htonl (bd_id);
6909
6910   S (mp);
6911   W (ret);
6912   return ret;
6913 }
6914
6915 static int
6916 api_l2fib_flush_int (vat_main_t * vam)
6917 {
6918   unformat_input_t *i = vam->input;
6919   vl_api_l2fib_flush_int_t *mp;
6920   u32 sw_if_index = ~0;
6921   int ret;
6922
6923   /* Parse args required to build the message */
6924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6925     {
6926       if (unformat (i, "sw_if_index %d", &sw_if_index));
6927       else
6928         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6929       else
6930         break;
6931     }
6932
6933   if (sw_if_index == ~0)
6934     {
6935       errmsg ("missing interface name or sw_if_index");
6936       return -99;
6937     }
6938
6939   M (L2FIB_FLUSH_INT, mp);
6940
6941   mp->sw_if_index = ntohl (sw_if_index);
6942
6943   S (mp);
6944   W (ret);
6945   return ret;
6946 }
6947
6948 static int
6949 api_l2fib_add_del (vat_main_t * vam)
6950 {
6951   unformat_input_t *i = vam->input;
6952   vl_api_l2fib_add_del_t *mp;
6953   f64 timeout;
6954   u8 mac[6] = { 0 };
6955   u8 mac_set = 0;
6956   u32 bd_id;
6957   u8 bd_id_set = 0;
6958   u32 sw_if_index = 0;
6959   u8 sw_if_index_set = 0;
6960   u8 is_add = 1;
6961   u8 static_mac = 0;
6962   u8 filter_mac = 0;
6963   u8 bvi_mac = 0;
6964   int count = 1;
6965   f64 before = 0;
6966   int j;
6967
6968   /* Parse args required to build the message */
6969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6970     {
6971       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6972         mac_set = 1;
6973       else if (unformat (i, "bd_id %d", &bd_id))
6974         bd_id_set = 1;
6975       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6976         sw_if_index_set = 1;
6977       else if (unformat (i, "sw_if"))
6978         {
6979           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6980             {
6981               if (unformat
6982                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6983                 sw_if_index_set = 1;
6984             }
6985           else
6986             break;
6987         }
6988       else if (unformat (i, "static"))
6989         static_mac = 1;
6990       else if (unformat (i, "filter"))
6991         {
6992           filter_mac = 1;
6993           static_mac = 1;
6994         }
6995       else if (unformat (i, "bvi"))
6996         {
6997           bvi_mac = 1;
6998           static_mac = 1;
6999         }
7000       else if (unformat (i, "del"))
7001         is_add = 0;
7002       else if (unformat (i, "count %d", &count))
7003         ;
7004       else
7005         break;
7006     }
7007
7008   if (mac_set == 0)
7009     {
7010       errmsg ("missing mac address");
7011       return -99;
7012     }
7013
7014   if (bd_id_set == 0)
7015     {
7016       errmsg ("missing bridge domain");
7017       return -99;
7018     }
7019
7020   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7021     {
7022       errmsg ("missing interface name or sw_if_index");
7023       return -99;
7024     }
7025
7026   if (count > 1)
7027     {
7028       /* Turn on async mode */
7029       vam->async_mode = 1;
7030       vam->async_errors = 0;
7031       before = vat_time_now (vam);
7032     }
7033
7034   for (j = 0; j < count; j++)
7035     {
7036       M (L2FIB_ADD_DEL, mp);
7037
7038       clib_memcpy (mp->mac, mac, 6);
7039       mp->bd_id = ntohl (bd_id);
7040       mp->is_add = is_add;
7041       mp->sw_if_index = ntohl (sw_if_index);
7042
7043       if (is_add)
7044         {
7045           mp->static_mac = static_mac;
7046           mp->filter_mac = filter_mac;
7047           mp->bvi_mac = bvi_mac;
7048         }
7049       increment_mac_address (mac);
7050       /* send it... */
7051       S (mp);
7052     }
7053
7054   if (count > 1)
7055     {
7056       vl_api_control_ping_t *mp_ping;
7057       f64 after;
7058
7059       /* Shut off async mode */
7060       vam->async_mode = 0;
7061
7062       MPING (CONTROL_PING, mp_ping);
7063       S (mp_ping);
7064
7065       timeout = vat_time_now (vam) + 1.0;
7066       while (vat_time_now (vam) < timeout)
7067         if (vam->result_ready == 1)
7068           goto out;
7069       vam->retval = -99;
7070
7071     out:
7072       if (vam->retval == -99)
7073         errmsg ("timeout");
7074
7075       if (vam->async_errors > 0)
7076         {
7077           errmsg ("%d asynchronous errors", vam->async_errors);
7078           vam->retval = -98;
7079         }
7080       vam->async_errors = 0;
7081       after = vat_time_now (vam);
7082
7083       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7084              count, after - before, count / (after - before));
7085     }
7086   else
7087     {
7088       int ret;
7089
7090       /* Wait for a reply... */
7091       W (ret);
7092       return ret;
7093     }
7094   /* Return the good/bad news */
7095   return (vam->retval);
7096 }
7097
7098 static int
7099 api_bridge_domain_set_mac_age (vat_main_t * vam)
7100 {
7101   unformat_input_t *i = vam->input;
7102   vl_api_bridge_domain_set_mac_age_t *mp;
7103   u32 bd_id = ~0;
7104   u32 mac_age = 0;
7105   int ret;
7106
7107   /* Parse args required to build the message */
7108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7109     {
7110       if (unformat (i, "bd_id %d", &bd_id));
7111       else if (unformat (i, "mac-age %d", &mac_age));
7112       else
7113         break;
7114     }
7115
7116   if (bd_id == ~0)
7117     {
7118       errmsg ("missing bridge domain");
7119       return -99;
7120     }
7121
7122   if (mac_age > 255)
7123     {
7124       errmsg ("mac age must be less than 256 ");
7125       return -99;
7126     }
7127
7128   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7129
7130   mp->bd_id = htonl (bd_id);
7131   mp->mac_age = (u8) mac_age;
7132
7133   S (mp);
7134   W (ret);
7135   return ret;
7136 }
7137
7138 static int
7139 api_l2_flags (vat_main_t * vam)
7140 {
7141   unformat_input_t *i = vam->input;
7142   vl_api_l2_flags_t *mp;
7143   u32 sw_if_index;
7144   u32 flags = 0;
7145   u8 sw_if_index_set = 0;
7146   u8 is_set = 0;
7147   int ret;
7148
7149   /* Parse args required to build the message */
7150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7151     {
7152       if (unformat (i, "sw_if_index %d", &sw_if_index))
7153         sw_if_index_set = 1;
7154       else if (unformat (i, "sw_if"))
7155         {
7156           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7157             {
7158               if (unformat
7159                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7160                 sw_if_index_set = 1;
7161             }
7162           else
7163             break;
7164         }
7165       else if (unformat (i, "learn"))
7166         flags |= L2_LEARN;
7167       else if (unformat (i, "forward"))
7168         flags |= L2_FWD;
7169       else if (unformat (i, "flood"))
7170         flags |= L2_FLOOD;
7171       else if (unformat (i, "uu-flood"))
7172         flags |= L2_UU_FLOOD;
7173       else if (unformat (i, "arp-term"))
7174         flags |= L2_ARP_TERM;
7175       else if (unformat (i, "off"))
7176         is_set = 0;
7177       else if (unformat (i, "disable"))
7178         is_set = 0;
7179       else
7180         break;
7181     }
7182
7183   if (sw_if_index_set == 0)
7184     {
7185       errmsg ("missing interface name or sw_if_index");
7186       return -99;
7187     }
7188
7189   M (L2_FLAGS, mp);
7190
7191   mp->sw_if_index = ntohl (sw_if_index);
7192   mp->feature_bitmap = ntohl (flags);
7193   mp->is_set = is_set;
7194
7195   S (mp);
7196   W (ret);
7197   return ret;
7198 }
7199
7200 static int
7201 api_bridge_flags (vat_main_t * vam)
7202 {
7203   unformat_input_t *i = vam->input;
7204   vl_api_bridge_flags_t *mp;
7205   u32 bd_id;
7206   u8 bd_id_set = 0;
7207   u8 is_set = 1;
7208   bd_flags_t flags = 0;
7209   int ret;
7210
7211   /* Parse args required to build the message */
7212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7213     {
7214       if (unformat (i, "bd_id %d", &bd_id))
7215         bd_id_set = 1;
7216       else if (unformat (i, "learn"))
7217         flags |= BRIDGE_API_FLAG_LEARN;
7218       else if (unformat (i, "forward"))
7219         flags |= BRIDGE_API_FLAG_FWD;
7220       else if (unformat (i, "flood"))
7221         flags |= BRIDGE_API_FLAG_FLOOD;
7222       else if (unformat (i, "uu-flood"))
7223         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7224       else if (unformat (i, "arp-term"))
7225         flags |= BRIDGE_API_FLAG_ARP_TERM;
7226       else if (unformat (i, "off"))
7227         is_set = 0;
7228       else if (unformat (i, "disable"))
7229         is_set = 0;
7230       else
7231         break;
7232     }
7233
7234   if (bd_id_set == 0)
7235     {
7236       errmsg ("missing bridge domain");
7237       return -99;
7238     }
7239
7240   M (BRIDGE_FLAGS, mp);
7241
7242   mp->bd_id = ntohl (bd_id);
7243   mp->flags = ntohl (flags);
7244   mp->is_set = is_set;
7245
7246   S (mp);
7247   W (ret);
7248   return ret;
7249 }
7250
7251 static int
7252 api_bd_ip_mac_add_del (vat_main_t * vam)
7253 {
7254   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7255   vl_api_mac_address_t mac = { 0 };
7256   unformat_input_t *i = vam->input;
7257   vl_api_bd_ip_mac_add_del_t *mp;
7258   u32 bd_id;
7259   u8 is_add = 1;
7260   u8 bd_id_set = 0;
7261   u8 ip_set = 0;
7262   u8 mac_set = 0;
7263   int ret;
7264
7265
7266   /* Parse args required to build the message */
7267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7268     {
7269       if (unformat (i, "bd_id %d", &bd_id))
7270         {
7271           bd_id_set++;
7272         }
7273       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7274         {
7275           ip_set++;
7276         }
7277       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7278         {
7279           mac_set++;
7280         }
7281       else if (unformat (i, "del"))
7282         is_add = 0;
7283       else
7284         break;
7285     }
7286
7287   if (bd_id_set == 0)
7288     {
7289       errmsg ("missing bridge domain");
7290       return -99;
7291     }
7292   else if (ip_set == 0)
7293     {
7294       errmsg ("missing IP address");
7295       return -99;
7296     }
7297   else if (mac_set == 0)
7298     {
7299       errmsg ("missing MAC address");
7300       return -99;
7301     }
7302
7303   M (BD_IP_MAC_ADD_DEL, mp);
7304
7305   mp->entry.bd_id = ntohl (bd_id);
7306   mp->is_add = is_add;
7307
7308   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7309   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7310
7311   S (mp);
7312   W (ret);
7313   return ret;
7314 }
7315
7316 static int
7317 api_bd_ip_mac_flush (vat_main_t * vam)
7318 {
7319   unformat_input_t *i = vam->input;
7320   vl_api_bd_ip_mac_flush_t *mp;
7321   u32 bd_id;
7322   u8 bd_id_set = 0;
7323   int ret;
7324
7325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326     {
7327       if (unformat (i, "bd_id %d", &bd_id))
7328         {
7329           bd_id_set++;
7330         }
7331       else
7332         break;
7333     }
7334
7335   if (bd_id_set == 0)
7336     {
7337       errmsg ("missing bridge domain");
7338       return -99;
7339     }
7340
7341   M (BD_IP_MAC_FLUSH, mp);
7342
7343   mp->bd_id = ntohl (bd_id);
7344
7345   S (mp);
7346   W (ret);
7347   return ret;
7348 }
7349
7350 static void vl_api_bd_ip_mac_details_t_handler
7351   (vl_api_bd_ip_mac_details_t * mp)
7352 {
7353   vat_main_t *vam = &vat_main;
7354
7355   print (vam->ofp,
7356          "\n%-5d %U %U",
7357          ntohl (mp->entry.bd_id),
7358          format_vl_api_mac_address, mp->entry.mac,
7359          format_vl_api_address, &mp->entry.ip);
7360 }
7361
7362 static void vl_api_bd_ip_mac_details_t_handler_json
7363   (vl_api_bd_ip_mac_details_t * mp)
7364 {
7365   vat_main_t *vam = &vat_main;
7366   vat_json_node_t *node = NULL;
7367
7368   if (VAT_JSON_ARRAY != vam->json_tree.type)
7369     {
7370       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7371       vat_json_init_array (&vam->json_tree);
7372     }
7373   node = vat_json_array_add (&vam->json_tree);
7374
7375   vat_json_init_object (node);
7376   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7377   vat_json_object_add_string_copy (node, "mac_address",
7378                                    format (0, "%U", format_vl_api_mac_address,
7379                                            &mp->entry.mac));
7380   u8 *ip = 0;
7381
7382   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7383   vat_json_object_add_string_copy (node, "ip_address", ip);
7384   vec_free (ip);
7385 }
7386
7387 static int
7388 api_bd_ip_mac_dump (vat_main_t * vam)
7389 {
7390   unformat_input_t *i = vam->input;
7391   vl_api_bd_ip_mac_dump_t *mp;
7392   vl_api_control_ping_t *mp_ping;
7393   int ret;
7394   u32 bd_id;
7395   u8 bd_id_set = 0;
7396
7397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7398     {
7399       if (unformat (i, "bd_id %d", &bd_id))
7400         {
7401           bd_id_set++;
7402         }
7403       else
7404         break;
7405     }
7406
7407   print (vam->ofp,
7408          "\n%-5s %-7s %-20s %-30s",
7409          "bd_id", "is_ipv6", "mac_address", "ip_address");
7410
7411   /* Dump Bridge Domain Ip to Mac entries */
7412   M (BD_IP_MAC_DUMP, mp);
7413
7414   if (bd_id_set)
7415     mp->bd_id = htonl (bd_id);
7416   else
7417     mp->bd_id = ~0;
7418
7419   S (mp);
7420
7421   /* Use a control ping for synchronization */
7422   MPING (CONTROL_PING, mp_ping);
7423   S (mp_ping);
7424
7425   W (ret);
7426   return ret;
7427 }
7428
7429 static int
7430 api_tap_create_v2 (vat_main_t * vam)
7431 {
7432   unformat_input_t *i = vam->input;
7433   vl_api_tap_create_v2_t *mp;
7434 #define TAP_FLAG_GSO (1 << 0)
7435   u8 mac_address[6];
7436   u8 random_mac = 1;
7437   u32 id = ~0;
7438   u8 *host_if_name = 0;
7439   u8 *host_ns = 0;
7440   u8 host_mac_addr[6];
7441   u8 host_mac_addr_set = 0;
7442   u8 *host_bridge = 0;
7443   ip4_address_t host_ip4_addr;
7444   ip4_address_t host_ip4_gw;
7445   u8 host_ip4_gw_set = 0;
7446   u32 host_ip4_prefix_len = 0;
7447   ip6_address_t host_ip6_addr;
7448   ip6_address_t host_ip6_gw;
7449   u8 host_ip6_gw_set = 0;
7450   u32 host_ip6_prefix_len = 0;
7451   u8 host_mtu_set = 0;
7452   u32 host_mtu_size = 0;
7453   u32 tap_flags = 0;
7454   int ret;
7455   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7456
7457   clib_memset (mac_address, 0, sizeof (mac_address));
7458
7459   /* Parse args required to build the message */
7460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7461     {
7462       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7463         {
7464           random_mac = 0;
7465         }
7466       else if (unformat (i, "id %u", &id))
7467         ;
7468       else if (unformat (i, "host-if-name %s", &host_if_name))
7469         ;
7470       else if (unformat (i, "host-ns %s", &host_ns))
7471         ;
7472       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7473                          host_mac_addr))
7474         host_mac_addr_set = 1;
7475       else if (unformat (i, "host-bridge %s", &host_bridge))
7476         ;
7477       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7478                          &host_ip4_addr, &host_ip4_prefix_len))
7479         ;
7480       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7481                          &host_ip6_addr, &host_ip6_prefix_len))
7482         ;
7483       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7484                          &host_ip4_gw))
7485         host_ip4_gw_set = 1;
7486       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7487                          &host_ip6_gw))
7488         host_ip6_gw_set = 1;
7489       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7490         ;
7491       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7492         ;
7493       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7494         host_mtu_set = 1;
7495       else if (unformat (i, "no-gso"))
7496         tap_flags &= ~TAP_FLAG_GSO;
7497       else if (unformat (i, "gso"))
7498         tap_flags |= TAP_FLAG_GSO;
7499       else
7500         break;
7501     }
7502
7503   if (vec_len (host_if_name) > 63)
7504     {
7505       errmsg ("tap name too long. ");
7506       return -99;
7507     }
7508   if (vec_len (host_ns) > 63)
7509     {
7510       errmsg ("host name space too long. ");
7511       return -99;
7512     }
7513   if (vec_len (host_bridge) > 63)
7514     {
7515       errmsg ("host bridge name too long. ");
7516       return -99;
7517     }
7518   if (host_ip4_prefix_len > 32)
7519     {
7520       errmsg ("host ip4 prefix length not valid. ");
7521       return -99;
7522     }
7523   if (host_ip6_prefix_len > 128)
7524     {
7525       errmsg ("host ip6 prefix length not valid. ");
7526       return -99;
7527     }
7528   if (!is_pow2 (rx_ring_sz))
7529     {
7530       errmsg ("rx ring size must be power of 2. ");
7531       return -99;
7532     }
7533   if (rx_ring_sz > 32768)
7534     {
7535       errmsg ("rx ring size must be 32768 or lower. ");
7536       return -99;
7537     }
7538   if (!is_pow2 (tx_ring_sz))
7539     {
7540       errmsg ("tx ring size must be power of 2. ");
7541       return -99;
7542     }
7543   if (tx_ring_sz > 32768)
7544     {
7545       errmsg ("tx ring size must be 32768 or lower. ");
7546       return -99;
7547     }
7548   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7549     {
7550       errmsg ("host MTU size must be in between 64 and 65355. ");
7551       return -99;
7552     }
7553
7554   /* Construct the API message */
7555   M (TAP_CREATE_V2, mp);
7556
7557   mp->use_random_mac = random_mac;
7558
7559   mp->id = ntohl (id);
7560   mp->host_namespace_set = host_ns != 0;
7561   mp->host_bridge_set = host_bridge != 0;
7562   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7563   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7564   mp->rx_ring_sz = ntohs (rx_ring_sz);
7565   mp->tx_ring_sz = ntohs (tx_ring_sz);
7566   mp->host_mtu_set = host_mtu_set;
7567   mp->host_mtu_size = ntohl (host_mtu_size);
7568   mp->tap_flags = ntohl (tap_flags);
7569
7570   if (random_mac == 0)
7571     clib_memcpy (mp->mac_address, mac_address, 6);
7572   if (host_mac_addr_set)
7573     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7574   if (host_if_name)
7575     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7576   if (host_ns)
7577     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7578   if (host_bridge)
7579     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7580   if (host_ip4_prefix_len)
7581     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7582   if (host_ip6_prefix_len)
7583     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7584   if (host_ip4_gw_set)
7585     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7586   if (host_ip6_gw_set)
7587     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7588
7589   vec_free (host_ns);
7590   vec_free (host_if_name);
7591   vec_free (host_bridge);
7592
7593   /* send it... */
7594   S (mp);
7595
7596   /* Wait for a reply... */
7597   W (ret);
7598   return ret;
7599 }
7600
7601 static int
7602 api_tap_delete_v2 (vat_main_t * vam)
7603 {
7604   unformat_input_t *i = vam->input;
7605   vl_api_tap_delete_v2_t *mp;
7606   u32 sw_if_index = ~0;
7607   u8 sw_if_index_set = 0;
7608   int ret;
7609
7610   /* Parse args required to build the message */
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7614         sw_if_index_set = 1;
7615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7616         sw_if_index_set = 1;
7617       else
7618         break;
7619     }
7620
7621   if (sw_if_index_set == 0)
7622     {
7623       errmsg ("missing vpp interface name. ");
7624       return -99;
7625     }
7626
7627   /* Construct the API message */
7628   M (TAP_DELETE_V2, mp);
7629
7630   mp->sw_if_index = ntohl (sw_if_index);
7631
7632   /* send it... */
7633   S (mp);
7634
7635   /* Wait for a reply... */
7636   W (ret);
7637   return ret;
7638 }
7639
7640 uword
7641 unformat_pci_addr (unformat_input_t * input, va_list * args)
7642 {
7643   struct pci_addr_t
7644   {
7645     u16 domain;
7646     u8 bus;
7647     u8 slot:5;
7648     u8 function:3;
7649   } *addr;
7650   addr = va_arg (*args, struct pci_addr_t *);
7651   u32 x[4];
7652
7653   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7654     return 0;
7655
7656   addr->domain = x[0];
7657   addr->bus = x[1];
7658   addr->slot = x[2];
7659   addr->function = x[3];
7660
7661   return 1;
7662 }
7663
7664 static int
7665 api_virtio_pci_create (vat_main_t * vam)
7666 {
7667   unformat_input_t *i = vam->input;
7668   vl_api_virtio_pci_create_t *mp;
7669   u8 mac_address[6];
7670   u8 random_mac = 1;
7671   u8 gso_enabled = 0;
7672   u32 pci_addr = 0;
7673   u64 features = (u64) ~ (0ULL);
7674   int ret;
7675
7676   clib_memset (mac_address, 0, sizeof (mac_address));
7677
7678   /* Parse args required to build the message */
7679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7680     {
7681       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7682         {
7683           random_mac = 0;
7684         }
7685       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7686         ;
7687       else if (unformat (i, "features 0x%llx", &features))
7688         ;
7689       else if (unformat (i, "gso-enabled"))
7690         gso_enabled = 1;
7691       else
7692         break;
7693     }
7694
7695   if (pci_addr == 0)
7696     {
7697       errmsg ("pci address must be non zero. ");
7698       return -99;
7699     }
7700
7701   /* Construct the API message */
7702   M (VIRTIO_PCI_CREATE, mp);
7703
7704   mp->use_random_mac = random_mac;
7705
7706   mp->pci_addr = htonl (pci_addr);
7707   mp->features = clib_host_to_net_u64 (features);
7708   mp->gso_enabled = gso_enabled;
7709
7710   if (random_mac == 0)
7711     clib_memcpy (mp->mac_address, mac_address, 6);
7712
7713   /* send it... */
7714   S (mp);
7715
7716   /* Wait for a reply... */
7717   W (ret);
7718   return ret;
7719 }
7720
7721 static int
7722 api_virtio_pci_delete (vat_main_t * vam)
7723 {
7724   unformat_input_t *i = vam->input;
7725   vl_api_virtio_pci_delete_t *mp;
7726   u32 sw_if_index = ~0;
7727   u8 sw_if_index_set = 0;
7728   int ret;
7729
7730   /* Parse args required to build the message */
7731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7732     {
7733       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7734         sw_if_index_set = 1;
7735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7736         sw_if_index_set = 1;
7737       else
7738         break;
7739     }
7740
7741   if (sw_if_index_set == 0)
7742     {
7743       errmsg ("missing vpp interface name. ");
7744       return -99;
7745     }
7746
7747   /* Construct the API message */
7748   M (VIRTIO_PCI_DELETE, mp);
7749
7750   mp->sw_if_index = htonl (sw_if_index);
7751
7752   /* send it... */
7753   S (mp);
7754
7755   /* Wait for a reply... */
7756   W (ret);
7757   return ret;
7758 }
7759
7760 static int
7761 api_bond_create (vat_main_t * vam)
7762 {
7763   unformat_input_t *i = vam->input;
7764   vl_api_bond_create_t *mp;
7765   u8 mac_address[6];
7766   u8 custom_mac = 0;
7767   int ret;
7768   u8 mode;
7769   u8 lb;
7770   u8 mode_is_set = 0;
7771   u32 id = ~0;
7772   u8 numa_only = 0;
7773
7774   clib_memset (mac_address, 0, sizeof (mac_address));
7775   lb = BOND_LB_L2;
7776
7777   /* Parse args required to build the message */
7778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779     {
7780       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7781         mode_is_set = 1;
7782       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7783                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7784         ;
7785       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7786                          mac_address))
7787         custom_mac = 1;
7788       else if (unformat (i, "numa-only"))
7789         numa_only = 1;
7790       else if (unformat (i, "id %u", &id))
7791         ;
7792       else
7793         break;
7794     }
7795
7796   if (mode_is_set == 0)
7797     {
7798       errmsg ("Missing bond mode. ");
7799       return -99;
7800     }
7801
7802   /* Construct the API message */
7803   M (BOND_CREATE, mp);
7804
7805   mp->use_custom_mac = custom_mac;
7806
7807   mp->mode = mode;
7808   mp->lb = lb;
7809   mp->id = htonl (id);
7810   mp->numa_only = numa_only;
7811
7812   if (custom_mac)
7813     clib_memcpy (mp->mac_address, mac_address, 6);
7814
7815   /* send it... */
7816   S (mp);
7817
7818   /* Wait for a reply... */
7819   W (ret);
7820   return ret;
7821 }
7822
7823 static int
7824 api_bond_delete (vat_main_t * vam)
7825 {
7826   unformat_input_t *i = vam->input;
7827   vl_api_bond_delete_t *mp;
7828   u32 sw_if_index = ~0;
7829   u8 sw_if_index_set = 0;
7830   int ret;
7831
7832   /* Parse args required to build the message */
7833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7834     {
7835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7836         sw_if_index_set = 1;
7837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7838         sw_if_index_set = 1;
7839       else
7840         break;
7841     }
7842
7843   if (sw_if_index_set == 0)
7844     {
7845       errmsg ("missing vpp interface name. ");
7846       return -99;
7847     }
7848
7849   /* Construct the API message */
7850   M (BOND_DELETE, mp);
7851
7852   mp->sw_if_index = ntohl (sw_if_index);
7853
7854   /* send it... */
7855   S (mp);
7856
7857   /* Wait for a reply... */
7858   W (ret);
7859   return ret;
7860 }
7861
7862 static int
7863 api_bond_enslave (vat_main_t * vam)
7864 {
7865   unformat_input_t *i = vam->input;
7866   vl_api_bond_enslave_t *mp;
7867   u32 bond_sw_if_index;
7868   int ret;
7869   u8 is_passive;
7870   u8 is_long_timeout;
7871   u32 bond_sw_if_index_is_set = 0;
7872   u32 sw_if_index;
7873   u8 sw_if_index_is_set = 0;
7874
7875   /* Parse args required to build the message */
7876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7877     {
7878       if (unformat (i, "sw_if_index %d", &sw_if_index))
7879         sw_if_index_is_set = 1;
7880       else if (unformat (i, "bond %u", &bond_sw_if_index))
7881         bond_sw_if_index_is_set = 1;
7882       else if (unformat (i, "passive %d", &is_passive))
7883         ;
7884       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7885         ;
7886       else
7887         break;
7888     }
7889
7890   if (bond_sw_if_index_is_set == 0)
7891     {
7892       errmsg ("Missing bond sw_if_index. ");
7893       return -99;
7894     }
7895   if (sw_if_index_is_set == 0)
7896     {
7897       errmsg ("Missing slave sw_if_index. ");
7898       return -99;
7899     }
7900
7901   /* Construct the API message */
7902   M (BOND_ENSLAVE, mp);
7903
7904   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7905   mp->sw_if_index = ntohl (sw_if_index);
7906   mp->is_long_timeout = is_long_timeout;
7907   mp->is_passive = is_passive;
7908
7909   /* send it... */
7910   S (mp);
7911
7912   /* Wait for a reply... */
7913   W (ret);
7914   return ret;
7915 }
7916
7917 static int
7918 api_bond_detach_slave (vat_main_t * vam)
7919 {
7920   unformat_input_t *i = vam->input;
7921   vl_api_bond_detach_slave_t *mp;
7922   u32 sw_if_index = ~0;
7923   u8 sw_if_index_set = 0;
7924   int ret;
7925
7926   /* Parse args required to build the message */
7927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7928     {
7929       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7930         sw_if_index_set = 1;
7931       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7932         sw_if_index_set = 1;
7933       else
7934         break;
7935     }
7936
7937   if (sw_if_index_set == 0)
7938     {
7939       errmsg ("missing vpp interface name. ");
7940       return -99;
7941     }
7942
7943   /* Construct the API message */
7944   M (BOND_DETACH_SLAVE, mp);
7945
7946   mp->sw_if_index = ntohl (sw_if_index);
7947
7948   /* send it... */
7949   S (mp);
7950
7951   /* Wait for a reply... */
7952   W (ret);
7953   return ret;
7954 }
7955
7956 static int
7957 api_ip_table_add_del (vat_main_t * vam)
7958 {
7959   unformat_input_t *i = vam->input;
7960   vl_api_ip_table_add_del_t *mp;
7961   u32 table_id = ~0;
7962   u8 is_ipv6 = 0;
7963   u8 is_add = 1;
7964   int ret = 0;
7965
7966   /* Parse args required to build the message */
7967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7968     {
7969       if (unformat (i, "ipv6"))
7970         is_ipv6 = 1;
7971       else if (unformat (i, "del"))
7972         is_add = 0;
7973       else if (unformat (i, "add"))
7974         is_add = 1;
7975       else if (unformat (i, "table %d", &table_id))
7976         ;
7977       else
7978         {
7979           clib_warning ("parse error '%U'", format_unformat_error, i);
7980           return -99;
7981         }
7982     }
7983
7984   if (~0 == table_id)
7985     {
7986       errmsg ("missing table-ID");
7987       return -99;
7988     }
7989
7990   /* Construct the API message */
7991   M (IP_TABLE_ADD_DEL, mp);
7992
7993   mp->table.table_id = ntohl (table_id);
7994   mp->table.is_ip6 = is_ipv6;
7995   mp->is_add = is_add;
7996
7997   /* send it... */
7998   S (mp);
7999
8000   /* Wait for a reply... */
8001   W (ret);
8002
8003   return ret;
8004 }
8005
8006 uword
8007 unformat_fib_path (unformat_input_t * input, va_list * args)
8008 {
8009   vat_main_t *vam = va_arg (*args, vat_main_t *);
8010   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8011   u32 weight, preference;
8012   mpls_label_t out_label;
8013
8014   clib_memset (path, 0, sizeof (*path));
8015   path->weight = 1;
8016   path->sw_if_index = ~0;
8017   path->rpf_id = ~0;
8018   path->n_labels = 0;
8019
8020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8021     {
8022       if (unformat (input, "%U %U",
8023                     unformat_vl_api_ip4_address,
8024                     &path->nh.address.ip4,
8025                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8026         {
8027           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8028         }
8029       else if (unformat (input, "%U %U",
8030                          unformat_vl_api_ip6_address,
8031                          &path->nh.address.ip6,
8032                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8033         {
8034           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8035         }
8036       else if (unformat (input, "weight %u", &weight))
8037         {
8038           path->weight = weight;
8039         }
8040       else if (unformat (input, "preference %u", &preference))
8041         {
8042           path->preference = preference;
8043         }
8044       else if (unformat (input, "%U next-hop-table %d",
8045                          unformat_vl_api_ip4_address,
8046                          &path->nh.address.ip4, &path->table_id))
8047         {
8048           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8049         }
8050       else if (unformat (input, "%U next-hop-table %d",
8051                          unformat_vl_api_ip6_address,
8052                          &path->nh.address.ip6, &path->table_id))
8053         {
8054           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8055         }
8056       else if (unformat (input, "%U",
8057                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8058         {
8059           /*
8060            * the recursive next-hops are by default in the default table
8061            */
8062           path->table_id = 0;
8063           path->sw_if_index = ~0;
8064           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8065         }
8066       else if (unformat (input, "%U",
8067                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8068         {
8069           /*
8070            * the recursive next-hops are by default in the default table
8071            */
8072           path->table_id = 0;
8073           path->sw_if_index = ~0;
8074           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8075         }
8076       else if (unformat (input, "resolve-via-host"))
8077         {
8078           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8079         }
8080       else if (unformat (input, "resolve-via-attached"))
8081         {
8082           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8083         }
8084       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8085         {
8086           path->type = FIB_API_PATH_TYPE_LOCAL;
8087           path->sw_if_index = ~0;
8088           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8089         }
8090       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8091         {
8092           path->type = FIB_API_PATH_TYPE_LOCAL;
8093           path->sw_if_index = ~0;
8094           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8095         }
8096       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8097         ;
8098       else if (unformat (input, "via-label %d", &path->nh.via_label))
8099         {
8100           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8101           path->sw_if_index = ~0;
8102         }
8103       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8104         {
8105           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8106           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8107         }
8108       else if (unformat (input, "local"))
8109         {
8110           path->type = FIB_API_PATH_TYPE_LOCAL;
8111         }
8112       else if (unformat (input, "out-labels"))
8113         {
8114           while (unformat (input, "%d", &out_label))
8115             {
8116               path->label_stack[path->n_labels].label = out_label;
8117               path->label_stack[path->n_labels].is_uniform = 0;
8118               path->label_stack[path->n_labels].ttl = 64;
8119               path->n_labels++;
8120             }
8121         }
8122       else if (unformat (input, "via"))
8123         {
8124           /* new path, back up and return */
8125           unformat_put_input (input);
8126           unformat_put_input (input);
8127           unformat_put_input (input);
8128           unformat_put_input (input);
8129           break;
8130         }
8131       else
8132         {
8133           return (0);
8134         }
8135     }
8136
8137   path->proto = ntohl (path->proto);
8138   path->type = ntohl (path->type);
8139   path->flags = ntohl (path->flags);
8140   path->table_id = ntohl (path->table_id);
8141   path->sw_if_index = ntohl (path->sw_if_index);
8142
8143   return (1);
8144 }
8145
8146 static int
8147 api_ip_route_add_del (vat_main_t * vam)
8148 {
8149   unformat_input_t *i = vam->input;
8150   vl_api_ip_route_add_del_t *mp;
8151   u32 vrf_id = 0;
8152   u8 is_add = 1;
8153   u8 is_multipath = 0;
8154   u8 prefix_set = 0;
8155   u8 path_count = 0;
8156   vl_api_prefix_t pfx = { };
8157   vl_api_fib_path_t paths[8];
8158   int count = 1;
8159   int j;
8160   f64 before = 0;
8161   u32 random_add_del = 0;
8162   u32 *random_vector = 0;
8163   u32 random_seed = 0xdeaddabe;
8164
8165   /* Parse args required to build the message */
8166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8167     {
8168       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8169         prefix_set = 1;
8170       else if (unformat (i, "del"))
8171         is_add = 0;
8172       else if (unformat (i, "add"))
8173         is_add = 1;
8174       else if (unformat (i, "vrf %d", &vrf_id))
8175         ;
8176       else if (unformat (i, "count %d", &count))
8177         ;
8178       else if (unformat (i, "random"))
8179         random_add_del = 1;
8180       else if (unformat (i, "multipath"))
8181         is_multipath = 1;
8182       else if (unformat (i, "seed %d", &random_seed))
8183         ;
8184       else
8185         if (unformat
8186             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8187         {
8188           path_count++;
8189           if (8 == path_count)
8190             {
8191               errmsg ("max 8 paths");
8192               return -99;
8193             }
8194         }
8195       else
8196         {
8197           clib_warning ("parse error '%U'", format_unformat_error, i);
8198           return -99;
8199         }
8200     }
8201
8202   if (!path_count)
8203     {
8204       errmsg ("specify a path; via ...");
8205       return -99;
8206     }
8207   if (prefix_set == 0)
8208     {
8209       errmsg ("missing prefix");
8210       return -99;
8211     }
8212
8213   /* Generate a pile of unique, random routes */
8214   if (random_add_del)
8215     {
8216       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8217       u32 this_random_address;
8218       uword *random_hash;
8219
8220       random_hash = hash_create (count, sizeof (uword));
8221
8222       hash_set (random_hash, i->as_u32, 1);
8223       for (j = 0; j <= count; j++)
8224         {
8225           do
8226             {
8227               this_random_address = random_u32 (&random_seed);
8228               this_random_address =
8229                 clib_host_to_net_u32 (this_random_address);
8230             }
8231           while (hash_get (random_hash, this_random_address));
8232           vec_add1 (random_vector, this_random_address);
8233           hash_set (random_hash, this_random_address, 1);
8234         }
8235       hash_free (random_hash);
8236       set_ip4_address (&pfx.address, random_vector[0]);
8237     }
8238
8239   if (count > 1)
8240     {
8241       /* Turn on async mode */
8242       vam->async_mode = 1;
8243       vam->async_errors = 0;
8244       before = vat_time_now (vam);
8245     }
8246
8247   for (j = 0; j < count; j++)
8248     {
8249       /* Construct the API message */
8250       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8251
8252       mp->is_add = is_add;
8253       mp->is_multipath = is_multipath;
8254
8255       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8256       mp->route.table_id = ntohl (vrf_id);
8257       mp->route.n_paths = path_count;
8258
8259       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8260
8261       if (random_add_del)
8262         set_ip4_address (&pfx.address, random_vector[j + 1]);
8263       else
8264         increment_address (&pfx.address);
8265       /* send it... */
8266       S (mp);
8267       /* If we receive SIGTERM, stop now... */
8268       if (vam->do_exit)
8269         break;
8270     }
8271
8272   /* When testing multiple add/del ops, use a control-ping to sync */
8273   if (count > 1)
8274     {
8275       vl_api_control_ping_t *mp_ping;
8276       f64 after;
8277       f64 timeout;
8278
8279       /* Shut off async mode */
8280       vam->async_mode = 0;
8281
8282       MPING (CONTROL_PING, mp_ping);
8283       S (mp_ping);
8284
8285       timeout = vat_time_now (vam) + 1.0;
8286       while (vat_time_now (vam) < timeout)
8287         if (vam->result_ready == 1)
8288           goto out;
8289       vam->retval = -99;
8290
8291     out:
8292       if (vam->retval == -99)
8293         errmsg ("timeout");
8294
8295       if (vam->async_errors > 0)
8296         {
8297           errmsg ("%d asynchronous errors", vam->async_errors);
8298           vam->retval = -98;
8299         }
8300       vam->async_errors = 0;
8301       after = vat_time_now (vam);
8302
8303       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8304       if (j > 0)
8305         count = j;
8306
8307       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8308              count, after - before, count / (after - before));
8309     }
8310   else
8311     {
8312       int ret;
8313
8314       /* Wait for a reply... */
8315       W (ret);
8316       return ret;
8317     }
8318
8319   /* Return the good/bad news */
8320   return (vam->retval);
8321 }
8322
8323 static int
8324 api_ip_mroute_add_del (vat_main_t * vam)
8325 {
8326   unformat_input_t *i = vam->input;
8327   u8 path_set = 0, prefix_set = 0, is_add = 1;
8328   vl_api_ip_mroute_add_del_t *mp;
8329   mfib_entry_flags_t eflags = 0;
8330   vl_api_mfib_path_t path;
8331   vl_api_mprefix_t pfx = { };
8332   u32 vrf_id = 0;
8333   int ret;
8334
8335   /* Parse args required to build the message */
8336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8337     {
8338       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8339         {
8340           prefix_set = 1;
8341           pfx.grp_address_length = htons (pfx.grp_address_length);
8342         }
8343       else if (unformat (i, "del"))
8344         is_add = 0;
8345       else if (unformat (i, "add"))
8346         is_add = 1;
8347       else if (unformat (i, "vrf %d", &vrf_id))
8348         ;
8349       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8350         path.itf_flags = htonl (path.itf_flags);
8351       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8352         ;
8353       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8354         path_set = 1;
8355       else
8356         {
8357           clib_warning ("parse error '%U'", format_unformat_error, i);
8358           return -99;
8359         }
8360     }
8361
8362   if (prefix_set == 0)
8363     {
8364       errmsg ("missing addresses\n");
8365       return -99;
8366     }
8367   if (path_set == 0)
8368     {
8369       errmsg ("missing path\n");
8370       return -99;
8371     }
8372
8373   /* Construct the API message */
8374   M (IP_MROUTE_ADD_DEL, mp);
8375
8376   mp->is_add = is_add;
8377   mp->is_multipath = 1;
8378
8379   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8380   mp->route.table_id = htonl (vrf_id);
8381   mp->route.n_paths = 1;
8382   mp->route.entry_flags = htonl (eflags);
8383
8384   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8385
8386   /* send it... */
8387   S (mp);
8388   /* Wait for a reply... */
8389   W (ret);
8390   return ret;
8391 }
8392
8393 static int
8394 api_mpls_table_add_del (vat_main_t * vam)
8395 {
8396   unformat_input_t *i = vam->input;
8397   vl_api_mpls_table_add_del_t *mp;
8398   u32 table_id = ~0;
8399   u8 is_add = 1;
8400   int ret = 0;
8401
8402   /* Parse args required to build the message */
8403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8404     {
8405       if (unformat (i, "table %d", &table_id))
8406         ;
8407       else if (unformat (i, "del"))
8408         is_add = 0;
8409       else if (unformat (i, "add"))
8410         is_add = 1;
8411       else
8412         {
8413           clib_warning ("parse error '%U'", format_unformat_error, i);
8414           return -99;
8415         }
8416     }
8417
8418   if (~0 == table_id)
8419     {
8420       errmsg ("missing table-ID");
8421       return -99;
8422     }
8423
8424   /* Construct the API message */
8425   M (MPLS_TABLE_ADD_DEL, mp);
8426
8427   mp->mt_table.mt_table_id = ntohl (table_id);
8428   mp->mt_is_add = is_add;
8429
8430   /* send it... */
8431   S (mp);
8432
8433   /* Wait for a reply... */
8434   W (ret);
8435
8436   return ret;
8437 }
8438
8439 static int
8440 api_mpls_route_add_del (vat_main_t * vam)
8441 {
8442   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8443   mpls_label_t local_label = MPLS_LABEL_INVALID;
8444   unformat_input_t *i = vam->input;
8445   vl_api_mpls_route_add_del_t *mp;
8446   vl_api_fib_path_t paths[8];
8447   int count = 1, j;
8448   f64 before = 0;
8449
8450   /* Parse args required to build the message */
8451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (i, "%d", &local_label))
8454         ;
8455       else if (unformat (i, "eos"))
8456         is_eos = 1;
8457       else if (unformat (i, "non-eos"))
8458         is_eos = 0;
8459       else if (unformat (i, "del"))
8460         is_add = 0;
8461       else if (unformat (i, "add"))
8462         is_add = 1;
8463       else if (unformat (i, "multipath"))
8464         is_multipath = 1;
8465       else if (unformat (i, "count %d", &count))
8466         ;
8467       else
8468         if (unformat
8469             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8470         {
8471           path_count++;
8472           if (8 == path_count)
8473             {
8474               errmsg ("max 8 paths");
8475               return -99;
8476             }
8477         }
8478       else
8479         {
8480           clib_warning ("parse error '%U'", format_unformat_error, i);
8481           return -99;
8482         }
8483     }
8484
8485   if (!path_count)
8486     {
8487       errmsg ("specify a path; via ...");
8488       return -99;
8489     }
8490
8491   if (MPLS_LABEL_INVALID == local_label)
8492     {
8493       errmsg ("missing label");
8494       return -99;
8495     }
8496
8497   if (count > 1)
8498     {
8499       /* Turn on async mode */
8500       vam->async_mode = 1;
8501       vam->async_errors = 0;
8502       before = vat_time_now (vam);
8503     }
8504
8505   for (j = 0; j < count; j++)
8506     {
8507       /* Construct the API message */
8508       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8509
8510       mp->mr_is_add = is_add;
8511       mp->mr_is_multipath = is_multipath;
8512
8513       mp->mr_route.mr_label = local_label;
8514       mp->mr_route.mr_eos = is_eos;
8515       mp->mr_route.mr_table_id = 0;
8516       mp->mr_route.mr_n_paths = path_count;
8517
8518       clib_memcpy (&mp->mr_route.mr_paths, paths,
8519                    sizeof (paths[0]) * path_count);
8520
8521       local_label++;
8522
8523       /* send it... */
8524       S (mp);
8525       /* If we receive SIGTERM, stop now... */
8526       if (vam->do_exit)
8527         break;
8528     }
8529
8530   /* When testing multiple add/del ops, use a control-ping to sync */
8531   if (count > 1)
8532     {
8533       vl_api_control_ping_t *mp_ping;
8534       f64 after;
8535       f64 timeout;
8536
8537       /* Shut off async mode */
8538       vam->async_mode = 0;
8539
8540       MPING (CONTROL_PING, mp_ping);
8541       S (mp_ping);
8542
8543       timeout = vat_time_now (vam) + 1.0;
8544       while (vat_time_now (vam) < timeout)
8545         if (vam->result_ready == 1)
8546           goto out;
8547       vam->retval = -99;
8548
8549     out:
8550       if (vam->retval == -99)
8551         errmsg ("timeout");
8552
8553       if (vam->async_errors > 0)
8554         {
8555           errmsg ("%d asynchronous errors", vam->async_errors);
8556           vam->retval = -98;
8557         }
8558       vam->async_errors = 0;
8559       after = vat_time_now (vam);
8560
8561       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8562       if (j > 0)
8563         count = j;
8564
8565       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8566              count, after - before, count / (after - before));
8567     }
8568   else
8569     {
8570       int ret;
8571
8572       /* Wait for a reply... */
8573       W (ret);
8574       return ret;
8575     }
8576
8577   /* Return the good/bad news */
8578   return (vam->retval);
8579   return (0);
8580 }
8581
8582 static int
8583 api_mpls_ip_bind_unbind (vat_main_t * vam)
8584 {
8585   unformat_input_t *i = vam->input;
8586   vl_api_mpls_ip_bind_unbind_t *mp;
8587   u32 ip_table_id = 0;
8588   u8 is_bind = 1;
8589   vl_api_prefix_t pfx;
8590   u8 prefix_set = 0;
8591   mpls_label_t local_label = MPLS_LABEL_INVALID;
8592   int ret;
8593
8594   /* Parse args required to build the message */
8595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8596     {
8597       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8598         prefix_set = 1;
8599       else if (unformat (i, "%d", &local_label))
8600         ;
8601       else if (unformat (i, "table-id %d", &ip_table_id))
8602         ;
8603       else if (unformat (i, "unbind"))
8604         is_bind = 0;
8605       else if (unformat (i, "bind"))
8606         is_bind = 1;
8607       else
8608         {
8609           clib_warning ("parse error '%U'", format_unformat_error, i);
8610           return -99;
8611         }
8612     }
8613
8614   if (!prefix_set)
8615     {
8616       errmsg ("IP prefix not set");
8617       return -99;
8618     }
8619
8620   if (MPLS_LABEL_INVALID == local_label)
8621     {
8622       errmsg ("missing label");
8623       return -99;
8624     }
8625
8626   /* Construct the API message */
8627   M (MPLS_IP_BIND_UNBIND, mp);
8628
8629   mp->mb_is_bind = is_bind;
8630   mp->mb_ip_table_id = ntohl (ip_table_id);
8631   mp->mb_mpls_table_id = 0;
8632   mp->mb_label = ntohl (local_label);
8633   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8634
8635   /* send it... */
8636   S (mp);
8637
8638   /* Wait for a reply... */
8639   W (ret);
8640   return ret;
8641   return (0);
8642 }
8643
8644 static int
8645 api_sr_mpls_policy_add (vat_main_t * vam)
8646 {
8647   unformat_input_t *i = vam->input;
8648   vl_api_sr_mpls_policy_add_t *mp;
8649   u32 bsid = 0;
8650   u32 weight = 1;
8651   u8 type = 0;
8652   u8 n_segments = 0;
8653   u32 sid;
8654   u32 *segments = NULL;
8655   int ret;
8656
8657   /* Parse args required to build the message */
8658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (i, "bsid %d", &bsid))
8661         ;
8662       else if (unformat (i, "weight %d", &weight))
8663         ;
8664       else if (unformat (i, "spray"))
8665         type = 1;
8666       else if (unformat (i, "next %d", &sid))
8667         {
8668           n_segments += 1;
8669           vec_add1 (segments, htonl (sid));
8670         }
8671       else
8672         {
8673           clib_warning ("parse error '%U'", format_unformat_error, i);
8674           return -99;
8675         }
8676     }
8677
8678   if (bsid == 0)
8679     {
8680       errmsg ("bsid not set");
8681       return -99;
8682     }
8683
8684   if (n_segments == 0)
8685     {
8686       errmsg ("no sid in segment stack");
8687       return -99;
8688     }
8689
8690   /* Construct the API message */
8691   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8692
8693   mp->bsid = htonl (bsid);
8694   mp->weight = htonl (weight);
8695   mp->type = type;
8696   mp->n_segments = n_segments;
8697   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8698   vec_free (segments);
8699
8700   /* send it... */
8701   S (mp);
8702
8703   /* Wait for a reply... */
8704   W (ret);
8705   return ret;
8706 }
8707
8708 static int
8709 api_sr_mpls_policy_del (vat_main_t * vam)
8710 {
8711   unformat_input_t *i = vam->input;
8712   vl_api_sr_mpls_policy_del_t *mp;
8713   u32 bsid = 0;
8714   int ret;
8715
8716   /* Parse args required to build the message */
8717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8718     {
8719       if (unformat (i, "bsid %d", &bsid))
8720         ;
8721       else
8722         {
8723           clib_warning ("parse error '%U'", format_unformat_error, i);
8724           return -99;
8725         }
8726     }
8727
8728   if (bsid == 0)
8729     {
8730       errmsg ("bsid not set");
8731       return -99;
8732     }
8733
8734   /* Construct the API message */
8735   M (SR_MPLS_POLICY_DEL, mp);
8736
8737   mp->bsid = htonl (bsid);
8738
8739   /* send it... */
8740   S (mp);
8741
8742   /* Wait for a reply... */
8743   W (ret);
8744   return ret;
8745 }
8746
8747 static int
8748 api_bier_table_add_del (vat_main_t * vam)
8749 {
8750   unformat_input_t *i = vam->input;
8751   vl_api_bier_table_add_del_t *mp;
8752   u8 is_add = 1;
8753   u32 set = 0, sub_domain = 0, hdr_len = 3;
8754   mpls_label_t local_label = MPLS_LABEL_INVALID;
8755   int ret;
8756
8757   /* Parse args required to build the message */
8758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8759     {
8760       if (unformat (i, "sub-domain %d", &sub_domain))
8761         ;
8762       else if (unformat (i, "set %d", &set))
8763         ;
8764       else if (unformat (i, "label %d", &local_label))
8765         ;
8766       else if (unformat (i, "hdr-len %d", &hdr_len))
8767         ;
8768       else if (unformat (i, "add"))
8769         is_add = 1;
8770       else if (unformat (i, "del"))
8771         is_add = 0;
8772       else
8773         {
8774           clib_warning ("parse error '%U'", format_unformat_error, i);
8775           return -99;
8776         }
8777     }
8778
8779   if (MPLS_LABEL_INVALID == local_label)
8780     {
8781       errmsg ("missing label\n");
8782       return -99;
8783     }
8784
8785   /* Construct the API message */
8786   M (BIER_TABLE_ADD_DEL, mp);
8787
8788   mp->bt_is_add = is_add;
8789   mp->bt_label = ntohl (local_label);
8790   mp->bt_tbl_id.bt_set = set;
8791   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8792   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8793
8794   /* send it... */
8795   S (mp);
8796
8797   /* Wait for a reply... */
8798   W (ret);
8799
8800   return (ret);
8801 }
8802
8803 static int
8804 api_bier_route_add_del (vat_main_t * vam)
8805 {
8806   unformat_input_t *i = vam->input;
8807   vl_api_bier_route_add_del_t *mp;
8808   u8 is_add = 1;
8809   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8810   ip4_address_t v4_next_hop_address;
8811   ip6_address_t v6_next_hop_address;
8812   u8 next_hop_set = 0;
8813   u8 next_hop_proto_is_ip4 = 1;
8814   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8815   int ret;
8816
8817   /* Parse args required to build the message */
8818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8819     {
8820       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8821         {
8822           next_hop_proto_is_ip4 = 1;
8823           next_hop_set = 1;
8824         }
8825       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8826         {
8827           next_hop_proto_is_ip4 = 0;
8828           next_hop_set = 1;
8829         }
8830       if (unformat (i, "sub-domain %d", &sub_domain))
8831         ;
8832       else if (unformat (i, "set %d", &set))
8833         ;
8834       else if (unformat (i, "hdr-len %d", &hdr_len))
8835         ;
8836       else if (unformat (i, "bp %d", &bp))
8837         ;
8838       else if (unformat (i, "add"))
8839         is_add = 1;
8840       else if (unformat (i, "del"))
8841         is_add = 0;
8842       else if (unformat (i, "out-label %d", &next_hop_out_label))
8843         ;
8844       else
8845         {
8846           clib_warning ("parse error '%U'", format_unformat_error, i);
8847           return -99;
8848         }
8849     }
8850
8851   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8852     {
8853       errmsg ("next hop / label set\n");
8854       return -99;
8855     }
8856   if (0 == bp)
8857     {
8858       errmsg ("bit=position not set\n");
8859       return -99;
8860     }
8861
8862   /* Construct the API message */
8863   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8864
8865   mp->br_is_add = is_add;
8866   mp->br_route.br_tbl_id.bt_set = set;
8867   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8868   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8869   mp->br_route.br_bp = ntohs (bp);
8870   mp->br_route.br_n_paths = 1;
8871   mp->br_route.br_paths[0].n_labels = 1;
8872   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8873   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8874                                     FIB_API_PATH_NH_PROTO_IP4 :
8875                                     FIB_API_PATH_NH_PROTO_IP6);
8876
8877   if (next_hop_proto_is_ip4)
8878     {
8879       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8880                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8881     }
8882   else
8883     {
8884       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8885                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8886     }
8887
8888   /* send it... */
8889   S (mp);
8890
8891   /* Wait for a reply... */
8892   W (ret);
8893
8894   return (ret);
8895 }
8896
8897 static int
8898 api_proxy_arp_add_del (vat_main_t * vam)
8899 {
8900   unformat_input_t *i = vam->input;
8901   vl_api_proxy_arp_add_del_t *mp;
8902   u32 vrf_id = 0;
8903   u8 is_add = 1;
8904   vl_api_ip4_address_t lo, hi;
8905   u8 range_set = 0;
8906   int ret;
8907
8908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8909     {
8910       if (unformat (i, "vrf %d", &vrf_id))
8911         ;
8912       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8913                          unformat_vl_api_ip4_address, &hi))
8914         range_set = 1;
8915       else if (unformat (i, "del"))
8916         is_add = 0;
8917       else
8918         {
8919           clib_warning ("parse error '%U'", format_unformat_error, i);
8920           return -99;
8921         }
8922     }
8923
8924   if (range_set == 0)
8925     {
8926       errmsg ("address range not set");
8927       return -99;
8928     }
8929
8930   M (PROXY_ARP_ADD_DEL, mp);
8931
8932   mp->proxy.table_id = ntohl (vrf_id);
8933   mp->is_add = is_add;
8934   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8935   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8936
8937   S (mp);
8938   W (ret);
8939   return ret;
8940 }
8941
8942 static int
8943 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8944 {
8945   unformat_input_t *i = vam->input;
8946   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8947   u32 sw_if_index;
8948   u8 enable = 1;
8949   u8 sw_if_index_set = 0;
8950   int ret;
8951
8952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8953     {
8954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8955         sw_if_index_set = 1;
8956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8957         sw_if_index_set = 1;
8958       else if (unformat (i, "enable"))
8959         enable = 1;
8960       else if (unformat (i, "disable"))
8961         enable = 0;
8962       else
8963         {
8964           clib_warning ("parse error '%U'", format_unformat_error, i);
8965           return -99;
8966         }
8967     }
8968
8969   if (sw_if_index_set == 0)
8970     {
8971       errmsg ("missing interface name or sw_if_index");
8972       return -99;
8973     }
8974
8975   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8976
8977   mp->sw_if_index = ntohl (sw_if_index);
8978   mp->enable_disable = enable;
8979
8980   S (mp);
8981   W (ret);
8982   return ret;
8983 }
8984
8985 static int
8986 api_mpls_tunnel_add_del (vat_main_t * vam)
8987 {
8988   unformat_input_t *i = vam->input;
8989   vl_api_mpls_tunnel_add_del_t *mp;
8990
8991   vl_api_fib_path_t paths[8];
8992   u32 sw_if_index = ~0;
8993   u8 path_count = 0;
8994   u8 l2_only = 0;
8995   u8 is_add = 1;
8996   int ret;
8997
8998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8999     {
9000       if (unformat (i, "add"))
9001         is_add = 1;
9002       else
9003         if (unformat
9004             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9005         is_add = 0;
9006       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9007         is_add = 0;
9008       else if (unformat (i, "l2-only"))
9009         l2_only = 1;
9010       else
9011         if (unformat
9012             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9013         {
9014           path_count++;
9015           if (8 == path_count)
9016             {
9017               errmsg ("max 8 paths");
9018               return -99;
9019             }
9020         }
9021       else
9022         {
9023           clib_warning ("parse error '%U'", format_unformat_error, i);
9024           return -99;
9025         }
9026     }
9027
9028   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9029
9030   mp->mt_is_add = is_add;
9031   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9032   mp->mt_tunnel.mt_l2_only = l2_only;
9033   mp->mt_tunnel.mt_is_multicast = 0;
9034   mp->mt_tunnel.mt_n_paths = path_count;
9035
9036   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9037                sizeof (paths[0]) * path_count);
9038
9039   S (mp);
9040   W (ret);
9041   return ret;
9042 }
9043
9044 static int
9045 api_sw_interface_set_unnumbered (vat_main_t * vam)
9046 {
9047   unformat_input_t *i = vam->input;
9048   vl_api_sw_interface_set_unnumbered_t *mp;
9049   u32 sw_if_index;
9050   u32 unnum_sw_index = ~0;
9051   u8 is_add = 1;
9052   u8 sw_if_index_set = 0;
9053   int ret;
9054
9055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9056     {
9057       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9058         sw_if_index_set = 1;
9059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9060         sw_if_index_set = 1;
9061       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9062         ;
9063       else if (unformat (i, "del"))
9064         is_add = 0;
9065       else
9066         {
9067           clib_warning ("parse error '%U'", format_unformat_error, i);
9068           return -99;
9069         }
9070     }
9071
9072   if (sw_if_index_set == 0)
9073     {
9074       errmsg ("missing interface name or sw_if_index");
9075       return -99;
9076     }
9077
9078   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9079
9080   mp->sw_if_index = ntohl (sw_if_index);
9081   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9082   mp->is_add = is_add;
9083
9084   S (mp);
9085   W (ret);
9086   return ret;
9087 }
9088
9089 static int
9090 api_ip_neighbor_add_del (vat_main_t * vam)
9091 {
9092   vl_api_mac_address_t mac_address;
9093   unformat_input_t *i = vam->input;
9094   vl_api_ip_neighbor_add_del_t *mp;
9095   vl_api_address_t ip_address;
9096   u32 sw_if_index;
9097   u8 sw_if_index_set = 0;
9098   u8 is_add = 1;
9099   u8 mac_set = 0;
9100   u8 address_set = 0;
9101   int ret;
9102   ip_neighbor_flags_t flags;
9103
9104   flags = IP_NEIGHBOR_FLAG_NONE;
9105   clib_memset (&ip_address, 0, sizeof (ip_address));
9106   clib_memset (&mac_address, 0, sizeof (mac_address));
9107
9108   /* Parse args required to build the message */
9109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9110     {
9111       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9112         {
9113           mac_set = 1;
9114         }
9115       else if (unformat (i, "del"))
9116         is_add = 0;
9117       else
9118         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9119         sw_if_index_set = 1;
9120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9121         sw_if_index_set = 1;
9122       else if (unformat (i, "static"))
9123         flags |= IP_NEIGHBOR_FLAG_STATIC;
9124       else if (unformat (i, "no-fib-entry"))
9125         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9126       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9127         address_set = 1;
9128       else
9129         {
9130           clib_warning ("parse error '%U'", format_unformat_error, i);
9131           return -99;
9132         }
9133     }
9134
9135   if (sw_if_index_set == 0)
9136     {
9137       errmsg ("missing interface name or sw_if_index");
9138       return -99;
9139     }
9140   if (!address_set)
9141     {
9142       errmsg ("no address set");
9143       return -99;
9144     }
9145
9146   /* Construct the API message */
9147   M (IP_NEIGHBOR_ADD_DEL, mp);
9148
9149   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9150   mp->is_add = is_add;
9151   mp->neighbor.flags = htonl (flags);
9152   if (mac_set)
9153     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9154                  sizeof (mac_address));
9155   if (address_set)
9156     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9157
9158   /* send it... */
9159   S (mp);
9160
9161   /* Wait for a reply, return good/bad news  */
9162   W (ret);
9163   return ret;
9164 }
9165
9166 static int
9167 api_create_vlan_subif (vat_main_t * vam)
9168 {
9169   unformat_input_t *i = vam->input;
9170   vl_api_create_vlan_subif_t *mp;
9171   u32 sw_if_index;
9172   u8 sw_if_index_set = 0;
9173   u32 vlan_id;
9174   u8 vlan_id_set = 0;
9175   int ret;
9176
9177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9178     {
9179       if (unformat (i, "sw_if_index %d", &sw_if_index))
9180         sw_if_index_set = 1;
9181       else
9182         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9183         sw_if_index_set = 1;
9184       else if (unformat (i, "vlan %d", &vlan_id))
9185         vlan_id_set = 1;
9186       else
9187         {
9188           clib_warning ("parse error '%U'", format_unformat_error, i);
9189           return -99;
9190         }
9191     }
9192
9193   if (sw_if_index_set == 0)
9194     {
9195       errmsg ("missing interface name or sw_if_index");
9196       return -99;
9197     }
9198
9199   if (vlan_id_set == 0)
9200     {
9201       errmsg ("missing vlan_id");
9202       return -99;
9203     }
9204   M (CREATE_VLAN_SUBIF, mp);
9205
9206   mp->sw_if_index = ntohl (sw_if_index);
9207   mp->vlan_id = ntohl (vlan_id);
9208
9209   S (mp);
9210   W (ret);
9211   return ret;
9212 }
9213
9214 #define foreach_create_subif_bit                \
9215 _(no_tags)                                      \
9216 _(one_tag)                                      \
9217 _(two_tags)                                     \
9218 _(dot1ad)                                       \
9219 _(exact_match)                                  \
9220 _(default_sub)                                  \
9221 _(outer_vlan_id_any)                            \
9222 _(inner_vlan_id_any)
9223
9224 static int
9225 api_create_subif (vat_main_t * vam)
9226 {
9227   unformat_input_t *i = vam->input;
9228   vl_api_create_subif_t *mp;
9229   u32 sw_if_index;
9230   u8 sw_if_index_set = 0;
9231   u32 sub_id;
9232   u8 sub_id_set = 0;
9233   u32 no_tags = 0;
9234   u32 one_tag = 0;
9235   u32 two_tags = 0;
9236   u32 dot1ad = 0;
9237   u32 exact_match = 0;
9238   u32 default_sub = 0;
9239   u32 outer_vlan_id_any = 0;
9240   u32 inner_vlan_id_any = 0;
9241   u32 tmp;
9242   u16 outer_vlan_id = 0;
9243   u16 inner_vlan_id = 0;
9244   int ret;
9245
9246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9247     {
9248       if (unformat (i, "sw_if_index %d", &sw_if_index))
9249         sw_if_index_set = 1;
9250       else
9251         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9252         sw_if_index_set = 1;
9253       else if (unformat (i, "sub_id %d", &sub_id))
9254         sub_id_set = 1;
9255       else if (unformat (i, "outer_vlan_id %d", &tmp))
9256         outer_vlan_id = tmp;
9257       else if (unformat (i, "inner_vlan_id %d", &tmp))
9258         inner_vlan_id = tmp;
9259
9260 #define _(a) else if (unformat (i, #a)) a = 1 ;
9261       foreach_create_subif_bit
9262 #undef _
9263         else
9264         {
9265           clib_warning ("parse error '%U'", format_unformat_error, i);
9266           return -99;
9267         }
9268     }
9269
9270   if (sw_if_index_set == 0)
9271     {
9272       errmsg ("missing interface name or sw_if_index");
9273       return -99;
9274     }
9275
9276   if (sub_id_set == 0)
9277     {
9278       errmsg ("missing sub_id");
9279       return -99;
9280     }
9281   M (CREATE_SUBIF, mp);
9282
9283   mp->sw_if_index = ntohl (sw_if_index);
9284   mp->sub_id = ntohl (sub_id);
9285
9286 #define _(a) mp->a = a;
9287   foreach_create_subif_bit;
9288 #undef _
9289
9290   mp->outer_vlan_id = ntohs (outer_vlan_id);
9291   mp->inner_vlan_id = ntohs (inner_vlan_id);
9292
9293   S (mp);
9294   W (ret);
9295   return ret;
9296 }
9297
9298 static int
9299 api_reset_fib (vat_main_t * vam)
9300 {
9301   unformat_input_t *i = vam->input;
9302   vl_api_reset_fib_t *mp;
9303   u32 vrf_id = 0;
9304   u8 is_ipv6 = 0;
9305   u8 vrf_id_set = 0;
9306
9307   int ret;
9308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9309     {
9310       if (unformat (i, "vrf %d", &vrf_id))
9311         vrf_id_set = 1;
9312       else if (unformat (i, "ipv6"))
9313         is_ipv6 = 1;
9314       else
9315         {
9316           clib_warning ("parse error '%U'", format_unformat_error, i);
9317           return -99;
9318         }
9319     }
9320
9321   if (vrf_id_set == 0)
9322     {
9323       errmsg ("missing vrf id");
9324       return -99;
9325     }
9326
9327   M (RESET_FIB, mp);
9328
9329   mp->vrf_id = ntohl (vrf_id);
9330   mp->is_ipv6 = is_ipv6;
9331
9332   S (mp);
9333   W (ret);
9334   return ret;
9335 }
9336
9337 static int
9338 api_dhcp_proxy_config (vat_main_t * vam)
9339 {
9340   unformat_input_t *i = vam->input;
9341   vl_api_dhcp_proxy_config_t *mp;
9342   u32 rx_vrf_id = 0;
9343   u32 server_vrf_id = 0;
9344   u8 is_add = 1;
9345   u8 v4_address_set = 0;
9346   u8 v6_address_set = 0;
9347   ip4_address_t v4address;
9348   ip6_address_t v6address;
9349   u8 v4_src_address_set = 0;
9350   u8 v6_src_address_set = 0;
9351   ip4_address_t v4srcaddress;
9352   ip6_address_t v6srcaddress;
9353   int ret;
9354
9355   /* Parse args required to build the message */
9356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9357     {
9358       if (unformat (i, "del"))
9359         is_add = 0;
9360       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9361         ;
9362       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9363         ;
9364       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9365         v4_address_set = 1;
9366       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9367         v6_address_set = 1;
9368       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9369         v4_src_address_set = 1;
9370       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9371         v6_src_address_set = 1;
9372       else
9373         break;
9374     }
9375
9376   if (v4_address_set && v6_address_set)
9377     {
9378       errmsg ("both v4 and v6 server addresses set");
9379       return -99;
9380     }
9381   if (!v4_address_set && !v6_address_set)
9382     {
9383       errmsg ("no server addresses set");
9384       return -99;
9385     }
9386
9387   if (v4_src_address_set && v6_src_address_set)
9388     {
9389       errmsg ("both v4 and v6  src addresses set");
9390       return -99;
9391     }
9392   if (!v4_src_address_set && !v6_src_address_set)
9393     {
9394       errmsg ("no src addresses set");
9395       return -99;
9396     }
9397
9398   if (!(v4_src_address_set && v4_address_set) &&
9399       !(v6_src_address_set && v6_address_set))
9400     {
9401       errmsg ("no matching server and src addresses set");
9402       return -99;
9403     }
9404
9405   /* Construct the API message */
9406   M (DHCP_PROXY_CONFIG, mp);
9407
9408   mp->is_add = is_add;
9409   mp->rx_vrf_id = ntohl (rx_vrf_id);
9410   mp->server_vrf_id = ntohl (server_vrf_id);
9411   if (v6_address_set)
9412     {
9413       mp->is_ipv6 = 1;
9414       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9415       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9416     }
9417   else
9418     {
9419       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9420       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9421     }
9422
9423   /* send it... */
9424   S (mp);
9425
9426   /* Wait for a reply, return good/bad news  */
9427   W (ret);
9428   return ret;
9429 }
9430
9431 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9432 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9433
9434 static void
9435 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9436 {
9437   vat_main_t *vam = &vat_main;
9438   u32 i, count = mp->count;
9439   vl_api_dhcp_server_t *s;
9440
9441   if (mp->is_ipv6)
9442     print (vam->ofp,
9443            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9444            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9445            ntohl (mp->rx_vrf_id),
9446            format_ip6_address, mp->dhcp_src_address,
9447            mp->vss_type, mp->vss_vpn_ascii_id,
9448            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9449   else
9450     print (vam->ofp,
9451            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9452            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9453            ntohl (mp->rx_vrf_id),
9454            format_ip4_address, mp->dhcp_src_address,
9455            mp->vss_type, mp->vss_vpn_ascii_id,
9456            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9457
9458   for (i = 0; i < count; i++)
9459     {
9460       s = &mp->servers[i];
9461
9462       if (mp->is_ipv6)
9463         print (vam->ofp,
9464                " Server Table-ID %d, Server Address %U",
9465                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9466       else
9467         print (vam->ofp,
9468                " Server Table-ID %d, Server Address %U",
9469                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9470     }
9471 }
9472
9473 static void vl_api_dhcp_proxy_details_t_handler_json
9474   (vl_api_dhcp_proxy_details_t * mp)
9475 {
9476   vat_main_t *vam = &vat_main;
9477   vat_json_node_t *node = NULL;
9478   u32 i, count = mp->count;
9479   struct in_addr ip4;
9480   struct in6_addr ip6;
9481   vl_api_dhcp_server_t *s;
9482
9483   if (VAT_JSON_ARRAY != vam->json_tree.type)
9484     {
9485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9486       vat_json_init_array (&vam->json_tree);
9487     }
9488   node = vat_json_array_add (&vam->json_tree);
9489
9490   vat_json_init_object (node);
9491   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9492   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9493                              sizeof (mp->vss_type));
9494   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9495                                    mp->vss_vpn_ascii_id);
9496   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9497   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9498
9499   if (mp->is_ipv6)
9500     {
9501       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9502       vat_json_object_add_ip6 (node, "src_address", ip6);
9503     }
9504   else
9505     {
9506       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9507       vat_json_object_add_ip4 (node, "src_address", ip4);
9508     }
9509
9510   for (i = 0; i < count; i++)
9511     {
9512       s = &mp->servers[i];
9513
9514       vat_json_object_add_uint (node, "server-table-id",
9515                                 ntohl (s->server_vrf_id));
9516
9517       if (mp->is_ipv6)
9518         {
9519           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9520           vat_json_object_add_ip4 (node, "src_address", ip4);
9521         }
9522       else
9523         {
9524           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9525           vat_json_object_add_ip6 (node, "server_address", ip6);
9526         }
9527     }
9528 }
9529
9530 static int
9531 api_dhcp_proxy_dump (vat_main_t * vam)
9532 {
9533   unformat_input_t *i = vam->input;
9534   vl_api_control_ping_t *mp_ping;
9535   vl_api_dhcp_proxy_dump_t *mp;
9536   u8 is_ipv6 = 0;
9537   int ret;
9538
9539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9540     {
9541       if (unformat (i, "ipv6"))
9542         is_ipv6 = 1;
9543       else
9544         {
9545           clib_warning ("parse error '%U'", format_unformat_error, i);
9546           return -99;
9547         }
9548     }
9549
9550   M (DHCP_PROXY_DUMP, mp);
9551
9552   mp->is_ip6 = is_ipv6;
9553   S (mp);
9554
9555   /* Use a control ping for synchronization */
9556   MPING (CONTROL_PING, mp_ping);
9557   S (mp_ping);
9558
9559   W (ret);
9560   return ret;
9561 }
9562
9563 static int
9564 api_dhcp_proxy_set_vss (vat_main_t * vam)
9565 {
9566   unformat_input_t *i = vam->input;
9567   vl_api_dhcp_proxy_set_vss_t *mp;
9568   u8 is_ipv6 = 0;
9569   u8 is_add = 1;
9570   u32 tbl_id = ~0;
9571   u8 vss_type = VSS_TYPE_DEFAULT;
9572   u8 *vpn_ascii_id = 0;
9573   u32 oui = 0;
9574   u32 fib_id = 0;
9575   int ret;
9576
9577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9578     {
9579       if (unformat (i, "tbl_id %d", &tbl_id))
9580         ;
9581       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9582         vss_type = VSS_TYPE_ASCII;
9583       else if (unformat (i, "fib_id %d", &fib_id))
9584         vss_type = VSS_TYPE_VPN_ID;
9585       else if (unformat (i, "oui %d", &oui))
9586         vss_type = VSS_TYPE_VPN_ID;
9587       else if (unformat (i, "ipv6"))
9588         is_ipv6 = 1;
9589       else if (unformat (i, "del"))
9590         is_add = 0;
9591       else
9592         break;
9593     }
9594
9595   if (tbl_id == ~0)
9596     {
9597       errmsg ("missing tbl_id ");
9598       vec_free (vpn_ascii_id);
9599       return -99;
9600     }
9601
9602   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9603     {
9604       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9605       vec_free (vpn_ascii_id);
9606       return -99;
9607     }
9608
9609   M (DHCP_PROXY_SET_VSS, mp);
9610   mp->tbl_id = ntohl (tbl_id);
9611   mp->vss_type = vss_type;
9612   if (vpn_ascii_id)
9613     {
9614       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9615       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9616     }
9617   mp->vpn_index = ntohl (fib_id);
9618   mp->oui = ntohl (oui);
9619   mp->is_ipv6 = is_ipv6;
9620   mp->is_add = is_add;
9621
9622   S (mp);
9623   W (ret);
9624
9625   vec_free (vpn_ascii_id);
9626   return ret;
9627 }
9628
9629 static int
9630 api_dhcp_client_config (vat_main_t * vam)
9631 {
9632   unformat_input_t *i = vam->input;
9633   vl_api_dhcp_client_config_t *mp;
9634   u32 sw_if_index;
9635   u8 sw_if_index_set = 0;
9636   u8 is_add = 1;
9637   u8 *hostname = 0;
9638   u8 disable_event = 0;
9639   int ret;
9640
9641   /* Parse args required to build the message */
9642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9643     {
9644       if (unformat (i, "del"))
9645         is_add = 0;
9646       else
9647         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9648         sw_if_index_set = 1;
9649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9650         sw_if_index_set = 1;
9651       else if (unformat (i, "hostname %s", &hostname))
9652         ;
9653       else if (unformat (i, "disable_event"))
9654         disable_event = 1;
9655       else
9656         break;
9657     }
9658
9659   if (sw_if_index_set == 0)
9660     {
9661       errmsg ("missing interface name or sw_if_index");
9662       return -99;
9663     }
9664
9665   if (vec_len (hostname) > 63)
9666     {
9667       errmsg ("hostname too long");
9668     }
9669   vec_add1 (hostname, 0);
9670
9671   /* Construct the API message */
9672   M (DHCP_CLIENT_CONFIG, mp);
9673
9674   mp->is_add = is_add;
9675   mp->client.sw_if_index = htonl (sw_if_index);
9676   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9677   vec_free (hostname);
9678   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9679   mp->client.pid = htonl (getpid ());
9680
9681   /* send it... */
9682   S (mp);
9683
9684   /* Wait for a reply, return good/bad news  */
9685   W (ret);
9686   return ret;
9687 }
9688
9689 static int
9690 api_set_ip_flow_hash (vat_main_t * vam)
9691 {
9692   unformat_input_t *i = vam->input;
9693   vl_api_set_ip_flow_hash_t *mp;
9694   u32 vrf_id = 0;
9695   u8 is_ipv6 = 0;
9696   u8 vrf_id_set = 0;
9697   u8 src = 0;
9698   u8 dst = 0;
9699   u8 sport = 0;
9700   u8 dport = 0;
9701   u8 proto = 0;
9702   u8 reverse = 0;
9703   int ret;
9704
9705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9706     {
9707       if (unformat (i, "vrf %d", &vrf_id))
9708         vrf_id_set = 1;
9709       else if (unformat (i, "ipv6"))
9710         is_ipv6 = 1;
9711       else if (unformat (i, "src"))
9712         src = 1;
9713       else if (unformat (i, "dst"))
9714         dst = 1;
9715       else if (unformat (i, "sport"))
9716         sport = 1;
9717       else if (unformat (i, "dport"))
9718         dport = 1;
9719       else if (unformat (i, "proto"))
9720         proto = 1;
9721       else if (unformat (i, "reverse"))
9722         reverse = 1;
9723
9724       else
9725         {
9726           clib_warning ("parse error '%U'", format_unformat_error, i);
9727           return -99;
9728         }
9729     }
9730
9731   if (vrf_id_set == 0)
9732     {
9733       errmsg ("missing vrf id");
9734       return -99;
9735     }
9736
9737   M (SET_IP_FLOW_HASH, mp);
9738   mp->src = src;
9739   mp->dst = dst;
9740   mp->sport = sport;
9741   mp->dport = dport;
9742   mp->proto = proto;
9743   mp->reverse = reverse;
9744   mp->vrf_id = ntohl (vrf_id);
9745   mp->is_ipv6 = is_ipv6;
9746
9747   S (mp);
9748   W (ret);
9749   return ret;
9750 }
9751
9752 static int
9753 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9754 {
9755   unformat_input_t *i = vam->input;
9756   vl_api_sw_interface_ip6_enable_disable_t *mp;
9757   u32 sw_if_index;
9758   u8 sw_if_index_set = 0;
9759   u8 enable = 0;
9760   int ret;
9761
9762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9763     {
9764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9765         sw_if_index_set = 1;
9766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9767         sw_if_index_set = 1;
9768       else if (unformat (i, "enable"))
9769         enable = 1;
9770       else if (unformat (i, "disable"))
9771         enable = 0;
9772       else
9773         {
9774           clib_warning ("parse error '%U'", format_unformat_error, i);
9775           return -99;
9776         }
9777     }
9778
9779   if (sw_if_index_set == 0)
9780     {
9781       errmsg ("missing interface name or sw_if_index");
9782       return -99;
9783     }
9784
9785   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9786
9787   mp->sw_if_index = ntohl (sw_if_index);
9788   mp->enable = enable;
9789
9790   S (mp);
9791   W (ret);
9792   return ret;
9793 }
9794
9795 static int
9796 api_ip6nd_proxy_add_del (vat_main_t * vam)
9797 {
9798   unformat_input_t *i = vam->input;
9799   vl_api_ip6nd_proxy_add_del_t *mp;
9800   u32 sw_if_index = ~0;
9801   u8 v6_address_set = 0;
9802   vl_api_ip6_address_t v6address;
9803   u8 is_del = 0;
9804   int ret;
9805
9806   /* Parse args required to build the message */
9807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9808     {
9809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9810         ;
9811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9812         ;
9813       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9814         v6_address_set = 1;
9815       if (unformat (i, "del"))
9816         is_del = 1;
9817       else
9818         {
9819           clib_warning ("parse error '%U'", format_unformat_error, i);
9820           return -99;
9821         }
9822     }
9823
9824   if (sw_if_index == ~0)
9825     {
9826       errmsg ("missing interface name or sw_if_index");
9827       return -99;
9828     }
9829   if (!v6_address_set)
9830     {
9831       errmsg ("no address set");
9832       return -99;
9833     }
9834
9835   /* Construct the API message */
9836   M (IP6ND_PROXY_ADD_DEL, mp);
9837
9838   mp->is_del = is_del;
9839   mp->sw_if_index = ntohl (sw_if_index);
9840   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9841
9842   /* send it... */
9843   S (mp);
9844
9845   /* Wait for a reply, return good/bad news  */
9846   W (ret);
9847   return ret;
9848 }
9849
9850 static int
9851 api_ip6nd_proxy_dump (vat_main_t * vam)
9852 {
9853   vl_api_ip6nd_proxy_dump_t *mp;
9854   vl_api_control_ping_t *mp_ping;
9855   int ret;
9856
9857   M (IP6ND_PROXY_DUMP, mp);
9858
9859   S (mp);
9860
9861   /* Use a control ping for synchronization */
9862   MPING (CONTROL_PING, mp_ping);
9863   S (mp_ping);
9864
9865   W (ret);
9866   return ret;
9867 }
9868
9869 static void vl_api_ip6nd_proxy_details_t_handler
9870   (vl_api_ip6nd_proxy_details_t * mp)
9871 {
9872   vat_main_t *vam = &vat_main;
9873
9874   print (vam->ofp, "host %U sw_if_index %d",
9875          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9876 }
9877
9878 static void vl_api_ip6nd_proxy_details_t_handler_json
9879   (vl_api_ip6nd_proxy_details_t * mp)
9880 {
9881   vat_main_t *vam = &vat_main;
9882   struct in6_addr ip6;
9883   vat_json_node_t *node = NULL;
9884
9885   if (VAT_JSON_ARRAY != vam->json_tree.type)
9886     {
9887       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9888       vat_json_init_array (&vam->json_tree);
9889     }
9890   node = vat_json_array_add (&vam->json_tree);
9891
9892   vat_json_init_object (node);
9893   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9894
9895   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9896   vat_json_object_add_ip6 (node, "host", ip6);
9897 }
9898
9899 static int
9900 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9901 {
9902   unformat_input_t *i = vam->input;
9903   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9904   u32 sw_if_index;
9905   u8 sw_if_index_set = 0;
9906   u8 v6_address_set = 0;
9907   vl_api_prefix_t pfx;
9908   u8 use_default = 0;
9909   u8 no_advertise = 0;
9910   u8 off_link = 0;
9911   u8 no_autoconfig = 0;
9912   u8 no_onlink = 0;
9913   u8 is_no = 0;
9914   u32 val_lifetime = 0;
9915   u32 pref_lifetime = 0;
9916   int ret;
9917
9918   /* Parse args required to build the message */
9919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9920     {
9921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9922         sw_if_index_set = 1;
9923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9924         sw_if_index_set = 1;
9925       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9926         v6_address_set = 1;
9927       else if (unformat (i, "val_life %d", &val_lifetime))
9928         ;
9929       else if (unformat (i, "pref_life %d", &pref_lifetime))
9930         ;
9931       else if (unformat (i, "def"))
9932         use_default = 1;
9933       else if (unformat (i, "noadv"))
9934         no_advertise = 1;
9935       else if (unformat (i, "offl"))
9936         off_link = 1;
9937       else if (unformat (i, "noauto"))
9938         no_autoconfig = 1;
9939       else if (unformat (i, "nolink"))
9940         no_onlink = 1;
9941       else if (unformat (i, "isno"))
9942         is_no = 1;
9943       else
9944         {
9945           clib_warning ("parse error '%U'", format_unformat_error, i);
9946           return -99;
9947         }
9948     }
9949
9950   if (sw_if_index_set == 0)
9951     {
9952       errmsg ("missing interface name or sw_if_index");
9953       return -99;
9954     }
9955   if (!v6_address_set)
9956     {
9957       errmsg ("no address set");
9958       return -99;
9959     }
9960
9961   /* Construct the API message */
9962   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9963
9964   mp->sw_if_index = ntohl (sw_if_index);
9965   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9966   mp->use_default = use_default;
9967   mp->no_advertise = no_advertise;
9968   mp->off_link = off_link;
9969   mp->no_autoconfig = no_autoconfig;
9970   mp->no_onlink = no_onlink;
9971   mp->is_no = is_no;
9972   mp->val_lifetime = ntohl (val_lifetime);
9973   mp->pref_lifetime = ntohl (pref_lifetime);
9974
9975   /* send it... */
9976   S (mp);
9977
9978   /* Wait for a reply, return good/bad news  */
9979   W (ret);
9980   return ret;
9981 }
9982
9983 static int
9984 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9985 {
9986   unformat_input_t *i = vam->input;
9987   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9988   u32 sw_if_index;
9989   u8 sw_if_index_set = 0;
9990   u8 suppress = 0;
9991   u8 managed = 0;
9992   u8 other = 0;
9993   u8 ll_option = 0;
9994   u8 send_unicast = 0;
9995   u8 cease = 0;
9996   u8 is_no = 0;
9997   u8 default_router = 0;
9998   u32 max_interval = 0;
9999   u32 min_interval = 0;
10000   u32 lifetime = 0;
10001   u32 initial_count = 0;
10002   u32 initial_interval = 0;
10003   int ret;
10004
10005
10006   /* Parse args required to build the message */
10007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10008     {
10009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10010         sw_if_index_set = 1;
10011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10012         sw_if_index_set = 1;
10013       else if (unformat (i, "maxint %d", &max_interval))
10014         ;
10015       else if (unformat (i, "minint %d", &min_interval))
10016         ;
10017       else if (unformat (i, "life %d", &lifetime))
10018         ;
10019       else if (unformat (i, "count %d", &initial_count))
10020         ;
10021       else if (unformat (i, "interval %d", &initial_interval))
10022         ;
10023       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10024         suppress = 1;
10025       else if (unformat (i, "managed"))
10026         managed = 1;
10027       else if (unformat (i, "other"))
10028         other = 1;
10029       else if (unformat (i, "ll"))
10030         ll_option = 1;
10031       else if (unformat (i, "send"))
10032         send_unicast = 1;
10033       else if (unformat (i, "cease"))
10034         cease = 1;
10035       else if (unformat (i, "isno"))
10036         is_no = 1;
10037       else if (unformat (i, "def"))
10038         default_router = 1;
10039       else
10040         {
10041           clib_warning ("parse error '%U'", format_unformat_error, i);
10042           return -99;
10043         }
10044     }
10045
10046   if (sw_if_index_set == 0)
10047     {
10048       errmsg ("missing interface name or sw_if_index");
10049       return -99;
10050     }
10051
10052   /* Construct the API message */
10053   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10054
10055   mp->sw_if_index = ntohl (sw_if_index);
10056   mp->max_interval = ntohl (max_interval);
10057   mp->min_interval = ntohl (min_interval);
10058   mp->lifetime = ntohl (lifetime);
10059   mp->initial_count = ntohl (initial_count);
10060   mp->initial_interval = ntohl (initial_interval);
10061   mp->suppress = suppress;
10062   mp->managed = managed;
10063   mp->other = other;
10064   mp->ll_option = ll_option;
10065   mp->send_unicast = send_unicast;
10066   mp->cease = cease;
10067   mp->is_no = is_no;
10068   mp->default_router = default_router;
10069
10070   /* send it... */
10071   S (mp);
10072
10073   /* Wait for a reply, return good/bad news  */
10074   W (ret);
10075   return ret;
10076 }
10077
10078 static int
10079 api_set_arp_neighbor_limit (vat_main_t * vam)
10080 {
10081   unformat_input_t *i = vam->input;
10082   vl_api_set_arp_neighbor_limit_t *mp;
10083   u32 arp_nbr_limit;
10084   u8 limit_set = 0;
10085   u8 is_ipv6 = 0;
10086   int ret;
10087
10088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10089     {
10090       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10091         limit_set = 1;
10092       else if (unformat (i, "ipv6"))
10093         is_ipv6 = 1;
10094       else
10095         {
10096           clib_warning ("parse error '%U'", format_unformat_error, i);
10097           return -99;
10098         }
10099     }
10100
10101   if (limit_set == 0)
10102     {
10103       errmsg ("missing limit value");
10104       return -99;
10105     }
10106
10107   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10108
10109   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10110   mp->is_ipv6 = is_ipv6;
10111
10112   S (mp);
10113   W (ret);
10114   return ret;
10115 }
10116
10117 static int
10118 api_l2_patch_add_del (vat_main_t * vam)
10119 {
10120   unformat_input_t *i = vam->input;
10121   vl_api_l2_patch_add_del_t *mp;
10122   u32 rx_sw_if_index;
10123   u8 rx_sw_if_index_set = 0;
10124   u32 tx_sw_if_index;
10125   u8 tx_sw_if_index_set = 0;
10126   u8 is_add = 1;
10127   int ret;
10128
10129   /* Parse args required to build the message */
10130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10131     {
10132       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10133         rx_sw_if_index_set = 1;
10134       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10135         tx_sw_if_index_set = 1;
10136       else if (unformat (i, "rx"))
10137         {
10138           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10139             {
10140               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10141                             &rx_sw_if_index))
10142                 rx_sw_if_index_set = 1;
10143             }
10144           else
10145             break;
10146         }
10147       else if (unformat (i, "tx"))
10148         {
10149           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10150             {
10151               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10152                             &tx_sw_if_index))
10153                 tx_sw_if_index_set = 1;
10154             }
10155           else
10156             break;
10157         }
10158       else if (unformat (i, "del"))
10159         is_add = 0;
10160       else
10161         break;
10162     }
10163
10164   if (rx_sw_if_index_set == 0)
10165     {
10166       errmsg ("missing rx interface name or rx_sw_if_index");
10167       return -99;
10168     }
10169
10170   if (tx_sw_if_index_set == 0)
10171     {
10172       errmsg ("missing tx interface name or tx_sw_if_index");
10173       return -99;
10174     }
10175
10176   M (L2_PATCH_ADD_DEL, mp);
10177
10178   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10179   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10180   mp->is_add = is_add;
10181
10182   S (mp);
10183   W (ret);
10184   return ret;
10185 }
10186
10187 u8 is_del;
10188 u8 localsid_addr[16];
10189 u8 end_psp;
10190 u8 behavior;
10191 u32 sw_if_index;
10192 u32 vlan_index;
10193 u32 fib_table;
10194 u8 nh_addr[16];
10195
10196 static int
10197 api_sr_localsid_add_del (vat_main_t * vam)
10198 {
10199   unformat_input_t *i = vam->input;
10200   vl_api_sr_localsid_add_del_t *mp;
10201
10202   u8 is_del;
10203   ip6_address_t localsid;
10204   u8 end_psp = 0;
10205   u8 behavior = ~0;
10206   u32 sw_if_index;
10207   u32 fib_table = ~(u32) 0;
10208   ip6_address_t nh_addr6;
10209   ip4_address_t nh_addr4;
10210   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10211   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10212
10213   bool nexthop_set = 0;
10214
10215   int ret;
10216
10217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10218     {
10219       if (unformat (i, "del"))
10220         is_del = 1;
10221       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10222       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10223         nexthop_set = 1;
10224       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10225         nexthop_set = 1;
10226       else if (unformat (i, "behavior %u", &behavior));
10227       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10228       else if (unformat (i, "fib-table %u", &fib_table));
10229       else if (unformat (i, "end.psp %u", &behavior));
10230       else
10231         break;
10232     }
10233
10234   M (SR_LOCALSID_ADD_DEL, mp);
10235
10236   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10237   if (nexthop_set)
10238     {
10239       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10240       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10241     }
10242   mp->behavior = behavior;
10243   mp->sw_if_index = ntohl (sw_if_index);
10244   mp->fib_table = ntohl (fib_table);
10245   mp->end_psp = end_psp;
10246   mp->is_del = is_del;
10247
10248   S (mp);
10249   W (ret);
10250   return ret;
10251 }
10252
10253 static int
10254 api_ioam_enable (vat_main_t * vam)
10255 {
10256   unformat_input_t *input = vam->input;
10257   vl_api_ioam_enable_t *mp;
10258   u32 id = 0;
10259   int has_trace_option = 0;
10260   int has_pot_option = 0;
10261   int has_seqno_option = 0;
10262   int has_analyse_option = 0;
10263   int ret;
10264
10265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10266     {
10267       if (unformat (input, "trace"))
10268         has_trace_option = 1;
10269       else if (unformat (input, "pot"))
10270         has_pot_option = 1;
10271       else if (unformat (input, "seqno"))
10272         has_seqno_option = 1;
10273       else if (unformat (input, "analyse"))
10274         has_analyse_option = 1;
10275       else
10276         break;
10277     }
10278   M (IOAM_ENABLE, mp);
10279   mp->id = htons (id);
10280   mp->seqno = has_seqno_option;
10281   mp->analyse = has_analyse_option;
10282   mp->pot_enable = has_pot_option;
10283   mp->trace_enable = has_trace_option;
10284
10285   S (mp);
10286   W (ret);
10287   return ret;
10288 }
10289
10290
10291 static int
10292 api_ioam_disable (vat_main_t * vam)
10293 {
10294   vl_api_ioam_disable_t *mp;
10295   int ret;
10296
10297   M (IOAM_DISABLE, mp);
10298   S (mp);
10299   W (ret);
10300   return ret;
10301 }
10302
10303 #define foreach_tcp_proto_field                 \
10304 _(src_port)                                     \
10305 _(dst_port)
10306
10307 #define foreach_udp_proto_field                 \
10308 _(src_port)                                     \
10309 _(dst_port)
10310
10311 #define foreach_ip4_proto_field                 \
10312 _(src_address)                                  \
10313 _(dst_address)                                  \
10314 _(tos)                                          \
10315 _(length)                                       \
10316 _(fragment_id)                                  \
10317 _(ttl)                                          \
10318 _(protocol)                                     \
10319 _(checksum)
10320
10321 typedef struct
10322 {
10323   u16 src_port, dst_port;
10324 } tcpudp_header_t;
10325
10326 #if VPP_API_TEST_BUILTIN == 0
10327 uword
10328 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10329 {
10330   u8 **maskp = va_arg (*args, u8 **);
10331   u8 *mask = 0;
10332   u8 found_something = 0;
10333   tcp_header_t *tcp;
10334
10335 #define _(a) u8 a=0;
10336   foreach_tcp_proto_field;
10337 #undef _
10338
10339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10340     {
10341       if (0);
10342 #define _(a) else if (unformat (input, #a)) a=1;
10343       foreach_tcp_proto_field
10344 #undef _
10345         else
10346         break;
10347     }
10348
10349 #define _(a) found_something += a;
10350   foreach_tcp_proto_field;
10351 #undef _
10352
10353   if (found_something == 0)
10354     return 0;
10355
10356   vec_validate (mask, sizeof (*tcp) - 1);
10357
10358   tcp = (tcp_header_t *) mask;
10359
10360 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10361   foreach_tcp_proto_field;
10362 #undef _
10363
10364   *maskp = mask;
10365   return 1;
10366 }
10367
10368 uword
10369 unformat_udp_mask (unformat_input_t * input, va_list * args)
10370 {
10371   u8 **maskp = va_arg (*args, u8 **);
10372   u8 *mask = 0;
10373   u8 found_something = 0;
10374   udp_header_t *udp;
10375
10376 #define _(a) u8 a=0;
10377   foreach_udp_proto_field;
10378 #undef _
10379
10380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10381     {
10382       if (0);
10383 #define _(a) else if (unformat (input, #a)) a=1;
10384       foreach_udp_proto_field
10385 #undef _
10386         else
10387         break;
10388     }
10389
10390 #define _(a) found_something += a;
10391   foreach_udp_proto_field;
10392 #undef _
10393
10394   if (found_something == 0)
10395     return 0;
10396
10397   vec_validate (mask, sizeof (*udp) - 1);
10398
10399   udp = (udp_header_t *) mask;
10400
10401 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10402   foreach_udp_proto_field;
10403 #undef _
10404
10405   *maskp = mask;
10406   return 1;
10407 }
10408
10409 uword
10410 unformat_l4_mask (unformat_input_t * input, va_list * args)
10411 {
10412   u8 **maskp = va_arg (*args, u8 **);
10413   u16 src_port = 0, dst_port = 0;
10414   tcpudp_header_t *tcpudp;
10415
10416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10417     {
10418       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10419         return 1;
10420       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10421         return 1;
10422       else if (unformat (input, "src_port"))
10423         src_port = 0xFFFF;
10424       else if (unformat (input, "dst_port"))
10425         dst_port = 0xFFFF;
10426       else
10427         return 0;
10428     }
10429
10430   if (!src_port && !dst_port)
10431     return 0;
10432
10433   u8 *mask = 0;
10434   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10435
10436   tcpudp = (tcpudp_header_t *) mask;
10437   tcpudp->src_port = src_port;
10438   tcpudp->dst_port = dst_port;
10439
10440   *maskp = mask;
10441
10442   return 1;
10443 }
10444
10445 uword
10446 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10447 {
10448   u8 **maskp = va_arg (*args, u8 **);
10449   u8 *mask = 0;
10450   u8 found_something = 0;
10451   ip4_header_t *ip;
10452
10453 #define _(a) u8 a=0;
10454   foreach_ip4_proto_field;
10455 #undef _
10456   u8 version = 0;
10457   u8 hdr_length = 0;
10458
10459
10460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10461     {
10462       if (unformat (input, "version"))
10463         version = 1;
10464       else if (unformat (input, "hdr_length"))
10465         hdr_length = 1;
10466       else if (unformat (input, "src"))
10467         src_address = 1;
10468       else if (unformat (input, "dst"))
10469         dst_address = 1;
10470       else if (unformat (input, "proto"))
10471         protocol = 1;
10472
10473 #define _(a) else if (unformat (input, #a)) a=1;
10474       foreach_ip4_proto_field
10475 #undef _
10476         else
10477         break;
10478     }
10479
10480 #define _(a) found_something += a;
10481   foreach_ip4_proto_field;
10482 #undef _
10483
10484   if (found_something == 0)
10485     return 0;
10486
10487   vec_validate (mask, sizeof (*ip) - 1);
10488
10489   ip = (ip4_header_t *) mask;
10490
10491 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10492   foreach_ip4_proto_field;
10493 #undef _
10494
10495   ip->ip_version_and_header_length = 0;
10496
10497   if (version)
10498     ip->ip_version_and_header_length |= 0xF0;
10499
10500   if (hdr_length)
10501     ip->ip_version_and_header_length |= 0x0F;
10502
10503   *maskp = mask;
10504   return 1;
10505 }
10506
10507 #define foreach_ip6_proto_field                 \
10508 _(src_address)                                  \
10509 _(dst_address)                                  \
10510 _(payload_length)                               \
10511 _(hop_limit)                                    \
10512 _(protocol)
10513
10514 uword
10515 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10516 {
10517   u8 **maskp = va_arg (*args, u8 **);
10518   u8 *mask = 0;
10519   u8 found_something = 0;
10520   ip6_header_t *ip;
10521   u32 ip_version_traffic_class_and_flow_label;
10522
10523 #define _(a) u8 a=0;
10524   foreach_ip6_proto_field;
10525 #undef _
10526   u8 version = 0;
10527   u8 traffic_class = 0;
10528   u8 flow_label = 0;
10529
10530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10531     {
10532       if (unformat (input, "version"))
10533         version = 1;
10534       else if (unformat (input, "traffic-class"))
10535         traffic_class = 1;
10536       else if (unformat (input, "flow-label"))
10537         flow_label = 1;
10538       else if (unformat (input, "src"))
10539         src_address = 1;
10540       else if (unformat (input, "dst"))
10541         dst_address = 1;
10542       else if (unformat (input, "proto"))
10543         protocol = 1;
10544
10545 #define _(a) else if (unformat (input, #a)) a=1;
10546       foreach_ip6_proto_field
10547 #undef _
10548         else
10549         break;
10550     }
10551
10552 #define _(a) found_something += a;
10553   foreach_ip6_proto_field;
10554 #undef _
10555
10556   if (found_something == 0)
10557     return 0;
10558
10559   vec_validate (mask, sizeof (*ip) - 1);
10560
10561   ip = (ip6_header_t *) mask;
10562
10563 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10564   foreach_ip6_proto_field;
10565 #undef _
10566
10567   ip_version_traffic_class_and_flow_label = 0;
10568
10569   if (version)
10570     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10571
10572   if (traffic_class)
10573     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10574
10575   if (flow_label)
10576     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10577
10578   ip->ip_version_traffic_class_and_flow_label =
10579     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10580
10581   *maskp = mask;
10582   return 1;
10583 }
10584
10585 uword
10586 unformat_l3_mask (unformat_input_t * input, va_list * args)
10587 {
10588   u8 **maskp = va_arg (*args, u8 **);
10589
10590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10591     {
10592       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10593         return 1;
10594       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10595         return 1;
10596       else
10597         break;
10598     }
10599   return 0;
10600 }
10601
10602 uword
10603 unformat_l2_mask (unformat_input_t * input, va_list * args)
10604 {
10605   u8 **maskp = va_arg (*args, u8 **);
10606   u8 *mask = 0;
10607   u8 src = 0;
10608   u8 dst = 0;
10609   u8 proto = 0;
10610   u8 tag1 = 0;
10611   u8 tag2 = 0;
10612   u8 ignore_tag1 = 0;
10613   u8 ignore_tag2 = 0;
10614   u8 cos1 = 0;
10615   u8 cos2 = 0;
10616   u8 dot1q = 0;
10617   u8 dot1ad = 0;
10618   int len = 14;
10619
10620   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10621     {
10622       if (unformat (input, "src"))
10623         src = 1;
10624       else if (unformat (input, "dst"))
10625         dst = 1;
10626       else if (unformat (input, "proto"))
10627         proto = 1;
10628       else if (unformat (input, "tag1"))
10629         tag1 = 1;
10630       else if (unformat (input, "tag2"))
10631         tag2 = 1;
10632       else if (unformat (input, "ignore-tag1"))
10633         ignore_tag1 = 1;
10634       else if (unformat (input, "ignore-tag2"))
10635         ignore_tag2 = 1;
10636       else if (unformat (input, "cos1"))
10637         cos1 = 1;
10638       else if (unformat (input, "cos2"))
10639         cos2 = 1;
10640       else if (unformat (input, "dot1q"))
10641         dot1q = 1;
10642       else if (unformat (input, "dot1ad"))
10643         dot1ad = 1;
10644       else
10645         break;
10646     }
10647   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10648        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10649     return 0;
10650
10651   if (tag1 || ignore_tag1 || cos1 || dot1q)
10652     len = 18;
10653   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10654     len = 22;
10655
10656   vec_validate (mask, len - 1);
10657
10658   if (dst)
10659     clib_memset (mask, 0xff, 6);
10660
10661   if (src)
10662     clib_memset (mask + 6, 0xff, 6);
10663
10664   if (tag2 || dot1ad)
10665     {
10666       /* inner vlan tag */
10667       if (tag2)
10668         {
10669           mask[19] = 0xff;
10670           mask[18] = 0x0f;
10671         }
10672       if (cos2)
10673         mask[18] |= 0xe0;
10674       if (proto)
10675         mask[21] = mask[20] = 0xff;
10676       if (tag1)
10677         {
10678           mask[15] = 0xff;
10679           mask[14] = 0x0f;
10680         }
10681       if (cos1)
10682         mask[14] |= 0xe0;
10683       *maskp = mask;
10684       return 1;
10685     }
10686   if (tag1 | dot1q)
10687     {
10688       if (tag1)
10689         {
10690           mask[15] = 0xff;
10691           mask[14] = 0x0f;
10692         }
10693       if (cos1)
10694         mask[14] |= 0xe0;
10695       if (proto)
10696         mask[16] = mask[17] = 0xff;
10697
10698       *maskp = mask;
10699       return 1;
10700     }
10701   if (cos2)
10702     mask[18] |= 0xe0;
10703   if (cos1)
10704     mask[14] |= 0xe0;
10705   if (proto)
10706     mask[12] = mask[13] = 0xff;
10707
10708   *maskp = mask;
10709   return 1;
10710 }
10711
10712 uword
10713 unformat_classify_mask (unformat_input_t * input, va_list * args)
10714 {
10715   u8 **maskp = va_arg (*args, u8 **);
10716   u32 *skipp = va_arg (*args, u32 *);
10717   u32 *matchp = va_arg (*args, u32 *);
10718   u32 match;
10719   u8 *mask = 0;
10720   u8 *l2 = 0;
10721   u8 *l3 = 0;
10722   u8 *l4 = 0;
10723   int i;
10724
10725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10726     {
10727       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10728         ;
10729       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10730         ;
10731       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10732         ;
10733       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10734         ;
10735       else
10736         break;
10737     }
10738
10739   if (l4 && !l3)
10740     {
10741       vec_free (mask);
10742       vec_free (l2);
10743       vec_free (l4);
10744       return 0;
10745     }
10746
10747   if (mask || l2 || l3 || l4)
10748     {
10749       if (l2 || l3 || l4)
10750         {
10751           /* "With a free Ethernet header in every package" */
10752           if (l2 == 0)
10753             vec_validate (l2, 13);
10754           mask = l2;
10755           if (vec_len (l3))
10756             {
10757               vec_append (mask, l3);
10758               vec_free (l3);
10759             }
10760           if (vec_len (l4))
10761             {
10762               vec_append (mask, l4);
10763               vec_free (l4);
10764             }
10765         }
10766
10767       /* Scan forward looking for the first significant mask octet */
10768       for (i = 0; i < vec_len (mask); i++)
10769         if (mask[i])
10770           break;
10771
10772       /* compute (skip, match) params */
10773       *skipp = i / sizeof (u32x4);
10774       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10775
10776       /* Pad mask to an even multiple of the vector size */
10777       while (vec_len (mask) % sizeof (u32x4))
10778         vec_add1 (mask, 0);
10779
10780       match = vec_len (mask) / sizeof (u32x4);
10781
10782       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10783         {
10784           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10785           if (*tmp || *(tmp + 1))
10786             break;
10787           match--;
10788         }
10789       if (match == 0)
10790         clib_warning ("BUG: match 0");
10791
10792       _vec_len (mask) = match * sizeof (u32x4);
10793
10794       *matchp = match;
10795       *maskp = mask;
10796
10797       return 1;
10798     }
10799
10800   return 0;
10801 }
10802 #endif /* VPP_API_TEST_BUILTIN */
10803
10804 #define foreach_l2_next                         \
10805 _(drop, DROP)                                   \
10806 _(ethernet, ETHERNET_INPUT)                     \
10807 _(ip4, IP4_INPUT)                               \
10808 _(ip6, IP6_INPUT)
10809
10810 uword
10811 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10812 {
10813   u32 *miss_next_indexp = va_arg (*args, u32 *);
10814   u32 next_index = 0;
10815   u32 tmp;
10816
10817 #define _(n,N) \
10818   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10819   foreach_l2_next;
10820 #undef _
10821
10822   if (unformat (input, "%d", &tmp))
10823     {
10824       next_index = tmp;
10825       goto out;
10826     }
10827
10828   return 0;
10829
10830 out:
10831   *miss_next_indexp = next_index;
10832   return 1;
10833 }
10834
10835 #define foreach_ip_next                         \
10836 _(drop, DROP)                                   \
10837 _(local, LOCAL)                                 \
10838 _(rewrite, REWRITE)
10839
10840 uword
10841 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10842 {
10843   u32 *miss_next_indexp = va_arg (*args, u32 *);
10844   u32 next_index = 0;
10845   u32 tmp;
10846
10847 #define _(n,N) \
10848   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10849   foreach_ip_next;
10850 #undef _
10851
10852   if (unformat (input, "%d", &tmp))
10853     {
10854       next_index = tmp;
10855       goto out;
10856     }
10857
10858   return 0;
10859
10860 out:
10861   *miss_next_indexp = next_index;
10862   return 1;
10863 }
10864
10865 #define foreach_acl_next                        \
10866 _(deny, DENY)
10867
10868 uword
10869 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10870 {
10871   u32 *miss_next_indexp = va_arg (*args, u32 *);
10872   u32 next_index = 0;
10873   u32 tmp;
10874
10875 #define _(n,N) \
10876   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10877   foreach_acl_next;
10878 #undef _
10879
10880   if (unformat (input, "permit"))
10881     {
10882       next_index = ~0;
10883       goto out;
10884     }
10885   else if (unformat (input, "%d", &tmp))
10886     {
10887       next_index = tmp;
10888       goto out;
10889     }
10890
10891   return 0;
10892
10893 out:
10894   *miss_next_indexp = next_index;
10895   return 1;
10896 }
10897
10898 uword
10899 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10900 {
10901   u32 *r = va_arg (*args, u32 *);
10902
10903   if (unformat (input, "conform-color"))
10904     *r = POLICE_CONFORM;
10905   else if (unformat (input, "exceed-color"))
10906     *r = POLICE_EXCEED;
10907   else
10908     return 0;
10909
10910   return 1;
10911 }
10912
10913 static int
10914 api_classify_add_del_table (vat_main_t * vam)
10915 {
10916   unformat_input_t *i = vam->input;
10917   vl_api_classify_add_del_table_t *mp;
10918
10919   u32 nbuckets = 2;
10920   u32 skip = ~0;
10921   u32 match = ~0;
10922   int is_add = 1;
10923   int del_chain = 0;
10924   u32 table_index = ~0;
10925   u32 next_table_index = ~0;
10926   u32 miss_next_index = ~0;
10927   u32 memory_size = 32 << 20;
10928   u8 *mask = 0;
10929   u32 current_data_flag = 0;
10930   int current_data_offset = 0;
10931   int ret;
10932
10933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10934     {
10935       if (unformat (i, "del"))
10936         is_add = 0;
10937       else if (unformat (i, "del-chain"))
10938         {
10939           is_add = 0;
10940           del_chain = 1;
10941         }
10942       else if (unformat (i, "buckets %d", &nbuckets))
10943         ;
10944       else if (unformat (i, "memory_size %d", &memory_size))
10945         ;
10946       else if (unformat (i, "skip %d", &skip))
10947         ;
10948       else if (unformat (i, "match %d", &match))
10949         ;
10950       else if (unformat (i, "table %d", &table_index))
10951         ;
10952       else if (unformat (i, "mask %U", unformat_classify_mask,
10953                          &mask, &skip, &match))
10954         ;
10955       else if (unformat (i, "next-table %d", &next_table_index))
10956         ;
10957       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10958                          &miss_next_index))
10959         ;
10960       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10961                          &miss_next_index))
10962         ;
10963       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10964                          &miss_next_index))
10965         ;
10966       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10967         ;
10968       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10969         ;
10970       else
10971         break;
10972     }
10973
10974   if (is_add && mask == 0)
10975     {
10976       errmsg ("Mask required");
10977       return -99;
10978     }
10979
10980   if (is_add && skip == ~0)
10981     {
10982       errmsg ("skip count required");
10983       return -99;
10984     }
10985
10986   if (is_add && match == ~0)
10987     {
10988       errmsg ("match count required");
10989       return -99;
10990     }
10991
10992   if (!is_add && table_index == ~0)
10993     {
10994       errmsg ("table index required for delete");
10995       return -99;
10996     }
10997
10998   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10999
11000   mp->is_add = is_add;
11001   mp->del_chain = del_chain;
11002   mp->table_index = ntohl (table_index);
11003   mp->nbuckets = ntohl (nbuckets);
11004   mp->memory_size = ntohl (memory_size);
11005   mp->skip_n_vectors = ntohl (skip);
11006   mp->match_n_vectors = ntohl (match);
11007   mp->next_table_index = ntohl (next_table_index);
11008   mp->miss_next_index = ntohl (miss_next_index);
11009   mp->current_data_flag = ntohl (current_data_flag);
11010   mp->current_data_offset = ntohl (current_data_offset);
11011   mp->mask_len = ntohl (vec_len (mask));
11012   clib_memcpy (mp->mask, mask, vec_len (mask));
11013
11014   vec_free (mask);
11015
11016   S (mp);
11017   W (ret);
11018   return ret;
11019 }
11020
11021 #if VPP_API_TEST_BUILTIN == 0
11022 uword
11023 unformat_l4_match (unformat_input_t * input, va_list * args)
11024 {
11025   u8 **matchp = va_arg (*args, u8 **);
11026
11027   u8 *proto_header = 0;
11028   int src_port = 0;
11029   int dst_port = 0;
11030
11031   tcpudp_header_t h;
11032
11033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11034     {
11035       if (unformat (input, "src_port %d", &src_port))
11036         ;
11037       else if (unformat (input, "dst_port %d", &dst_port))
11038         ;
11039       else
11040         return 0;
11041     }
11042
11043   h.src_port = clib_host_to_net_u16 (src_port);
11044   h.dst_port = clib_host_to_net_u16 (dst_port);
11045   vec_validate (proto_header, sizeof (h) - 1);
11046   memcpy (proto_header, &h, sizeof (h));
11047
11048   *matchp = proto_header;
11049
11050   return 1;
11051 }
11052
11053 uword
11054 unformat_ip4_match (unformat_input_t * input, va_list * args)
11055 {
11056   u8 **matchp = va_arg (*args, u8 **);
11057   u8 *match = 0;
11058   ip4_header_t *ip;
11059   int version = 0;
11060   u32 version_val;
11061   int hdr_length = 0;
11062   u32 hdr_length_val;
11063   int src = 0, dst = 0;
11064   ip4_address_t src_val, dst_val;
11065   int proto = 0;
11066   u32 proto_val;
11067   int tos = 0;
11068   u32 tos_val;
11069   int length = 0;
11070   u32 length_val;
11071   int fragment_id = 0;
11072   u32 fragment_id_val;
11073   int ttl = 0;
11074   int ttl_val;
11075   int checksum = 0;
11076   u32 checksum_val;
11077
11078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11079     {
11080       if (unformat (input, "version %d", &version_val))
11081         version = 1;
11082       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11083         hdr_length = 1;
11084       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11085         src = 1;
11086       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11087         dst = 1;
11088       else if (unformat (input, "proto %d", &proto_val))
11089         proto = 1;
11090       else if (unformat (input, "tos %d", &tos_val))
11091         tos = 1;
11092       else if (unformat (input, "length %d", &length_val))
11093         length = 1;
11094       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11095         fragment_id = 1;
11096       else if (unformat (input, "ttl %d", &ttl_val))
11097         ttl = 1;
11098       else if (unformat (input, "checksum %d", &checksum_val))
11099         checksum = 1;
11100       else
11101         break;
11102     }
11103
11104   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11105       + ttl + checksum == 0)
11106     return 0;
11107
11108   /*
11109    * Aligned because we use the real comparison functions
11110    */
11111   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11112
11113   ip = (ip4_header_t *) match;
11114
11115   /* These are realistically matched in practice */
11116   if (src)
11117     ip->src_address.as_u32 = src_val.as_u32;
11118
11119   if (dst)
11120     ip->dst_address.as_u32 = dst_val.as_u32;
11121
11122   if (proto)
11123     ip->protocol = proto_val;
11124
11125
11126   /* These are not, but they're included for completeness */
11127   if (version)
11128     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11129
11130   if (hdr_length)
11131     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11132
11133   if (tos)
11134     ip->tos = tos_val;
11135
11136   if (length)
11137     ip->length = clib_host_to_net_u16 (length_val);
11138
11139   if (ttl)
11140     ip->ttl = ttl_val;
11141
11142   if (checksum)
11143     ip->checksum = clib_host_to_net_u16 (checksum_val);
11144
11145   *matchp = match;
11146   return 1;
11147 }
11148
11149 uword
11150 unformat_ip6_match (unformat_input_t * input, va_list * args)
11151 {
11152   u8 **matchp = va_arg (*args, u8 **);
11153   u8 *match = 0;
11154   ip6_header_t *ip;
11155   int version = 0;
11156   u32 version_val;
11157   u8 traffic_class = 0;
11158   u32 traffic_class_val = 0;
11159   u8 flow_label = 0;
11160   u8 flow_label_val;
11161   int src = 0, dst = 0;
11162   ip6_address_t src_val, dst_val;
11163   int proto = 0;
11164   u32 proto_val;
11165   int payload_length = 0;
11166   u32 payload_length_val;
11167   int hop_limit = 0;
11168   int hop_limit_val;
11169   u32 ip_version_traffic_class_and_flow_label;
11170
11171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11172     {
11173       if (unformat (input, "version %d", &version_val))
11174         version = 1;
11175       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11176         traffic_class = 1;
11177       else if (unformat (input, "flow_label %d", &flow_label_val))
11178         flow_label = 1;
11179       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11180         src = 1;
11181       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11182         dst = 1;
11183       else if (unformat (input, "proto %d", &proto_val))
11184         proto = 1;
11185       else if (unformat (input, "payload_length %d", &payload_length_val))
11186         payload_length = 1;
11187       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11188         hop_limit = 1;
11189       else
11190         break;
11191     }
11192
11193   if (version + traffic_class + flow_label + src + dst + proto +
11194       payload_length + hop_limit == 0)
11195     return 0;
11196
11197   /*
11198    * Aligned because we use the real comparison functions
11199    */
11200   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11201
11202   ip = (ip6_header_t *) match;
11203
11204   if (src)
11205     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11206
11207   if (dst)
11208     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11209
11210   if (proto)
11211     ip->protocol = proto_val;
11212
11213   ip_version_traffic_class_and_flow_label = 0;
11214
11215   if (version)
11216     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11217
11218   if (traffic_class)
11219     ip_version_traffic_class_and_flow_label |=
11220       (traffic_class_val & 0xFF) << 20;
11221
11222   if (flow_label)
11223     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11224
11225   ip->ip_version_traffic_class_and_flow_label =
11226     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11227
11228   if (payload_length)
11229     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11230
11231   if (hop_limit)
11232     ip->hop_limit = hop_limit_val;
11233
11234   *matchp = match;
11235   return 1;
11236 }
11237
11238 uword
11239 unformat_l3_match (unformat_input_t * input, va_list * args)
11240 {
11241   u8 **matchp = va_arg (*args, u8 **);
11242
11243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11244     {
11245       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11246         return 1;
11247       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11248         return 1;
11249       else
11250         break;
11251     }
11252   return 0;
11253 }
11254
11255 uword
11256 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11257 {
11258   u8 *tagp = va_arg (*args, u8 *);
11259   u32 tag;
11260
11261   if (unformat (input, "%d", &tag))
11262     {
11263       tagp[0] = (tag >> 8) & 0x0F;
11264       tagp[1] = tag & 0xFF;
11265       return 1;
11266     }
11267
11268   return 0;
11269 }
11270
11271 uword
11272 unformat_l2_match (unformat_input_t * input, va_list * args)
11273 {
11274   u8 **matchp = va_arg (*args, u8 **);
11275   u8 *match = 0;
11276   u8 src = 0;
11277   u8 src_val[6];
11278   u8 dst = 0;
11279   u8 dst_val[6];
11280   u8 proto = 0;
11281   u16 proto_val;
11282   u8 tag1 = 0;
11283   u8 tag1_val[2];
11284   u8 tag2 = 0;
11285   u8 tag2_val[2];
11286   int len = 14;
11287   u8 ignore_tag1 = 0;
11288   u8 ignore_tag2 = 0;
11289   u8 cos1 = 0;
11290   u8 cos2 = 0;
11291   u32 cos1_val = 0;
11292   u32 cos2_val = 0;
11293
11294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11295     {
11296       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11297         src = 1;
11298       else
11299         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11300         dst = 1;
11301       else if (unformat (input, "proto %U",
11302                          unformat_ethernet_type_host_byte_order, &proto_val))
11303         proto = 1;
11304       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11305         tag1 = 1;
11306       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11307         tag2 = 1;
11308       else if (unformat (input, "ignore-tag1"))
11309         ignore_tag1 = 1;
11310       else if (unformat (input, "ignore-tag2"))
11311         ignore_tag2 = 1;
11312       else if (unformat (input, "cos1 %d", &cos1_val))
11313         cos1 = 1;
11314       else if (unformat (input, "cos2 %d", &cos2_val))
11315         cos2 = 1;
11316       else
11317         break;
11318     }
11319   if ((src + dst + proto + tag1 + tag2 +
11320        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11321     return 0;
11322
11323   if (tag1 || ignore_tag1 || cos1)
11324     len = 18;
11325   if (tag2 || ignore_tag2 || cos2)
11326     len = 22;
11327
11328   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11329
11330   if (dst)
11331     clib_memcpy (match, dst_val, 6);
11332
11333   if (src)
11334     clib_memcpy (match + 6, src_val, 6);
11335
11336   if (tag2)
11337     {
11338       /* inner vlan tag */
11339       match[19] = tag2_val[1];
11340       match[18] = tag2_val[0];
11341       if (cos2)
11342         match[18] |= (cos2_val & 0x7) << 5;
11343       if (proto)
11344         {
11345           match[21] = proto_val & 0xff;
11346           match[20] = proto_val >> 8;
11347         }
11348       if (tag1)
11349         {
11350           match[15] = tag1_val[1];
11351           match[14] = tag1_val[0];
11352         }
11353       if (cos1)
11354         match[14] |= (cos1_val & 0x7) << 5;
11355       *matchp = match;
11356       return 1;
11357     }
11358   if (tag1)
11359     {
11360       match[15] = tag1_val[1];
11361       match[14] = tag1_val[0];
11362       if (proto)
11363         {
11364           match[17] = proto_val & 0xff;
11365           match[16] = proto_val >> 8;
11366         }
11367       if (cos1)
11368         match[14] |= (cos1_val & 0x7) << 5;
11369
11370       *matchp = match;
11371       return 1;
11372     }
11373   if (cos2)
11374     match[18] |= (cos2_val & 0x7) << 5;
11375   if (cos1)
11376     match[14] |= (cos1_val & 0x7) << 5;
11377   if (proto)
11378     {
11379       match[13] = proto_val & 0xff;
11380       match[12] = proto_val >> 8;
11381     }
11382
11383   *matchp = match;
11384   return 1;
11385 }
11386
11387 uword
11388 unformat_qos_source (unformat_input_t * input, va_list * args)
11389 {
11390   int *qs = va_arg (*args, int *);
11391
11392   if (unformat (input, "ip"))
11393     *qs = QOS_SOURCE_IP;
11394   else if (unformat (input, "mpls"))
11395     *qs = QOS_SOURCE_MPLS;
11396   else if (unformat (input, "ext"))
11397     *qs = QOS_SOURCE_EXT;
11398   else if (unformat (input, "vlan"))
11399     *qs = QOS_SOURCE_VLAN;
11400   else
11401     return 0;
11402
11403   return 1;
11404 }
11405 #endif
11406
11407 uword
11408 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11409 {
11410   u8 **matchp = va_arg (*args, u8 **);
11411   u32 skip_n_vectors = va_arg (*args, u32);
11412   u32 match_n_vectors = va_arg (*args, u32);
11413
11414   u8 *match = 0;
11415   u8 *l2 = 0;
11416   u8 *l3 = 0;
11417   u8 *l4 = 0;
11418
11419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11420     {
11421       if (unformat (input, "hex %U", unformat_hex_string, &match))
11422         ;
11423       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11424         ;
11425       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11426         ;
11427       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11428         ;
11429       else
11430         break;
11431     }
11432
11433   if (l4 && !l3)
11434     {
11435       vec_free (match);
11436       vec_free (l2);
11437       vec_free (l4);
11438       return 0;
11439     }
11440
11441   if (match || l2 || l3 || l4)
11442     {
11443       if (l2 || l3 || l4)
11444         {
11445           /* "Win a free Ethernet header in every packet" */
11446           if (l2 == 0)
11447             vec_validate_aligned (l2, 13, sizeof (u32x4));
11448           match = l2;
11449           if (vec_len (l3))
11450             {
11451               vec_append_aligned (match, l3, sizeof (u32x4));
11452               vec_free (l3);
11453             }
11454           if (vec_len (l4))
11455             {
11456               vec_append_aligned (match, l4, sizeof (u32x4));
11457               vec_free (l4);
11458             }
11459         }
11460
11461       /* Make sure the vector is big enough even if key is all 0's */
11462       vec_validate_aligned
11463         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11464          sizeof (u32x4));
11465
11466       /* Set size, include skipped vectors */
11467       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11468
11469       *matchp = match;
11470
11471       return 1;
11472     }
11473
11474   return 0;
11475 }
11476
11477 static int
11478 api_classify_add_del_session (vat_main_t * vam)
11479 {
11480   unformat_input_t *i = vam->input;
11481   vl_api_classify_add_del_session_t *mp;
11482   int is_add = 1;
11483   u32 table_index = ~0;
11484   u32 hit_next_index = ~0;
11485   u32 opaque_index = ~0;
11486   u8 *match = 0;
11487   i32 advance = 0;
11488   u32 skip_n_vectors = 0;
11489   u32 match_n_vectors = 0;
11490   u32 action = 0;
11491   u32 metadata = 0;
11492   int ret;
11493
11494   /*
11495    * Warning: you have to supply skip_n and match_n
11496    * because the API client cant simply look at the classify
11497    * table object.
11498    */
11499
11500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11501     {
11502       if (unformat (i, "del"))
11503         is_add = 0;
11504       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11505                          &hit_next_index))
11506         ;
11507       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11508                          &hit_next_index))
11509         ;
11510       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11511                          &hit_next_index))
11512         ;
11513       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11514         ;
11515       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11516         ;
11517       else if (unformat (i, "opaque-index %d", &opaque_index))
11518         ;
11519       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11520         ;
11521       else if (unformat (i, "match_n %d", &match_n_vectors))
11522         ;
11523       else if (unformat (i, "match %U", api_unformat_classify_match,
11524                          &match, skip_n_vectors, match_n_vectors))
11525         ;
11526       else if (unformat (i, "advance %d", &advance))
11527         ;
11528       else if (unformat (i, "table-index %d", &table_index))
11529         ;
11530       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11531         action = 1;
11532       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11533         action = 2;
11534       else if (unformat (i, "action %d", &action))
11535         ;
11536       else if (unformat (i, "metadata %d", &metadata))
11537         ;
11538       else
11539         break;
11540     }
11541
11542   if (table_index == ~0)
11543     {
11544       errmsg ("Table index required");
11545       return -99;
11546     }
11547
11548   if (is_add && match == 0)
11549     {
11550       errmsg ("Match value required");
11551       return -99;
11552     }
11553
11554   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11555
11556   mp->is_add = is_add;
11557   mp->table_index = ntohl (table_index);
11558   mp->hit_next_index = ntohl (hit_next_index);
11559   mp->opaque_index = ntohl (opaque_index);
11560   mp->advance = ntohl (advance);
11561   mp->action = action;
11562   mp->metadata = ntohl (metadata);
11563   mp->match_len = ntohl (vec_len (match));
11564   clib_memcpy (mp->match, match, vec_len (match));
11565   vec_free (match);
11566
11567   S (mp);
11568   W (ret);
11569   return ret;
11570 }
11571
11572 static int
11573 api_classify_set_interface_ip_table (vat_main_t * vam)
11574 {
11575   unformat_input_t *i = vam->input;
11576   vl_api_classify_set_interface_ip_table_t *mp;
11577   u32 sw_if_index;
11578   int sw_if_index_set;
11579   u32 table_index = ~0;
11580   u8 is_ipv6 = 0;
11581   int ret;
11582
11583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11584     {
11585       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11586         sw_if_index_set = 1;
11587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11588         sw_if_index_set = 1;
11589       else if (unformat (i, "table %d", &table_index))
11590         ;
11591       else
11592         {
11593           clib_warning ("parse error '%U'", format_unformat_error, i);
11594           return -99;
11595         }
11596     }
11597
11598   if (sw_if_index_set == 0)
11599     {
11600       errmsg ("missing interface name or sw_if_index");
11601       return -99;
11602     }
11603
11604
11605   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11606
11607   mp->sw_if_index = ntohl (sw_if_index);
11608   mp->table_index = ntohl (table_index);
11609   mp->is_ipv6 = is_ipv6;
11610
11611   S (mp);
11612   W (ret);
11613   return ret;
11614 }
11615
11616 static int
11617 api_classify_set_interface_l2_tables (vat_main_t * vam)
11618 {
11619   unformat_input_t *i = vam->input;
11620   vl_api_classify_set_interface_l2_tables_t *mp;
11621   u32 sw_if_index;
11622   int sw_if_index_set;
11623   u32 ip4_table_index = ~0;
11624   u32 ip6_table_index = ~0;
11625   u32 other_table_index = ~0;
11626   u32 is_input = 1;
11627   int ret;
11628
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11632         sw_if_index_set = 1;
11633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11634         sw_if_index_set = 1;
11635       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11636         ;
11637       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11638         ;
11639       else if (unformat (i, "other-table %d", &other_table_index))
11640         ;
11641       else if (unformat (i, "is-input %d", &is_input))
11642         ;
11643       else
11644         {
11645           clib_warning ("parse error '%U'", format_unformat_error, i);
11646           return -99;
11647         }
11648     }
11649
11650   if (sw_if_index_set == 0)
11651     {
11652       errmsg ("missing interface name or sw_if_index");
11653       return -99;
11654     }
11655
11656
11657   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11658
11659   mp->sw_if_index = ntohl (sw_if_index);
11660   mp->ip4_table_index = ntohl (ip4_table_index);
11661   mp->ip6_table_index = ntohl (ip6_table_index);
11662   mp->other_table_index = ntohl (other_table_index);
11663   mp->is_input = (u8) is_input;
11664
11665   S (mp);
11666   W (ret);
11667   return ret;
11668 }
11669
11670 static int
11671 api_set_ipfix_exporter (vat_main_t * vam)
11672 {
11673   unformat_input_t *i = vam->input;
11674   vl_api_set_ipfix_exporter_t *mp;
11675   ip4_address_t collector_address;
11676   u8 collector_address_set = 0;
11677   u32 collector_port = ~0;
11678   ip4_address_t src_address;
11679   u8 src_address_set = 0;
11680   u32 vrf_id = ~0;
11681   u32 path_mtu = ~0;
11682   u32 template_interval = ~0;
11683   u8 udp_checksum = 0;
11684   int ret;
11685
11686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11687     {
11688       if (unformat (i, "collector_address %U", unformat_ip4_address,
11689                     &collector_address))
11690         collector_address_set = 1;
11691       else if (unformat (i, "collector_port %d", &collector_port))
11692         ;
11693       else if (unformat (i, "src_address %U", unformat_ip4_address,
11694                          &src_address))
11695         src_address_set = 1;
11696       else if (unformat (i, "vrf_id %d", &vrf_id))
11697         ;
11698       else if (unformat (i, "path_mtu %d", &path_mtu))
11699         ;
11700       else if (unformat (i, "template_interval %d", &template_interval))
11701         ;
11702       else if (unformat (i, "udp_checksum"))
11703         udp_checksum = 1;
11704       else
11705         break;
11706     }
11707
11708   if (collector_address_set == 0)
11709     {
11710       errmsg ("collector_address required");
11711       return -99;
11712     }
11713
11714   if (src_address_set == 0)
11715     {
11716       errmsg ("src_address required");
11717       return -99;
11718     }
11719
11720   M (SET_IPFIX_EXPORTER, mp);
11721
11722   memcpy (mp->collector_address, collector_address.data,
11723           sizeof (collector_address.data));
11724   mp->collector_port = htons ((u16) collector_port);
11725   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11726   mp->vrf_id = htonl (vrf_id);
11727   mp->path_mtu = htonl (path_mtu);
11728   mp->template_interval = htonl (template_interval);
11729   mp->udp_checksum = udp_checksum;
11730
11731   S (mp);
11732   W (ret);
11733   return ret;
11734 }
11735
11736 static int
11737 api_set_ipfix_classify_stream (vat_main_t * vam)
11738 {
11739   unformat_input_t *i = vam->input;
11740   vl_api_set_ipfix_classify_stream_t *mp;
11741   u32 domain_id = 0;
11742   u32 src_port = UDP_DST_PORT_ipfix;
11743   int ret;
11744
11745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11746     {
11747       if (unformat (i, "domain %d", &domain_id))
11748         ;
11749       else if (unformat (i, "src_port %d", &src_port))
11750         ;
11751       else
11752         {
11753           errmsg ("unknown input `%U'", format_unformat_error, i);
11754           return -99;
11755         }
11756     }
11757
11758   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11759
11760   mp->domain_id = htonl (domain_id);
11761   mp->src_port = htons ((u16) src_port);
11762
11763   S (mp);
11764   W (ret);
11765   return ret;
11766 }
11767
11768 static int
11769 api_ipfix_classify_table_add_del (vat_main_t * vam)
11770 {
11771   unformat_input_t *i = vam->input;
11772   vl_api_ipfix_classify_table_add_del_t *mp;
11773   int is_add = -1;
11774   u32 classify_table_index = ~0;
11775   u8 ip_version = 0;
11776   u8 transport_protocol = 255;
11777   int ret;
11778
11779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11780     {
11781       if (unformat (i, "add"))
11782         is_add = 1;
11783       else if (unformat (i, "del"))
11784         is_add = 0;
11785       else if (unformat (i, "table %d", &classify_table_index))
11786         ;
11787       else if (unformat (i, "ip4"))
11788         ip_version = 4;
11789       else if (unformat (i, "ip6"))
11790         ip_version = 6;
11791       else if (unformat (i, "tcp"))
11792         transport_protocol = 6;
11793       else if (unformat (i, "udp"))
11794         transport_protocol = 17;
11795       else
11796         {
11797           errmsg ("unknown input `%U'", format_unformat_error, i);
11798           return -99;
11799         }
11800     }
11801
11802   if (is_add == -1)
11803     {
11804       errmsg ("expecting: add|del");
11805       return -99;
11806     }
11807   if (classify_table_index == ~0)
11808     {
11809       errmsg ("classifier table not specified");
11810       return -99;
11811     }
11812   if (ip_version == 0)
11813     {
11814       errmsg ("IP version not specified");
11815       return -99;
11816     }
11817
11818   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11819
11820   mp->is_add = is_add;
11821   mp->table_id = htonl (classify_table_index);
11822   mp->ip_version = ip_version;
11823   mp->transport_protocol = transport_protocol;
11824
11825   S (mp);
11826   W (ret);
11827   return ret;
11828 }
11829
11830 static int
11831 api_get_node_index (vat_main_t * vam)
11832 {
11833   unformat_input_t *i = vam->input;
11834   vl_api_get_node_index_t *mp;
11835   u8 *name = 0;
11836   int ret;
11837
11838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11839     {
11840       if (unformat (i, "node %s", &name))
11841         ;
11842       else
11843         break;
11844     }
11845   if (name == 0)
11846     {
11847       errmsg ("node name required");
11848       return -99;
11849     }
11850   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11851     {
11852       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11853       return -99;
11854     }
11855
11856   M (GET_NODE_INDEX, mp);
11857   clib_memcpy (mp->node_name, name, vec_len (name));
11858   vec_free (name);
11859
11860   S (mp);
11861   W (ret);
11862   return ret;
11863 }
11864
11865 static int
11866 api_get_next_index (vat_main_t * vam)
11867 {
11868   unformat_input_t *i = vam->input;
11869   vl_api_get_next_index_t *mp;
11870   u8 *node_name = 0, *next_node_name = 0;
11871   int ret;
11872
11873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (i, "node-name %s", &node_name))
11876         ;
11877       else if (unformat (i, "next-node-name %s", &next_node_name))
11878         break;
11879     }
11880
11881   if (node_name == 0)
11882     {
11883       errmsg ("node name required");
11884       return -99;
11885     }
11886   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11887     {
11888       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11889       return -99;
11890     }
11891
11892   if (next_node_name == 0)
11893     {
11894       errmsg ("next node name required");
11895       return -99;
11896     }
11897   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11898     {
11899       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11900       return -99;
11901     }
11902
11903   M (GET_NEXT_INDEX, mp);
11904   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11905   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11906   vec_free (node_name);
11907   vec_free (next_node_name);
11908
11909   S (mp);
11910   W (ret);
11911   return ret;
11912 }
11913
11914 static int
11915 api_add_node_next (vat_main_t * vam)
11916 {
11917   unformat_input_t *i = vam->input;
11918   vl_api_add_node_next_t *mp;
11919   u8 *name = 0;
11920   u8 *next = 0;
11921   int ret;
11922
11923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11924     {
11925       if (unformat (i, "node %s", &name))
11926         ;
11927       else if (unformat (i, "next %s", &next))
11928         ;
11929       else
11930         break;
11931     }
11932   if (name == 0)
11933     {
11934       errmsg ("node name required");
11935       return -99;
11936     }
11937   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11938     {
11939       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11940       return -99;
11941     }
11942   if (next == 0)
11943     {
11944       errmsg ("next node required");
11945       return -99;
11946     }
11947   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11948     {
11949       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11950       return -99;
11951     }
11952
11953   M (ADD_NODE_NEXT, mp);
11954   clib_memcpy (mp->node_name, name, vec_len (name));
11955   clib_memcpy (mp->next_name, next, vec_len (next));
11956   vec_free (name);
11957   vec_free (next);
11958
11959   S (mp);
11960   W (ret);
11961   return ret;
11962 }
11963
11964 static int
11965 api_l2tpv3_create_tunnel (vat_main_t * vam)
11966 {
11967   unformat_input_t *i = vam->input;
11968   ip6_address_t client_address, our_address;
11969   int client_address_set = 0;
11970   int our_address_set = 0;
11971   u32 local_session_id = 0;
11972   u32 remote_session_id = 0;
11973   u64 local_cookie = 0;
11974   u64 remote_cookie = 0;
11975   u8 l2_sublayer_present = 0;
11976   vl_api_l2tpv3_create_tunnel_t *mp;
11977   int ret;
11978
11979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11980     {
11981       if (unformat (i, "client_address %U", unformat_ip6_address,
11982                     &client_address))
11983         client_address_set = 1;
11984       else if (unformat (i, "our_address %U", unformat_ip6_address,
11985                          &our_address))
11986         our_address_set = 1;
11987       else if (unformat (i, "local_session_id %d", &local_session_id))
11988         ;
11989       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11990         ;
11991       else if (unformat (i, "local_cookie %lld", &local_cookie))
11992         ;
11993       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11994         ;
11995       else if (unformat (i, "l2-sublayer-present"))
11996         l2_sublayer_present = 1;
11997       else
11998         break;
11999     }
12000
12001   if (client_address_set == 0)
12002     {
12003       errmsg ("client_address required");
12004       return -99;
12005     }
12006
12007   if (our_address_set == 0)
12008     {
12009       errmsg ("our_address required");
12010       return -99;
12011     }
12012
12013   M (L2TPV3_CREATE_TUNNEL, mp);
12014
12015   clib_memcpy (mp->client_address, client_address.as_u8,
12016                sizeof (mp->client_address));
12017
12018   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12019
12020   mp->local_session_id = ntohl (local_session_id);
12021   mp->remote_session_id = ntohl (remote_session_id);
12022   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12023   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12024   mp->l2_sublayer_present = l2_sublayer_present;
12025   mp->is_ipv6 = 1;
12026
12027   S (mp);
12028   W (ret);
12029   return ret;
12030 }
12031
12032 static int
12033 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12034 {
12035   unformat_input_t *i = vam->input;
12036   u32 sw_if_index;
12037   u8 sw_if_index_set = 0;
12038   u64 new_local_cookie = 0;
12039   u64 new_remote_cookie = 0;
12040   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12041   int ret;
12042
12043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12044     {
12045       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12046         sw_if_index_set = 1;
12047       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12048         sw_if_index_set = 1;
12049       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12050         ;
12051       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12052         ;
12053       else
12054         break;
12055     }
12056
12057   if (sw_if_index_set == 0)
12058     {
12059       errmsg ("missing interface name or sw_if_index");
12060       return -99;
12061     }
12062
12063   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12064
12065   mp->sw_if_index = ntohl (sw_if_index);
12066   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12067   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12068
12069   S (mp);
12070   W (ret);
12071   return ret;
12072 }
12073
12074 static int
12075 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12076 {
12077   unformat_input_t *i = vam->input;
12078   vl_api_l2tpv3_interface_enable_disable_t *mp;
12079   u32 sw_if_index;
12080   u8 sw_if_index_set = 0;
12081   u8 enable_disable = 1;
12082   int ret;
12083
12084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12085     {
12086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12087         sw_if_index_set = 1;
12088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12089         sw_if_index_set = 1;
12090       else if (unformat (i, "enable"))
12091         enable_disable = 1;
12092       else if (unformat (i, "disable"))
12093         enable_disable = 0;
12094       else
12095         break;
12096     }
12097
12098   if (sw_if_index_set == 0)
12099     {
12100       errmsg ("missing interface name or sw_if_index");
12101       return -99;
12102     }
12103
12104   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12105
12106   mp->sw_if_index = ntohl (sw_if_index);
12107   mp->enable_disable = enable_disable;
12108
12109   S (mp);
12110   W (ret);
12111   return ret;
12112 }
12113
12114 static int
12115 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12116 {
12117   unformat_input_t *i = vam->input;
12118   vl_api_l2tpv3_set_lookup_key_t *mp;
12119   u8 key = ~0;
12120   int ret;
12121
12122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12123     {
12124       if (unformat (i, "lookup_v6_src"))
12125         key = L2T_LOOKUP_SRC_ADDRESS;
12126       else if (unformat (i, "lookup_v6_dst"))
12127         key = L2T_LOOKUP_DST_ADDRESS;
12128       else if (unformat (i, "lookup_session_id"))
12129         key = L2T_LOOKUP_SESSION_ID;
12130       else
12131         break;
12132     }
12133
12134   if (key == (u8) ~ 0)
12135     {
12136       errmsg ("l2tp session lookup key unset");
12137       return -99;
12138     }
12139
12140   M (L2TPV3_SET_LOOKUP_KEY, mp);
12141
12142   mp->key = key;
12143
12144   S (mp);
12145   W (ret);
12146   return ret;
12147 }
12148
12149 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12150   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12151 {
12152   vat_main_t *vam = &vat_main;
12153
12154   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12155          format_ip6_address, mp->our_address,
12156          format_ip6_address, mp->client_address,
12157          clib_net_to_host_u32 (mp->sw_if_index));
12158
12159   print (vam->ofp,
12160          "   local cookies %016llx %016llx remote cookie %016llx",
12161          clib_net_to_host_u64 (mp->local_cookie[0]),
12162          clib_net_to_host_u64 (mp->local_cookie[1]),
12163          clib_net_to_host_u64 (mp->remote_cookie));
12164
12165   print (vam->ofp, "   local session-id %d remote session-id %d",
12166          clib_net_to_host_u32 (mp->local_session_id),
12167          clib_net_to_host_u32 (mp->remote_session_id));
12168
12169   print (vam->ofp, "   l2 specific sublayer %s\n",
12170          mp->l2_sublayer_present ? "preset" : "absent");
12171
12172 }
12173
12174 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12175   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12176 {
12177   vat_main_t *vam = &vat_main;
12178   vat_json_node_t *node = NULL;
12179   struct in6_addr addr;
12180
12181   if (VAT_JSON_ARRAY != vam->json_tree.type)
12182     {
12183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12184       vat_json_init_array (&vam->json_tree);
12185     }
12186   node = vat_json_array_add (&vam->json_tree);
12187
12188   vat_json_init_object (node);
12189
12190   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12191   vat_json_object_add_ip6 (node, "our_address", addr);
12192   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12193   vat_json_object_add_ip6 (node, "client_address", addr);
12194
12195   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12196   vat_json_init_array (lc);
12197   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12198   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12199   vat_json_object_add_uint (node, "remote_cookie",
12200                             clib_net_to_host_u64 (mp->remote_cookie));
12201
12202   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12203   vat_json_object_add_uint (node, "local_session_id",
12204                             clib_net_to_host_u32 (mp->local_session_id));
12205   vat_json_object_add_uint (node, "remote_session_id",
12206                             clib_net_to_host_u32 (mp->remote_session_id));
12207   vat_json_object_add_string_copy (node, "l2_sublayer",
12208                                    mp->l2_sublayer_present ? (u8 *) "present"
12209                                    : (u8 *) "absent");
12210 }
12211
12212 static int
12213 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12214 {
12215   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12216   vl_api_control_ping_t *mp_ping;
12217   int ret;
12218
12219   /* Get list of l2tpv3-tunnel interfaces */
12220   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12221   S (mp);
12222
12223   /* Use a control ping for synchronization */
12224   MPING (CONTROL_PING, mp_ping);
12225   S (mp_ping);
12226
12227   W (ret);
12228   return ret;
12229 }
12230
12231
12232 static void vl_api_sw_interface_tap_v2_details_t_handler
12233   (vl_api_sw_interface_tap_v2_details_t * mp)
12234 {
12235   vat_main_t *vam = &vat_main;
12236
12237   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12238                     mp->host_ip4_prefix_len);
12239   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12240                     mp->host_ip6_prefix_len);
12241
12242   print (vam->ofp,
12243          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12244          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12245          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12246          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12247          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12248
12249   vec_free (ip4);
12250   vec_free (ip6);
12251 }
12252
12253 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12254   (vl_api_sw_interface_tap_v2_details_t * mp)
12255 {
12256   vat_main_t *vam = &vat_main;
12257   vat_json_node_t *node = NULL;
12258
12259   if (VAT_JSON_ARRAY != vam->json_tree.type)
12260     {
12261       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12262       vat_json_init_array (&vam->json_tree);
12263     }
12264   node = vat_json_array_add (&vam->json_tree);
12265
12266   vat_json_init_object (node);
12267   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12268   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12269   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12270   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12271   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12272   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12273   vat_json_object_add_string_copy (node, "host_mac_addr",
12274                                    format (0, "%U", format_ethernet_address,
12275                                            &mp->host_mac_addr));
12276   vat_json_object_add_string_copy (node, "host_namespace",
12277                                    mp->host_namespace);
12278   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12279   vat_json_object_add_string_copy (node, "host_ip4_addr",
12280                                    format (0, "%U/%d", format_ip4_address,
12281                                            mp->host_ip4_addr,
12282                                            mp->host_ip4_prefix_len));
12283   vat_json_object_add_string_copy (node, "host_ip6_addr",
12284                                    format (0, "%U/%d", format_ip6_address,
12285                                            mp->host_ip6_addr,
12286                                            mp->host_ip6_prefix_len));
12287
12288 }
12289
12290 static int
12291 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12292 {
12293   vl_api_sw_interface_tap_v2_dump_t *mp;
12294   vl_api_control_ping_t *mp_ping;
12295   int ret;
12296
12297   print (vam->ofp,
12298          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12299          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12300          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12301          "host_ip6_addr");
12302
12303   /* Get list of tap interfaces */
12304   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12305   S (mp);
12306
12307   /* Use a control ping for synchronization */
12308   MPING (CONTROL_PING, mp_ping);
12309   S (mp_ping);
12310
12311   W (ret);
12312   return ret;
12313 }
12314
12315 static void vl_api_sw_interface_virtio_pci_details_t_handler
12316   (vl_api_sw_interface_virtio_pci_details_t * mp)
12317 {
12318   vat_main_t *vam = &vat_main;
12319
12320   typedef union
12321   {
12322     struct
12323     {
12324       u16 domain;
12325       u8 bus;
12326       u8 slot:5;
12327       u8 function:3;
12328     };
12329     u32 as_u32;
12330   } pci_addr_t;
12331   pci_addr_t addr;
12332   addr.as_u32 = ntohl (mp->pci_addr);
12333   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12334                          addr.slot, addr.function);
12335
12336   print (vam->ofp,
12337          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12338          pci_addr, ntohl (mp->sw_if_index),
12339          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12340          format_ethernet_address, mp->mac_addr,
12341          clib_net_to_host_u64 (mp->features));
12342   vec_free (pci_addr);
12343 }
12344
12345 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12346   (vl_api_sw_interface_virtio_pci_details_t * mp)
12347 {
12348   vat_main_t *vam = &vat_main;
12349   vat_json_node_t *node = NULL;
12350
12351   if (VAT_JSON_ARRAY != vam->json_tree.type)
12352     {
12353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12354       vat_json_init_array (&vam->json_tree);
12355     }
12356   node = vat_json_array_add (&vam->json_tree);
12357
12358   vat_json_init_object (node);
12359   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12360   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12361   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12362   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12363   vat_json_object_add_uint (node, "features",
12364                             clib_net_to_host_u64 (mp->features));
12365   vat_json_object_add_string_copy (node, "mac_addr",
12366                                    format (0, "%U", format_ethernet_address,
12367                                            &mp->mac_addr));
12368 }
12369
12370 static int
12371 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12372 {
12373   vl_api_sw_interface_virtio_pci_dump_t *mp;
12374   vl_api_control_ping_t *mp_ping;
12375   int ret;
12376
12377   print (vam->ofp,
12378          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12379          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12380          "mac_addr", "features");
12381
12382   /* Get list of tap interfaces */
12383   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12384   S (mp);
12385
12386   /* Use a control ping for synchronization */
12387   MPING (CONTROL_PING, mp_ping);
12388   S (mp_ping);
12389
12390   W (ret);
12391   return ret;
12392 }
12393
12394 static int
12395 api_vxlan_offload_rx (vat_main_t * vam)
12396 {
12397   unformat_input_t *line_input = vam->input;
12398   vl_api_vxlan_offload_rx_t *mp;
12399   u32 hw_if_index = ~0, rx_if_index = ~0;
12400   u8 is_add = 1;
12401   int ret;
12402
12403   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12404     {
12405       if (unformat (line_input, "del"))
12406         is_add = 0;
12407       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12408                          &hw_if_index))
12409         ;
12410       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12411         ;
12412       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12413                          &rx_if_index))
12414         ;
12415       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12416         ;
12417       else
12418         {
12419           errmsg ("parse error '%U'", format_unformat_error, line_input);
12420           return -99;
12421         }
12422     }
12423
12424   if (hw_if_index == ~0)
12425     {
12426       errmsg ("no hw interface");
12427       return -99;
12428     }
12429
12430   if (rx_if_index == ~0)
12431     {
12432       errmsg ("no rx tunnel");
12433       return -99;
12434     }
12435
12436   M (VXLAN_OFFLOAD_RX, mp);
12437
12438   mp->hw_if_index = ntohl (hw_if_index);
12439   mp->sw_if_index = ntohl (rx_if_index);
12440   mp->enable = is_add;
12441
12442   S (mp);
12443   W (ret);
12444   return ret;
12445 }
12446
12447 static uword unformat_vxlan_decap_next
12448   (unformat_input_t * input, va_list * args)
12449 {
12450   u32 *result = va_arg (*args, u32 *);
12451   u32 tmp;
12452
12453   if (unformat (input, "l2"))
12454     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12455   else if (unformat (input, "%d", &tmp))
12456     *result = tmp;
12457   else
12458     return 0;
12459   return 1;
12460 }
12461
12462 static int
12463 api_vxlan_add_del_tunnel (vat_main_t * vam)
12464 {
12465   unformat_input_t *line_input = vam->input;
12466   vl_api_vxlan_add_del_tunnel_t *mp;
12467   ip46_address_t src, dst;
12468   u8 is_add = 1;
12469   u8 ipv4_set = 0, ipv6_set = 0;
12470   u8 src_set = 0;
12471   u8 dst_set = 0;
12472   u8 grp_set = 0;
12473   u32 instance = ~0;
12474   u32 mcast_sw_if_index = ~0;
12475   u32 encap_vrf_id = 0;
12476   u32 decap_next_index = ~0;
12477   u32 vni = 0;
12478   int ret;
12479
12480   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12481   clib_memset (&src, 0, sizeof src);
12482   clib_memset (&dst, 0, sizeof dst);
12483
12484   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12485     {
12486       if (unformat (line_input, "del"))
12487         is_add = 0;
12488       else if (unformat (line_input, "instance %d", &instance))
12489         ;
12490       else
12491         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12492         {
12493           ipv4_set = 1;
12494           src_set = 1;
12495         }
12496       else
12497         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12498         {
12499           ipv4_set = 1;
12500           dst_set = 1;
12501         }
12502       else
12503         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12504         {
12505           ipv6_set = 1;
12506           src_set = 1;
12507         }
12508       else
12509         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12510         {
12511           ipv6_set = 1;
12512           dst_set = 1;
12513         }
12514       else if (unformat (line_input, "group %U %U",
12515                          unformat_ip4_address, &dst.ip4,
12516                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12517         {
12518           grp_set = dst_set = 1;
12519           ipv4_set = 1;
12520         }
12521       else if (unformat (line_input, "group %U",
12522                          unformat_ip4_address, &dst.ip4))
12523         {
12524           grp_set = dst_set = 1;
12525           ipv4_set = 1;
12526         }
12527       else if (unformat (line_input, "group %U %U",
12528                          unformat_ip6_address, &dst.ip6,
12529                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12530         {
12531           grp_set = dst_set = 1;
12532           ipv6_set = 1;
12533         }
12534       else if (unformat (line_input, "group %U",
12535                          unformat_ip6_address, &dst.ip6))
12536         {
12537           grp_set = dst_set = 1;
12538           ipv6_set = 1;
12539         }
12540       else
12541         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12542         ;
12543       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12544         ;
12545       else if (unformat (line_input, "decap-next %U",
12546                          unformat_vxlan_decap_next, &decap_next_index))
12547         ;
12548       else if (unformat (line_input, "vni %d", &vni))
12549         ;
12550       else
12551         {
12552           errmsg ("parse error '%U'", format_unformat_error, line_input);
12553           return -99;
12554         }
12555     }
12556
12557   if (src_set == 0)
12558     {
12559       errmsg ("tunnel src address not specified");
12560       return -99;
12561     }
12562   if (dst_set == 0)
12563     {
12564       errmsg ("tunnel dst address not specified");
12565       return -99;
12566     }
12567
12568   if (grp_set && !ip46_address_is_multicast (&dst))
12569     {
12570       errmsg ("tunnel group address not multicast");
12571       return -99;
12572     }
12573   if (grp_set && mcast_sw_if_index == ~0)
12574     {
12575       errmsg ("tunnel nonexistent multicast device");
12576       return -99;
12577     }
12578   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12579     {
12580       errmsg ("tunnel dst address must be unicast");
12581       return -99;
12582     }
12583
12584
12585   if (ipv4_set && ipv6_set)
12586     {
12587       errmsg ("both IPv4 and IPv6 addresses specified");
12588       return -99;
12589     }
12590
12591   if ((vni == 0) || (vni >> 24))
12592     {
12593       errmsg ("vni not specified or out of range");
12594       return -99;
12595     }
12596
12597   M (VXLAN_ADD_DEL_TUNNEL, mp);
12598
12599   if (ipv6_set)
12600     {
12601       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12602       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12603     }
12604   else
12605     {
12606       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12607       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12608     }
12609
12610   mp->instance = htonl (instance);
12611   mp->encap_vrf_id = ntohl (encap_vrf_id);
12612   mp->decap_next_index = ntohl (decap_next_index);
12613   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12614   mp->vni = ntohl (vni);
12615   mp->is_add = is_add;
12616   mp->is_ipv6 = ipv6_set;
12617
12618   S (mp);
12619   W (ret);
12620   return ret;
12621 }
12622
12623 static void vl_api_vxlan_tunnel_details_t_handler
12624   (vl_api_vxlan_tunnel_details_t * mp)
12625 {
12626   vat_main_t *vam = &vat_main;
12627   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12628   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12629
12630   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12631          ntohl (mp->sw_if_index),
12632          ntohl (mp->instance),
12633          format_ip46_address, &src, IP46_TYPE_ANY,
12634          format_ip46_address, &dst, IP46_TYPE_ANY,
12635          ntohl (mp->encap_vrf_id),
12636          ntohl (mp->decap_next_index), ntohl (mp->vni),
12637          ntohl (mp->mcast_sw_if_index));
12638 }
12639
12640 static void vl_api_vxlan_tunnel_details_t_handler_json
12641   (vl_api_vxlan_tunnel_details_t * mp)
12642 {
12643   vat_main_t *vam = &vat_main;
12644   vat_json_node_t *node = NULL;
12645
12646   if (VAT_JSON_ARRAY != vam->json_tree.type)
12647     {
12648       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12649       vat_json_init_array (&vam->json_tree);
12650     }
12651   node = vat_json_array_add (&vam->json_tree);
12652
12653   vat_json_init_object (node);
12654   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12655
12656   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12657
12658   if (mp->is_ipv6)
12659     {
12660       struct in6_addr ip6;
12661
12662       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12663       vat_json_object_add_ip6 (node, "src_address", ip6);
12664       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12665       vat_json_object_add_ip6 (node, "dst_address", ip6);
12666     }
12667   else
12668     {
12669       struct in_addr ip4;
12670
12671       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12672       vat_json_object_add_ip4 (node, "src_address", ip4);
12673       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12674       vat_json_object_add_ip4 (node, "dst_address", ip4);
12675     }
12676   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12677   vat_json_object_add_uint (node, "decap_next_index",
12678                             ntohl (mp->decap_next_index));
12679   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12680   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12681   vat_json_object_add_uint (node, "mcast_sw_if_index",
12682                             ntohl (mp->mcast_sw_if_index));
12683 }
12684
12685 static int
12686 api_vxlan_tunnel_dump (vat_main_t * vam)
12687 {
12688   unformat_input_t *i = vam->input;
12689   vl_api_vxlan_tunnel_dump_t *mp;
12690   vl_api_control_ping_t *mp_ping;
12691   u32 sw_if_index;
12692   u8 sw_if_index_set = 0;
12693   int ret;
12694
12695   /* Parse args required to build the message */
12696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12697     {
12698       if (unformat (i, "sw_if_index %d", &sw_if_index))
12699         sw_if_index_set = 1;
12700       else
12701         break;
12702     }
12703
12704   if (sw_if_index_set == 0)
12705     {
12706       sw_if_index = ~0;
12707     }
12708
12709   if (!vam->json_output)
12710     {
12711       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12712              "sw_if_index", "instance", "src_address", "dst_address",
12713              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12714     }
12715
12716   /* Get list of vxlan-tunnel interfaces */
12717   M (VXLAN_TUNNEL_DUMP, mp);
12718
12719   mp->sw_if_index = htonl (sw_if_index);
12720
12721   S (mp);
12722
12723   /* Use a control ping for synchronization */
12724   MPING (CONTROL_PING, mp_ping);
12725   S (mp_ping);
12726
12727   W (ret);
12728   return ret;
12729 }
12730
12731 static uword unformat_geneve_decap_next
12732   (unformat_input_t * input, va_list * args)
12733 {
12734   u32 *result = va_arg (*args, u32 *);
12735   u32 tmp;
12736
12737   if (unformat (input, "l2"))
12738     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12739   else if (unformat (input, "%d", &tmp))
12740     *result = tmp;
12741   else
12742     return 0;
12743   return 1;
12744 }
12745
12746 static int
12747 api_geneve_add_del_tunnel (vat_main_t * vam)
12748 {
12749   unformat_input_t *line_input = vam->input;
12750   vl_api_geneve_add_del_tunnel_t *mp;
12751   ip46_address_t src, dst;
12752   u8 is_add = 1;
12753   u8 ipv4_set = 0, ipv6_set = 0;
12754   u8 src_set = 0;
12755   u8 dst_set = 0;
12756   u8 grp_set = 0;
12757   u32 mcast_sw_if_index = ~0;
12758   u32 encap_vrf_id = 0;
12759   u32 decap_next_index = ~0;
12760   u32 vni = 0;
12761   int ret;
12762
12763   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12764   clib_memset (&src, 0, sizeof src);
12765   clib_memset (&dst, 0, sizeof dst);
12766
12767   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12768     {
12769       if (unformat (line_input, "del"))
12770         is_add = 0;
12771       else
12772         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12773         {
12774           ipv4_set = 1;
12775           src_set = 1;
12776         }
12777       else
12778         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12779         {
12780           ipv4_set = 1;
12781           dst_set = 1;
12782         }
12783       else
12784         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12785         {
12786           ipv6_set = 1;
12787           src_set = 1;
12788         }
12789       else
12790         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12791         {
12792           ipv6_set = 1;
12793           dst_set = 1;
12794         }
12795       else if (unformat (line_input, "group %U %U",
12796                          unformat_ip4_address, &dst.ip4,
12797                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12798         {
12799           grp_set = dst_set = 1;
12800           ipv4_set = 1;
12801         }
12802       else if (unformat (line_input, "group %U",
12803                          unformat_ip4_address, &dst.ip4))
12804         {
12805           grp_set = dst_set = 1;
12806           ipv4_set = 1;
12807         }
12808       else if (unformat (line_input, "group %U %U",
12809                          unformat_ip6_address, &dst.ip6,
12810                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12811         {
12812           grp_set = dst_set = 1;
12813           ipv6_set = 1;
12814         }
12815       else if (unformat (line_input, "group %U",
12816                          unformat_ip6_address, &dst.ip6))
12817         {
12818           grp_set = dst_set = 1;
12819           ipv6_set = 1;
12820         }
12821       else
12822         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12823         ;
12824       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12825         ;
12826       else if (unformat (line_input, "decap-next %U",
12827                          unformat_geneve_decap_next, &decap_next_index))
12828         ;
12829       else if (unformat (line_input, "vni %d", &vni))
12830         ;
12831       else
12832         {
12833           errmsg ("parse error '%U'", format_unformat_error, line_input);
12834           return -99;
12835         }
12836     }
12837
12838   if (src_set == 0)
12839     {
12840       errmsg ("tunnel src address not specified");
12841       return -99;
12842     }
12843   if (dst_set == 0)
12844     {
12845       errmsg ("tunnel dst address not specified");
12846       return -99;
12847     }
12848
12849   if (grp_set && !ip46_address_is_multicast (&dst))
12850     {
12851       errmsg ("tunnel group address not multicast");
12852       return -99;
12853     }
12854   if (grp_set && mcast_sw_if_index == ~0)
12855     {
12856       errmsg ("tunnel nonexistent multicast device");
12857       return -99;
12858     }
12859   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12860     {
12861       errmsg ("tunnel dst address must be unicast");
12862       return -99;
12863     }
12864
12865
12866   if (ipv4_set && ipv6_set)
12867     {
12868       errmsg ("both IPv4 and IPv6 addresses specified");
12869       return -99;
12870     }
12871
12872   if ((vni == 0) || (vni >> 24))
12873     {
12874       errmsg ("vni not specified or out of range");
12875       return -99;
12876     }
12877
12878   M (GENEVE_ADD_DEL_TUNNEL, mp);
12879
12880   if (ipv6_set)
12881     {
12882       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12883       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12884     }
12885   else
12886     {
12887       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12888       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12889     }
12890   mp->encap_vrf_id = ntohl (encap_vrf_id);
12891   mp->decap_next_index = ntohl (decap_next_index);
12892   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12893   mp->vni = ntohl (vni);
12894   mp->is_add = is_add;
12895   mp->is_ipv6 = ipv6_set;
12896
12897   S (mp);
12898   W (ret);
12899   return ret;
12900 }
12901
12902 static void vl_api_geneve_tunnel_details_t_handler
12903   (vl_api_geneve_tunnel_details_t * mp)
12904 {
12905   vat_main_t *vam = &vat_main;
12906   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12907   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12908
12909   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12910          ntohl (mp->sw_if_index),
12911          format_ip46_address, &src, IP46_TYPE_ANY,
12912          format_ip46_address, &dst, IP46_TYPE_ANY,
12913          ntohl (mp->encap_vrf_id),
12914          ntohl (mp->decap_next_index), ntohl (mp->vni),
12915          ntohl (mp->mcast_sw_if_index));
12916 }
12917
12918 static void vl_api_geneve_tunnel_details_t_handler_json
12919   (vl_api_geneve_tunnel_details_t * mp)
12920 {
12921   vat_main_t *vam = &vat_main;
12922   vat_json_node_t *node = NULL;
12923
12924   if (VAT_JSON_ARRAY != vam->json_tree.type)
12925     {
12926       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12927       vat_json_init_array (&vam->json_tree);
12928     }
12929   node = vat_json_array_add (&vam->json_tree);
12930
12931   vat_json_init_object (node);
12932   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12933   if (mp->is_ipv6)
12934     {
12935       struct in6_addr ip6;
12936
12937       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12938       vat_json_object_add_ip6 (node, "src_address", ip6);
12939       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12940       vat_json_object_add_ip6 (node, "dst_address", ip6);
12941     }
12942   else
12943     {
12944       struct in_addr ip4;
12945
12946       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12947       vat_json_object_add_ip4 (node, "src_address", ip4);
12948       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12949       vat_json_object_add_ip4 (node, "dst_address", ip4);
12950     }
12951   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12952   vat_json_object_add_uint (node, "decap_next_index",
12953                             ntohl (mp->decap_next_index));
12954   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12955   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12956   vat_json_object_add_uint (node, "mcast_sw_if_index",
12957                             ntohl (mp->mcast_sw_if_index));
12958 }
12959
12960 static int
12961 api_geneve_tunnel_dump (vat_main_t * vam)
12962 {
12963   unformat_input_t *i = vam->input;
12964   vl_api_geneve_tunnel_dump_t *mp;
12965   vl_api_control_ping_t *mp_ping;
12966   u32 sw_if_index;
12967   u8 sw_if_index_set = 0;
12968   int ret;
12969
12970   /* Parse args required to build the message */
12971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12972     {
12973       if (unformat (i, "sw_if_index %d", &sw_if_index))
12974         sw_if_index_set = 1;
12975       else
12976         break;
12977     }
12978
12979   if (sw_if_index_set == 0)
12980     {
12981       sw_if_index = ~0;
12982     }
12983
12984   if (!vam->json_output)
12985     {
12986       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12987              "sw_if_index", "local_address", "remote_address",
12988              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12989     }
12990
12991   /* Get list of geneve-tunnel interfaces */
12992   M (GENEVE_TUNNEL_DUMP, mp);
12993
12994   mp->sw_if_index = htonl (sw_if_index);
12995
12996   S (mp);
12997
12998   /* Use a control ping for synchronization */
12999   M (CONTROL_PING, mp_ping);
13000   S (mp_ping);
13001
13002   W (ret);
13003   return ret;
13004 }
13005
13006 static int
13007 api_gre_tunnel_add_del (vat_main_t * vam)
13008 {
13009   unformat_input_t *line_input = vam->input;
13010   vl_api_address_t src = { }, dst =
13011   {
13012   };
13013   vl_api_gre_tunnel_add_del_t *mp;
13014   vl_api_gre_tunnel_type_t t_type;
13015   u8 is_add = 1;
13016   u8 src_set = 0;
13017   u8 dst_set = 0;
13018   u32 outer_fib_id = 0;
13019   u32 session_id = 0;
13020   u32 instance = ~0;
13021   int ret;
13022
13023   t_type = GRE_API_TUNNEL_TYPE_L3;
13024
13025   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (line_input, "del"))
13028         is_add = 0;
13029       else if (unformat (line_input, "instance %d", &instance))
13030         ;
13031       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13032         {
13033           src_set = 1;
13034         }
13035       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13036         {
13037           dst_set = 1;
13038         }
13039       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13040         ;
13041       else if (unformat (line_input, "teb"))
13042         t_type = GRE_API_TUNNEL_TYPE_TEB;
13043       else if (unformat (line_input, "erspan %d", &session_id))
13044         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13045       else
13046         {
13047           errmsg ("parse error '%U'", format_unformat_error, line_input);
13048           return -99;
13049         }
13050     }
13051
13052   if (src_set == 0)
13053     {
13054       errmsg ("tunnel src address not specified");
13055       return -99;
13056     }
13057   if (dst_set == 0)
13058     {
13059       errmsg ("tunnel dst address not specified");
13060       return -99;
13061     }
13062
13063   M (GRE_TUNNEL_ADD_DEL, mp);
13064
13065   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13066   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13067
13068   mp->tunnel.instance = htonl (instance);
13069   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13070   mp->is_add = is_add;
13071   mp->tunnel.session_id = htons ((u16) session_id);
13072   mp->tunnel.type = htonl (t_type);
13073
13074   S (mp);
13075   W (ret);
13076   return ret;
13077 }
13078
13079 static void vl_api_gre_tunnel_details_t_handler
13080   (vl_api_gre_tunnel_details_t * mp)
13081 {
13082   vat_main_t *vam = &vat_main;
13083
13084   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13085          ntohl (mp->tunnel.sw_if_index),
13086          ntohl (mp->tunnel.instance),
13087          format_vl_api_address, &mp->tunnel.src,
13088          format_vl_api_address, &mp->tunnel.dst,
13089          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13090          ntohl (mp->tunnel.session_id));
13091 }
13092
13093 static void vl_api_gre_tunnel_details_t_handler_json
13094   (vl_api_gre_tunnel_details_t * mp)
13095 {
13096   vat_main_t *vam = &vat_main;
13097   vat_json_node_t *node = NULL;
13098
13099   if (VAT_JSON_ARRAY != vam->json_tree.type)
13100     {
13101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13102       vat_json_init_array (&vam->json_tree);
13103     }
13104   node = vat_json_array_add (&vam->json_tree);
13105
13106   vat_json_init_object (node);
13107   vat_json_object_add_uint (node, "sw_if_index",
13108                             ntohl (mp->tunnel.sw_if_index));
13109   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13110
13111   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13112   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13113   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13114   vat_json_object_add_uint (node, "outer_fib_id",
13115                             ntohl (mp->tunnel.outer_fib_id));
13116   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13117 }
13118
13119 static int
13120 api_gre_tunnel_dump (vat_main_t * vam)
13121 {
13122   unformat_input_t *i = vam->input;
13123   vl_api_gre_tunnel_dump_t *mp;
13124   vl_api_control_ping_t *mp_ping;
13125   u32 sw_if_index;
13126   u8 sw_if_index_set = 0;
13127   int ret;
13128
13129   /* Parse args required to build the message */
13130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13131     {
13132       if (unformat (i, "sw_if_index %d", &sw_if_index))
13133         sw_if_index_set = 1;
13134       else
13135         break;
13136     }
13137
13138   if (sw_if_index_set == 0)
13139     {
13140       sw_if_index = ~0;
13141     }
13142
13143   if (!vam->json_output)
13144     {
13145       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13146              "sw_if_index", "instance", "src_address", "dst_address",
13147              "tunnel_type", "outer_fib_id", "session_id");
13148     }
13149
13150   /* Get list of gre-tunnel interfaces */
13151   M (GRE_TUNNEL_DUMP, mp);
13152
13153   mp->sw_if_index = htonl (sw_if_index);
13154
13155   S (mp);
13156
13157   /* Use a control ping for synchronization */
13158   MPING (CONTROL_PING, mp_ping);
13159   S (mp_ping);
13160
13161   W (ret);
13162   return ret;
13163 }
13164
13165 static int
13166 api_l2_fib_clear_table (vat_main_t * vam)
13167 {
13168 //  unformat_input_t * i = vam->input;
13169   vl_api_l2_fib_clear_table_t *mp;
13170   int ret;
13171
13172   M (L2_FIB_CLEAR_TABLE, mp);
13173
13174   S (mp);
13175   W (ret);
13176   return ret;
13177 }
13178
13179 static int
13180 api_l2_interface_efp_filter (vat_main_t * vam)
13181 {
13182   unformat_input_t *i = vam->input;
13183   vl_api_l2_interface_efp_filter_t *mp;
13184   u32 sw_if_index;
13185   u8 enable = 1;
13186   u8 sw_if_index_set = 0;
13187   int ret;
13188
13189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13190     {
13191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13192         sw_if_index_set = 1;
13193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13194         sw_if_index_set = 1;
13195       else if (unformat (i, "enable"))
13196         enable = 1;
13197       else if (unformat (i, "disable"))
13198         enable = 0;
13199       else
13200         {
13201           clib_warning ("parse error '%U'", format_unformat_error, i);
13202           return -99;
13203         }
13204     }
13205
13206   if (sw_if_index_set == 0)
13207     {
13208       errmsg ("missing sw_if_index");
13209       return -99;
13210     }
13211
13212   M (L2_INTERFACE_EFP_FILTER, mp);
13213
13214   mp->sw_if_index = ntohl (sw_if_index);
13215   mp->enable_disable = enable;
13216
13217   S (mp);
13218   W (ret);
13219   return ret;
13220 }
13221
13222 #define foreach_vtr_op                          \
13223 _("disable",  L2_VTR_DISABLED)                  \
13224 _("push-1",  L2_VTR_PUSH_1)                     \
13225 _("push-2",  L2_VTR_PUSH_2)                     \
13226 _("pop-1",  L2_VTR_POP_1)                       \
13227 _("pop-2",  L2_VTR_POP_2)                       \
13228 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13229 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13230 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13231 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13232
13233 static int
13234 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13235 {
13236   unformat_input_t *i = vam->input;
13237   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13238   u32 sw_if_index;
13239   u8 sw_if_index_set = 0;
13240   u8 vtr_op_set = 0;
13241   u32 vtr_op = 0;
13242   u32 push_dot1q = 1;
13243   u32 tag1 = ~0;
13244   u32 tag2 = ~0;
13245   int ret;
13246
13247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13248     {
13249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13250         sw_if_index_set = 1;
13251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13252         sw_if_index_set = 1;
13253       else if (unformat (i, "vtr_op %d", &vtr_op))
13254         vtr_op_set = 1;
13255 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13256       foreach_vtr_op
13257 #undef _
13258         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13259         ;
13260       else if (unformat (i, "tag1 %d", &tag1))
13261         ;
13262       else if (unformat (i, "tag2 %d", &tag2))
13263         ;
13264       else
13265         {
13266           clib_warning ("parse error '%U'", format_unformat_error, i);
13267           return -99;
13268         }
13269     }
13270
13271   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13272     {
13273       errmsg ("missing vtr operation or sw_if_index");
13274       return -99;
13275     }
13276
13277   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13278   mp->sw_if_index = ntohl (sw_if_index);
13279   mp->vtr_op = ntohl (vtr_op);
13280   mp->push_dot1q = ntohl (push_dot1q);
13281   mp->tag1 = ntohl (tag1);
13282   mp->tag2 = ntohl (tag2);
13283
13284   S (mp);
13285   W (ret);
13286   return ret;
13287 }
13288
13289 static int
13290 api_create_vhost_user_if (vat_main_t * vam)
13291 {
13292   unformat_input_t *i = vam->input;
13293   vl_api_create_vhost_user_if_t *mp;
13294   u8 *file_name;
13295   u8 is_server = 0;
13296   u8 file_name_set = 0;
13297   u32 custom_dev_instance = ~0;
13298   u8 hwaddr[6];
13299   u8 use_custom_mac = 0;
13300   u8 disable_mrg_rxbuf = 0;
13301   u8 disable_indirect_desc = 0;
13302   u8 *tag = 0;
13303   u8 enable_gso = 0;
13304   int ret;
13305
13306   /* Shut up coverity */
13307   clib_memset (hwaddr, 0, sizeof (hwaddr));
13308
13309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13310     {
13311       if (unformat (i, "socket %s", &file_name))
13312         {
13313           file_name_set = 1;
13314         }
13315       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13316         ;
13317       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13318         use_custom_mac = 1;
13319       else if (unformat (i, "server"))
13320         is_server = 1;
13321       else if (unformat (i, "disable_mrg_rxbuf"))
13322         disable_mrg_rxbuf = 1;
13323       else if (unformat (i, "disable_indirect_desc"))
13324         disable_indirect_desc = 1;
13325       else if (unformat (i, "gso"))
13326         enable_gso = 1;
13327       else if (unformat (i, "tag %s", &tag))
13328         ;
13329       else
13330         break;
13331     }
13332
13333   if (file_name_set == 0)
13334     {
13335       errmsg ("missing socket file name");
13336       return -99;
13337     }
13338
13339   if (vec_len (file_name) > 255)
13340     {
13341       errmsg ("socket file name too long");
13342       return -99;
13343     }
13344   vec_add1 (file_name, 0);
13345
13346   M (CREATE_VHOST_USER_IF, mp);
13347
13348   mp->is_server = is_server;
13349   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13350   mp->disable_indirect_desc = disable_indirect_desc;
13351   mp->enable_gso = enable_gso;
13352   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13353   vec_free (file_name);
13354   if (custom_dev_instance != ~0)
13355     {
13356       mp->renumber = 1;
13357       mp->custom_dev_instance = ntohl (custom_dev_instance);
13358     }
13359
13360   mp->use_custom_mac = use_custom_mac;
13361   clib_memcpy (mp->mac_address, hwaddr, 6);
13362   if (tag)
13363     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13364   vec_free (tag);
13365
13366   S (mp);
13367   W (ret);
13368   return ret;
13369 }
13370
13371 static int
13372 api_modify_vhost_user_if (vat_main_t * vam)
13373 {
13374   unformat_input_t *i = vam->input;
13375   vl_api_modify_vhost_user_if_t *mp;
13376   u8 *file_name;
13377   u8 is_server = 0;
13378   u8 file_name_set = 0;
13379   u32 custom_dev_instance = ~0;
13380   u8 sw_if_index_set = 0;
13381   u32 sw_if_index = (u32) ~ 0;
13382   u8 enable_gso = 0;
13383   int ret;
13384
13385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13386     {
13387       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13388         sw_if_index_set = 1;
13389       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13390         sw_if_index_set = 1;
13391       else if (unformat (i, "socket %s", &file_name))
13392         {
13393           file_name_set = 1;
13394         }
13395       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13396         ;
13397       else if (unformat (i, "server"))
13398         is_server = 1;
13399       else if (unformat (i, "gso"))
13400         enable_gso = 1;
13401       else
13402         break;
13403     }
13404
13405   if (sw_if_index_set == 0)
13406     {
13407       errmsg ("missing sw_if_index or interface name");
13408       return -99;
13409     }
13410
13411   if (file_name_set == 0)
13412     {
13413       errmsg ("missing socket file name");
13414       return -99;
13415     }
13416
13417   if (vec_len (file_name) > 255)
13418     {
13419       errmsg ("socket file name too long");
13420       return -99;
13421     }
13422   vec_add1 (file_name, 0);
13423
13424   M (MODIFY_VHOST_USER_IF, mp);
13425
13426   mp->sw_if_index = ntohl (sw_if_index);
13427   mp->is_server = is_server;
13428   mp->enable_gso = enable_gso;
13429   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13430   vec_free (file_name);
13431   if (custom_dev_instance != ~0)
13432     {
13433       mp->renumber = 1;
13434       mp->custom_dev_instance = ntohl (custom_dev_instance);
13435     }
13436
13437   S (mp);
13438   W (ret);
13439   return ret;
13440 }
13441
13442 static int
13443 api_delete_vhost_user_if (vat_main_t * vam)
13444 {
13445   unformat_input_t *i = vam->input;
13446   vl_api_delete_vhost_user_if_t *mp;
13447   u32 sw_if_index = ~0;
13448   u8 sw_if_index_set = 0;
13449   int ret;
13450
13451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13452     {
13453       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13454         sw_if_index_set = 1;
13455       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13456         sw_if_index_set = 1;
13457       else
13458         break;
13459     }
13460
13461   if (sw_if_index_set == 0)
13462     {
13463       errmsg ("missing sw_if_index or interface name");
13464       return -99;
13465     }
13466
13467
13468   M (DELETE_VHOST_USER_IF, mp);
13469
13470   mp->sw_if_index = ntohl (sw_if_index);
13471
13472   S (mp);
13473   W (ret);
13474   return ret;
13475 }
13476
13477 static void vl_api_sw_interface_vhost_user_details_t_handler
13478   (vl_api_sw_interface_vhost_user_details_t * mp)
13479 {
13480   vat_main_t *vam = &vat_main;
13481
13482   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13483          (char *) mp->interface_name,
13484          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13485          clib_net_to_host_u64 (mp->features), mp->is_server,
13486          ntohl (mp->num_regions), (char *) mp->sock_filename);
13487   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13488 }
13489
13490 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13491   (vl_api_sw_interface_vhost_user_details_t * mp)
13492 {
13493   vat_main_t *vam = &vat_main;
13494   vat_json_node_t *node = NULL;
13495
13496   if (VAT_JSON_ARRAY != vam->json_tree.type)
13497     {
13498       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13499       vat_json_init_array (&vam->json_tree);
13500     }
13501   node = vat_json_array_add (&vam->json_tree);
13502
13503   vat_json_init_object (node);
13504   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13505   vat_json_object_add_string_copy (node, "interface_name",
13506                                    mp->interface_name);
13507   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13508                             ntohl (mp->virtio_net_hdr_sz));
13509   vat_json_object_add_uint (node, "features",
13510                             clib_net_to_host_u64 (mp->features));
13511   vat_json_object_add_uint (node, "is_server", mp->is_server);
13512   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13513   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13514   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13515 }
13516
13517 static int
13518 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13519 {
13520   vl_api_sw_interface_vhost_user_dump_t *mp;
13521   vl_api_control_ping_t *mp_ping;
13522   int ret;
13523   print (vam->ofp,
13524          "Interface name            idx hdr_sz features server regions filename");
13525
13526   /* Get list of vhost-user interfaces */
13527   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13528   S (mp);
13529
13530   /* Use a control ping for synchronization */
13531   MPING (CONTROL_PING, mp_ping);
13532   S (mp_ping);
13533
13534   W (ret);
13535   return ret;
13536 }
13537
13538 static int
13539 api_show_version (vat_main_t * vam)
13540 {
13541   vl_api_show_version_t *mp;
13542   int ret;
13543
13544   M (SHOW_VERSION, mp);
13545
13546   S (mp);
13547   W (ret);
13548   return ret;
13549 }
13550
13551
13552 static int
13553 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13554 {
13555   unformat_input_t *line_input = vam->input;
13556   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13557   ip4_address_t local4, remote4;
13558   ip6_address_t local6, remote6;
13559   u8 is_add = 1;
13560   u8 ipv4_set = 0, ipv6_set = 0;
13561   u8 local_set = 0;
13562   u8 remote_set = 0;
13563   u8 grp_set = 0;
13564   u32 mcast_sw_if_index = ~0;
13565   u32 encap_vrf_id = 0;
13566   u32 decap_vrf_id = 0;
13567   u8 protocol = ~0;
13568   u32 vni;
13569   u8 vni_set = 0;
13570   int ret;
13571
13572   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13573   clib_memset (&local4, 0, sizeof local4);
13574   clib_memset (&remote4, 0, sizeof remote4);
13575   clib_memset (&local6, 0, sizeof local6);
13576   clib_memset (&remote6, 0, sizeof remote6);
13577
13578   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13579     {
13580       if (unformat (line_input, "del"))
13581         is_add = 0;
13582       else if (unformat (line_input, "local %U",
13583                          unformat_ip4_address, &local4))
13584         {
13585           local_set = 1;
13586           ipv4_set = 1;
13587         }
13588       else if (unformat (line_input, "remote %U",
13589                          unformat_ip4_address, &remote4))
13590         {
13591           remote_set = 1;
13592           ipv4_set = 1;
13593         }
13594       else if (unformat (line_input, "local %U",
13595                          unformat_ip6_address, &local6))
13596         {
13597           local_set = 1;
13598           ipv6_set = 1;
13599         }
13600       else if (unformat (line_input, "remote %U",
13601                          unformat_ip6_address, &remote6))
13602         {
13603           remote_set = 1;
13604           ipv6_set = 1;
13605         }
13606       else if (unformat (line_input, "group %U %U",
13607                          unformat_ip4_address, &remote4,
13608                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13609         {
13610           grp_set = remote_set = 1;
13611           ipv4_set = 1;
13612         }
13613       else if (unformat (line_input, "group %U",
13614                          unformat_ip4_address, &remote4))
13615         {
13616           grp_set = remote_set = 1;
13617           ipv4_set = 1;
13618         }
13619       else if (unformat (line_input, "group %U %U",
13620                          unformat_ip6_address, &remote6,
13621                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13622         {
13623           grp_set = remote_set = 1;
13624           ipv6_set = 1;
13625         }
13626       else if (unformat (line_input, "group %U",
13627                          unformat_ip6_address, &remote6))
13628         {
13629           grp_set = remote_set = 1;
13630           ipv6_set = 1;
13631         }
13632       else
13633         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13634         ;
13635       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13636         ;
13637       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13638         ;
13639       else if (unformat (line_input, "vni %d", &vni))
13640         vni_set = 1;
13641       else if (unformat (line_input, "next-ip4"))
13642         protocol = 1;
13643       else if (unformat (line_input, "next-ip6"))
13644         protocol = 2;
13645       else if (unformat (line_input, "next-ethernet"))
13646         protocol = 3;
13647       else if (unformat (line_input, "next-nsh"))
13648         protocol = 4;
13649       else
13650         {
13651           errmsg ("parse error '%U'", format_unformat_error, line_input);
13652           return -99;
13653         }
13654     }
13655
13656   if (local_set == 0)
13657     {
13658       errmsg ("tunnel local address not specified");
13659       return -99;
13660     }
13661   if (remote_set == 0)
13662     {
13663       errmsg ("tunnel remote address not specified");
13664       return -99;
13665     }
13666   if (grp_set && mcast_sw_if_index == ~0)
13667     {
13668       errmsg ("tunnel nonexistent multicast device");
13669       return -99;
13670     }
13671   if (ipv4_set && ipv6_set)
13672     {
13673       errmsg ("both IPv4 and IPv6 addresses specified");
13674       return -99;
13675     }
13676
13677   if (vni_set == 0)
13678     {
13679       errmsg ("vni not specified");
13680       return -99;
13681     }
13682
13683   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13684
13685
13686   if (ipv6_set)
13687     {
13688       clib_memcpy (&mp->local, &local6, sizeof (local6));
13689       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13690     }
13691   else
13692     {
13693       clib_memcpy (&mp->local, &local4, sizeof (local4));
13694       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13695     }
13696
13697   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13698   mp->encap_vrf_id = ntohl (encap_vrf_id);
13699   mp->decap_vrf_id = ntohl (decap_vrf_id);
13700   mp->protocol = protocol;
13701   mp->vni = ntohl (vni);
13702   mp->is_add = is_add;
13703   mp->is_ipv6 = ipv6_set;
13704
13705   S (mp);
13706   W (ret);
13707   return ret;
13708 }
13709
13710 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13711   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13712 {
13713   vat_main_t *vam = &vat_main;
13714   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13715   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13716
13717   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13718          ntohl (mp->sw_if_index),
13719          format_ip46_address, &local, IP46_TYPE_ANY,
13720          format_ip46_address, &remote, IP46_TYPE_ANY,
13721          ntohl (mp->vni), mp->protocol,
13722          ntohl (mp->mcast_sw_if_index),
13723          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13724 }
13725
13726
13727 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13728   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13729 {
13730   vat_main_t *vam = &vat_main;
13731   vat_json_node_t *node = NULL;
13732   struct in_addr ip4;
13733   struct in6_addr ip6;
13734
13735   if (VAT_JSON_ARRAY != vam->json_tree.type)
13736     {
13737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13738       vat_json_init_array (&vam->json_tree);
13739     }
13740   node = vat_json_array_add (&vam->json_tree);
13741
13742   vat_json_init_object (node);
13743   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13744   if (mp->is_ipv6)
13745     {
13746       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13747       vat_json_object_add_ip6 (node, "local", ip6);
13748       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13749       vat_json_object_add_ip6 (node, "remote", ip6);
13750     }
13751   else
13752     {
13753       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13754       vat_json_object_add_ip4 (node, "local", ip4);
13755       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13756       vat_json_object_add_ip4 (node, "remote", ip4);
13757     }
13758   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13759   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13760   vat_json_object_add_uint (node, "mcast_sw_if_index",
13761                             ntohl (mp->mcast_sw_if_index));
13762   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13763   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13764   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13765 }
13766
13767 static int
13768 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13769 {
13770   unformat_input_t *i = vam->input;
13771   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13772   vl_api_control_ping_t *mp_ping;
13773   u32 sw_if_index;
13774   u8 sw_if_index_set = 0;
13775   int ret;
13776
13777   /* Parse args required to build the message */
13778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13779     {
13780       if (unformat (i, "sw_if_index %d", &sw_if_index))
13781         sw_if_index_set = 1;
13782       else
13783         break;
13784     }
13785
13786   if (sw_if_index_set == 0)
13787     {
13788       sw_if_index = ~0;
13789     }
13790
13791   if (!vam->json_output)
13792     {
13793       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13794              "sw_if_index", "local", "remote", "vni",
13795              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13796     }
13797
13798   /* Get list of vxlan-tunnel interfaces */
13799   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13800
13801   mp->sw_if_index = htonl (sw_if_index);
13802
13803   S (mp);
13804
13805   /* Use a control ping for synchronization */
13806   MPING (CONTROL_PING, mp_ping);
13807   S (mp_ping);
13808
13809   W (ret);
13810   return ret;
13811 }
13812
13813 static void vl_api_l2_fib_table_details_t_handler
13814   (vl_api_l2_fib_table_details_t * mp)
13815 {
13816   vat_main_t *vam = &vat_main;
13817
13818   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13819          "       %d       %d     %d",
13820          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13821          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13822          mp->bvi_mac);
13823 }
13824
13825 static void vl_api_l2_fib_table_details_t_handler_json
13826   (vl_api_l2_fib_table_details_t * mp)
13827 {
13828   vat_main_t *vam = &vat_main;
13829   vat_json_node_t *node = NULL;
13830
13831   if (VAT_JSON_ARRAY != vam->json_tree.type)
13832     {
13833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13834       vat_json_init_array (&vam->json_tree);
13835     }
13836   node = vat_json_array_add (&vam->json_tree);
13837
13838   vat_json_init_object (node);
13839   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13840   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13841   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13842   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13843   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13844   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13845 }
13846
13847 static int
13848 api_l2_fib_table_dump (vat_main_t * vam)
13849 {
13850   unformat_input_t *i = vam->input;
13851   vl_api_l2_fib_table_dump_t *mp;
13852   vl_api_control_ping_t *mp_ping;
13853   u32 bd_id;
13854   u8 bd_id_set = 0;
13855   int ret;
13856
13857   /* Parse args required to build the message */
13858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13859     {
13860       if (unformat (i, "bd_id %d", &bd_id))
13861         bd_id_set = 1;
13862       else
13863         break;
13864     }
13865
13866   if (bd_id_set == 0)
13867     {
13868       errmsg ("missing bridge domain");
13869       return -99;
13870     }
13871
13872   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13873
13874   /* Get list of l2 fib entries */
13875   M (L2_FIB_TABLE_DUMP, mp);
13876
13877   mp->bd_id = ntohl (bd_id);
13878   S (mp);
13879
13880   /* Use a control ping for synchronization */
13881   MPING (CONTROL_PING, mp_ping);
13882   S (mp_ping);
13883
13884   W (ret);
13885   return ret;
13886 }
13887
13888
13889 static int
13890 api_interface_name_renumber (vat_main_t * vam)
13891 {
13892   unformat_input_t *line_input = vam->input;
13893   vl_api_interface_name_renumber_t *mp;
13894   u32 sw_if_index = ~0;
13895   u32 new_show_dev_instance = ~0;
13896   int ret;
13897
13898   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13899     {
13900       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13901                     &sw_if_index))
13902         ;
13903       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13904         ;
13905       else if (unformat (line_input, "new_show_dev_instance %d",
13906                          &new_show_dev_instance))
13907         ;
13908       else
13909         break;
13910     }
13911
13912   if (sw_if_index == ~0)
13913     {
13914       errmsg ("missing interface name or sw_if_index");
13915       return -99;
13916     }
13917
13918   if (new_show_dev_instance == ~0)
13919     {
13920       errmsg ("missing new_show_dev_instance");
13921       return -99;
13922     }
13923
13924   M (INTERFACE_NAME_RENUMBER, mp);
13925
13926   mp->sw_if_index = ntohl (sw_if_index);
13927   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13928
13929   S (mp);
13930   W (ret);
13931   return ret;
13932 }
13933
13934 static int
13935 api_ip_probe_neighbor (vat_main_t * vam)
13936 {
13937   unformat_input_t *i = vam->input;
13938   vl_api_ip_probe_neighbor_t *mp;
13939   vl_api_address_t dst_adr = { };
13940   u8 int_set = 0;
13941   u8 adr_set = 0;
13942   u32 sw_if_index;
13943   int ret;
13944
13945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13946     {
13947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13948         int_set = 1;
13949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13950         int_set = 1;
13951       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13952         adr_set = 1;
13953       else
13954         break;
13955     }
13956
13957   if (int_set == 0)
13958     {
13959       errmsg ("missing interface");
13960       return -99;
13961     }
13962
13963   if (adr_set == 0)
13964     {
13965       errmsg ("missing addresses");
13966       return -99;
13967     }
13968
13969   M (IP_PROBE_NEIGHBOR, mp);
13970
13971   mp->sw_if_index = ntohl (sw_if_index);
13972   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13973
13974   S (mp);
13975   W (ret);
13976   return ret;
13977 }
13978
13979 static int
13980 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13981 {
13982   unformat_input_t *i = vam->input;
13983   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13984   u8 mode = IP_SCAN_V46_NEIGHBORS;
13985   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13986   int ret;
13987
13988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13989     {
13990       if (unformat (i, "ip4"))
13991         mode = IP_SCAN_V4_NEIGHBORS;
13992       else if (unformat (i, "ip6"))
13993         mode = IP_SCAN_V6_NEIGHBORS;
13994       if (unformat (i, "both"))
13995         mode = IP_SCAN_V46_NEIGHBORS;
13996       else if (unformat (i, "disable"))
13997         mode = IP_SCAN_DISABLED;
13998       else if (unformat (i, "interval %d", &interval))
13999         ;
14000       else if (unformat (i, "max-time %d", &time))
14001         ;
14002       else if (unformat (i, "max-update %d", &update))
14003         ;
14004       else if (unformat (i, "delay %d", &delay))
14005         ;
14006       else if (unformat (i, "stale %d", &stale))
14007         ;
14008       else
14009         break;
14010     }
14011
14012   if (interval > 255)
14013     {
14014       errmsg ("interval cannot exceed 255 minutes.");
14015       return -99;
14016     }
14017   if (time > 255)
14018     {
14019       errmsg ("max-time cannot exceed 255 usec.");
14020       return -99;
14021     }
14022   if (update > 255)
14023     {
14024       errmsg ("max-update cannot exceed 255.");
14025       return -99;
14026     }
14027   if (delay > 255)
14028     {
14029       errmsg ("delay cannot exceed 255 msec.");
14030       return -99;
14031     }
14032   if (stale > 255)
14033     {
14034       errmsg ("stale cannot exceed 255 minutes.");
14035       return -99;
14036     }
14037
14038   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14039   mp->mode = mode;
14040   mp->scan_interval = interval;
14041   mp->max_proc_time = time;
14042   mp->max_update = update;
14043   mp->scan_int_delay = delay;
14044   mp->stale_threshold = stale;
14045
14046   S (mp);
14047   W (ret);
14048   return ret;
14049 }
14050
14051 static int
14052 api_want_ip4_arp_events (vat_main_t * vam)
14053 {
14054   unformat_input_t *line_input = vam->input;
14055   vl_api_want_ip4_arp_events_t *mp;
14056   ip4_address_t address;
14057   int address_set = 0;
14058   u32 enable_disable = 1;
14059   int ret;
14060
14061   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14062     {
14063       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14064         address_set = 1;
14065       else if (unformat (line_input, "del"))
14066         enable_disable = 0;
14067       else
14068         break;
14069     }
14070
14071   if (address_set == 0)
14072     {
14073       errmsg ("missing addresses");
14074       return -99;
14075     }
14076
14077   M (WANT_IP4_ARP_EVENTS, mp);
14078   mp->enable_disable = enable_disable;
14079   mp->pid = htonl (getpid ());
14080   clib_memcpy (mp->ip, &address, sizeof (address));
14081
14082   S (mp);
14083   W (ret);
14084   return ret;
14085 }
14086
14087 static int
14088 api_want_ip6_nd_events (vat_main_t * vam)
14089 {
14090   unformat_input_t *line_input = vam->input;
14091   vl_api_want_ip6_nd_events_t *mp;
14092   vl_api_ip6_address_t address;
14093   int address_set = 0;
14094   u32 enable_disable = 1;
14095   int ret;
14096
14097   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14098     {
14099       if (unformat
14100           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14101         address_set = 1;
14102       else if (unformat (line_input, "del"))
14103         enable_disable = 0;
14104       else
14105         break;
14106     }
14107
14108   if (address_set == 0)
14109     {
14110       errmsg ("missing addresses");
14111       return -99;
14112     }
14113
14114   M (WANT_IP6_ND_EVENTS, mp);
14115   mp->enable_disable = enable_disable;
14116   mp->pid = htonl (getpid ());
14117   clib_memcpy (&mp->ip, &address, sizeof (address));
14118
14119   S (mp);
14120   W (ret);
14121   return ret;
14122 }
14123
14124 static int
14125 api_want_l2_macs_events (vat_main_t * vam)
14126 {
14127   unformat_input_t *line_input = vam->input;
14128   vl_api_want_l2_macs_events_t *mp;
14129   u8 enable_disable = 1;
14130   u32 scan_delay = 0;
14131   u32 max_macs_in_event = 0;
14132   u32 learn_limit = 0;
14133   int ret;
14134
14135   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14136     {
14137       if (unformat (line_input, "learn-limit %d", &learn_limit))
14138         ;
14139       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14140         ;
14141       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14142         ;
14143       else if (unformat (line_input, "disable"))
14144         enable_disable = 0;
14145       else
14146         break;
14147     }
14148
14149   M (WANT_L2_MACS_EVENTS, mp);
14150   mp->enable_disable = enable_disable;
14151   mp->pid = htonl (getpid ());
14152   mp->learn_limit = htonl (learn_limit);
14153   mp->scan_delay = (u8) scan_delay;
14154   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14155   S (mp);
14156   W (ret);
14157   return ret;
14158 }
14159
14160 static int
14161 api_input_acl_set_interface (vat_main_t * vam)
14162 {
14163   unformat_input_t *i = vam->input;
14164   vl_api_input_acl_set_interface_t *mp;
14165   u32 sw_if_index;
14166   int sw_if_index_set;
14167   u32 ip4_table_index = ~0;
14168   u32 ip6_table_index = ~0;
14169   u32 l2_table_index = ~0;
14170   u8 is_add = 1;
14171   int ret;
14172
14173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14174     {
14175       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14176         sw_if_index_set = 1;
14177       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14178         sw_if_index_set = 1;
14179       else if (unformat (i, "del"))
14180         is_add = 0;
14181       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14182         ;
14183       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14184         ;
14185       else if (unformat (i, "l2-table %d", &l2_table_index))
14186         ;
14187       else
14188         {
14189           clib_warning ("parse error '%U'", format_unformat_error, i);
14190           return -99;
14191         }
14192     }
14193
14194   if (sw_if_index_set == 0)
14195     {
14196       errmsg ("missing interface name or sw_if_index");
14197       return -99;
14198     }
14199
14200   M (INPUT_ACL_SET_INTERFACE, mp);
14201
14202   mp->sw_if_index = ntohl (sw_if_index);
14203   mp->ip4_table_index = ntohl (ip4_table_index);
14204   mp->ip6_table_index = ntohl (ip6_table_index);
14205   mp->l2_table_index = ntohl (l2_table_index);
14206   mp->is_add = is_add;
14207
14208   S (mp);
14209   W (ret);
14210   return ret;
14211 }
14212
14213 static int
14214 api_output_acl_set_interface (vat_main_t * vam)
14215 {
14216   unformat_input_t *i = vam->input;
14217   vl_api_output_acl_set_interface_t *mp;
14218   u32 sw_if_index;
14219   int sw_if_index_set;
14220   u32 ip4_table_index = ~0;
14221   u32 ip6_table_index = ~0;
14222   u32 l2_table_index = ~0;
14223   u8 is_add = 1;
14224   int ret;
14225
14226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14227     {
14228       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14229         sw_if_index_set = 1;
14230       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14231         sw_if_index_set = 1;
14232       else if (unformat (i, "del"))
14233         is_add = 0;
14234       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14235         ;
14236       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14237         ;
14238       else if (unformat (i, "l2-table %d", &l2_table_index))
14239         ;
14240       else
14241         {
14242           clib_warning ("parse error '%U'", format_unformat_error, i);
14243           return -99;
14244         }
14245     }
14246
14247   if (sw_if_index_set == 0)
14248     {
14249       errmsg ("missing interface name or sw_if_index");
14250       return -99;
14251     }
14252
14253   M (OUTPUT_ACL_SET_INTERFACE, mp);
14254
14255   mp->sw_if_index = ntohl (sw_if_index);
14256   mp->ip4_table_index = ntohl (ip4_table_index);
14257   mp->ip6_table_index = ntohl (ip6_table_index);
14258   mp->l2_table_index = ntohl (l2_table_index);
14259   mp->is_add = is_add;
14260
14261   S (mp);
14262   W (ret);
14263   return ret;
14264 }
14265
14266 static int
14267 api_ip_address_dump (vat_main_t * vam)
14268 {
14269   unformat_input_t *i = vam->input;
14270   vl_api_ip_address_dump_t *mp;
14271   vl_api_control_ping_t *mp_ping;
14272   u32 sw_if_index = ~0;
14273   u8 sw_if_index_set = 0;
14274   u8 ipv4_set = 0;
14275   u8 ipv6_set = 0;
14276   int ret;
14277
14278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14279     {
14280       if (unformat (i, "sw_if_index %d", &sw_if_index))
14281         sw_if_index_set = 1;
14282       else
14283         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14284         sw_if_index_set = 1;
14285       else if (unformat (i, "ipv4"))
14286         ipv4_set = 1;
14287       else if (unformat (i, "ipv6"))
14288         ipv6_set = 1;
14289       else
14290         break;
14291     }
14292
14293   if (ipv4_set && ipv6_set)
14294     {
14295       errmsg ("ipv4 and ipv6 flags cannot be both set");
14296       return -99;
14297     }
14298
14299   if ((!ipv4_set) && (!ipv6_set))
14300     {
14301       errmsg ("no ipv4 nor ipv6 flag set");
14302       return -99;
14303     }
14304
14305   if (sw_if_index_set == 0)
14306     {
14307       errmsg ("missing interface name or sw_if_index");
14308       return -99;
14309     }
14310
14311   vam->current_sw_if_index = sw_if_index;
14312   vam->is_ipv6 = ipv6_set;
14313
14314   M (IP_ADDRESS_DUMP, mp);
14315   mp->sw_if_index = ntohl (sw_if_index);
14316   mp->is_ipv6 = ipv6_set;
14317   S (mp);
14318
14319   /* Use a control ping for synchronization */
14320   MPING (CONTROL_PING, mp_ping);
14321   S (mp_ping);
14322
14323   W (ret);
14324   return ret;
14325 }
14326
14327 static int
14328 api_ip_dump (vat_main_t * vam)
14329 {
14330   vl_api_ip_dump_t *mp;
14331   vl_api_control_ping_t *mp_ping;
14332   unformat_input_t *in = vam->input;
14333   int ipv4_set = 0;
14334   int ipv6_set = 0;
14335   int is_ipv6;
14336   int i;
14337   int ret;
14338
14339   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14340     {
14341       if (unformat (in, "ipv4"))
14342         ipv4_set = 1;
14343       else if (unformat (in, "ipv6"))
14344         ipv6_set = 1;
14345       else
14346         break;
14347     }
14348
14349   if (ipv4_set && ipv6_set)
14350     {
14351       errmsg ("ipv4 and ipv6 flags cannot be both set");
14352       return -99;
14353     }
14354
14355   if ((!ipv4_set) && (!ipv6_set))
14356     {
14357       errmsg ("no ipv4 nor ipv6 flag set");
14358       return -99;
14359     }
14360
14361   is_ipv6 = ipv6_set;
14362   vam->is_ipv6 = is_ipv6;
14363
14364   /* free old data */
14365   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14366     {
14367       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14368     }
14369   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14370
14371   M (IP_DUMP, mp);
14372   mp->is_ipv6 = ipv6_set;
14373   S (mp);
14374
14375   /* Use a control ping for synchronization */
14376   MPING (CONTROL_PING, mp_ping);
14377   S (mp_ping);
14378
14379   W (ret);
14380   return ret;
14381 }
14382
14383 static int
14384 api_ipsec_spd_add_del (vat_main_t * vam)
14385 {
14386   unformat_input_t *i = vam->input;
14387   vl_api_ipsec_spd_add_del_t *mp;
14388   u32 spd_id = ~0;
14389   u8 is_add = 1;
14390   int ret;
14391
14392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14393     {
14394       if (unformat (i, "spd_id %d", &spd_id))
14395         ;
14396       else if (unformat (i, "del"))
14397         is_add = 0;
14398       else
14399         {
14400           clib_warning ("parse error '%U'", format_unformat_error, i);
14401           return -99;
14402         }
14403     }
14404   if (spd_id == ~0)
14405     {
14406       errmsg ("spd_id must be set");
14407       return -99;
14408     }
14409
14410   M (IPSEC_SPD_ADD_DEL, mp);
14411
14412   mp->spd_id = ntohl (spd_id);
14413   mp->is_add = is_add;
14414
14415   S (mp);
14416   W (ret);
14417   return ret;
14418 }
14419
14420 static int
14421 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14422 {
14423   unformat_input_t *i = vam->input;
14424   vl_api_ipsec_interface_add_del_spd_t *mp;
14425   u32 sw_if_index;
14426   u8 sw_if_index_set = 0;
14427   u32 spd_id = (u32) ~ 0;
14428   u8 is_add = 1;
14429   int ret;
14430
14431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14432     {
14433       if (unformat (i, "del"))
14434         is_add = 0;
14435       else if (unformat (i, "spd_id %d", &spd_id))
14436         ;
14437       else
14438         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14439         sw_if_index_set = 1;
14440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14441         sw_if_index_set = 1;
14442       else
14443         {
14444           clib_warning ("parse error '%U'", format_unformat_error, i);
14445           return -99;
14446         }
14447
14448     }
14449
14450   if (spd_id == (u32) ~ 0)
14451     {
14452       errmsg ("spd_id must be set");
14453       return -99;
14454     }
14455
14456   if (sw_if_index_set == 0)
14457     {
14458       errmsg ("missing interface name or sw_if_index");
14459       return -99;
14460     }
14461
14462   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14463
14464   mp->spd_id = ntohl (spd_id);
14465   mp->sw_if_index = ntohl (sw_if_index);
14466   mp->is_add = is_add;
14467
14468   S (mp);
14469   W (ret);
14470   return ret;
14471 }
14472
14473 static int
14474 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14475 {
14476   unformat_input_t *i = vam->input;
14477   vl_api_ipsec_spd_entry_add_del_t *mp;
14478   u8 is_add = 1, is_outbound = 0;
14479   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14480   i32 priority = 0;
14481   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14482   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14483   vl_api_address_t laddr_start = { }, laddr_stop =
14484   {
14485   }, raddr_start =
14486   {
14487   }, raddr_stop =
14488   {
14489   };
14490   int ret;
14491
14492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14493     {
14494       if (unformat (i, "del"))
14495         is_add = 0;
14496       if (unformat (i, "outbound"))
14497         is_outbound = 1;
14498       if (unformat (i, "inbound"))
14499         is_outbound = 0;
14500       else if (unformat (i, "spd_id %d", &spd_id))
14501         ;
14502       else if (unformat (i, "sa_id %d", &sa_id))
14503         ;
14504       else if (unformat (i, "priority %d", &priority))
14505         ;
14506       else if (unformat (i, "protocol %d", &protocol))
14507         ;
14508       else if (unformat (i, "lport_start %d", &lport_start))
14509         ;
14510       else if (unformat (i, "lport_stop %d", &lport_stop))
14511         ;
14512       else if (unformat (i, "rport_start %d", &rport_start))
14513         ;
14514       else if (unformat (i, "rport_stop %d", &rport_stop))
14515         ;
14516       else if (unformat (i, "laddr_start %U",
14517                          unformat_vl_api_address, &laddr_start))
14518         ;
14519       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14520                          &laddr_stop))
14521         ;
14522       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14523                          &raddr_start))
14524         ;
14525       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14526                          &raddr_stop))
14527         ;
14528       else
14529         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14530         {
14531           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14532             {
14533               clib_warning ("unsupported action: 'resolve'");
14534               return -99;
14535             }
14536         }
14537       else
14538         {
14539           clib_warning ("parse error '%U'", format_unformat_error, i);
14540           return -99;
14541         }
14542
14543     }
14544
14545   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14546
14547   mp->is_add = is_add;
14548
14549   mp->entry.spd_id = ntohl (spd_id);
14550   mp->entry.priority = ntohl (priority);
14551   mp->entry.is_outbound = is_outbound;
14552
14553   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14554                sizeof (vl_api_address_t));
14555   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14556                sizeof (vl_api_address_t));
14557   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14558                sizeof (vl_api_address_t));
14559   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14560                sizeof (vl_api_address_t));
14561
14562   mp->entry.protocol = (u8) protocol;
14563   mp->entry.local_port_start = ntohs ((u16) lport_start);
14564   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14565   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14566   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14567   mp->entry.policy = (u8) policy;
14568   mp->entry.sa_id = ntohl (sa_id);
14569
14570   S (mp);
14571   W (ret);
14572   return ret;
14573 }
14574
14575 static int
14576 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14577 {
14578   unformat_input_t *i = vam->input;
14579   vl_api_ipsec_sad_entry_add_del_t *mp;
14580   u32 sad_id = 0, spi = 0;
14581   u8 *ck = 0, *ik = 0;
14582   u8 is_add = 1;
14583
14584   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14585   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14586   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14587   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14588   vl_api_address_t tun_src, tun_dst;
14589   int ret;
14590
14591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14592     {
14593       if (unformat (i, "del"))
14594         is_add = 0;
14595       else if (unformat (i, "sad_id %d", &sad_id))
14596         ;
14597       else if (unformat (i, "spi %d", &spi))
14598         ;
14599       else if (unformat (i, "esp"))
14600         protocol = IPSEC_API_PROTO_ESP;
14601       else
14602         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14603         {
14604           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14605           if (ADDRESS_IP6 == tun_src.af)
14606             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14607         }
14608       else
14609         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14610         {
14611           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14612           if (ADDRESS_IP6 == tun_src.af)
14613             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14614         }
14615       else
14616         if (unformat (i, "crypto_alg %U",
14617                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14618         ;
14619       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14620         ;
14621       else if (unformat (i, "integ_alg %U",
14622                          unformat_ipsec_api_integ_alg, &integ_alg))
14623         ;
14624       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14625         ;
14626       else
14627         {
14628           clib_warning ("parse error '%U'", format_unformat_error, i);
14629           return -99;
14630         }
14631
14632     }
14633
14634   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14635
14636   mp->is_add = is_add;
14637   mp->entry.sad_id = ntohl (sad_id);
14638   mp->entry.protocol = protocol;
14639   mp->entry.spi = ntohl (spi);
14640   mp->entry.flags = flags;
14641
14642   mp->entry.crypto_algorithm = crypto_alg;
14643   mp->entry.integrity_algorithm = integ_alg;
14644   mp->entry.crypto_key.length = vec_len (ck);
14645   mp->entry.integrity_key.length = vec_len (ik);
14646
14647   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14648     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14649
14650   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14651     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14652
14653   if (ck)
14654     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14655   if (ik)
14656     clib_memcpy (mp->entry.integrity_key.data, ik,
14657                  mp->entry.integrity_key.length);
14658
14659   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14660     {
14661       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14662                    sizeof (mp->entry.tunnel_src));
14663       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14664                    sizeof (mp->entry.tunnel_dst));
14665     }
14666
14667   S (mp);
14668   W (ret);
14669   return ret;
14670 }
14671
14672 static int
14673 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14674 {
14675   unformat_input_t *i = vam->input;
14676   vl_api_ipsec_tunnel_if_add_del_t *mp;
14677   u32 local_spi = 0, remote_spi = 0;
14678   u32 crypto_alg = 0, integ_alg = 0;
14679   u8 *lck = NULL, *rck = NULL;
14680   u8 *lik = NULL, *rik = NULL;
14681   vl_api_address_t local_ip = { 0 };
14682   vl_api_address_t remote_ip = { 0 };
14683   f64 before = 0;
14684   u8 is_add = 1;
14685   u8 esn = 0;
14686   u8 anti_replay = 0;
14687   u8 renumber = 0;
14688   u32 instance = ~0;
14689   u32 count = 1, jj;
14690   int ret = -1;
14691
14692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14693     {
14694       if (unformat (i, "del"))
14695         is_add = 0;
14696       else if (unformat (i, "esn"))
14697         esn = 1;
14698       else if (unformat (i, "anti-replay"))
14699         anti_replay = 1;
14700       else if (unformat (i, "count %d", &count))
14701         ;
14702       else if (unformat (i, "local_spi %d", &local_spi))
14703         ;
14704       else if (unformat (i, "remote_spi %d", &remote_spi))
14705         ;
14706       else
14707         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14708         ;
14709       else
14710         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14711         ;
14712       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14713         ;
14714       else
14715         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14716         ;
14717       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14718         ;
14719       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14720         ;
14721       else
14722         if (unformat
14723             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14724         {
14725           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14726             {
14727               errmsg ("unsupported crypto-alg: '%U'\n",
14728                       format_ipsec_crypto_alg, crypto_alg);
14729               return -99;
14730             }
14731         }
14732       else
14733         if (unformat
14734             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14735         {
14736           if (integ_alg >= IPSEC_INTEG_N_ALG)
14737             {
14738               errmsg ("unsupported integ-alg: '%U'\n",
14739                       format_ipsec_integ_alg, integ_alg);
14740               return -99;
14741             }
14742         }
14743       else if (unformat (i, "instance %u", &instance))
14744         renumber = 1;
14745       else
14746         {
14747           errmsg ("parse error '%U'\n", format_unformat_error, i);
14748           return -99;
14749         }
14750     }
14751
14752   if (count > 1)
14753     {
14754       /* Turn on async mode */
14755       vam->async_mode = 1;
14756       vam->async_errors = 0;
14757       before = vat_time_now (vam);
14758     }
14759
14760   for (jj = 0; jj < count; jj++)
14761     {
14762       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14763
14764       mp->is_add = is_add;
14765       mp->esn = esn;
14766       mp->anti_replay = anti_replay;
14767
14768       if (jj > 0)
14769         increment_address (&remote_ip);
14770
14771       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14772       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14773
14774       mp->local_spi = htonl (local_spi + jj);
14775       mp->remote_spi = htonl (remote_spi + jj);
14776       mp->crypto_alg = (u8) crypto_alg;
14777
14778       mp->local_crypto_key_len = 0;
14779       if (lck)
14780         {
14781           mp->local_crypto_key_len = vec_len (lck);
14782           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14783             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14784           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14785         }
14786
14787       mp->remote_crypto_key_len = 0;
14788       if (rck)
14789         {
14790           mp->remote_crypto_key_len = vec_len (rck);
14791           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14792             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14793           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14794         }
14795
14796       mp->integ_alg = (u8) integ_alg;
14797
14798       mp->local_integ_key_len = 0;
14799       if (lik)
14800         {
14801           mp->local_integ_key_len = vec_len (lik);
14802           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14803             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14804           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14805         }
14806
14807       mp->remote_integ_key_len = 0;
14808       if (rik)
14809         {
14810           mp->remote_integ_key_len = vec_len (rik);
14811           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14812             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14813           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14814         }
14815
14816       if (renumber)
14817         {
14818           mp->renumber = renumber;
14819           mp->show_instance = ntohl (instance);
14820         }
14821       S (mp);
14822     }
14823
14824   /* When testing multiple add/del ops, use a control-ping to sync */
14825   if (count > 1)
14826     {
14827       vl_api_control_ping_t *mp_ping;
14828       f64 after;
14829       f64 timeout;
14830
14831       /* Shut off async mode */
14832       vam->async_mode = 0;
14833
14834       MPING (CONTROL_PING, mp_ping);
14835       S (mp_ping);
14836
14837       timeout = vat_time_now (vam) + 1.0;
14838       while (vat_time_now (vam) < timeout)
14839         if (vam->result_ready == 1)
14840           goto out;
14841       vam->retval = -99;
14842
14843     out:
14844       if (vam->retval == -99)
14845         errmsg ("timeout");
14846
14847       if (vam->async_errors > 0)
14848         {
14849           errmsg ("%d asynchronous errors", vam->async_errors);
14850           vam->retval = -98;
14851         }
14852       vam->async_errors = 0;
14853       after = vat_time_now (vam);
14854
14855       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14856       if (jj > 0)
14857         count = jj;
14858
14859       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14860              count, after - before, count / (after - before));
14861     }
14862   else
14863     {
14864       /* Wait for a reply... */
14865       W (ret);
14866       return ret;
14867     }
14868
14869   return ret;
14870 }
14871
14872 static void
14873 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14874 {
14875   vat_main_t *vam = &vat_main;
14876
14877   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14878          "crypto_key %U integ_alg %u integ_key %U flags %x "
14879          "tunnel_src_addr %U tunnel_dst_addr %U "
14880          "salt %u seq_outbound %lu last_seq_inbound %lu "
14881          "replay_window %lu\n",
14882          ntohl (mp->entry.sad_id),
14883          ntohl (mp->sw_if_index),
14884          ntohl (mp->entry.spi),
14885          ntohl (mp->entry.protocol),
14886          ntohl (mp->entry.crypto_algorithm),
14887          format_hex_bytes, mp->entry.crypto_key.data,
14888          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14889          format_hex_bytes, mp->entry.integrity_key.data,
14890          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14891          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14892          &mp->entry.tunnel_dst, ntohl (mp->salt),
14893          clib_net_to_host_u64 (mp->seq_outbound),
14894          clib_net_to_host_u64 (mp->last_seq_inbound),
14895          clib_net_to_host_u64 (mp->replay_window));
14896 }
14897
14898 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14899 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14900
14901 static void vl_api_ipsec_sa_details_t_handler_json
14902   (vl_api_ipsec_sa_details_t * mp)
14903 {
14904   vat_main_t *vam = &vat_main;
14905   vat_json_node_t *node = NULL;
14906   vl_api_ipsec_sad_flags_t flags;
14907
14908   if (VAT_JSON_ARRAY != vam->json_tree.type)
14909     {
14910       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14911       vat_json_init_array (&vam->json_tree);
14912     }
14913   node = vat_json_array_add (&vam->json_tree);
14914
14915   vat_json_init_object (node);
14916   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14917   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14918   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14919   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14920   vat_json_object_add_uint (node, "crypto_alg",
14921                             ntohl (mp->entry.crypto_algorithm));
14922   vat_json_object_add_uint (node, "integ_alg",
14923                             ntohl (mp->entry.integrity_algorithm));
14924   flags = ntohl (mp->entry.flags);
14925   vat_json_object_add_uint (node, "use_esn",
14926                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14927   vat_json_object_add_uint (node, "use_anti_replay",
14928                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14929   vat_json_object_add_uint (node, "is_tunnel",
14930                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14931   vat_json_object_add_uint (node, "is_tunnel_ip6",
14932                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14933   vat_json_object_add_uint (node, "udp_encap",
14934                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14935   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14936                              mp->entry.crypto_key.length);
14937   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14938                              mp->entry.integrity_key.length);
14939   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14940   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14941   vat_json_object_add_uint (node, "replay_window",
14942                             clib_net_to_host_u64 (mp->replay_window));
14943 }
14944
14945 static int
14946 api_ipsec_sa_dump (vat_main_t * vam)
14947 {
14948   unformat_input_t *i = vam->input;
14949   vl_api_ipsec_sa_dump_t *mp;
14950   vl_api_control_ping_t *mp_ping;
14951   u32 sa_id = ~0;
14952   int ret;
14953
14954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14955     {
14956       if (unformat (i, "sa_id %d", &sa_id))
14957         ;
14958       else
14959         {
14960           clib_warning ("parse error '%U'", format_unformat_error, i);
14961           return -99;
14962         }
14963     }
14964
14965   M (IPSEC_SA_DUMP, mp);
14966
14967   mp->sa_id = ntohl (sa_id);
14968
14969   S (mp);
14970
14971   /* Use a control ping for synchronization */
14972   M (CONTROL_PING, mp_ping);
14973   S (mp_ping);
14974
14975   W (ret);
14976   return ret;
14977 }
14978
14979 static int
14980 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14981 {
14982   unformat_input_t *i = vam->input;
14983   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14984   u32 sw_if_index = ~0;
14985   u32 sa_id = ~0;
14986   u8 is_outbound = (u8) ~ 0;
14987   int ret;
14988
14989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14990     {
14991       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14992         ;
14993       else if (unformat (i, "sa_id %d", &sa_id))
14994         ;
14995       else if (unformat (i, "outbound"))
14996         is_outbound = 1;
14997       else if (unformat (i, "inbound"))
14998         is_outbound = 0;
14999       else
15000         {
15001           clib_warning ("parse error '%U'", format_unformat_error, i);
15002           return -99;
15003         }
15004     }
15005
15006   if (sw_if_index == ~0)
15007     {
15008       errmsg ("interface must be specified");
15009       return -99;
15010     }
15011
15012   if (sa_id == ~0)
15013     {
15014       errmsg ("SA ID must be specified");
15015       return -99;
15016     }
15017
15018   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15019
15020   mp->sw_if_index = htonl (sw_if_index);
15021   mp->sa_id = htonl (sa_id);
15022   mp->is_outbound = is_outbound;
15023
15024   S (mp);
15025   W (ret);
15026
15027   return ret;
15028 }
15029
15030 static int
15031 api_get_first_msg_id (vat_main_t * vam)
15032 {
15033   vl_api_get_first_msg_id_t *mp;
15034   unformat_input_t *i = vam->input;
15035   u8 *name;
15036   u8 name_set = 0;
15037   int ret;
15038
15039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15040     {
15041       if (unformat (i, "client %s", &name))
15042         name_set = 1;
15043       else
15044         break;
15045     }
15046
15047   if (name_set == 0)
15048     {
15049       errmsg ("missing client name");
15050       return -99;
15051     }
15052   vec_add1 (name, 0);
15053
15054   if (vec_len (name) > 63)
15055     {
15056       errmsg ("client name too long");
15057       return -99;
15058     }
15059
15060   M (GET_FIRST_MSG_ID, mp);
15061   clib_memcpy (mp->name, name, vec_len (name));
15062   S (mp);
15063   W (ret);
15064   return ret;
15065 }
15066
15067 static int
15068 api_cop_interface_enable_disable (vat_main_t * vam)
15069 {
15070   unformat_input_t *line_input = vam->input;
15071   vl_api_cop_interface_enable_disable_t *mp;
15072   u32 sw_if_index = ~0;
15073   u8 enable_disable = 1;
15074   int ret;
15075
15076   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15077     {
15078       if (unformat (line_input, "disable"))
15079         enable_disable = 0;
15080       if (unformat (line_input, "enable"))
15081         enable_disable = 1;
15082       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15083                          vam, &sw_if_index))
15084         ;
15085       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15086         ;
15087       else
15088         break;
15089     }
15090
15091   if (sw_if_index == ~0)
15092     {
15093       errmsg ("missing interface name or sw_if_index");
15094       return -99;
15095     }
15096
15097   /* Construct the API message */
15098   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15099   mp->sw_if_index = ntohl (sw_if_index);
15100   mp->enable_disable = enable_disable;
15101
15102   /* send it... */
15103   S (mp);
15104   /* Wait for the reply */
15105   W (ret);
15106   return ret;
15107 }
15108
15109 static int
15110 api_cop_whitelist_enable_disable (vat_main_t * vam)
15111 {
15112   unformat_input_t *line_input = vam->input;
15113   vl_api_cop_whitelist_enable_disable_t *mp;
15114   u32 sw_if_index = ~0;
15115   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15116   u32 fib_id = 0;
15117   int ret;
15118
15119   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15120     {
15121       if (unformat (line_input, "ip4"))
15122         ip4 = 1;
15123       else if (unformat (line_input, "ip6"))
15124         ip6 = 1;
15125       else if (unformat (line_input, "default"))
15126         default_cop = 1;
15127       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15128                          vam, &sw_if_index))
15129         ;
15130       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15131         ;
15132       else if (unformat (line_input, "fib-id %d", &fib_id))
15133         ;
15134       else
15135         break;
15136     }
15137
15138   if (sw_if_index == ~0)
15139     {
15140       errmsg ("missing interface name or sw_if_index");
15141       return -99;
15142     }
15143
15144   /* Construct the API message */
15145   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15146   mp->sw_if_index = ntohl (sw_if_index);
15147   mp->fib_id = ntohl (fib_id);
15148   mp->ip4 = ip4;
15149   mp->ip6 = ip6;
15150   mp->default_cop = default_cop;
15151
15152   /* send it... */
15153   S (mp);
15154   /* Wait for the reply */
15155   W (ret);
15156   return ret;
15157 }
15158
15159 static int
15160 api_get_node_graph (vat_main_t * vam)
15161 {
15162   vl_api_get_node_graph_t *mp;
15163   int ret;
15164
15165   M (GET_NODE_GRAPH, mp);
15166
15167   /* send it... */
15168   S (mp);
15169   /* Wait for the reply */
15170   W (ret);
15171   return ret;
15172 }
15173
15174 /* *INDENT-OFF* */
15175 /** Used for parsing LISP eids */
15176 typedef CLIB_PACKED(struct{
15177   u8 addr[16];   /**< eid address */
15178   u32 len;       /**< prefix length if IP */
15179   u8 type;      /**< type of eid */
15180 }) lisp_eid_vat_t;
15181 /* *INDENT-ON* */
15182
15183 static uword
15184 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15185 {
15186   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15187
15188   clib_memset (a, 0, sizeof (a[0]));
15189
15190   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15191     {
15192       a->type = 0;              /* ipv4 type */
15193     }
15194   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15195     {
15196       a->type = 1;              /* ipv6 type */
15197     }
15198   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15199     {
15200       a->type = 2;              /* mac type */
15201     }
15202   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15203     {
15204       a->type = 3;              /* NSH type */
15205       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15206       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15207     }
15208   else
15209     {
15210       return 0;
15211     }
15212
15213   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15214     {
15215       return 0;
15216     }
15217
15218   return 1;
15219 }
15220
15221 static int
15222 lisp_eid_size_vat (u8 type)
15223 {
15224   switch (type)
15225     {
15226     case 0:
15227       return 4;
15228     case 1:
15229       return 16;
15230     case 2:
15231       return 6;
15232     case 3:
15233       return 5;
15234     }
15235   return 0;
15236 }
15237
15238 static void
15239 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15240 {
15241   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15242 }
15243
15244 static int
15245 api_one_add_del_locator_set (vat_main_t * vam)
15246 {
15247   unformat_input_t *input = vam->input;
15248   vl_api_one_add_del_locator_set_t *mp;
15249   u8 is_add = 1;
15250   u8 *locator_set_name = NULL;
15251   u8 locator_set_name_set = 0;
15252   vl_api_local_locator_t locator, *locators = 0;
15253   u32 sw_if_index, priority, weight;
15254   u32 data_len = 0;
15255
15256   int ret;
15257   /* Parse args required to build the message */
15258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15259     {
15260       if (unformat (input, "del"))
15261         {
15262           is_add = 0;
15263         }
15264       else if (unformat (input, "locator-set %s", &locator_set_name))
15265         {
15266           locator_set_name_set = 1;
15267         }
15268       else if (unformat (input, "sw_if_index %u p %u w %u",
15269                          &sw_if_index, &priority, &weight))
15270         {
15271           locator.sw_if_index = htonl (sw_if_index);
15272           locator.priority = priority;
15273           locator.weight = weight;
15274           vec_add1 (locators, locator);
15275         }
15276       else
15277         if (unformat
15278             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15279              &sw_if_index, &priority, &weight))
15280         {
15281           locator.sw_if_index = htonl (sw_if_index);
15282           locator.priority = priority;
15283           locator.weight = weight;
15284           vec_add1 (locators, locator);
15285         }
15286       else
15287         break;
15288     }
15289
15290   if (locator_set_name_set == 0)
15291     {
15292       errmsg ("missing locator-set name");
15293       vec_free (locators);
15294       return -99;
15295     }
15296
15297   if (vec_len (locator_set_name) > 64)
15298     {
15299       errmsg ("locator-set name too long");
15300       vec_free (locator_set_name);
15301       vec_free (locators);
15302       return -99;
15303     }
15304   vec_add1 (locator_set_name, 0);
15305
15306   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15307
15308   /* Construct the API message */
15309   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15310
15311   mp->is_add = is_add;
15312   clib_memcpy (mp->locator_set_name, locator_set_name,
15313                vec_len (locator_set_name));
15314   vec_free (locator_set_name);
15315
15316   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15317   if (locators)
15318     clib_memcpy (mp->locators, locators, data_len);
15319   vec_free (locators);
15320
15321   /* send it... */
15322   S (mp);
15323
15324   /* Wait for a reply... */
15325   W (ret);
15326   return ret;
15327 }
15328
15329 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15330
15331 static int
15332 api_one_add_del_locator (vat_main_t * vam)
15333 {
15334   unformat_input_t *input = vam->input;
15335   vl_api_one_add_del_locator_t *mp;
15336   u32 tmp_if_index = ~0;
15337   u32 sw_if_index = ~0;
15338   u8 sw_if_index_set = 0;
15339   u8 sw_if_index_if_name_set = 0;
15340   u32 priority = ~0;
15341   u8 priority_set = 0;
15342   u32 weight = ~0;
15343   u8 weight_set = 0;
15344   u8 is_add = 1;
15345   u8 *locator_set_name = NULL;
15346   u8 locator_set_name_set = 0;
15347   int ret;
15348
15349   /* Parse args required to build the message */
15350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15351     {
15352       if (unformat (input, "del"))
15353         {
15354           is_add = 0;
15355         }
15356       else if (unformat (input, "locator-set %s", &locator_set_name))
15357         {
15358           locator_set_name_set = 1;
15359         }
15360       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15361                          &tmp_if_index))
15362         {
15363           sw_if_index_if_name_set = 1;
15364           sw_if_index = tmp_if_index;
15365         }
15366       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15367         {
15368           sw_if_index_set = 1;
15369           sw_if_index = tmp_if_index;
15370         }
15371       else if (unformat (input, "p %d", &priority))
15372         {
15373           priority_set = 1;
15374         }
15375       else if (unformat (input, "w %d", &weight))
15376         {
15377           weight_set = 1;
15378         }
15379       else
15380         break;
15381     }
15382
15383   if (locator_set_name_set == 0)
15384     {
15385       errmsg ("missing locator-set name");
15386       return -99;
15387     }
15388
15389   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15390     {
15391       errmsg ("missing sw_if_index");
15392       vec_free (locator_set_name);
15393       return -99;
15394     }
15395
15396   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15397     {
15398       errmsg ("cannot use both params interface name and sw_if_index");
15399       vec_free (locator_set_name);
15400       return -99;
15401     }
15402
15403   if (priority_set == 0)
15404     {
15405       errmsg ("missing locator-set priority");
15406       vec_free (locator_set_name);
15407       return -99;
15408     }
15409
15410   if (weight_set == 0)
15411     {
15412       errmsg ("missing locator-set weight");
15413       vec_free (locator_set_name);
15414       return -99;
15415     }
15416
15417   if (vec_len (locator_set_name) > 64)
15418     {
15419       errmsg ("locator-set name too long");
15420       vec_free (locator_set_name);
15421       return -99;
15422     }
15423   vec_add1 (locator_set_name, 0);
15424
15425   /* Construct the API message */
15426   M (ONE_ADD_DEL_LOCATOR, mp);
15427
15428   mp->is_add = is_add;
15429   mp->sw_if_index = ntohl (sw_if_index);
15430   mp->priority = priority;
15431   mp->weight = weight;
15432   clib_memcpy (mp->locator_set_name, locator_set_name,
15433                vec_len (locator_set_name));
15434   vec_free (locator_set_name);
15435
15436   /* send it... */
15437   S (mp);
15438
15439   /* Wait for a reply... */
15440   W (ret);
15441   return ret;
15442 }
15443
15444 #define api_lisp_add_del_locator api_one_add_del_locator
15445
15446 uword
15447 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15448 {
15449   u32 *key_id = va_arg (*args, u32 *);
15450   u8 *s = 0;
15451
15452   if (unformat (input, "%s", &s))
15453     {
15454       if (!strcmp ((char *) s, "sha1"))
15455         key_id[0] = HMAC_SHA_1_96;
15456       else if (!strcmp ((char *) s, "sha256"))
15457         key_id[0] = HMAC_SHA_256_128;
15458       else
15459         {
15460           clib_warning ("invalid key_id: '%s'", s);
15461           key_id[0] = HMAC_NO_KEY;
15462         }
15463     }
15464   else
15465     return 0;
15466
15467   vec_free (s);
15468   return 1;
15469 }
15470
15471 static int
15472 api_one_add_del_local_eid (vat_main_t * vam)
15473 {
15474   unformat_input_t *input = vam->input;
15475   vl_api_one_add_del_local_eid_t *mp;
15476   u8 is_add = 1;
15477   u8 eid_set = 0;
15478   lisp_eid_vat_t _eid, *eid = &_eid;
15479   u8 *locator_set_name = 0;
15480   u8 locator_set_name_set = 0;
15481   u32 vni = 0;
15482   u16 key_id = 0;
15483   u8 *key = 0;
15484   int ret;
15485
15486   /* Parse args required to build the message */
15487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15488     {
15489       if (unformat (input, "del"))
15490         {
15491           is_add = 0;
15492         }
15493       else if (unformat (input, "vni %d", &vni))
15494         {
15495           ;
15496         }
15497       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15498         {
15499           eid_set = 1;
15500         }
15501       else if (unformat (input, "locator-set %s", &locator_set_name))
15502         {
15503           locator_set_name_set = 1;
15504         }
15505       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15506         ;
15507       else if (unformat (input, "secret-key %_%v%_", &key))
15508         ;
15509       else
15510         break;
15511     }
15512
15513   if (locator_set_name_set == 0)
15514     {
15515       errmsg ("missing locator-set name");
15516       return -99;
15517     }
15518
15519   if (0 == eid_set)
15520     {
15521       errmsg ("EID address not set!");
15522       vec_free (locator_set_name);
15523       return -99;
15524     }
15525
15526   if (key && (0 == key_id))
15527     {
15528       errmsg ("invalid key_id!");
15529       return -99;
15530     }
15531
15532   if (vec_len (key) > 64)
15533     {
15534       errmsg ("key too long");
15535       vec_free (key);
15536       return -99;
15537     }
15538
15539   if (vec_len (locator_set_name) > 64)
15540     {
15541       errmsg ("locator-set name too long");
15542       vec_free (locator_set_name);
15543       return -99;
15544     }
15545   vec_add1 (locator_set_name, 0);
15546
15547   /* Construct the API message */
15548   M (ONE_ADD_DEL_LOCAL_EID, mp);
15549
15550   mp->is_add = is_add;
15551   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15552   mp->eid_type = eid->type;
15553   mp->prefix_len = eid->len;
15554   mp->vni = clib_host_to_net_u32 (vni);
15555   mp->key_id = clib_host_to_net_u16 (key_id);
15556   clib_memcpy (mp->locator_set_name, locator_set_name,
15557                vec_len (locator_set_name));
15558   clib_memcpy (mp->key, key, vec_len (key));
15559
15560   vec_free (locator_set_name);
15561   vec_free (key);
15562
15563   /* send it... */
15564   S (mp);
15565
15566   /* Wait for a reply... */
15567   W (ret);
15568   return ret;
15569 }
15570
15571 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15572
15573 static int
15574 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15575 {
15576   u32 dp_table = 0, vni = 0;;
15577   unformat_input_t *input = vam->input;
15578   vl_api_gpe_add_del_fwd_entry_t *mp;
15579   u8 is_add = 1;
15580   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15581   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15582   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15583   u32 action = ~0, w;
15584   ip4_address_t rmt_rloc4, lcl_rloc4;
15585   ip6_address_t rmt_rloc6, lcl_rloc6;
15586   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15587   int ret;
15588
15589   clib_memset (&rloc, 0, sizeof (rloc));
15590
15591   /* Parse args required to build the message */
15592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15593     {
15594       if (unformat (input, "del"))
15595         is_add = 0;
15596       else if (unformat (input, "add"))
15597         is_add = 1;
15598       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15599         {
15600           rmt_eid_set = 1;
15601         }
15602       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15603         {
15604           lcl_eid_set = 1;
15605         }
15606       else if (unformat (input, "vrf %d", &dp_table))
15607         ;
15608       else if (unformat (input, "bd %d", &dp_table))
15609         ;
15610       else if (unformat (input, "vni %d", &vni))
15611         ;
15612       else if (unformat (input, "w %d", &w))
15613         {
15614           if (!curr_rloc)
15615             {
15616               errmsg ("No RLOC configured for setting priority/weight!");
15617               return -99;
15618             }
15619           curr_rloc->weight = w;
15620         }
15621       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15622                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15623         {
15624           rloc.is_ip4 = 1;
15625
15626           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15627           rloc.weight = 0;
15628           vec_add1 (lcl_locs, rloc);
15629
15630           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15631           vec_add1 (rmt_locs, rloc);
15632           /* weight saved in rmt loc */
15633           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15634         }
15635       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15636                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15637         {
15638           rloc.is_ip4 = 0;
15639           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15640           rloc.weight = 0;
15641           vec_add1 (lcl_locs, rloc);
15642
15643           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15644           vec_add1 (rmt_locs, rloc);
15645           /* weight saved in rmt loc */
15646           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15647         }
15648       else if (unformat (input, "action %d", &action))
15649         {
15650           ;
15651         }
15652       else
15653         {
15654           clib_warning ("parse error '%U'", format_unformat_error, input);
15655           return -99;
15656         }
15657     }
15658
15659   if (!rmt_eid_set)
15660     {
15661       errmsg ("remote eid addresses not set");
15662       return -99;
15663     }
15664
15665   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15666     {
15667       errmsg ("eid types don't match");
15668       return -99;
15669     }
15670
15671   if (0 == rmt_locs && (u32) ~ 0 == action)
15672     {
15673       errmsg ("action not set for negative mapping");
15674       return -99;
15675     }
15676
15677   /* Construct the API message */
15678   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15679       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15680
15681   mp->is_add = is_add;
15682   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15683   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15684   mp->eid_type = rmt_eid->type;
15685   mp->dp_table = clib_host_to_net_u32 (dp_table);
15686   mp->vni = clib_host_to_net_u32 (vni);
15687   mp->rmt_len = rmt_eid->len;
15688   mp->lcl_len = lcl_eid->len;
15689   mp->action = action;
15690
15691   if (0 != rmt_locs && 0 != lcl_locs)
15692     {
15693       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15694       clib_memcpy (mp->locs, lcl_locs,
15695                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15696
15697       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15698       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15699                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15700     }
15701   vec_free (lcl_locs);
15702   vec_free (rmt_locs);
15703
15704   /* send it... */
15705   S (mp);
15706
15707   /* Wait for a reply... */
15708   W (ret);
15709   return ret;
15710 }
15711
15712 static int
15713 api_one_add_del_map_server (vat_main_t * vam)
15714 {
15715   unformat_input_t *input = vam->input;
15716   vl_api_one_add_del_map_server_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_SERVER, 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_server api_one_add_del_map_server
15779
15780 static int
15781 api_one_add_del_map_resolver (vat_main_t * vam)
15782 {
15783   unformat_input_t *input = vam->input;
15784   vl_api_one_add_del_map_resolver_t *mp;
15785   u8 is_add = 1;
15786   u8 ipv4_set = 0;
15787   u8 ipv6_set = 0;
15788   ip4_address_t ipv4;
15789   ip6_address_t ipv6;
15790   int ret;
15791
15792   /* Parse args required to build the message */
15793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15794     {
15795       if (unformat (input, "del"))
15796         {
15797           is_add = 0;
15798         }
15799       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15800         {
15801           ipv4_set = 1;
15802         }
15803       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15804         {
15805           ipv6_set = 1;
15806         }
15807       else
15808         break;
15809     }
15810
15811   if (ipv4_set && ipv6_set)
15812     {
15813       errmsg ("both eid v4 and v6 addresses set");
15814       return -99;
15815     }
15816
15817   if (!ipv4_set && !ipv6_set)
15818     {
15819       errmsg ("eid addresses not set");
15820       return -99;
15821     }
15822
15823   /* Construct the API message */
15824   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15825
15826   mp->is_add = is_add;
15827   if (ipv6_set)
15828     {
15829       mp->is_ipv6 = 1;
15830       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15831     }
15832   else
15833     {
15834       mp->is_ipv6 = 0;
15835       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15836     }
15837
15838   /* send it... */
15839   S (mp);
15840
15841   /* Wait for a reply... */
15842   W (ret);
15843   return ret;
15844 }
15845
15846 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15847
15848 static int
15849 api_lisp_gpe_enable_disable (vat_main_t * vam)
15850 {
15851   unformat_input_t *input = vam->input;
15852   vl_api_gpe_enable_disable_t *mp;
15853   u8 is_set = 0;
15854   u8 is_en = 1;
15855   int ret;
15856
15857   /* Parse args required to build the message */
15858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15859     {
15860       if (unformat (input, "enable"))
15861         {
15862           is_set = 1;
15863           is_en = 1;
15864         }
15865       else if (unformat (input, "disable"))
15866         {
15867           is_set = 1;
15868           is_en = 0;
15869         }
15870       else
15871         break;
15872     }
15873
15874   if (is_set == 0)
15875     {
15876       errmsg ("Value not set");
15877       return -99;
15878     }
15879
15880   /* Construct the API message */
15881   M (GPE_ENABLE_DISABLE, mp);
15882
15883   mp->is_en = is_en;
15884
15885   /* send it... */
15886   S (mp);
15887
15888   /* Wait for a reply... */
15889   W (ret);
15890   return ret;
15891 }
15892
15893 static int
15894 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15895 {
15896   unformat_input_t *input = vam->input;
15897   vl_api_one_rloc_probe_enable_disable_t *mp;
15898   u8 is_set = 0;
15899   u8 is_en = 0;
15900   int ret;
15901
15902   /* Parse args required to build the message */
15903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15904     {
15905       if (unformat (input, "enable"))
15906         {
15907           is_set = 1;
15908           is_en = 1;
15909         }
15910       else if (unformat (input, "disable"))
15911         is_set = 1;
15912       else
15913         break;
15914     }
15915
15916   if (!is_set)
15917     {
15918       errmsg ("Value not set");
15919       return -99;
15920     }
15921
15922   /* Construct the API message */
15923   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15924
15925   mp->is_enabled = is_en;
15926
15927   /* send it... */
15928   S (mp);
15929
15930   /* Wait for a reply... */
15931   W (ret);
15932   return ret;
15933 }
15934
15935 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15936
15937 static int
15938 api_one_map_register_enable_disable (vat_main_t * vam)
15939 {
15940   unformat_input_t *input = vam->input;
15941   vl_api_one_map_register_enable_disable_t *mp;
15942   u8 is_set = 0;
15943   u8 is_en = 0;
15944   int ret;
15945
15946   /* Parse args required to build the message */
15947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15948     {
15949       if (unformat (input, "enable"))
15950         {
15951           is_set = 1;
15952           is_en = 1;
15953         }
15954       else if (unformat (input, "disable"))
15955         is_set = 1;
15956       else
15957         break;
15958     }
15959
15960   if (!is_set)
15961     {
15962       errmsg ("Value not set");
15963       return -99;
15964     }
15965
15966   /* Construct the API message */
15967   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15968
15969   mp->is_enabled = is_en;
15970
15971   /* send it... */
15972   S (mp);
15973
15974   /* Wait for a reply... */
15975   W (ret);
15976   return ret;
15977 }
15978
15979 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15980
15981 static int
15982 api_one_enable_disable (vat_main_t * vam)
15983 {
15984   unformat_input_t *input = vam->input;
15985   vl_api_one_enable_disable_t *mp;
15986   u8 is_set = 0;
15987   u8 is_en = 0;
15988   int ret;
15989
15990   /* Parse args required to build the message */
15991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15992     {
15993       if (unformat (input, "enable"))
15994         {
15995           is_set = 1;
15996           is_en = 1;
15997         }
15998       else if (unformat (input, "disable"))
15999         {
16000           is_set = 1;
16001         }
16002       else
16003         break;
16004     }
16005
16006   if (!is_set)
16007     {
16008       errmsg ("Value not set");
16009       return -99;
16010     }
16011
16012   /* Construct the API message */
16013   M (ONE_ENABLE_DISABLE, mp);
16014
16015   mp->is_en = is_en;
16016
16017   /* send it... */
16018   S (mp);
16019
16020   /* Wait for a reply... */
16021   W (ret);
16022   return ret;
16023 }
16024
16025 #define api_lisp_enable_disable api_one_enable_disable
16026
16027 static int
16028 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16029 {
16030   unformat_input_t *input = vam->input;
16031   vl_api_one_enable_disable_xtr_mode_t *mp;
16032   u8 is_set = 0;
16033   u8 is_en = 0;
16034   int ret;
16035
16036   /* Parse args required to build the message */
16037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16038     {
16039       if (unformat (input, "enable"))
16040         {
16041           is_set = 1;
16042           is_en = 1;
16043         }
16044       else if (unformat (input, "disable"))
16045         {
16046           is_set = 1;
16047         }
16048       else
16049         break;
16050     }
16051
16052   if (!is_set)
16053     {
16054       errmsg ("Value not set");
16055       return -99;
16056     }
16057
16058   /* Construct the API message */
16059   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16060
16061   mp->is_en = is_en;
16062
16063   /* send it... */
16064   S (mp);
16065
16066   /* Wait for a reply... */
16067   W (ret);
16068   return ret;
16069 }
16070
16071 static int
16072 api_one_show_xtr_mode (vat_main_t * vam)
16073 {
16074   vl_api_one_show_xtr_mode_t *mp;
16075   int ret;
16076
16077   /* Construct the API message */
16078   M (ONE_SHOW_XTR_MODE, mp);
16079
16080   /* send it... */
16081   S (mp);
16082
16083   /* Wait for a reply... */
16084   W (ret);
16085   return ret;
16086 }
16087
16088 static int
16089 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16090 {
16091   unformat_input_t *input = vam->input;
16092   vl_api_one_enable_disable_pitr_mode_t *mp;
16093   u8 is_set = 0;
16094   u8 is_en = 0;
16095   int ret;
16096
16097   /* Parse args required to build the message */
16098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16099     {
16100       if (unformat (input, "enable"))
16101         {
16102           is_set = 1;
16103           is_en = 1;
16104         }
16105       else if (unformat (input, "disable"))
16106         {
16107           is_set = 1;
16108         }
16109       else
16110         break;
16111     }
16112
16113   if (!is_set)
16114     {
16115       errmsg ("Value not set");
16116       return -99;
16117     }
16118
16119   /* Construct the API message */
16120   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16121
16122   mp->is_en = is_en;
16123
16124   /* send it... */
16125   S (mp);
16126
16127   /* Wait for a reply... */
16128   W (ret);
16129   return ret;
16130 }
16131
16132 static int
16133 api_one_show_pitr_mode (vat_main_t * vam)
16134 {
16135   vl_api_one_show_pitr_mode_t *mp;
16136   int ret;
16137
16138   /* Construct the API message */
16139   M (ONE_SHOW_PITR_MODE, mp);
16140
16141   /* send it... */
16142   S (mp);
16143
16144   /* Wait for a reply... */
16145   W (ret);
16146   return ret;
16147 }
16148
16149 static int
16150 api_one_enable_disable_petr_mode (vat_main_t * vam)
16151 {
16152   unformat_input_t *input = vam->input;
16153   vl_api_one_enable_disable_petr_mode_t *mp;
16154   u8 is_set = 0;
16155   u8 is_en = 0;
16156   int ret;
16157
16158   /* Parse args required to build the message */
16159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16160     {
16161       if (unformat (input, "enable"))
16162         {
16163           is_set = 1;
16164           is_en = 1;
16165         }
16166       else if (unformat (input, "disable"))
16167         {
16168           is_set = 1;
16169         }
16170       else
16171         break;
16172     }
16173
16174   if (!is_set)
16175     {
16176       errmsg ("Value not set");
16177       return -99;
16178     }
16179
16180   /* Construct the API message */
16181   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16182
16183   mp->is_en = is_en;
16184
16185   /* send it... */
16186   S (mp);
16187
16188   /* Wait for a reply... */
16189   W (ret);
16190   return ret;
16191 }
16192
16193 static int
16194 api_one_show_petr_mode (vat_main_t * vam)
16195 {
16196   vl_api_one_show_petr_mode_t *mp;
16197   int ret;
16198
16199   /* Construct the API message */
16200   M (ONE_SHOW_PETR_MODE, mp);
16201
16202   /* send it... */
16203   S (mp);
16204
16205   /* Wait for a reply... */
16206   W (ret);
16207   return ret;
16208 }
16209
16210 static int
16211 api_show_one_map_register_state (vat_main_t * vam)
16212 {
16213   vl_api_show_one_map_register_state_t *mp;
16214   int ret;
16215
16216   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16217
16218   /* send */
16219   S (mp);
16220
16221   /* wait for reply */
16222   W (ret);
16223   return ret;
16224 }
16225
16226 #define api_show_lisp_map_register_state api_show_one_map_register_state
16227
16228 static int
16229 api_show_one_rloc_probe_state (vat_main_t * vam)
16230 {
16231   vl_api_show_one_rloc_probe_state_t *mp;
16232   int ret;
16233
16234   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16235
16236   /* send */
16237   S (mp);
16238
16239   /* wait for reply */
16240   W (ret);
16241   return ret;
16242 }
16243
16244 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16245
16246 static int
16247 api_one_add_del_ndp_entry (vat_main_t * vam)
16248 {
16249   vl_api_one_add_del_ndp_entry_t *mp;
16250   unformat_input_t *input = vam->input;
16251   u8 is_add = 1;
16252   u8 mac_set = 0;
16253   u8 bd_set = 0;
16254   u8 ip_set = 0;
16255   u8 mac[6] = { 0, };
16256   u8 ip6[16] = { 0, };
16257   u32 bd = ~0;
16258   int ret;
16259
16260   /* Parse args required to build the message */
16261   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16262     {
16263       if (unformat (input, "del"))
16264         is_add = 0;
16265       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16266         mac_set = 1;
16267       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16268         ip_set = 1;
16269       else if (unformat (input, "bd %d", &bd))
16270         bd_set = 1;
16271       else
16272         {
16273           errmsg ("parse error '%U'", format_unformat_error, input);
16274           return -99;
16275         }
16276     }
16277
16278   if (!bd_set || !ip_set || (!mac_set && is_add))
16279     {
16280       errmsg ("Missing BD, IP or MAC!");
16281       return -99;
16282     }
16283
16284   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16285   mp->is_add = is_add;
16286   clib_memcpy (mp->mac, mac, 6);
16287   mp->bd = clib_host_to_net_u32 (bd);
16288   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16289
16290   /* send */
16291   S (mp);
16292
16293   /* wait for reply */
16294   W (ret);
16295   return ret;
16296 }
16297
16298 static int
16299 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16300 {
16301   vl_api_one_add_del_l2_arp_entry_t *mp;
16302   unformat_input_t *input = vam->input;
16303   u8 is_add = 1;
16304   u8 mac_set = 0;
16305   u8 bd_set = 0;
16306   u8 ip_set = 0;
16307   u8 mac[6] = { 0, };
16308   u32 ip4 = 0, bd = ~0;
16309   int ret;
16310
16311   /* Parse args required to build the message */
16312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16313     {
16314       if (unformat (input, "del"))
16315         is_add = 0;
16316       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16317         mac_set = 1;
16318       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16319         ip_set = 1;
16320       else if (unformat (input, "bd %d", &bd))
16321         bd_set = 1;
16322       else
16323         {
16324           errmsg ("parse error '%U'", format_unformat_error, input);
16325           return -99;
16326         }
16327     }
16328
16329   if (!bd_set || !ip_set || (!mac_set && is_add))
16330     {
16331       errmsg ("Missing BD, IP or MAC!");
16332       return -99;
16333     }
16334
16335   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16336   mp->is_add = is_add;
16337   clib_memcpy (mp->mac, mac, 6);
16338   mp->bd = clib_host_to_net_u32 (bd);
16339   mp->ip4 = ip4;
16340
16341   /* send */
16342   S (mp);
16343
16344   /* wait for reply */
16345   W (ret);
16346   return ret;
16347 }
16348
16349 static int
16350 api_one_ndp_bd_get (vat_main_t * vam)
16351 {
16352   vl_api_one_ndp_bd_get_t *mp;
16353   int ret;
16354
16355   M (ONE_NDP_BD_GET, mp);
16356
16357   /* send */
16358   S (mp);
16359
16360   /* wait for reply */
16361   W (ret);
16362   return ret;
16363 }
16364
16365 static int
16366 api_one_ndp_entries_get (vat_main_t * vam)
16367 {
16368   vl_api_one_ndp_entries_get_t *mp;
16369   unformat_input_t *input = vam->input;
16370   u8 bd_set = 0;
16371   u32 bd = ~0;
16372   int ret;
16373
16374   /* Parse args required to build the message */
16375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16376     {
16377       if (unformat (input, "bd %d", &bd))
16378         bd_set = 1;
16379       else
16380         {
16381           errmsg ("parse error '%U'", format_unformat_error, input);
16382           return -99;
16383         }
16384     }
16385
16386   if (!bd_set)
16387     {
16388       errmsg ("Expected bridge domain!");
16389       return -99;
16390     }
16391
16392   M (ONE_NDP_ENTRIES_GET, mp);
16393   mp->bd = clib_host_to_net_u32 (bd);
16394
16395   /* send */
16396   S (mp);
16397
16398   /* wait for reply */
16399   W (ret);
16400   return ret;
16401 }
16402
16403 static int
16404 api_one_l2_arp_bd_get (vat_main_t * vam)
16405 {
16406   vl_api_one_l2_arp_bd_get_t *mp;
16407   int ret;
16408
16409   M (ONE_L2_ARP_BD_GET, mp);
16410
16411   /* send */
16412   S (mp);
16413
16414   /* wait for reply */
16415   W (ret);
16416   return ret;
16417 }
16418
16419 static int
16420 api_one_l2_arp_entries_get (vat_main_t * vam)
16421 {
16422   vl_api_one_l2_arp_entries_get_t *mp;
16423   unformat_input_t *input = vam->input;
16424   u8 bd_set = 0;
16425   u32 bd = ~0;
16426   int ret;
16427
16428   /* Parse args required to build the message */
16429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16430     {
16431       if (unformat (input, "bd %d", &bd))
16432         bd_set = 1;
16433       else
16434         {
16435           errmsg ("parse error '%U'", format_unformat_error, input);
16436           return -99;
16437         }
16438     }
16439
16440   if (!bd_set)
16441     {
16442       errmsg ("Expected bridge domain!");
16443       return -99;
16444     }
16445
16446   M (ONE_L2_ARP_ENTRIES_GET, mp);
16447   mp->bd = clib_host_to_net_u32 (bd);
16448
16449   /* send */
16450   S (mp);
16451
16452   /* wait for reply */
16453   W (ret);
16454   return ret;
16455 }
16456
16457 static int
16458 api_one_stats_enable_disable (vat_main_t * vam)
16459 {
16460   vl_api_one_stats_enable_disable_t *mp;
16461   unformat_input_t *input = vam->input;
16462   u8 is_set = 0;
16463   u8 is_en = 0;
16464   int ret;
16465
16466   /* Parse args required to build the message */
16467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16468     {
16469       if (unformat (input, "enable"))
16470         {
16471           is_set = 1;
16472           is_en = 1;
16473         }
16474       else if (unformat (input, "disable"))
16475         {
16476           is_set = 1;
16477         }
16478       else
16479         break;
16480     }
16481
16482   if (!is_set)
16483     {
16484       errmsg ("Value not set");
16485       return -99;
16486     }
16487
16488   M (ONE_STATS_ENABLE_DISABLE, mp);
16489   mp->is_en = is_en;
16490
16491   /* send */
16492   S (mp);
16493
16494   /* wait for reply */
16495   W (ret);
16496   return ret;
16497 }
16498
16499 static int
16500 api_show_one_stats_enable_disable (vat_main_t * vam)
16501 {
16502   vl_api_show_one_stats_enable_disable_t *mp;
16503   int ret;
16504
16505   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16506
16507   /* send */
16508   S (mp);
16509
16510   /* wait for reply */
16511   W (ret);
16512   return ret;
16513 }
16514
16515 static int
16516 api_show_one_map_request_mode (vat_main_t * vam)
16517 {
16518   vl_api_show_one_map_request_mode_t *mp;
16519   int ret;
16520
16521   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16522
16523   /* send */
16524   S (mp);
16525
16526   /* wait for reply */
16527   W (ret);
16528   return ret;
16529 }
16530
16531 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16532
16533 static int
16534 api_one_map_request_mode (vat_main_t * vam)
16535 {
16536   unformat_input_t *input = vam->input;
16537   vl_api_one_map_request_mode_t *mp;
16538   u8 mode = 0;
16539   int ret;
16540
16541   /* Parse args required to build the message */
16542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16543     {
16544       if (unformat (input, "dst-only"))
16545         mode = 0;
16546       else if (unformat (input, "src-dst"))
16547         mode = 1;
16548       else
16549         {
16550           errmsg ("parse error '%U'", format_unformat_error, input);
16551           return -99;
16552         }
16553     }
16554
16555   M (ONE_MAP_REQUEST_MODE, mp);
16556
16557   mp->mode = mode;
16558
16559   /* send */
16560   S (mp);
16561
16562   /* wait for reply */
16563   W (ret);
16564   return ret;
16565 }
16566
16567 #define api_lisp_map_request_mode api_one_map_request_mode
16568
16569 /**
16570  * Enable/disable ONE proxy ITR.
16571  *
16572  * @param vam vpp API test context
16573  * @return return code
16574  */
16575 static int
16576 api_one_pitr_set_locator_set (vat_main_t * vam)
16577 {
16578   u8 ls_name_set = 0;
16579   unformat_input_t *input = vam->input;
16580   vl_api_one_pitr_set_locator_set_t *mp;
16581   u8 is_add = 1;
16582   u8 *ls_name = 0;
16583   int ret;
16584
16585   /* Parse args required to build the message */
16586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16587     {
16588       if (unformat (input, "del"))
16589         is_add = 0;
16590       else if (unformat (input, "locator-set %s", &ls_name))
16591         ls_name_set = 1;
16592       else
16593         {
16594           errmsg ("parse error '%U'", format_unformat_error, input);
16595           return -99;
16596         }
16597     }
16598
16599   if (!ls_name_set)
16600     {
16601       errmsg ("locator-set name not set!");
16602       return -99;
16603     }
16604
16605   M (ONE_PITR_SET_LOCATOR_SET, mp);
16606
16607   mp->is_add = is_add;
16608   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16609   vec_free (ls_name);
16610
16611   /* send */
16612   S (mp);
16613
16614   /* wait for reply */
16615   W (ret);
16616   return ret;
16617 }
16618
16619 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16620
16621 static int
16622 api_one_nsh_set_locator_set (vat_main_t * vam)
16623 {
16624   u8 ls_name_set = 0;
16625   unformat_input_t *input = vam->input;
16626   vl_api_one_nsh_set_locator_set_t *mp;
16627   u8 is_add = 1;
16628   u8 *ls_name = 0;
16629   int ret;
16630
16631   /* Parse args required to build the message */
16632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16633     {
16634       if (unformat (input, "del"))
16635         is_add = 0;
16636       else if (unformat (input, "ls %s", &ls_name))
16637         ls_name_set = 1;
16638       else
16639         {
16640           errmsg ("parse error '%U'", format_unformat_error, input);
16641           return -99;
16642         }
16643     }
16644
16645   if (!ls_name_set && is_add)
16646     {
16647       errmsg ("locator-set name not set!");
16648       return -99;
16649     }
16650
16651   M (ONE_NSH_SET_LOCATOR_SET, mp);
16652
16653   mp->is_add = is_add;
16654   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16655   vec_free (ls_name);
16656
16657   /* send */
16658   S (mp);
16659
16660   /* wait for reply */
16661   W (ret);
16662   return ret;
16663 }
16664
16665 static int
16666 api_show_one_pitr (vat_main_t * vam)
16667 {
16668   vl_api_show_one_pitr_t *mp;
16669   int ret;
16670
16671   if (!vam->json_output)
16672     {
16673       print (vam->ofp, "%=20s", "lisp status:");
16674     }
16675
16676   M (SHOW_ONE_PITR, mp);
16677   /* send it... */
16678   S (mp);
16679
16680   /* Wait for a reply... */
16681   W (ret);
16682   return ret;
16683 }
16684
16685 #define api_show_lisp_pitr api_show_one_pitr
16686
16687 static int
16688 api_one_use_petr (vat_main_t * vam)
16689 {
16690   unformat_input_t *input = vam->input;
16691   vl_api_one_use_petr_t *mp;
16692   u8 is_add = 0;
16693   ip_address_t ip;
16694   int ret;
16695
16696   clib_memset (&ip, 0, sizeof (ip));
16697
16698   /* Parse args required to build the message */
16699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16700     {
16701       if (unformat (input, "disable"))
16702         is_add = 0;
16703       else
16704         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16705         {
16706           is_add = 1;
16707           ip_addr_version (&ip) = IP4;
16708         }
16709       else
16710         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16711         {
16712           is_add = 1;
16713           ip_addr_version (&ip) = IP6;
16714         }
16715       else
16716         {
16717           errmsg ("parse error '%U'", format_unformat_error, input);
16718           return -99;
16719         }
16720     }
16721
16722   M (ONE_USE_PETR, mp);
16723
16724   mp->is_add = is_add;
16725   if (is_add)
16726     {
16727       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16728       if (mp->is_ip4)
16729         clib_memcpy (mp->address, &ip, 4);
16730       else
16731         clib_memcpy (mp->address, &ip, 16);
16732     }
16733
16734   /* send */
16735   S (mp);
16736
16737   /* wait for reply */
16738   W (ret);
16739   return ret;
16740 }
16741
16742 #define api_lisp_use_petr api_one_use_petr
16743
16744 static int
16745 api_show_one_nsh_mapping (vat_main_t * vam)
16746 {
16747   vl_api_show_one_use_petr_t *mp;
16748   int ret;
16749
16750   if (!vam->json_output)
16751     {
16752       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16753     }
16754
16755   M (SHOW_ONE_NSH_MAPPING, mp);
16756   /* send it... */
16757   S (mp);
16758
16759   /* Wait for a reply... */
16760   W (ret);
16761   return ret;
16762 }
16763
16764 static int
16765 api_show_one_use_petr (vat_main_t * vam)
16766 {
16767   vl_api_show_one_use_petr_t *mp;
16768   int ret;
16769
16770   if (!vam->json_output)
16771     {
16772       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16773     }
16774
16775   M (SHOW_ONE_USE_PETR, mp);
16776   /* send it... */
16777   S (mp);
16778
16779   /* Wait for a reply... */
16780   W (ret);
16781   return ret;
16782 }
16783
16784 #define api_show_lisp_use_petr api_show_one_use_petr
16785
16786 /**
16787  * Add/delete mapping between vni and vrf
16788  */
16789 static int
16790 api_one_eid_table_add_del_map (vat_main_t * vam)
16791 {
16792   unformat_input_t *input = vam->input;
16793   vl_api_one_eid_table_add_del_map_t *mp;
16794   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16795   u32 vni, vrf, bd_index;
16796   int ret;
16797
16798   /* Parse args required to build the message */
16799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16800     {
16801       if (unformat (input, "del"))
16802         is_add = 0;
16803       else if (unformat (input, "vrf %d", &vrf))
16804         vrf_set = 1;
16805       else if (unformat (input, "bd_index %d", &bd_index))
16806         bd_index_set = 1;
16807       else if (unformat (input, "vni %d", &vni))
16808         vni_set = 1;
16809       else
16810         break;
16811     }
16812
16813   if (!vni_set || (!vrf_set && !bd_index_set))
16814     {
16815       errmsg ("missing arguments!");
16816       return -99;
16817     }
16818
16819   if (vrf_set && bd_index_set)
16820     {
16821       errmsg ("error: both vrf and bd entered!");
16822       return -99;
16823     }
16824
16825   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16826
16827   mp->is_add = is_add;
16828   mp->vni = htonl (vni);
16829   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16830   mp->is_l2 = bd_index_set;
16831
16832   /* send */
16833   S (mp);
16834
16835   /* wait for reply */
16836   W (ret);
16837   return ret;
16838 }
16839
16840 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16841
16842 uword
16843 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16844 {
16845   u32 *action = va_arg (*args, u32 *);
16846   u8 *s = 0;
16847
16848   if (unformat (input, "%s", &s))
16849     {
16850       if (!strcmp ((char *) s, "no-action"))
16851         action[0] = 0;
16852       else if (!strcmp ((char *) s, "natively-forward"))
16853         action[0] = 1;
16854       else if (!strcmp ((char *) s, "send-map-request"))
16855         action[0] = 2;
16856       else if (!strcmp ((char *) s, "drop"))
16857         action[0] = 3;
16858       else
16859         {
16860           clib_warning ("invalid action: '%s'", s);
16861           action[0] = 3;
16862         }
16863     }
16864   else
16865     return 0;
16866
16867   vec_free (s);
16868   return 1;
16869 }
16870
16871 /**
16872  * Add/del remote mapping to/from ONE control plane
16873  *
16874  * @param vam vpp API test context
16875  * @return return code
16876  */
16877 static int
16878 api_one_add_del_remote_mapping (vat_main_t * vam)
16879 {
16880   unformat_input_t *input = vam->input;
16881   vl_api_one_add_del_remote_mapping_t *mp;
16882   u32 vni = 0;
16883   lisp_eid_vat_t _eid, *eid = &_eid;
16884   lisp_eid_vat_t _seid, *seid = &_seid;
16885   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16886   u32 action = ~0, p, w, data_len;
16887   ip4_address_t rloc4;
16888   ip6_address_t rloc6;
16889   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16890   int ret;
16891
16892   clib_memset (&rloc, 0, sizeof (rloc));
16893
16894   /* Parse args required to build the message */
16895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16896     {
16897       if (unformat (input, "del-all"))
16898         {
16899           del_all = 1;
16900         }
16901       else if (unformat (input, "del"))
16902         {
16903           is_add = 0;
16904         }
16905       else if (unformat (input, "add"))
16906         {
16907           is_add = 1;
16908         }
16909       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16910         {
16911           eid_set = 1;
16912         }
16913       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16914         {
16915           seid_set = 1;
16916         }
16917       else if (unformat (input, "vni %d", &vni))
16918         {
16919           ;
16920         }
16921       else if (unformat (input, "p %d w %d", &p, &w))
16922         {
16923           if (!curr_rloc)
16924             {
16925               errmsg ("No RLOC configured for setting priority/weight!");
16926               return -99;
16927             }
16928           curr_rloc->priority = p;
16929           curr_rloc->weight = w;
16930         }
16931       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16932         {
16933           rloc.is_ip4 = 1;
16934           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16935           vec_add1 (rlocs, rloc);
16936           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16937         }
16938       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16939         {
16940           rloc.is_ip4 = 0;
16941           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16942           vec_add1 (rlocs, rloc);
16943           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16944         }
16945       else if (unformat (input, "action %U",
16946                          unformat_negative_mapping_action, &action))
16947         {
16948           ;
16949         }
16950       else
16951         {
16952           clib_warning ("parse error '%U'", format_unformat_error, input);
16953           return -99;
16954         }
16955     }
16956
16957   if (0 == eid_set)
16958     {
16959       errmsg ("missing params!");
16960       return -99;
16961     }
16962
16963   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16964     {
16965       errmsg ("no action set for negative map-reply!");
16966       return -99;
16967     }
16968
16969   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16970
16971   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16972   mp->is_add = is_add;
16973   mp->vni = htonl (vni);
16974   mp->action = (u8) action;
16975   mp->is_src_dst = seid_set;
16976   mp->eid_len = eid->len;
16977   mp->seid_len = seid->len;
16978   mp->del_all = del_all;
16979   mp->eid_type = eid->type;
16980   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16981   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16982
16983   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16984   clib_memcpy (mp->rlocs, rlocs, data_len);
16985   vec_free (rlocs);
16986
16987   /* send it... */
16988   S (mp);
16989
16990   /* Wait for a reply... */
16991   W (ret);
16992   return ret;
16993 }
16994
16995 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16996
16997 /**
16998  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16999  * forwarding entries in data-plane accordingly.
17000  *
17001  * @param vam vpp API test context
17002  * @return return code
17003  */
17004 static int
17005 api_one_add_del_adjacency (vat_main_t * vam)
17006 {
17007   unformat_input_t *input = vam->input;
17008   vl_api_one_add_del_adjacency_t *mp;
17009   u32 vni = 0;
17010   ip4_address_t leid4, reid4;
17011   ip6_address_t leid6, reid6;
17012   u8 reid_mac[6] = { 0 };
17013   u8 leid_mac[6] = { 0 };
17014   u8 reid_type, leid_type;
17015   u32 leid_len = 0, reid_len = 0, len;
17016   u8 is_add = 1;
17017   int ret;
17018
17019   leid_type = reid_type = (u8) ~ 0;
17020
17021   /* Parse args required to build the message */
17022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17023     {
17024       if (unformat (input, "del"))
17025         {
17026           is_add = 0;
17027         }
17028       else if (unformat (input, "add"))
17029         {
17030           is_add = 1;
17031         }
17032       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17033                          &reid4, &len))
17034         {
17035           reid_type = 0;        /* ipv4 */
17036           reid_len = len;
17037         }
17038       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17039                          &reid6, &len))
17040         {
17041           reid_type = 1;        /* ipv6 */
17042           reid_len = len;
17043         }
17044       else if (unformat (input, "reid %U", unformat_ethernet_address,
17045                          reid_mac))
17046         {
17047           reid_type = 2;        /* mac */
17048         }
17049       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17050                          &leid4, &len))
17051         {
17052           leid_type = 0;        /* ipv4 */
17053           leid_len = len;
17054         }
17055       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17056                          &leid6, &len))
17057         {
17058           leid_type = 1;        /* ipv6 */
17059           leid_len = len;
17060         }
17061       else if (unformat (input, "leid %U", unformat_ethernet_address,
17062                          leid_mac))
17063         {
17064           leid_type = 2;        /* mac */
17065         }
17066       else if (unformat (input, "vni %d", &vni))
17067         {
17068           ;
17069         }
17070       else
17071         {
17072           errmsg ("parse error '%U'", format_unformat_error, input);
17073           return -99;
17074         }
17075     }
17076
17077   if ((u8) ~ 0 == reid_type)
17078     {
17079       errmsg ("missing params!");
17080       return -99;
17081     }
17082
17083   if (leid_type != reid_type)
17084     {
17085       errmsg ("remote and local EIDs are of different types!");
17086       return -99;
17087     }
17088
17089   M (ONE_ADD_DEL_ADJACENCY, mp);
17090   mp->is_add = is_add;
17091   mp->vni = htonl (vni);
17092   mp->leid_len = leid_len;
17093   mp->reid_len = reid_len;
17094   mp->eid_type = reid_type;
17095
17096   switch (mp->eid_type)
17097     {
17098     case 0:
17099       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17100       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17101       break;
17102     case 1:
17103       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17104       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17105       break;
17106     case 2:
17107       clib_memcpy (mp->leid, leid_mac, 6);
17108       clib_memcpy (mp->reid, reid_mac, 6);
17109       break;
17110     default:
17111       errmsg ("unknown EID type %d!", mp->eid_type);
17112       return 0;
17113     }
17114
17115   /* send it... */
17116   S (mp);
17117
17118   /* Wait for a reply... */
17119   W (ret);
17120   return ret;
17121 }
17122
17123 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17124
17125 uword
17126 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17127 {
17128   u32 *mode = va_arg (*args, u32 *);
17129
17130   if (unformat (input, "lisp"))
17131     *mode = 0;
17132   else if (unformat (input, "vxlan"))
17133     *mode = 1;
17134   else
17135     return 0;
17136
17137   return 1;
17138 }
17139
17140 static int
17141 api_gpe_get_encap_mode (vat_main_t * vam)
17142 {
17143   vl_api_gpe_get_encap_mode_t *mp;
17144   int ret;
17145
17146   /* Construct the API message */
17147   M (GPE_GET_ENCAP_MODE, mp);
17148
17149   /* send it... */
17150   S (mp);
17151
17152   /* Wait for a reply... */
17153   W (ret);
17154   return ret;
17155 }
17156
17157 static int
17158 api_gpe_set_encap_mode (vat_main_t * vam)
17159 {
17160   unformat_input_t *input = vam->input;
17161   vl_api_gpe_set_encap_mode_t *mp;
17162   int ret;
17163   u32 mode = 0;
17164
17165   /* Parse args required to build the message */
17166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17167     {
17168       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17169         ;
17170       else
17171         break;
17172     }
17173
17174   /* Construct the API message */
17175   M (GPE_SET_ENCAP_MODE, mp);
17176
17177   mp->mode = mode;
17178
17179   /* send it... */
17180   S (mp);
17181
17182   /* Wait for a reply... */
17183   W (ret);
17184   return ret;
17185 }
17186
17187 static int
17188 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17189 {
17190   unformat_input_t *input = vam->input;
17191   vl_api_gpe_add_del_iface_t *mp;
17192   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17193   u32 dp_table = 0, vni = 0;
17194   int ret;
17195
17196   /* Parse args required to build the message */
17197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17198     {
17199       if (unformat (input, "up"))
17200         {
17201           action_set = 1;
17202           is_add = 1;
17203         }
17204       else if (unformat (input, "down"))
17205         {
17206           action_set = 1;
17207           is_add = 0;
17208         }
17209       else if (unformat (input, "table_id %d", &dp_table))
17210         {
17211           dp_table_set = 1;
17212         }
17213       else if (unformat (input, "bd_id %d", &dp_table))
17214         {
17215           dp_table_set = 1;
17216           is_l2 = 1;
17217         }
17218       else if (unformat (input, "vni %d", &vni))
17219         {
17220           vni_set = 1;
17221         }
17222       else
17223         break;
17224     }
17225
17226   if (action_set == 0)
17227     {
17228       errmsg ("Action not set");
17229       return -99;
17230     }
17231   if (dp_table_set == 0 || vni_set == 0)
17232     {
17233       errmsg ("vni and dp_table must be set");
17234       return -99;
17235     }
17236
17237   /* Construct the API message */
17238   M (GPE_ADD_DEL_IFACE, mp);
17239
17240   mp->is_add = is_add;
17241   mp->dp_table = clib_host_to_net_u32 (dp_table);
17242   mp->is_l2 = is_l2;
17243   mp->vni = clib_host_to_net_u32 (vni);
17244
17245   /* send it... */
17246   S (mp);
17247
17248   /* Wait for a reply... */
17249   W (ret);
17250   return ret;
17251 }
17252
17253 static int
17254 api_one_map_register_fallback_threshold (vat_main_t * vam)
17255 {
17256   unformat_input_t *input = vam->input;
17257   vl_api_one_map_register_fallback_threshold_t *mp;
17258   u32 value = 0;
17259   u8 is_set = 0;
17260   int ret;
17261
17262   /* Parse args required to build the message */
17263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17264     {
17265       if (unformat (input, "%u", &value))
17266         is_set = 1;
17267       else
17268         {
17269           clib_warning ("parse error '%U'", format_unformat_error, input);
17270           return -99;
17271         }
17272     }
17273
17274   if (!is_set)
17275     {
17276       errmsg ("fallback threshold value is missing!");
17277       return -99;
17278     }
17279
17280   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17281   mp->value = clib_host_to_net_u32 (value);
17282
17283   /* send it... */
17284   S (mp);
17285
17286   /* Wait for a reply... */
17287   W (ret);
17288   return ret;
17289 }
17290
17291 static int
17292 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17293 {
17294   vl_api_show_one_map_register_fallback_threshold_t *mp;
17295   int ret;
17296
17297   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17298
17299   /* send it... */
17300   S (mp);
17301
17302   /* Wait for a reply... */
17303   W (ret);
17304   return ret;
17305 }
17306
17307 uword
17308 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17309 {
17310   u32 *proto = va_arg (*args, u32 *);
17311
17312   if (unformat (input, "udp"))
17313     *proto = 1;
17314   else if (unformat (input, "api"))
17315     *proto = 2;
17316   else
17317     return 0;
17318
17319   return 1;
17320 }
17321
17322 static int
17323 api_one_set_transport_protocol (vat_main_t * vam)
17324 {
17325   unformat_input_t *input = vam->input;
17326   vl_api_one_set_transport_protocol_t *mp;
17327   u8 is_set = 0;
17328   u32 protocol = 0;
17329   int ret;
17330
17331   /* Parse args required to build the message */
17332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17333     {
17334       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17335         is_set = 1;
17336       else
17337         {
17338           clib_warning ("parse error '%U'", format_unformat_error, input);
17339           return -99;
17340         }
17341     }
17342
17343   if (!is_set)
17344     {
17345       errmsg ("Transport protocol missing!");
17346       return -99;
17347     }
17348
17349   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17350   mp->protocol = (u8) protocol;
17351
17352   /* send it... */
17353   S (mp);
17354
17355   /* Wait for a reply... */
17356   W (ret);
17357   return ret;
17358 }
17359
17360 static int
17361 api_one_get_transport_protocol (vat_main_t * vam)
17362 {
17363   vl_api_one_get_transport_protocol_t *mp;
17364   int ret;
17365
17366   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17367
17368   /* send it... */
17369   S (mp);
17370
17371   /* Wait for a reply... */
17372   W (ret);
17373   return ret;
17374 }
17375
17376 static int
17377 api_one_map_register_set_ttl (vat_main_t * vam)
17378 {
17379   unformat_input_t *input = vam->input;
17380   vl_api_one_map_register_set_ttl_t *mp;
17381   u32 ttl = 0;
17382   u8 is_set = 0;
17383   int ret;
17384
17385   /* Parse args required to build the message */
17386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17387     {
17388       if (unformat (input, "%u", &ttl))
17389         is_set = 1;
17390       else
17391         {
17392           clib_warning ("parse error '%U'", format_unformat_error, input);
17393           return -99;
17394         }
17395     }
17396
17397   if (!is_set)
17398     {
17399       errmsg ("TTL value missing!");
17400       return -99;
17401     }
17402
17403   M (ONE_MAP_REGISTER_SET_TTL, mp);
17404   mp->ttl = clib_host_to_net_u32 (ttl);
17405
17406   /* send it... */
17407   S (mp);
17408
17409   /* Wait for a reply... */
17410   W (ret);
17411   return ret;
17412 }
17413
17414 static int
17415 api_show_one_map_register_ttl (vat_main_t * vam)
17416 {
17417   vl_api_show_one_map_register_ttl_t *mp;
17418   int ret;
17419
17420   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17421
17422   /* send it... */
17423   S (mp);
17424
17425   /* Wait for a reply... */
17426   W (ret);
17427   return ret;
17428 }
17429
17430 /**
17431  * Add/del map request itr rlocs from ONE control plane and updates
17432  *
17433  * @param vam vpp API test context
17434  * @return return code
17435  */
17436 static int
17437 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17438 {
17439   unformat_input_t *input = vam->input;
17440   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17441   u8 *locator_set_name = 0;
17442   u8 locator_set_name_set = 0;
17443   u8 is_add = 1;
17444   int ret;
17445
17446   /* Parse args required to build the message */
17447   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17448     {
17449       if (unformat (input, "del"))
17450         {
17451           is_add = 0;
17452         }
17453       else if (unformat (input, "%_%v%_", &locator_set_name))
17454         {
17455           locator_set_name_set = 1;
17456         }
17457       else
17458         {
17459           clib_warning ("parse error '%U'", format_unformat_error, input);
17460           return -99;
17461         }
17462     }
17463
17464   if (is_add && !locator_set_name_set)
17465     {
17466       errmsg ("itr-rloc is not set!");
17467       return -99;
17468     }
17469
17470   if (is_add && vec_len (locator_set_name) > 64)
17471     {
17472       errmsg ("itr-rloc locator-set name too long");
17473       vec_free (locator_set_name);
17474       return -99;
17475     }
17476
17477   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17478   mp->is_add = is_add;
17479   if (is_add)
17480     {
17481       clib_memcpy (mp->locator_set_name, locator_set_name,
17482                    vec_len (locator_set_name));
17483     }
17484   else
17485     {
17486       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17487     }
17488   vec_free (locator_set_name);
17489
17490   /* send it... */
17491   S (mp);
17492
17493   /* Wait for a reply... */
17494   W (ret);
17495   return ret;
17496 }
17497
17498 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17499
17500 static int
17501 api_one_locator_dump (vat_main_t * vam)
17502 {
17503   unformat_input_t *input = vam->input;
17504   vl_api_one_locator_dump_t *mp;
17505   vl_api_control_ping_t *mp_ping;
17506   u8 is_index_set = 0, is_name_set = 0;
17507   u8 *ls_name = 0;
17508   u32 ls_index = ~0;
17509   int ret;
17510
17511   /* Parse args required to build the message */
17512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17513     {
17514       if (unformat (input, "ls_name %_%v%_", &ls_name))
17515         {
17516           is_name_set = 1;
17517         }
17518       else if (unformat (input, "ls_index %d", &ls_index))
17519         {
17520           is_index_set = 1;
17521         }
17522       else
17523         {
17524           errmsg ("parse error '%U'", format_unformat_error, input);
17525           return -99;
17526         }
17527     }
17528
17529   if (!is_index_set && !is_name_set)
17530     {
17531       errmsg ("error: expected one of index or name!");
17532       return -99;
17533     }
17534
17535   if (is_index_set && is_name_set)
17536     {
17537       errmsg ("error: only one param expected!");
17538       return -99;
17539     }
17540
17541   if (vec_len (ls_name) > 62)
17542     {
17543       errmsg ("error: locator set name too long!");
17544       return -99;
17545     }
17546
17547   if (!vam->json_output)
17548     {
17549       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17550     }
17551
17552   M (ONE_LOCATOR_DUMP, mp);
17553   mp->is_index_set = is_index_set;
17554
17555   if (is_index_set)
17556     mp->ls_index = clib_host_to_net_u32 (ls_index);
17557   else
17558     {
17559       vec_add1 (ls_name, 0);
17560       strncpy ((char *) mp->ls_name, (char *) ls_name,
17561                sizeof (mp->ls_name) - 1);
17562     }
17563
17564   /* send it... */
17565   S (mp);
17566
17567   /* Use a control ping for synchronization */
17568   MPING (CONTROL_PING, mp_ping);
17569   S (mp_ping);
17570
17571   /* Wait for a reply... */
17572   W (ret);
17573   return ret;
17574 }
17575
17576 #define api_lisp_locator_dump api_one_locator_dump
17577
17578 static int
17579 api_one_locator_set_dump (vat_main_t * vam)
17580 {
17581   vl_api_one_locator_set_dump_t *mp;
17582   vl_api_control_ping_t *mp_ping;
17583   unformat_input_t *input = vam->input;
17584   u8 filter = 0;
17585   int ret;
17586
17587   /* Parse args required to build the message */
17588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17589     {
17590       if (unformat (input, "local"))
17591         {
17592           filter = 1;
17593         }
17594       else if (unformat (input, "remote"))
17595         {
17596           filter = 2;
17597         }
17598       else
17599         {
17600           errmsg ("parse error '%U'", format_unformat_error, input);
17601           return -99;
17602         }
17603     }
17604
17605   if (!vam->json_output)
17606     {
17607       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17608     }
17609
17610   M (ONE_LOCATOR_SET_DUMP, mp);
17611
17612   mp->filter = filter;
17613
17614   /* send it... */
17615   S (mp);
17616
17617   /* Use a control ping for synchronization */
17618   MPING (CONTROL_PING, mp_ping);
17619   S (mp_ping);
17620
17621   /* Wait for a reply... */
17622   W (ret);
17623   return ret;
17624 }
17625
17626 #define api_lisp_locator_set_dump api_one_locator_set_dump
17627
17628 static int
17629 api_one_eid_table_map_dump (vat_main_t * vam)
17630 {
17631   u8 is_l2 = 0;
17632   u8 mode_set = 0;
17633   unformat_input_t *input = vam->input;
17634   vl_api_one_eid_table_map_dump_t *mp;
17635   vl_api_control_ping_t *mp_ping;
17636   int ret;
17637
17638   /* Parse args required to build the message */
17639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17640     {
17641       if (unformat (input, "l2"))
17642         {
17643           is_l2 = 1;
17644           mode_set = 1;
17645         }
17646       else if (unformat (input, "l3"))
17647         {
17648           is_l2 = 0;
17649           mode_set = 1;
17650         }
17651       else
17652         {
17653           errmsg ("parse error '%U'", format_unformat_error, input);
17654           return -99;
17655         }
17656     }
17657
17658   if (!mode_set)
17659     {
17660       errmsg ("expected one of 'l2' or 'l3' parameter!");
17661       return -99;
17662     }
17663
17664   if (!vam->json_output)
17665     {
17666       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17667     }
17668
17669   M (ONE_EID_TABLE_MAP_DUMP, mp);
17670   mp->is_l2 = is_l2;
17671
17672   /* send it... */
17673   S (mp);
17674
17675   /* Use a control ping for synchronization */
17676   MPING (CONTROL_PING, mp_ping);
17677   S (mp_ping);
17678
17679   /* Wait for a reply... */
17680   W (ret);
17681   return ret;
17682 }
17683
17684 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17685
17686 static int
17687 api_one_eid_table_vni_dump (vat_main_t * vam)
17688 {
17689   vl_api_one_eid_table_vni_dump_t *mp;
17690   vl_api_control_ping_t *mp_ping;
17691   int ret;
17692
17693   if (!vam->json_output)
17694     {
17695       print (vam->ofp, "VNI");
17696     }
17697
17698   M (ONE_EID_TABLE_VNI_DUMP, mp);
17699
17700   /* send it... */
17701   S (mp);
17702
17703   /* Use a control ping for synchronization */
17704   MPING (CONTROL_PING, mp_ping);
17705   S (mp_ping);
17706
17707   /* Wait for a reply... */
17708   W (ret);
17709   return ret;
17710 }
17711
17712 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17713
17714 static int
17715 api_one_eid_table_dump (vat_main_t * vam)
17716 {
17717   unformat_input_t *i = vam->input;
17718   vl_api_one_eid_table_dump_t *mp;
17719   vl_api_control_ping_t *mp_ping;
17720   struct in_addr ip4;
17721   struct in6_addr ip6;
17722   u8 mac[6];
17723   u8 eid_type = ~0, eid_set = 0;
17724   u32 prefix_length = ~0, t, vni = 0;
17725   u8 filter = 0;
17726   int ret;
17727   lisp_nsh_api_t nsh;
17728
17729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17730     {
17731       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17732         {
17733           eid_set = 1;
17734           eid_type = 0;
17735           prefix_length = t;
17736         }
17737       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17738         {
17739           eid_set = 1;
17740           eid_type = 1;
17741           prefix_length = t;
17742         }
17743       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17744         {
17745           eid_set = 1;
17746           eid_type = 2;
17747         }
17748       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17749         {
17750           eid_set = 1;
17751           eid_type = 3;
17752         }
17753       else if (unformat (i, "vni %d", &t))
17754         {
17755           vni = t;
17756         }
17757       else if (unformat (i, "local"))
17758         {
17759           filter = 1;
17760         }
17761       else if (unformat (i, "remote"))
17762         {
17763           filter = 2;
17764         }
17765       else
17766         {
17767           errmsg ("parse error '%U'", format_unformat_error, i);
17768           return -99;
17769         }
17770     }
17771
17772   if (!vam->json_output)
17773     {
17774       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17775              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17776     }
17777
17778   M (ONE_EID_TABLE_DUMP, mp);
17779
17780   mp->filter = filter;
17781   if (eid_set)
17782     {
17783       mp->eid_set = 1;
17784       mp->vni = htonl (vni);
17785       mp->eid_type = eid_type;
17786       switch (eid_type)
17787         {
17788         case 0:
17789           mp->prefix_length = prefix_length;
17790           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17791           break;
17792         case 1:
17793           mp->prefix_length = prefix_length;
17794           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17795           break;
17796         case 2:
17797           clib_memcpy (mp->eid, mac, sizeof (mac));
17798           break;
17799         case 3:
17800           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17801           break;
17802         default:
17803           errmsg ("unknown EID type %d!", eid_type);
17804           return -99;
17805         }
17806     }
17807
17808   /* send it... */
17809   S (mp);
17810
17811   /* Use a control ping for synchronization */
17812   MPING (CONTROL_PING, mp_ping);
17813   S (mp_ping);
17814
17815   /* Wait for a reply... */
17816   W (ret);
17817   return ret;
17818 }
17819
17820 #define api_lisp_eid_table_dump api_one_eid_table_dump
17821
17822 static int
17823 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17824 {
17825   unformat_input_t *i = vam->input;
17826   vl_api_gpe_fwd_entries_get_t *mp;
17827   u8 vni_set = 0;
17828   u32 vni = ~0;
17829   int ret;
17830
17831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17832     {
17833       if (unformat (i, "vni %d", &vni))
17834         {
17835           vni_set = 1;
17836         }
17837       else
17838         {
17839           errmsg ("parse error '%U'", format_unformat_error, i);
17840           return -99;
17841         }
17842     }
17843
17844   if (!vni_set)
17845     {
17846       errmsg ("vni not set!");
17847       return -99;
17848     }
17849
17850   if (!vam->json_output)
17851     {
17852       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17853              "leid", "reid");
17854     }
17855
17856   M (GPE_FWD_ENTRIES_GET, mp);
17857   mp->vni = clib_host_to_net_u32 (vni);
17858
17859   /* send it... */
17860   S (mp);
17861
17862   /* Wait for a reply... */
17863   W (ret);
17864   return ret;
17865 }
17866
17867 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17868 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17869 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17870 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17871 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17872 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17873 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17874 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17875
17876 static int
17877 api_one_adjacencies_get (vat_main_t * vam)
17878 {
17879   unformat_input_t *i = vam->input;
17880   vl_api_one_adjacencies_get_t *mp;
17881   u8 vni_set = 0;
17882   u32 vni = ~0;
17883   int ret;
17884
17885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17886     {
17887       if (unformat (i, "vni %d", &vni))
17888         {
17889           vni_set = 1;
17890         }
17891       else
17892         {
17893           errmsg ("parse error '%U'", format_unformat_error, i);
17894           return -99;
17895         }
17896     }
17897
17898   if (!vni_set)
17899     {
17900       errmsg ("vni not set!");
17901       return -99;
17902     }
17903
17904   if (!vam->json_output)
17905     {
17906       print (vam->ofp, "%s %40s", "leid", "reid");
17907     }
17908
17909   M (ONE_ADJACENCIES_GET, mp);
17910   mp->vni = clib_host_to_net_u32 (vni);
17911
17912   /* send it... */
17913   S (mp);
17914
17915   /* Wait for a reply... */
17916   W (ret);
17917   return ret;
17918 }
17919
17920 #define api_lisp_adjacencies_get api_one_adjacencies_get
17921
17922 static int
17923 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17924 {
17925   unformat_input_t *i = vam->input;
17926   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17927   int ret;
17928   u8 ip_family_set = 0, is_ip4 = 1;
17929
17930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17931     {
17932       if (unformat (i, "ip4"))
17933         {
17934           ip_family_set = 1;
17935           is_ip4 = 1;
17936         }
17937       else if (unformat (i, "ip6"))
17938         {
17939           ip_family_set = 1;
17940           is_ip4 = 0;
17941         }
17942       else
17943         {
17944           errmsg ("parse error '%U'", format_unformat_error, i);
17945           return -99;
17946         }
17947     }
17948
17949   if (!ip_family_set)
17950     {
17951       errmsg ("ip family not set!");
17952       return -99;
17953     }
17954
17955   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17956   mp->is_ip4 = is_ip4;
17957
17958   /* send it... */
17959   S (mp);
17960
17961   /* Wait for a reply... */
17962   W (ret);
17963   return ret;
17964 }
17965
17966 static int
17967 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17968 {
17969   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17970   int ret;
17971
17972   if (!vam->json_output)
17973     {
17974       print (vam->ofp, "VNIs");
17975     }
17976
17977   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17978
17979   /* send it... */
17980   S (mp);
17981
17982   /* Wait for a reply... */
17983   W (ret);
17984   return ret;
17985 }
17986
17987 static int
17988 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17989 {
17990   unformat_input_t *i = vam->input;
17991   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17992   int ret = 0;
17993   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17994   struct in_addr ip4;
17995   struct in6_addr ip6;
17996   u32 table_id = 0, nh_sw_if_index = ~0;
17997
17998   clib_memset (&ip4, 0, sizeof (ip4));
17999   clib_memset (&ip6, 0, sizeof (ip6));
18000
18001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18002     {
18003       if (unformat (i, "del"))
18004         is_add = 0;
18005       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18006                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18007         {
18008           ip_set = 1;
18009           is_ip4 = 1;
18010         }
18011       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18012                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18013         {
18014           ip_set = 1;
18015           is_ip4 = 0;
18016         }
18017       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18018         {
18019           ip_set = 1;
18020           is_ip4 = 1;
18021           nh_sw_if_index = ~0;
18022         }
18023       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18024         {
18025           ip_set = 1;
18026           is_ip4 = 0;
18027           nh_sw_if_index = ~0;
18028         }
18029       else if (unformat (i, "table %d", &table_id))
18030         ;
18031       else
18032         {
18033           errmsg ("parse error '%U'", format_unformat_error, i);
18034           return -99;
18035         }
18036     }
18037
18038   if (!ip_set)
18039     {
18040       errmsg ("nh addr not set!");
18041       return -99;
18042     }
18043
18044   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18045   mp->is_add = is_add;
18046   mp->table_id = clib_host_to_net_u32 (table_id);
18047   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18048   mp->is_ip4 = is_ip4;
18049   if (is_ip4)
18050     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18051   else
18052     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18053
18054   /* send it... */
18055   S (mp);
18056
18057   /* Wait for a reply... */
18058   W (ret);
18059   return ret;
18060 }
18061
18062 static int
18063 api_one_map_server_dump (vat_main_t * vam)
18064 {
18065   vl_api_one_map_server_dump_t *mp;
18066   vl_api_control_ping_t *mp_ping;
18067   int ret;
18068
18069   if (!vam->json_output)
18070     {
18071       print (vam->ofp, "%=20s", "Map server");
18072     }
18073
18074   M (ONE_MAP_SERVER_DUMP, mp);
18075   /* send it... */
18076   S (mp);
18077
18078   /* Use a control ping for synchronization */
18079   MPING (CONTROL_PING, mp_ping);
18080   S (mp_ping);
18081
18082   /* Wait for a reply... */
18083   W (ret);
18084   return ret;
18085 }
18086
18087 #define api_lisp_map_server_dump api_one_map_server_dump
18088
18089 static int
18090 api_one_map_resolver_dump (vat_main_t * vam)
18091 {
18092   vl_api_one_map_resolver_dump_t *mp;
18093   vl_api_control_ping_t *mp_ping;
18094   int ret;
18095
18096   if (!vam->json_output)
18097     {
18098       print (vam->ofp, "%=20s", "Map resolver");
18099     }
18100
18101   M (ONE_MAP_RESOLVER_DUMP, mp);
18102   /* send it... */
18103   S (mp);
18104
18105   /* Use a control ping for synchronization */
18106   MPING (CONTROL_PING, mp_ping);
18107   S (mp_ping);
18108
18109   /* Wait for a reply... */
18110   W (ret);
18111   return ret;
18112 }
18113
18114 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18115
18116 static int
18117 api_one_stats_flush (vat_main_t * vam)
18118 {
18119   vl_api_one_stats_flush_t *mp;
18120   int ret = 0;
18121
18122   M (ONE_STATS_FLUSH, mp);
18123   S (mp);
18124   W (ret);
18125   return ret;
18126 }
18127
18128 static int
18129 api_one_stats_dump (vat_main_t * vam)
18130 {
18131   vl_api_one_stats_dump_t *mp;
18132   vl_api_control_ping_t *mp_ping;
18133   int ret;
18134
18135   M (ONE_STATS_DUMP, mp);
18136   /* send it... */
18137   S (mp);
18138
18139   /* Use a control ping for synchronization */
18140   MPING (CONTROL_PING, mp_ping);
18141   S (mp_ping);
18142
18143   /* Wait for a reply... */
18144   W (ret);
18145   return ret;
18146 }
18147
18148 static int
18149 api_show_one_status (vat_main_t * vam)
18150 {
18151   vl_api_show_one_status_t *mp;
18152   int ret;
18153
18154   if (!vam->json_output)
18155     {
18156       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18157     }
18158
18159   M (SHOW_ONE_STATUS, mp);
18160   /* send it... */
18161   S (mp);
18162   /* Wait for a reply... */
18163   W (ret);
18164   return ret;
18165 }
18166
18167 #define api_show_lisp_status api_show_one_status
18168
18169 static int
18170 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18171 {
18172   vl_api_gpe_fwd_entry_path_dump_t *mp;
18173   vl_api_control_ping_t *mp_ping;
18174   unformat_input_t *i = vam->input;
18175   u32 fwd_entry_index = ~0;
18176   int ret;
18177
18178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18179     {
18180       if (unformat (i, "index %d", &fwd_entry_index))
18181         ;
18182       else
18183         break;
18184     }
18185
18186   if (~0 == fwd_entry_index)
18187     {
18188       errmsg ("no index specified!");
18189       return -99;
18190     }
18191
18192   if (!vam->json_output)
18193     {
18194       print (vam->ofp, "first line");
18195     }
18196
18197   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18198
18199   /* send it... */
18200   S (mp);
18201   /* Use a control ping for synchronization */
18202   MPING (CONTROL_PING, mp_ping);
18203   S (mp_ping);
18204
18205   /* Wait for a reply... */
18206   W (ret);
18207   return ret;
18208 }
18209
18210 static int
18211 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18212 {
18213   vl_api_one_get_map_request_itr_rlocs_t *mp;
18214   int ret;
18215
18216   if (!vam->json_output)
18217     {
18218       print (vam->ofp, "%=20s", "itr-rlocs:");
18219     }
18220
18221   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18222   /* send it... */
18223   S (mp);
18224   /* Wait for a reply... */
18225   W (ret);
18226   return ret;
18227 }
18228
18229 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18230
18231 static int
18232 api_af_packet_create (vat_main_t * vam)
18233 {
18234   unformat_input_t *i = vam->input;
18235   vl_api_af_packet_create_t *mp;
18236   u8 *host_if_name = 0;
18237   u8 hw_addr[6];
18238   u8 random_hw_addr = 1;
18239   int ret;
18240
18241   clib_memset (hw_addr, 0, sizeof (hw_addr));
18242
18243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18244     {
18245       if (unformat (i, "name %s", &host_if_name))
18246         vec_add1 (host_if_name, 0);
18247       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18248         random_hw_addr = 0;
18249       else
18250         break;
18251     }
18252
18253   if (!vec_len (host_if_name))
18254     {
18255       errmsg ("host-interface name must be specified");
18256       return -99;
18257     }
18258
18259   if (vec_len (host_if_name) > 64)
18260     {
18261       errmsg ("host-interface name too long");
18262       return -99;
18263     }
18264
18265   M (AF_PACKET_CREATE, mp);
18266
18267   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18268   clib_memcpy (mp->hw_addr, hw_addr, 6);
18269   mp->use_random_hw_addr = random_hw_addr;
18270   vec_free (host_if_name);
18271
18272   S (mp);
18273
18274   /* *INDENT-OFF* */
18275   W2 (ret,
18276       ({
18277         if (ret == 0)
18278           fprintf (vam->ofp ? vam->ofp : stderr,
18279                    " new sw_if_index = %d\n", vam->sw_if_index);
18280       }));
18281   /* *INDENT-ON* */
18282   return ret;
18283 }
18284
18285 static int
18286 api_af_packet_delete (vat_main_t * vam)
18287 {
18288   unformat_input_t *i = vam->input;
18289   vl_api_af_packet_delete_t *mp;
18290   u8 *host_if_name = 0;
18291   int ret;
18292
18293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18294     {
18295       if (unformat (i, "name %s", &host_if_name))
18296         vec_add1 (host_if_name, 0);
18297       else
18298         break;
18299     }
18300
18301   if (!vec_len (host_if_name))
18302     {
18303       errmsg ("host-interface name must be specified");
18304       return -99;
18305     }
18306
18307   if (vec_len (host_if_name) > 64)
18308     {
18309       errmsg ("host-interface name too long");
18310       return -99;
18311     }
18312
18313   M (AF_PACKET_DELETE, mp);
18314
18315   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18316   vec_free (host_if_name);
18317
18318   S (mp);
18319   W (ret);
18320   return ret;
18321 }
18322
18323 static void vl_api_af_packet_details_t_handler
18324   (vl_api_af_packet_details_t * mp)
18325 {
18326   vat_main_t *vam = &vat_main;
18327
18328   print (vam->ofp, "%-16s %d",
18329          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18330 }
18331
18332 static void vl_api_af_packet_details_t_handler_json
18333   (vl_api_af_packet_details_t * mp)
18334 {
18335   vat_main_t *vam = &vat_main;
18336   vat_json_node_t *node = NULL;
18337
18338   if (VAT_JSON_ARRAY != vam->json_tree.type)
18339     {
18340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18341       vat_json_init_array (&vam->json_tree);
18342     }
18343   node = vat_json_array_add (&vam->json_tree);
18344
18345   vat_json_init_object (node);
18346   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18347   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18348 }
18349
18350 static int
18351 api_af_packet_dump (vat_main_t * vam)
18352 {
18353   vl_api_af_packet_dump_t *mp;
18354   vl_api_control_ping_t *mp_ping;
18355   int ret;
18356
18357   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18358   /* Get list of tap interfaces */
18359   M (AF_PACKET_DUMP, mp);
18360   S (mp);
18361
18362   /* Use a control ping for synchronization */
18363   MPING (CONTROL_PING, mp_ping);
18364   S (mp_ping);
18365
18366   W (ret);
18367   return ret;
18368 }
18369
18370 static int
18371 api_policer_add_del (vat_main_t * vam)
18372 {
18373   unformat_input_t *i = vam->input;
18374   vl_api_policer_add_del_t *mp;
18375   u8 is_add = 1;
18376   u8 *name = 0;
18377   u32 cir = 0;
18378   u32 eir = 0;
18379   u64 cb = 0;
18380   u64 eb = 0;
18381   u8 rate_type = 0;
18382   u8 round_type = 0;
18383   u8 type = 0;
18384   u8 color_aware = 0;
18385   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18386   int ret;
18387
18388   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18389   conform_action.dscp = 0;
18390   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18391   exceed_action.dscp = 0;
18392   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18393   violate_action.dscp = 0;
18394
18395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18396     {
18397       if (unformat (i, "del"))
18398         is_add = 0;
18399       else if (unformat (i, "name %s", &name))
18400         vec_add1 (name, 0);
18401       else if (unformat (i, "cir %u", &cir))
18402         ;
18403       else if (unformat (i, "eir %u", &eir))
18404         ;
18405       else if (unformat (i, "cb %u", &cb))
18406         ;
18407       else if (unformat (i, "eb %u", &eb))
18408         ;
18409       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18410                          &rate_type))
18411         ;
18412       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18413                          &round_type))
18414         ;
18415       else if (unformat (i, "type %U", unformat_policer_type, &type))
18416         ;
18417       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18418                          &conform_action))
18419         ;
18420       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18421                          &exceed_action))
18422         ;
18423       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18424                          &violate_action))
18425         ;
18426       else if (unformat (i, "color-aware"))
18427         color_aware = 1;
18428       else
18429         break;
18430     }
18431
18432   if (!vec_len (name))
18433     {
18434       errmsg ("policer name must be specified");
18435       return -99;
18436     }
18437
18438   if (vec_len (name) > 64)
18439     {
18440       errmsg ("policer name too long");
18441       return -99;
18442     }
18443
18444   M (POLICER_ADD_DEL, mp);
18445
18446   clib_memcpy (mp->name, name, vec_len (name));
18447   vec_free (name);
18448   mp->is_add = is_add;
18449   mp->cir = ntohl (cir);
18450   mp->eir = ntohl (eir);
18451   mp->cb = clib_net_to_host_u64 (cb);
18452   mp->eb = clib_net_to_host_u64 (eb);
18453   mp->rate_type = rate_type;
18454   mp->round_type = round_type;
18455   mp->type = type;
18456   mp->conform_action_type = conform_action.action_type;
18457   mp->conform_dscp = conform_action.dscp;
18458   mp->exceed_action_type = exceed_action.action_type;
18459   mp->exceed_dscp = exceed_action.dscp;
18460   mp->violate_action_type = violate_action.action_type;
18461   mp->violate_dscp = violate_action.dscp;
18462   mp->color_aware = color_aware;
18463
18464   S (mp);
18465   W (ret);
18466   return ret;
18467 }
18468
18469 static int
18470 api_policer_dump (vat_main_t * vam)
18471 {
18472   unformat_input_t *i = vam->input;
18473   vl_api_policer_dump_t *mp;
18474   vl_api_control_ping_t *mp_ping;
18475   u8 *match_name = 0;
18476   u8 match_name_valid = 0;
18477   int ret;
18478
18479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18480     {
18481       if (unformat (i, "name %s", &match_name))
18482         {
18483           vec_add1 (match_name, 0);
18484           match_name_valid = 1;
18485         }
18486       else
18487         break;
18488     }
18489
18490   M (POLICER_DUMP, mp);
18491   mp->match_name_valid = match_name_valid;
18492   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18493   vec_free (match_name);
18494   /* send it... */
18495   S (mp);
18496
18497   /* Use a control ping for synchronization */
18498   MPING (CONTROL_PING, mp_ping);
18499   S (mp_ping);
18500
18501   /* Wait for a reply... */
18502   W (ret);
18503   return ret;
18504 }
18505
18506 static int
18507 api_policer_classify_set_interface (vat_main_t * vam)
18508 {
18509   unformat_input_t *i = vam->input;
18510   vl_api_policer_classify_set_interface_t *mp;
18511   u32 sw_if_index;
18512   int sw_if_index_set;
18513   u32 ip4_table_index = ~0;
18514   u32 ip6_table_index = ~0;
18515   u32 l2_table_index = ~0;
18516   u8 is_add = 1;
18517   int ret;
18518
18519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18520     {
18521       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18522         sw_if_index_set = 1;
18523       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18524         sw_if_index_set = 1;
18525       else if (unformat (i, "del"))
18526         is_add = 0;
18527       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18528         ;
18529       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18530         ;
18531       else if (unformat (i, "l2-table %d", &l2_table_index))
18532         ;
18533       else
18534         {
18535           clib_warning ("parse error '%U'", format_unformat_error, i);
18536           return -99;
18537         }
18538     }
18539
18540   if (sw_if_index_set == 0)
18541     {
18542       errmsg ("missing interface name or sw_if_index");
18543       return -99;
18544     }
18545
18546   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18547
18548   mp->sw_if_index = ntohl (sw_if_index);
18549   mp->ip4_table_index = ntohl (ip4_table_index);
18550   mp->ip6_table_index = ntohl (ip6_table_index);
18551   mp->l2_table_index = ntohl (l2_table_index);
18552   mp->is_add = is_add;
18553
18554   S (mp);
18555   W (ret);
18556   return ret;
18557 }
18558
18559 static int
18560 api_policer_classify_dump (vat_main_t * vam)
18561 {
18562   unformat_input_t *i = vam->input;
18563   vl_api_policer_classify_dump_t *mp;
18564   vl_api_control_ping_t *mp_ping;
18565   u8 type = POLICER_CLASSIFY_N_TABLES;
18566   int ret;
18567
18568   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18569     ;
18570   else
18571     {
18572       errmsg ("classify table type must be specified");
18573       return -99;
18574     }
18575
18576   if (!vam->json_output)
18577     {
18578       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18579     }
18580
18581   M (POLICER_CLASSIFY_DUMP, mp);
18582   mp->type = type;
18583   /* send it... */
18584   S (mp);
18585
18586   /* Use a control ping for synchronization */
18587   MPING (CONTROL_PING, mp_ping);
18588   S (mp_ping);
18589
18590   /* Wait for a reply... */
18591   W (ret);
18592   return ret;
18593 }
18594
18595 static int
18596 api_netmap_create (vat_main_t * vam)
18597 {
18598   unformat_input_t *i = vam->input;
18599   vl_api_netmap_create_t *mp;
18600   u8 *if_name = 0;
18601   u8 hw_addr[6];
18602   u8 random_hw_addr = 1;
18603   u8 is_pipe = 0;
18604   u8 is_master = 0;
18605   int ret;
18606
18607   clib_memset (hw_addr, 0, sizeof (hw_addr));
18608
18609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18610     {
18611       if (unformat (i, "name %s", &if_name))
18612         vec_add1 (if_name, 0);
18613       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18614         random_hw_addr = 0;
18615       else if (unformat (i, "pipe"))
18616         is_pipe = 1;
18617       else if (unformat (i, "master"))
18618         is_master = 1;
18619       else if (unformat (i, "slave"))
18620         is_master = 0;
18621       else
18622         break;
18623     }
18624
18625   if (!vec_len (if_name))
18626     {
18627       errmsg ("interface name must be specified");
18628       return -99;
18629     }
18630
18631   if (vec_len (if_name) > 64)
18632     {
18633       errmsg ("interface name too long");
18634       return -99;
18635     }
18636
18637   M (NETMAP_CREATE, mp);
18638
18639   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18640   clib_memcpy (mp->hw_addr, hw_addr, 6);
18641   mp->use_random_hw_addr = random_hw_addr;
18642   mp->is_pipe = is_pipe;
18643   mp->is_master = is_master;
18644   vec_free (if_name);
18645
18646   S (mp);
18647   W (ret);
18648   return ret;
18649 }
18650
18651 static int
18652 api_netmap_delete (vat_main_t * vam)
18653 {
18654   unformat_input_t *i = vam->input;
18655   vl_api_netmap_delete_t *mp;
18656   u8 *if_name = 0;
18657   int ret;
18658
18659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18660     {
18661       if (unformat (i, "name %s", &if_name))
18662         vec_add1 (if_name, 0);
18663       else
18664         break;
18665     }
18666
18667   if (!vec_len (if_name))
18668     {
18669       errmsg ("interface name must be specified");
18670       return -99;
18671     }
18672
18673   if (vec_len (if_name) > 64)
18674     {
18675       errmsg ("interface name too long");
18676       return -99;
18677     }
18678
18679   M (NETMAP_DELETE, mp);
18680
18681   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18682   vec_free (if_name);
18683
18684   S (mp);
18685   W (ret);
18686   return ret;
18687 }
18688
18689 static u8 *
18690 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18691 {
18692   vl_api_fib_path_nh_proto_t proto =
18693     va_arg (*args, vl_api_fib_path_nh_proto_t);
18694
18695   switch (proto)
18696     {
18697     case FIB_API_PATH_NH_PROTO_IP4:
18698       s = format (s, "ip4");
18699       break;
18700     case FIB_API_PATH_NH_PROTO_IP6:
18701       s = format (s, "ip6");
18702       break;
18703     case FIB_API_PATH_NH_PROTO_MPLS:
18704       s = format (s, "mpls");
18705       break;
18706     case FIB_API_PATH_NH_PROTO_BIER:
18707       s = format (s, "bier");
18708       break;
18709     case FIB_API_PATH_NH_PROTO_ETHERNET:
18710       s = format (s, "ethernet");
18711       break;
18712     }
18713
18714   return (s);
18715 }
18716
18717 static u8 *
18718 format_vl_api_ip_address_union (u8 * s, va_list * args)
18719 {
18720   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18721   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18722
18723   switch (af)
18724     {
18725     case ADDRESS_IP4:
18726       s = format (s, "%U", format_ip4_address, u->ip4);
18727       break;
18728     case ADDRESS_IP6:
18729       s = format (s, "%U", format_ip6_address, u->ip6);
18730       break;
18731     }
18732   return (s);
18733 }
18734
18735 static u8 *
18736 format_vl_api_fib_path_type (u8 * s, va_list * args)
18737 {
18738   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18739
18740   switch (t)
18741     {
18742     case FIB_API_PATH_TYPE_NORMAL:
18743       s = format (s, "normal");
18744       break;
18745     case FIB_API_PATH_TYPE_LOCAL:
18746       s = format (s, "local");
18747       break;
18748     case FIB_API_PATH_TYPE_DROP:
18749       s = format (s, "drop");
18750       break;
18751     case FIB_API_PATH_TYPE_UDP_ENCAP:
18752       s = format (s, "udp-encap");
18753       break;
18754     case FIB_API_PATH_TYPE_BIER_IMP:
18755       s = format (s, "bier-imp");
18756       break;
18757     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18758       s = format (s, "unreach");
18759       break;
18760     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18761       s = format (s, "prohibit");
18762       break;
18763     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18764       s = format (s, "src-lookup");
18765       break;
18766     case FIB_API_PATH_TYPE_DVR:
18767       s = format (s, "dvr");
18768       break;
18769     case FIB_API_PATH_TYPE_INTERFACE_RX:
18770       s = format (s, "interface-rx");
18771       break;
18772     case FIB_API_PATH_TYPE_CLASSIFY:
18773       s = format (s, "classify");
18774       break;
18775     }
18776
18777   return (s);
18778 }
18779
18780 static void
18781 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18782 {
18783   print (vam->ofp,
18784          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18785          ntohl (fp->weight), ntohl (fp->sw_if_index),
18786          format_vl_api_fib_path_type, fp->type,
18787          format_fib_api_path_nh_proto, fp->proto,
18788          format_vl_api_ip_address_union, &fp->nh.address);
18789 }
18790
18791 static void
18792 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18793                                  vl_api_fib_path_t * fp)
18794 {
18795   struct in_addr ip4;
18796   struct in6_addr ip6;
18797
18798   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18799   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18800   vat_json_object_add_uint (node, "type", fp->type);
18801   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18802   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18803     {
18804       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18805       vat_json_object_add_ip4 (node, "next_hop", ip4);
18806     }
18807   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18808     {
18809       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18810       vat_json_object_add_ip6 (node, "next_hop", ip6);
18811     }
18812 }
18813
18814 static void
18815 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18816 {
18817   vat_main_t *vam = &vat_main;
18818   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18819   vl_api_fib_path_t *fp;
18820   i32 i;
18821
18822   print (vam->ofp, "sw_if_index %d via:",
18823          ntohl (mp->mt_tunnel.mt_sw_if_index));
18824   fp = mp->mt_tunnel.mt_paths;
18825   for (i = 0; i < count; i++)
18826     {
18827       vl_api_fib_path_print (vam, fp);
18828       fp++;
18829     }
18830
18831   print (vam->ofp, "");
18832 }
18833
18834 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18835 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18836
18837 static void
18838 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18839 {
18840   vat_main_t *vam = &vat_main;
18841   vat_json_node_t *node = NULL;
18842   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18843   vl_api_fib_path_t *fp;
18844   i32 i;
18845
18846   if (VAT_JSON_ARRAY != vam->json_tree.type)
18847     {
18848       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18849       vat_json_init_array (&vam->json_tree);
18850     }
18851   node = vat_json_array_add (&vam->json_tree);
18852
18853   vat_json_init_object (node);
18854   vat_json_object_add_uint (node, "sw_if_index",
18855                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18856
18857   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18858
18859   fp = mp->mt_tunnel.mt_paths;
18860   for (i = 0; i < count; i++)
18861     {
18862       vl_api_mpls_fib_path_json_print (node, fp);
18863       fp++;
18864     }
18865 }
18866
18867 static int
18868 api_mpls_tunnel_dump (vat_main_t * vam)
18869 {
18870   vl_api_mpls_tunnel_dump_t *mp;
18871   vl_api_control_ping_t *mp_ping;
18872   int ret;
18873
18874   M (MPLS_TUNNEL_DUMP, mp);
18875
18876   S (mp);
18877
18878   /* Use a control ping for synchronization */
18879   MPING (CONTROL_PING, mp_ping);
18880   S (mp_ping);
18881
18882   W (ret);
18883   return ret;
18884 }
18885
18886 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18887 #define vl_api_mpls_table_details_t_print vl_noop_handler
18888
18889
18890 static void
18891 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18892 {
18893   vat_main_t *vam = &vat_main;
18894
18895   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18896 }
18897
18898 static void vl_api_mpls_table_details_t_handler_json
18899   (vl_api_mpls_table_details_t * mp)
18900 {
18901   vat_main_t *vam = &vat_main;
18902   vat_json_node_t *node = NULL;
18903
18904   if (VAT_JSON_ARRAY != vam->json_tree.type)
18905     {
18906       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18907       vat_json_init_array (&vam->json_tree);
18908     }
18909   node = vat_json_array_add (&vam->json_tree);
18910
18911   vat_json_init_object (node);
18912   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18913 }
18914
18915 static int
18916 api_mpls_table_dump (vat_main_t * vam)
18917 {
18918   vl_api_mpls_table_dump_t *mp;
18919   vl_api_control_ping_t *mp_ping;
18920   int ret;
18921
18922   M (MPLS_TABLE_DUMP, mp);
18923   S (mp);
18924
18925   /* Use a control ping for synchronization */
18926   MPING (CONTROL_PING, mp_ping);
18927   S (mp_ping);
18928
18929   W (ret);
18930   return ret;
18931 }
18932
18933 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18934 #define vl_api_mpls_route_details_t_print vl_noop_handler
18935
18936 static void
18937 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18938 {
18939   vat_main_t *vam = &vat_main;
18940   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18941   vl_api_fib_path_t *fp;
18942   int i;
18943
18944   print (vam->ofp,
18945          "table-id %d, label %u, ess_bit %u",
18946          ntohl (mp->mr_route.mr_table_id),
18947          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18948   fp = mp->mr_route.mr_paths;
18949   for (i = 0; i < count; i++)
18950     {
18951       vl_api_fib_path_print (vam, fp);
18952       fp++;
18953     }
18954 }
18955
18956 static void vl_api_mpls_route_details_t_handler_json
18957   (vl_api_mpls_route_details_t * mp)
18958 {
18959   vat_main_t *vam = &vat_main;
18960   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18961   vat_json_node_t *node = NULL;
18962   vl_api_fib_path_t *fp;
18963   int i;
18964
18965   if (VAT_JSON_ARRAY != vam->json_tree.type)
18966     {
18967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18968       vat_json_init_array (&vam->json_tree);
18969     }
18970   node = vat_json_array_add (&vam->json_tree);
18971
18972   vat_json_init_object (node);
18973   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18974   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18975   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18976   vat_json_object_add_uint (node, "path_count", count);
18977   fp = mp->mr_route.mr_paths;
18978   for (i = 0; i < count; i++)
18979     {
18980       vl_api_mpls_fib_path_json_print (node, fp);
18981       fp++;
18982     }
18983 }
18984
18985 static int
18986 api_mpls_route_dump (vat_main_t * vam)
18987 {
18988   unformat_input_t *input = vam->input;
18989   vl_api_mpls_route_dump_t *mp;
18990   vl_api_control_ping_t *mp_ping;
18991   u32 table_id;
18992   int ret;
18993
18994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18995     {
18996       if (unformat (input, "table_id %d", &table_id))
18997         ;
18998       else
18999         break;
19000     }
19001   if (table_id == ~0)
19002     {
19003       errmsg ("missing table id");
19004       return -99;
19005     }
19006
19007   M (MPLS_ROUTE_DUMP, mp);
19008
19009   mp->table.mt_table_id = ntohl (table_id);
19010   S (mp);
19011
19012   /* Use a control ping for synchronization */
19013   MPING (CONTROL_PING, mp_ping);
19014   S (mp_ping);
19015
19016   W (ret);
19017   return ret;
19018 }
19019
19020 #define vl_api_ip_table_details_t_endian vl_noop_handler
19021 #define vl_api_ip_table_details_t_print vl_noop_handler
19022
19023 static void
19024 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19025 {
19026   vat_main_t *vam = &vat_main;
19027
19028   print (vam->ofp,
19029          "%s; table-id %d, prefix %U/%d",
19030          mp->table.name, ntohl (mp->table.table_id));
19031 }
19032
19033
19034 static void vl_api_ip_table_details_t_handler_json
19035   (vl_api_ip_table_details_t * mp)
19036 {
19037   vat_main_t *vam = &vat_main;
19038   vat_json_node_t *node = NULL;
19039
19040   if (VAT_JSON_ARRAY != vam->json_tree.type)
19041     {
19042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19043       vat_json_init_array (&vam->json_tree);
19044     }
19045   node = vat_json_array_add (&vam->json_tree);
19046
19047   vat_json_init_object (node);
19048   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19049 }
19050
19051 static int
19052 api_ip_table_dump (vat_main_t * vam)
19053 {
19054   vl_api_ip_table_dump_t *mp;
19055   vl_api_control_ping_t *mp_ping;
19056   int ret;
19057
19058   M (IP_TABLE_DUMP, mp);
19059   S (mp);
19060
19061   /* Use a control ping for synchronization */
19062   MPING (CONTROL_PING, mp_ping);
19063   S (mp_ping);
19064
19065   W (ret);
19066   return ret;
19067 }
19068
19069 static int
19070 api_ip_mtable_dump (vat_main_t * vam)
19071 {
19072   vl_api_ip_mtable_dump_t *mp;
19073   vl_api_control_ping_t *mp_ping;
19074   int ret;
19075
19076   M (IP_MTABLE_DUMP, mp);
19077   S (mp);
19078
19079   /* Use a control ping for synchronization */
19080   MPING (CONTROL_PING, mp_ping);
19081   S (mp_ping);
19082
19083   W (ret);
19084   return ret;
19085 }
19086
19087 static int
19088 api_ip_mroute_dump (vat_main_t * vam)
19089 {
19090   unformat_input_t *input = vam->input;
19091   vl_api_control_ping_t *mp_ping;
19092   vl_api_ip_mroute_dump_t *mp;
19093   int ret, is_ip6;
19094   u32 table_id;
19095
19096   is_ip6 = 0;
19097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19098     {
19099       if (unformat (input, "table_id %d", &table_id))
19100         ;
19101       else if (unformat (input, "ip6"))
19102         is_ip6 = 1;
19103       else if (unformat (input, "ip4"))
19104         is_ip6 = 0;
19105       else
19106         break;
19107     }
19108   if (table_id == ~0)
19109     {
19110       errmsg ("missing table id");
19111       return -99;
19112     }
19113
19114   M (IP_MROUTE_DUMP, mp);
19115   mp->table.table_id = table_id;
19116   mp->table.is_ip6 = is_ip6;
19117   S (mp);
19118
19119   /* Use a control ping for synchronization */
19120   MPING (CONTROL_PING, mp_ping);
19121   S (mp_ping);
19122
19123   W (ret);
19124   return ret;
19125 }
19126
19127 static void vl_api_ip_neighbor_details_t_handler
19128   (vl_api_ip_neighbor_details_t * mp)
19129 {
19130   vat_main_t *vam = &vat_main;
19131
19132   print (vam->ofp, "%c %U %U",
19133          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19134          format_vl_api_mac_address, &mp->neighbor.mac_address,
19135          format_vl_api_address, &mp->neighbor.ip_address);
19136 }
19137
19138 static void vl_api_ip_neighbor_details_t_handler_json
19139   (vl_api_ip_neighbor_details_t * mp)
19140 {
19141
19142   vat_main_t *vam = &vat_main;
19143   vat_json_node_t *node;
19144
19145   if (VAT_JSON_ARRAY != vam->json_tree.type)
19146     {
19147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19148       vat_json_init_array (&vam->json_tree);
19149     }
19150   node = vat_json_array_add (&vam->json_tree);
19151
19152   vat_json_init_object (node);
19153   vat_json_object_add_string_copy
19154     (node, "flag",
19155      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19156       (u8 *) "static" : (u8 *) "dynamic"));
19157
19158   vat_json_object_add_string_copy (node, "link_layer",
19159                                    format (0, "%U", format_vl_api_mac_address,
19160                                            &mp->neighbor.mac_address));
19161   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19162 }
19163
19164 static int
19165 api_ip_neighbor_dump (vat_main_t * vam)
19166 {
19167   unformat_input_t *i = vam->input;
19168   vl_api_ip_neighbor_dump_t *mp;
19169   vl_api_control_ping_t *mp_ping;
19170   u8 is_ipv6 = 0;
19171   u32 sw_if_index = ~0;
19172   int ret;
19173
19174   /* Parse args required to build the message */
19175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19176     {
19177       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19178         ;
19179       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19180         ;
19181       else if (unformat (i, "ip6"))
19182         is_ipv6 = 1;
19183       else
19184         break;
19185     }
19186
19187   if (sw_if_index == ~0)
19188     {
19189       errmsg ("missing interface name or sw_if_index");
19190       return -99;
19191     }
19192
19193   M (IP_NEIGHBOR_DUMP, mp);
19194   mp->is_ipv6 = (u8) is_ipv6;
19195   mp->sw_if_index = ntohl (sw_if_index);
19196   S (mp);
19197
19198   /* Use a control ping for synchronization */
19199   MPING (CONTROL_PING, mp_ping);
19200   S (mp_ping);
19201
19202   W (ret);
19203   return ret;
19204 }
19205
19206 #define vl_api_ip_route_details_t_endian vl_noop_handler
19207 #define vl_api_ip_route_details_t_print vl_noop_handler
19208
19209 static void
19210 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19211 {
19212   vat_main_t *vam = &vat_main;
19213   u8 count = mp->route.n_paths;
19214   vl_api_fib_path_t *fp;
19215   int i;
19216
19217   print (vam->ofp,
19218          "table-id %d, prefix %U/%d",
19219          ntohl (mp->route.table_id),
19220          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19221   for (i = 0; i < count; i++)
19222     {
19223       fp = &mp->route.paths[i];
19224
19225       vl_api_fib_path_print (vam, fp);
19226       fp++;
19227     }
19228 }
19229
19230 static void vl_api_ip_route_details_t_handler_json
19231   (vl_api_ip_route_details_t * mp)
19232 {
19233   vat_main_t *vam = &vat_main;
19234   u8 count = mp->route.n_paths;
19235   vat_json_node_t *node = NULL;
19236   struct in_addr ip4;
19237   struct in6_addr ip6;
19238   vl_api_fib_path_t *fp;
19239   int i;
19240
19241   if (VAT_JSON_ARRAY != vam->json_tree.type)
19242     {
19243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19244       vat_json_init_array (&vam->json_tree);
19245     }
19246   node = vat_json_array_add (&vam->json_tree);
19247
19248   vat_json_init_object (node);
19249   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19250   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19251     {
19252       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19253       vat_json_object_add_ip6 (node, "prefix", ip6);
19254     }
19255   else
19256     {
19257       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19258       vat_json_object_add_ip4 (node, "prefix", ip4);
19259     }
19260   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19261   vat_json_object_add_uint (node, "path_count", count);
19262   for (i = 0; i < count; i++)
19263     {
19264       fp = &mp->route.paths[i];
19265       vl_api_mpls_fib_path_json_print (node, fp);
19266     }
19267 }
19268
19269 static int
19270 api_ip_route_dump (vat_main_t * vam)
19271 {
19272   unformat_input_t *input = vam->input;
19273   vl_api_ip_route_dump_t *mp;
19274   vl_api_control_ping_t *mp_ping;
19275   u32 table_id;
19276   u8 is_ip6;
19277   int ret;
19278
19279   is_ip6 = 0;
19280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19281     {
19282       if (unformat (input, "table_id %d", &table_id))
19283         ;
19284       else if (unformat (input, "ip6"))
19285         is_ip6 = 1;
19286       else if (unformat (input, "ip4"))
19287         is_ip6 = 0;
19288       else
19289         break;
19290     }
19291   if (table_id == ~0)
19292     {
19293       errmsg ("missing table id");
19294       return -99;
19295     }
19296
19297   M (IP_ROUTE_DUMP, mp);
19298
19299   mp->table.table_id = table_id;
19300   mp->table.is_ip6 = is_ip6;
19301
19302   S (mp);
19303
19304   /* Use a control ping for synchronization */
19305   MPING (CONTROL_PING, mp_ping);
19306   S (mp_ping);
19307
19308   W (ret);
19309   return ret;
19310 }
19311
19312 int
19313 api_classify_table_ids (vat_main_t * vam)
19314 {
19315   vl_api_classify_table_ids_t *mp;
19316   int ret;
19317
19318   /* Construct the API message */
19319   M (CLASSIFY_TABLE_IDS, mp);
19320   mp->context = 0;
19321
19322   S (mp);
19323   W (ret);
19324   return ret;
19325 }
19326
19327 int
19328 api_classify_table_by_interface (vat_main_t * vam)
19329 {
19330   unformat_input_t *input = vam->input;
19331   vl_api_classify_table_by_interface_t *mp;
19332
19333   u32 sw_if_index = ~0;
19334   int ret;
19335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19336     {
19337       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19338         ;
19339       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19340         ;
19341       else
19342         break;
19343     }
19344   if (sw_if_index == ~0)
19345     {
19346       errmsg ("missing interface name or sw_if_index");
19347       return -99;
19348     }
19349
19350   /* Construct the API message */
19351   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19352   mp->context = 0;
19353   mp->sw_if_index = ntohl (sw_if_index);
19354
19355   S (mp);
19356   W (ret);
19357   return ret;
19358 }
19359
19360 int
19361 api_classify_table_info (vat_main_t * vam)
19362 {
19363   unformat_input_t *input = vam->input;
19364   vl_api_classify_table_info_t *mp;
19365
19366   u32 table_id = ~0;
19367   int ret;
19368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19369     {
19370       if (unformat (input, "table_id %d", &table_id))
19371         ;
19372       else
19373         break;
19374     }
19375   if (table_id == ~0)
19376     {
19377       errmsg ("missing table id");
19378       return -99;
19379     }
19380
19381   /* Construct the API message */
19382   M (CLASSIFY_TABLE_INFO, mp);
19383   mp->context = 0;
19384   mp->table_id = ntohl (table_id);
19385
19386   S (mp);
19387   W (ret);
19388   return ret;
19389 }
19390
19391 int
19392 api_classify_session_dump (vat_main_t * vam)
19393 {
19394   unformat_input_t *input = vam->input;
19395   vl_api_classify_session_dump_t *mp;
19396   vl_api_control_ping_t *mp_ping;
19397
19398   u32 table_id = ~0;
19399   int ret;
19400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19401     {
19402       if (unformat (input, "table_id %d", &table_id))
19403         ;
19404       else
19405         break;
19406     }
19407   if (table_id == ~0)
19408     {
19409       errmsg ("missing table id");
19410       return -99;
19411     }
19412
19413   /* Construct the API message */
19414   M (CLASSIFY_SESSION_DUMP, mp);
19415   mp->context = 0;
19416   mp->table_id = ntohl (table_id);
19417   S (mp);
19418
19419   /* Use a control ping for synchronization */
19420   MPING (CONTROL_PING, mp_ping);
19421   S (mp_ping);
19422
19423   W (ret);
19424   return ret;
19425 }
19426
19427 static void
19428 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19429 {
19430   vat_main_t *vam = &vat_main;
19431
19432   print (vam->ofp, "collector_address %U, collector_port %d, "
19433          "src_address %U, vrf_id %d, path_mtu %u, "
19434          "template_interval %u, udp_checksum %d",
19435          format_ip4_address, mp->collector_address,
19436          ntohs (mp->collector_port),
19437          format_ip4_address, mp->src_address,
19438          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19439          ntohl (mp->template_interval), mp->udp_checksum);
19440
19441   vam->retval = 0;
19442   vam->result_ready = 1;
19443 }
19444
19445 static void
19446   vl_api_ipfix_exporter_details_t_handler_json
19447   (vl_api_ipfix_exporter_details_t * mp)
19448 {
19449   vat_main_t *vam = &vat_main;
19450   vat_json_node_t node;
19451   struct in_addr collector_address;
19452   struct in_addr src_address;
19453
19454   vat_json_init_object (&node);
19455   clib_memcpy (&collector_address, &mp->collector_address,
19456                sizeof (collector_address));
19457   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19458   vat_json_object_add_uint (&node, "collector_port",
19459                             ntohs (mp->collector_port));
19460   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19461   vat_json_object_add_ip4 (&node, "src_address", src_address);
19462   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19463   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19464   vat_json_object_add_uint (&node, "template_interval",
19465                             ntohl (mp->template_interval));
19466   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19467
19468   vat_json_print (vam->ofp, &node);
19469   vat_json_free (&node);
19470   vam->retval = 0;
19471   vam->result_ready = 1;
19472 }
19473
19474 int
19475 api_ipfix_exporter_dump (vat_main_t * vam)
19476 {
19477   vl_api_ipfix_exporter_dump_t *mp;
19478   int ret;
19479
19480   /* Construct the API message */
19481   M (IPFIX_EXPORTER_DUMP, mp);
19482   mp->context = 0;
19483
19484   S (mp);
19485   W (ret);
19486   return ret;
19487 }
19488
19489 static int
19490 api_ipfix_classify_stream_dump (vat_main_t * vam)
19491 {
19492   vl_api_ipfix_classify_stream_dump_t *mp;
19493   int ret;
19494
19495   /* Construct the API message */
19496   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19497   mp->context = 0;
19498
19499   S (mp);
19500   W (ret);
19501   return ret;
19502   /* NOTREACHED */
19503   return 0;
19504 }
19505
19506 static void
19507   vl_api_ipfix_classify_stream_details_t_handler
19508   (vl_api_ipfix_classify_stream_details_t * mp)
19509 {
19510   vat_main_t *vam = &vat_main;
19511   print (vam->ofp, "domain_id %d, src_port %d",
19512          ntohl (mp->domain_id), ntohs (mp->src_port));
19513   vam->retval = 0;
19514   vam->result_ready = 1;
19515 }
19516
19517 static void
19518   vl_api_ipfix_classify_stream_details_t_handler_json
19519   (vl_api_ipfix_classify_stream_details_t * mp)
19520 {
19521   vat_main_t *vam = &vat_main;
19522   vat_json_node_t node;
19523
19524   vat_json_init_object (&node);
19525   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19526   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19527
19528   vat_json_print (vam->ofp, &node);
19529   vat_json_free (&node);
19530   vam->retval = 0;
19531   vam->result_ready = 1;
19532 }
19533
19534 static int
19535 api_ipfix_classify_table_dump (vat_main_t * vam)
19536 {
19537   vl_api_ipfix_classify_table_dump_t *mp;
19538   vl_api_control_ping_t *mp_ping;
19539   int ret;
19540
19541   if (!vam->json_output)
19542     {
19543       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19544              "transport_protocol");
19545     }
19546
19547   /* Construct the API message */
19548   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19549
19550   /* send it... */
19551   S (mp);
19552
19553   /* Use a control ping for synchronization */
19554   MPING (CONTROL_PING, mp_ping);
19555   S (mp_ping);
19556
19557   W (ret);
19558   return ret;
19559 }
19560
19561 static void
19562   vl_api_ipfix_classify_table_details_t_handler
19563   (vl_api_ipfix_classify_table_details_t * mp)
19564 {
19565   vat_main_t *vam = &vat_main;
19566   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19567          mp->transport_protocol);
19568 }
19569
19570 static void
19571   vl_api_ipfix_classify_table_details_t_handler_json
19572   (vl_api_ipfix_classify_table_details_t * mp)
19573 {
19574   vat_json_node_t *node = NULL;
19575   vat_main_t *vam = &vat_main;
19576
19577   if (VAT_JSON_ARRAY != vam->json_tree.type)
19578     {
19579       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19580       vat_json_init_array (&vam->json_tree);
19581     }
19582
19583   node = vat_json_array_add (&vam->json_tree);
19584   vat_json_init_object (node);
19585
19586   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19587   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19588   vat_json_object_add_uint (node, "transport_protocol",
19589                             mp->transport_protocol);
19590 }
19591
19592 static int
19593 api_sw_interface_span_enable_disable (vat_main_t * vam)
19594 {
19595   unformat_input_t *i = vam->input;
19596   vl_api_sw_interface_span_enable_disable_t *mp;
19597   u32 src_sw_if_index = ~0;
19598   u32 dst_sw_if_index = ~0;
19599   u8 state = 3;
19600   int ret;
19601   u8 is_l2 = 0;
19602
19603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19604     {
19605       if (unformat
19606           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19607         ;
19608       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19609         ;
19610       else
19611         if (unformat
19612             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19613         ;
19614       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19615         ;
19616       else if (unformat (i, "disable"))
19617         state = 0;
19618       else if (unformat (i, "rx"))
19619         state = 1;
19620       else if (unformat (i, "tx"))
19621         state = 2;
19622       else if (unformat (i, "both"))
19623         state = 3;
19624       else if (unformat (i, "l2"))
19625         is_l2 = 1;
19626       else
19627         break;
19628     }
19629
19630   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19631
19632   mp->sw_if_index_from = htonl (src_sw_if_index);
19633   mp->sw_if_index_to = htonl (dst_sw_if_index);
19634   mp->state = state;
19635   mp->is_l2 = is_l2;
19636
19637   S (mp);
19638   W (ret);
19639   return ret;
19640 }
19641
19642 static void
19643 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19644                                             * mp)
19645 {
19646   vat_main_t *vam = &vat_main;
19647   u8 *sw_if_from_name = 0;
19648   u8 *sw_if_to_name = 0;
19649   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19650   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19651   char *states[] = { "none", "rx", "tx", "both" };
19652   hash_pair_t *p;
19653
19654   /* *INDENT-OFF* */
19655   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19656   ({
19657     if ((u32) p->value[0] == sw_if_index_from)
19658       {
19659         sw_if_from_name = (u8 *)(p->key);
19660         if (sw_if_to_name)
19661           break;
19662       }
19663     if ((u32) p->value[0] == sw_if_index_to)
19664       {
19665         sw_if_to_name = (u8 *)(p->key);
19666         if (sw_if_from_name)
19667           break;
19668       }
19669   }));
19670   /* *INDENT-ON* */
19671   print (vam->ofp, "%20s => %20s (%s) %s",
19672          sw_if_from_name, sw_if_to_name, states[mp->state],
19673          mp->is_l2 ? "l2" : "device");
19674 }
19675
19676 static void
19677   vl_api_sw_interface_span_details_t_handler_json
19678   (vl_api_sw_interface_span_details_t * mp)
19679 {
19680   vat_main_t *vam = &vat_main;
19681   vat_json_node_t *node = NULL;
19682   u8 *sw_if_from_name = 0;
19683   u8 *sw_if_to_name = 0;
19684   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19685   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19686   hash_pair_t *p;
19687
19688   /* *INDENT-OFF* */
19689   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19690   ({
19691     if ((u32) p->value[0] == sw_if_index_from)
19692       {
19693         sw_if_from_name = (u8 *)(p->key);
19694         if (sw_if_to_name)
19695           break;
19696       }
19697     if ((u32) p->value[0] == sw_if_index_to)
19698       {
19699         sw_if_to_name = (u8 *)(p->key);
19700         if (sw_if_from_name)
19701           break;
19702       }
19703   }));
19704   /* *INDENT-ON* */
19705
19706   if (VAT_JSON_ARRAY != vam->json_tree.type)
19707     {
19708       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19709       vat_json_init_array (&vam->json_tree);
19710     }
19711   node = vat_json_array_add (&vam->json_tree);
19712
19713   vat_json_init_object (node);
19714   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19715   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19716   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19717   if (0 != sw_if_to_name)
19718     {
19719       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19720     }
19721   vat_json_object_add_uint (node, "state", mp->state);
19722   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19723 }
19724
19725 static int
19726 api_sw_interface_span_dump (vat_main_t * vam)
19727 {
19728   unformat_input_t *input = vam->input;
19729   vl_api_sw_interface_span_dump_t *mp;
19730   vl_api_control_ping_t *mp_ping;
19731   u8 is_l2 = 0;
19732   int ret;
19733
19734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19735     {
19736       if (unformat (input, "l2"))
19737         is_l2 = 1;
19738       else
19739         break;
19740     }
19741
19742   M (SW_INTERFACE_SPAN_DUMP, mp);
19743   mp->is_l2 = is_l2;
19744   S (mp);
19745
19746   /* Use a control ping for synchronization */
19747   MPING (CONTROL_PING, mp_ping);
19748   S (mp_ping);
19749
19750   W (ret);
19751   return ret;
19752 }
19753
19754 int
19755 api_pg_create_interface (vat_main_t * vam)
19756 {
19757   unformat_input_t *input = vam->input;
19758   vl_api_pg_create_interface_t *mp;
19759
19760   u32 if_id = ~0, gso_size = 0;
19761   u8 gso_enabled = 0;
19762   int ret;
19763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19764     {
19765       if (unformat (input, "if_id %d", &if_id))
19766         ;
19767       else if (unformat (input, "gso-enabled"))
19768         {
19769           gso_enabled = 1;
19770           if (unformat (input, "gso-size %u", &gso_size))
19771             ;
19772           else
19773             {
19774               errmsg ("missing gso-size");
19775               return -99;
19776             }
19777         }
19778       else
19779         break;
19780     }
19781   if (if_id == ~0)
19782     {
19783       errmsg ("missing pg interface index");
19784       return -99;
19785     }
19786
19787   /* Construct the API message */
19788   M (PG_CREATE_INTERFACE, mp);
19789   mp->context = 0;
19790   mp->interface_id = ntohl (if_id);
19791   mp->gso_enabled = gso_enabled;
19792
19793   S (mp);
19794   W (ret);
19795   return ret;
19796 }
19797
19798 int
19799 api_pg_capture (vat_main_t * vam)
19800 {
19801   unformat_input_t *input = vam->input;
19802   vl_api_pg_capture_t *mp;
19803
19804   u32 if_id = ~0;
19805   u8 enable = 1;
19806   u32 count = 1;
19807   u8 pcap_file_set = 0;
19808   u8 *pcap_file = 0;
19809   int ret;
19810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19811     {
19812       if (unformat (input, "if_id %d", &if_id))
19813         ;
19814       else if (unformat (input, "pcap %s", &pcap_file))
19815         pcap_file_set = 1;
19816       else if (unformat (input, "count %d", &count))
19817         ;
19818       else if (unformat (input, "disable"))
19819         enable = 0;
19820       else
19821         break;
19822     }
19823   if (if_id == ~0)
19824     {
19825       errmsg ("missing pg interface index");
19826       return -99;
19827     }
19828   if (pcap_file_set > 0)
19829     {
19830       if (vec_len (pcap_file) > 255)
19831         {
19832           errmsg ("pcap file name is too long");
19833           return -99;
19834         }
19835     }
19836
19837   u32 name_len = vec_len (pcap_file);
19838   /* Construct the API message */
19839   M (PG_CAPTURE, mp);
19840   mp->context = 0;
19841   mp->interface_id = ntohl (if_id);
19842   mp->is_enabled = enable;
19843   mp->count = ntohl (count);
19844   mp->pcap_name_length = ntohl (name_len);
19845   if (pcap_file_set != 0)
19846     {
19847       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19848     }
19849   vec_free (pcap_file);
19850
19851   S (mp);
19852   W (ret);
19853   return ret;
19854 }
19855
19856 int
19857 api_pg_enable_disable (vat_main_t * vam)
19858 {
19859   unformat_input_t *input = vam->input;
19860   vl_api_pg_enable_disable_t *mp;
19861
19862   u8 enable = 1;
19863   u8 stream_name_set = 0;
19864   u8 *stream_name = 0;
19865   int ret;
19866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19867     {
19868       if (unformat (input, "stream %s", &stream_name))
19869         stream_name_set = 1;
19870       else if (unformat (input, "disable"))
19871         enable = 0;
19872       else
19873         break;
19874     }
19875
19876   if (stream_name_set > 0)
19877     {
19878       if (vec_len (stream_name) > 255)
19879         {
19880           errmsg ("stream name too long");
19881           return -99;
19882         }
19883     }
19884
19885   u32 name_len = vec_len (stream_name);
19886   /* Construct the API message */
19887   M (PG_ENABLE_DISABLE, mp);
19888   mp->context = 0;
19889   mp->is_enabled = enable;
19890   if (stream_name_set != 0)
19891     {
19892       mp->stream_name_length = ntohl (name_len);
19893       clib_memcpy (mp->stream_name, stream_name, name_len);
19894     }
19895   vec_free (stream_name);
19896
19897   S (mp);
19898   W (ret);
19899   return ret;
19900 }
19901
19902 int
19903 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19904 {
19905   unformat_input_t *input = vam->input;
19906   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19907
19908   u16 *low_ports = 0;
19909   u16 *high_ports = 0;
19910   u16 this_low;
19911   u16 this_hi;
19912   vl_api_prefix_t prefix;
19913   u32 tmp, tmp2;
19914   u8 prefix_set = 0;
19915   u32 vrf_id = ~0;
19916   u8 is_add = 1;
19917   int ret;
19918
19919   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19920     {
19921       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19922         prefix_set = 1;
19923       else if (unformat (input, "vrf %d", &vrf_id))
19924         ;
19925       else if (unformat (input, "del"))
19926         is_add = 0;
19927       else if (unformat (input, "port %d", &tmp))
19928         {
19929           if (tmp == 0 || tmp > 65535)
19930             {
19931               errmsg ("port %d out of range", tmp);
19932               return -99;
19933             }
19934           this_low = tmp;
19935           this_hi = this_low + 1;
19936           vec_add1 (low_ports, this_low);
19937           vec_add1 (high_ports, this_hi);
19938         }
19939       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19940         {
19941           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19942             {
19943               errmsg ("incorrect range parameters");
19944               return -99;
19945             }
19946           this_low = tmp;
19947           /* Note: in debug CLI +1 is added to high before
19948              passing to real fn that does "the work"
19949              (ip_source_and_port_range_check_add_del).
19950              This fn is a wrapper around the binary API fn a
19951              control plane will call, which expects this increment
19952              to have occurred. Hence letting the binary API control
19953              plane fn do the increment for consistency between VAT
19954              and other control planes.
19955            */
19956           this_hi = tmp2;
19957           vec_add1 (low_ports, this_low);
19958           vec_add1 (high_ports, this_hi);
19959         }
19960       else
19961         break;
19962     }
19963
19964   if (prefix_set == 0)
19965     {
19966       errmsg ("<address>/<mask> not specified");
19967       return -99;
19968     }
19969
19970   if (vrf_id == ~0)
19971     {
19972       errmsg ("VRF ID required, not specified");
19973       return -99;
19974     }
19975
19976   if (vrf_id == 0)
19977     {
19978       errmsg
19979         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19980       return -99;
19981     }
19982
19983   if (vec_len (low_ports) == 0)
19984     {
19985       errmsg ("At least one port or port range required");
19986       return -99;
19987     }
19988
19989   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19990
19991   mp->is_add = is_add;
19992
19993   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19994
19995   mp->number_of_ranges = vec_len (low_ports);
19996
19997   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19998   vec_free (low_ports);
19999
20000   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20001   vec_free (high_ports);
20002
20003   mp->vrf_id = ntohl (vrf_id);
20004
20005   S (mp);
20006   W (ret);
20007   return ret;
20008 }
20009
20010 int
20011 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20012 {
20013   unformat_input_t *input = vam->input;
20014   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20015   u32 sw_if_index = ~0;
20016   int vrf_set = 0;
20017   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20018   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20019   u8 is_add = 1;
20020   int ret;
20021
20022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20023     {
20024       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20025         ;
20026       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20027         ;
20028       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20029         vrf_set = 1;
20030       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20031         vrf_set = 1;
20032       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20033         vrf_set = 1;
20034       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20035         vrf_set = 1;
20036       else if (unformat (input, "del"))
20037         is_add = 0;
20038       else
20039         break;
20040     }
20041
20042   if (sw_if_index == ~0)
20043     {
20044       errmsg ("Interface required but not specified");
20045       return -99;
20046     }
20047
20048   if (vrf_set == 0)
20049     {
20050       errmsg ("VRF ID required but not specified");
20051       return -99;
20052     }
20053
20054   if (tcp_out_vrf_id == 0
20055       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20056     {
20057       errmsg
20058         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20059       return -99;
20060     }
20061
20062   /* Construct the API message */
20063   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20064
20065   mp->sw_if_index = ntohl (sw_if_index);
20066   mp->is_add = is_add;
20067   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20068   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20069   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20070   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20071
20072   /* send it... */
20073   S (mp);
20074
20075   /* Wait for a reply... */
20076   W (ret);
20077   return ret;
20078 }
20079
20080 static int
20081 api_set_punt (vat_main_t * vam)
20082 {
20083   unformat_input_t *i = vam->input;
20084   vl_api_address_family_t af;
20085   vl_api_set_punt_t *mp;
20086   u32 protocol = ~0;
20087   u32 port = ~0;
20088   int is_add = 1;
20089   int ret;
20090
20091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20092     {
20093       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20094         ;
20095       else if (unformat (i, "protocol %d", &protocol))
20096         ;
20097       else if (unformat (i, "port %d", &port))
20098         ;
20099       else if (unformat (i, "del"))
20100         is_add = 0;
20101       else
20102         {
20103           clib_warning ("parse error '%U'", format_unformat_error, i);
20104           return -99;
20105         }
20106     }
20107
20108   M (SET_PUNT, mp);
20109
20110   mp->is_add = (u8) is_add;
20111   mp->punt.type = PUNT_API_TYPE_L4;
20112   mp->punt.punt.l4.af = af;
20113   mp->punt.punt.l4.protocol = (u8) protocol;
20114   mp->punt.punt.l4.port = htons ((u16) port);
20115
20116   S (mp);
20117   W (ret);
20118   return ret;
20119 }
20120
20121 static int
20122 api_delete_subif (vat_main_t * vam)
20123 {
20124   unformat_input_t *i = vam->input;
20125   vl_api_delete_subif_t *mp;
20126   u32 sw_if_index = ~0;
20127   int ret;
20128
20129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20130     {
20131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20132         ;
20133       if (unformat (i, "sw_if_index %d", &sw_if_index))
20134         ;
20135       else
20136         break;
20137     }
20138
20139   if (sw_if_index == ~0)
20140     {
20141       errmsg ("missing sw_if_index");
20142       return -99;
20143     }
20144
20145   /* Construct the API message */
20146   M (DELETE_SUBIF, mp);
20147   mp->sw_if_index = ntohl (sw_if_index);
20148
20149   S (mp);
20150   W (ret);
20151   return ret;
20152 }
20153
20154 #define foreach_pbb_vtr_op      \
20155 _("disable",  L2_VTR_DISABLED)  \
20156 _("pop",  L2_VTR_POP_2)         \
20157 _("push",  L2_VTR_PUSH_2)
20158
20159 static int
20160 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20161 {
20162   unformat_input_t *i = vam->input;
20163   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20164   u32 sw_if_index = ~0, vtr_op = ~0;
20165   u16 outer_tag = ~0;
20166   u8 dmac[6], smac[6];
20167   u8 dmac_set = 0, smac_set = 0;
20168   u16 vlanid = 0;
20169   u32 sid = ~0;
20170   u32 tmp;
20171   int ret;
20172
20173   /* Shut up coverity */
20174   clib_memset (dmac, 0, sizeof (dmac));
20175   clib_memset (smac, 0, sizeof (smac));
20176
20177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20178     {
20179       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20180         ;
20181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20182         ;
20183       else if (unformat (i, "vtr_op %d", &vtr_op))
20184         ;
20185 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20186       foreach_pbb_vtr_op
20187 #undef _
20188         else if (unformat (i, "translate_pbb_stag"))
20189         {
20190           if (unformat (i, "%d", &tmp))
20191             {
20192               vtr_op = L2_VTR_TRANSLATE_2_1;
20193               outer_tag = tmp;
20194             }
20195           else
20196             {
20197               errmsg
20198                 ("translate_pbb_stag operation requires outer tag definition");
20199               return -99;
20200             }
20201         }
20202       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20203         dmac_set++;
20204       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20205         smac_set++;
20206       else if (unformat (i, "sid %d", &sid))
20207         ;
20208       else if (unformat (i, "vlanid %d", &tmp))
20209         vlanid = tmp;
20210       else
20211         {
20212           clib_warning ("parse error '%U'", format_unformat_error, i);
20213           return -99;
20214         }
20215     }
20216
20217   if ((sw_if_index == ~0) || (vtr_op == ~0))
20218     {
20219       errmsg ("missing sw_if_index or vtr operation");
20220       return -99;
20221     }
20222   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20223       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20224     {
20225       errmsg
20226         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20227       return -99;
20228     }
20229
20230   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20231   mp->sw_if_index = ntohl (sw_if_index);
20232   mp->vtr_op = ntohl (vtr_op);
20233   mp->outer_tag = ntohs (outer_tag);
20234   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20235   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20236   mp->b_vlanid = ntohs (vlanid);
20237   mp->i_sid = ntohl (sid);
20238
20239   S (mp);
20240   W (ret);
20241   return ret;
20242 }
20243
20244 static int
20245 api_flow_classify_set_interface (vat_main_t * vam)
20246 {
20247   unformat_input_t *i = vam->input;
20248   vl_api_flow_classify_set_interface_t *mp;
20249   u32 sw_if_index;
20250   int sw_if_index_set;
20251   u32 ip4_table_index = ~0;
20252   u32 ip6_table_index = ~0;
20253   u8 is_add = 1;
20254   int ret;
20255
20256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20257     {
20258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20259         sw_if_index_set = 1;
20260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20261         sw_if_index_set = 1;
20262       else if (unformat (i, "del"))
20263         is_add = 0;
20264       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20265         ;
20266       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20267         ;
20268       else
20269         {
20270           clib_warning ("parse error '%U'", format_unformat_error, i);
20271           return -99;
20272         }
20273     }
20274
20275   if (sw_if_index_set == 0)
20276     {
20277       errmsg ("missing interface name or sw_if_index");
20278       return -99;
20279     }
20280
20281   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20282
20283   mp->sw_if_index = ntohl (sw_if_index);
20284   mp->ip4_table_index = ntohl (ip4_table_index);
20285   mp->ip6_table_index = ntohl (ip6_table_index);
20286   mp->is_add = is_add;
20287
20288   S (mp);
20289   W (ret);
20290   return ret;
20291 }
20292
20293 static int
20294 api_flow_classify_dump (vat_main_t * vam)
20295 {
20296   unformat_input_t *i = vam->input;
20297   vl_api_flow_classify_dump_t *mp;
20298   vl_api_control_ping_t *mp_ping;
20299   u8 type = FLOW_CLASSIFY_N_TABLES;
20300   int ret;
20301
20302   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20303     ;
20304   else
20305     {
20306       errmsg ("classify table type must be specified");
20307       return -99;
20308     }
20309
20310   if (!vam->json_output)
20311     {
20312       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20313     }
20314
20315   M (FLOW_CLASSIFY_DUMP, mp);
20316   mp->type = type;
20317   /* send it... */
20318   S (mp);
20319
20320   /* Use a control ping for synchronization */
20321   MPING (CONTROL_PING, mp_ping);
20322   S (mp_ping);
20323
20324   /* Wait for a reply... */
20325   W (ret);
20326   return ret;
20327 }
20328
20329 static int
20330 api_feature_enable_disable (vat_main_t * vam)
20331 {
20332   unformat_input_t *i = vam->input;
20333   vl_api_feature_enable_disable_t *mp;
20334   u8 *arc_name = 0;
20335   u8 *feature_name = 0;
20336   u32 sw_if_index = ~0;
20337   u8 enable = 1;
20338   int ret;
20339
20340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20341     {
20342       if (unformat (i, "arc_name %s", &arc_name))
20343         ;
20344       else if (unformat (i, "feature_name %s", &feature_name))
20345         ;
20346       else
20347         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20348         ;
20349       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20350         ;
20351       else if (unformat (i, "disable"))
20352         enable = 0;
20353       else
20354         break;
20355     }
20356
20357   if (arc_name == 0)
20358     {
20359       errmsg ("missing arc name");
20360       return -99;
20361     }
20362   if (vec_len (arc_name) > 63)
20363     {
20364       errmsg ("arc name too long");
20365     }
20366
20367   if (feature_name == 0)
20368     {
20369       errmsg ("missing feature name");
20370       return -99;
20371     }
20372   if (vec_len (feature_name) > 63)
20373     {
20374       errmsg ("feature name too long");
20375     }
20376
20377   if (sw_if_index == ~0)
20378     {
20379       errmsg ("missing interface name or sw_if_index");
20380       return -99;
20381     }
20382
20383   /* Construct the API message */
20384   M (FEATURE_ENABLE_DISABLE, mp);
20385   mp->sw_if_index = ntohl (sw_if_index);
20386   mp->enable = enable;
20387   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20388   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20389   vec_free (arc_name);
20390   vec_free (feature_name);
20391
20392   S (mp);
20393   W (ret);
20394   return ret;
20395 }
20396
20397 static int
20398 api_sw_interface_tag_add_del (vat_main_t * vam)
20399 {
20400   unformat_input_t *i = vam->input;
20401   vl_api_sw_interface_tag_add_del_t *mp;
20402   u32 sw_if_index = ~0;
20403   u8 *tag = 0;
20404   u8 enable = 1;
20405   int ret;
20406
20407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20408     {
20409       if (unformat (i, "tag %s", &tag))
20410         ;
20411       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20412         ;
20413       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20414         ;
20415       else if (unformat (i, "del"))
20416         enable = 0;
20417       else
20418         break;
20419     }
20420
20421   if (sw_if_index == ~0)
20422     {
20423       errmsg ("missing interface name or sw_if_index");
20424       return -99;
20425     }
20426
20427   if (enable && (tag == 0))
20428     {
20429       errmsg ("no tag specified");
20430       return -99;
20431     }
20432
20433   /* Construct the API message */
20434   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20435   mp->sw_if_index = ntohl (sw_if_index);
20436   mp->is_add = enable;
20437   if (enable)
20438     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20439   vec_free (tag);
20440
20441   S (mp);
20442   W (ret);
20443   return ret;
20444 }
20445
20446 static void vl_api_l2_xconnect_details_t_handler
20447   (vl_api_l2_xconnect_details_t * mp)
20448 {
20449   vat_main_t *vam = &vat_main;
20450
20451   print (vam->ofp, "%15d%15d",
20452          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20453 }
20454
20455 static void vl_api_l2_xconnect_details_t_handler_json
20456   (vl_api_l2_xconnect_details_t * mp)
20457 {
20458   vat_main_t *vam = &vat_main;
20459   vat_json_node_t *node = NULL;
20460
20461   if (VAT_JSON_ARRAY != vam->json_tree.type)
20462     {
20463       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20464       vat_json_init_array (&vam->json_tree);
20465     }
20466   node = vat_json_array_add (&vam->json_tree);
20467
20468   vat_json_init_object (node);
20469   vat_json_object_add_uint (node, "rx_sw_if_index",
20470                             ntohl (mp->rx_sw_if_index));
20471   vat_json_object_add_uint (node, "tx_sw_if_index",
20472                             ntohl (mp->tx_sw_if_index));
20473 }
20474
20475 static int
20476 api_l2_xconnect_dump (vat_main_t * vam)
20477 {
20478   vl_api_l2_xconnect_dump_t *mp;
20479   vl_api_control_ping_t *mp_ping;
20480   int ret;
20481
20482   if (!vam->json_output)
20483     {
20484       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20485     }
20486
20487   M (L2_XCONNECT_DUMP, mp);
20488
20489   S (mp);
20490
20491   /* Use a control ping for synchronization */
20492   MPING (CONTROL_PING, mp_ping);
20493   S (mp_ping);
20494
20495   W (ret);
20496   return ret;
20497 }
20498
20499 static int
20500 api_hw_interface_set_mtu (vat_main_t * vam)
20501 {
20502   unformat_input_t *i = vam->input;
20503   vl_api_hw_interface_set_mtu_t *mp;
20504   u32 sw_if_index = ~0;
20505   u32 mtu = 0;
20506   int ret;
20507
20508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20509     {
20510       if (unformat (i, "mtu %d", &mtu))
20511         ;
20512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20513         ;
20514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20515         ;
20516       else
20517         break;
20518     }
20519
20520   if (sw_if_index == ~0)
20521     {
20522       errmsg ("missing interface name or sw_if_index");
20523       return -99;
20524     }
20525
20526   if (mtu == 0)
20527     {
20528       errmsg ("no mtu specified");
20529       return -99;
20530     }
20531
20532   /* Construct the API message */
20533   M (HW_INTERFACE_SET_MTU, mp);
20534   mp->sw_if_index = ntohl (sw_if_index);
20535   mp->mtu = ntohs ((u16) mtu);
20536
20537   S (mp);
20538   W (ret);
20539   return ret;
20540 }
20541
20542 static int
20543 api_p2p_ethernet_add (vat_main_t * vam)
20544 {
20545   unformat_input_t *i = vam->input;
20546   vl_api_p2p_ethernet_add_t *mp;
20547   u32 parent_if_index = ~0;
20548   u32 sub_id = ~0;
20549   u8 remote_mac[6];
20550   u8 mac_set = 0;
20551   int ret;
20552
20553   clib_memset (remote_mac, 0, sizeof (remote_mac));
20554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20555     {
20556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20557         ;
20558       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20559         ;
20560       else
20561         if (unformat
20562             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20563         mac_set++;
20564       else if (unformat (i, "sub_id %d", &sub_id))
20565         ;
20566       else
20567         {
20568           clib_warning ("parse error '%U'", format_unformat_error, i);
20569           return -99;
20570         }
20571     }
20572
20573   if (parent_if_index == ~0)
20574     {
20575       errmsg ("missing interface name or sw_if_index");
20576       return -99;
20577     }
20578   if (mac_set == 0)
20579     {
20580       errmsg ("missing remote mac address");
20581       return -99;
20582     }
20583   if (sub_id == ~0)
20584     {
20585       errmsg ("missing sub-interface id");
20586       return -99;
20587     }
20588
20589   M (P2P_ETHERNET_ADD, mp);
20590   mp->parent_if_index = ntohl (parent_if_index);
20591   mp->subif_id = ntohl (sub_id);
20592   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20593
20594   S (mp);
20595   W (ret);
20596   return ret;
20597 }
20598
20599 static int
20600 api_p2p_ethernet_del (vat_main_t * vam)
20601 {
20602   unformat_input_t *i = vam->input;
20603   vl_api_p2p_ethernet_del_t *mp;
20604   u32 parent_if_index = ~0;
20605   u8 remote_mac[6];
20606   u8 mac_set = 0;
20607   int ret;
20608
20609   clib_memset (remote_mac, 0, sizeof (remote_mac));
20610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20611     {
20612       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20613         ;
20614       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20615         ;
20616       else
20617         if (unformat
20618             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20619         mac_set++;
20620       else
20621         {
20622           clib_warning ("parse error '%U'", format_unformat_error, i);
20623           return -99;
20624         }
20625     }
20626
20627   if (parent_if_index == ~0)
20628     {
20629       errmsg ("missing interface name or sw_if_index");
20630       return -99;
20631     }
20632   if (mac_set == 0)
20633     {
20634       errmsg ("missing remote mac address");
20635       return -99;
20636     }
20637
20638   M (P2P_ETHERNET_DEL, mp);
20639   mp->parent_if_index = ntohl (parent_if_index);
20640   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20641
20642   S (mp);
20643   W (ret);
20644   return ret;
20645 }
20646
20647 static int
20648 api_lldp_config (vat_main_t * vam)
20649 {
20650   unformat_input_t *i = vam->input;
20651   vl_api_lldp_config_t *mp;
20652   int tx_hold = 0;
20653   int tx_interval = 0;
20654   u8 *sys_name = NULL;
20655   int ret;
20656
20657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20658     {
20659       if (unformat (i, "system-name %s", &sys_name))
20660         ;
20661       else if (unformat (i, "tx-hold %d", &tx_hold))
20662         ;
20663       else if (unformat (i, "tx-interval %d", &tx_interval))
20664         ;
20665       else
20666         {
20667           clib_warning ("parse error '%U'", format_unformat_error, i);
20668           return -99;
20669         }
20670     }
20671
20672   vec_add1 (sys_name, 0);
20673
20674   M (LLDP_CONFIG, mp);
20675   mp->tx_hold = htonl (tx_hold);
20676   mp->tx_interval = htonl (tx_interval);
20677   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20678   vec_free (sys_name);
20679
20680   S (mp);
20681   W (ret);
20682   return ret;
20683 }
20684
20685 static int
20686 api_sw_interface_set_lldp (vat_main_t * vam)
20687 {
20688   unformat_input_t *i = vam->input;
20689   vl_api_sw_interface_set_lldp_t *mp;
20690   u32 sw_if_index = ~0;
20691   u32 enable = 1;
20692   u8 *port_desc = NULL, *mgmt_oid = NULL;
20693   ip4_address_t ip4_addr;
20694   ip6_address_t ip6_addr;
20695   int ret;
20696
20697   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20698   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20699
20700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20701     {
20702       if (unformat (i, "disable"))
20703         enable = 0;
20704       else
20705         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20706         ;
20707       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20708         ;
20709       else if (unformat (i, "port-desc %s", &port_desc))
20710         ;
20711       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20712         ;
20713       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20714         ;
20715       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20716         ;
20717       else
20718         break;
20719     }
20720
20721   if (sw_if_index == ~0)
20722     {
20723       errmsg ("missing interface name or sw_if_index");
20724       return -99;
20725     }
20726
20727   /* Construct the API message */
20728   vec_add1 (port_desc, 0);
20729   vec_add1 (mgmt_oid, 0);
20730   M (SW_INTERFACE_SET_LLDP, mp);
20731   mp->sw_if_index = ntohl (sw_if_index);
20732   mp->enable = enable;
20733   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20734   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20735   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20736   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20737   vec_free (port_desc);
20738   vec_free (mgmt_oid);
20739
20740   S (mp);
20741   W (ret);
20742   return ret;
20743 }
20744
20745 static int
20746 api_tcp_configure_src_addresses (vat_main_t * vam)
20747 {
20748   vl_api_tcp_configure_src_addresses_t *mp;
20749   unformat_input_t *i = vam->input;
20750   ip4_address_t v4first, v4last;
20751   ip6_address_t v6first, v6last;
20752   u8 range_set = 0;
20753   u32 vrf_id = 0;
20754   int ret;
20755
20756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20757     {
20758       if (unformat (i, "%U - %U",
20759                     unformat_ip4_address, &v4first,
20760                     unformat_ip4_address, &v4last))
20761         {
20762           if (range_set)
20763             {
20764               errmsg ("one range per message (range already set)");
20765               return -99;
20766             }
20767           range_set = 1;
20768         }
20769       else if (unformat (i, "%U - %U",
20770                          unformat_ip6_address, &v6first,
20771                          unformat_ip6_address, &v6last))
20772         {
20773           if (range_set)
20774             {
20775               errmsg ("one range per message (range already set)");
20776               return -99;
20777             }
20778           range_set = 2;
20779         }
20780       else if (unformat (i, "vrf %d", &vrf_id))
20781         ;
20782       else
20783         break;
20784     }
20785
20786   if (range_set == 0)
20787     {
20788       errmsg ("address range not set");
20789       return -99;
20790     }
20791
20792   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20793   mp->vrf_id = ntohl (vrf_id);
20794   /* ipv6? */
20795   if (range_set == 2)
20796     {
20797       mp->is_ipv6 = 1;
20798       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20799       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20800     }
20801   else
20802     {
20803       mp->is_ipv6 = 0;
20804       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20805       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20806     }
20807   S (mp);
20808   W (ret);
20809   return ret;
20810 }
20811
20812 static void vl_api_app_namespace_add_del_reply_t_handler
20813   (vl_api_app_namespace_add_del_reply_t * mp)
20814 {
20815   vat_main_t *vam = &vat_main;
20816   i32 retval = ntohl (mp->retval);
20817   if (vam->async_mode)
20818     {
20819       vam->async_errors += (retval < 0);
20820     }
20821   else
20822     {
20823       vam->retval = retval;
20824       if (retval == 0)
20825         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20826       vam->result_ready = 1;
20827     }
20828 }
20829
20830 static void vl_api_app_namespace_add_del_reply_t_handler_json
20831   (vl_api_app_namespace_add_del_reply_t * mp)
20832 {
20833   vat_main_t *vam = &vat_main;
20834   vat_json_node_t node;
20835
20836   vat_json_init_object (&node);
20837   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20838   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20839
20840   vat_json_print (vam->ofp, &node);
20841   vat_json_free (&node);
20842
20843   vam->retval = ntohl (mp->retval);
20844   vam->result_ready = 1;
20845 }
20846
20847 static int
20848 api_app_namespace_add_del (vat_main_t * vam)
20849 {
20850   vl_api_app_namespace_add_del_t *mp;
20851   unformat_input_t *i = vam->input;
20852   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20853   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20854   u64 secret;
20855   int ret;
20856
20857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20858     {
20859       if (unformat (i, "id %_%v%_", &ns_id))
20860         ;
20861       else if (unformat (i, "secret %lu", &secret))
20862         secret_set = 1;
20863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20864         sw_if_index_set = 1;
20865       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20866         ;
20867       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20868         ;
20869       else
20870         break;
20871     }
20872   if (!ns_id || !secret_set || !sw_if_index_set)
20873     {
20874       errmsg ("namespace id, secret and sw_if_index must be set");
20875       return -99;
20876     }
20877   if (vec_len (ns_id) > 64)
20878     {
20879       errmsg ("namespace id too long");
20880       return -99;
20881     }
20882   M (APP_NAMESPACE_ADD_DEL, mp);
20883
20884   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20885   mp->namespace_id_len = vec_len (ns_id);
20886   mp->secret = clib_host_to_net_u64 (secret);
20887   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20888   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20889   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20890   vec_free (ns_id);
20891   S (mp);
20892   W (ret);
20893   return ret;
20894 }
20895
20896 static int
20897 api_sock_init_shm (vat_main_t * vam)
20898 {
20899 #if VPP_API_TEST_BUILTIN == 0
20900   unformat_input_t *i = vam->input;
20901   vl_api_shm_elem_config_t *config = 0;
20902   u64 size = 64 << 20;
20903   int rv;
20904
20905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20906     {
20907       if (unformat (i, "size %U", unformat_memory_size, &size))
20908         ;
20909       else
20910         break;
20911     }
20912
20913   /*
20914    * Canned custom ring allocator config.
20915    * Should probably parse all of this
20916    */
20917   vec_validate (config, 6);
20918   config[0].type = VL_API_VLIB_RING;
20919   config[0].size = 256;
20920   config[0].count = 32;
20921
20922   config[1].type = VL_API_VLIB_RING;
20923   config[1].size = 1024;
20924   config[1].count = 16;
20925
20926   config[2].type = VL_API_VLIB_RING;
20927   config[2].size = 4096;
20928   config[2].count = 2;
20929
20930   config[3].type = VL_API_CLIENT_RING;
20931   config[3].size = 256;
20932   config[3].count = 32;
20933
20934   config[4].type = VL_API_CLIENT_RING;
20935   config[4].size = 1024;
20936   config[4].count = 16;
20937
20938   config[5].type = VL_API_CLIENT_RING;
20939   config[5].size = 4096;
20940   config[5].count = 2;
20941
20942   config[6].type = VL_API_QUEUE;
20943   config[6].count = 128;
20944   config[6].size = sizeof (uword);
20945
20946   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20947   if (!rv)
20948     vam->client_index_invalid = 1;
20949   return rv;
20950 #else
20951   return -99;
20952 #endif
20953 }
20954
20955 static int
20956 api_dns_enable_disable (vat_main_t * vam)
20957 {
20958   unformat_input_t *line_input = vam->input;
20959   vl_api_dns_enable_disable_t *mp;
20960   u8 enable_disable = 1;
20961   int ret;
20962
20963   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20964     {
20965       if (unformat (line_input, "disable"))
20966         enable_disable = 0;
20967       if (unformat (line_input, "enable"))
20968         enable_disable = 1;
20969       else
20970         break;
20971     }
20972
20973   /* Construct the API message */
20974   M (DNS_ENABLE_DISABLE, mp);
20975   mp->enable = enable_disable;
20976
20977   /* send it... */
20978   S (mp);
20979   /* Wait for the reply */
20980   W (ret);
20981   return ret;
20982 }
20983
20984 static int
20985 api_dns_resolve_name (vat_main_t * vam)
20986 {
20987   unformat_input_t *line_input = vam->input;
20988   vl_api_dns_resolve_name_t *mp;
20989   u8 *name = 0;
20990   int ret;
20991
20992   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20993     {
20994       if (unformat (line_input, "%s", &name))
20995         ;
20996       else
20997         break;
20998     }
20999
21000   if (vec_len (name) > 127)
21001     {
21002       errmsg ("name too long");
21003       return -99;
21004     }
21005
21006   /* Construct the API message */
21007   M (DNS_RESOLVE_NAME, mp);
21008   memcpy (mp->name, name, vec_len (name));
21009   vec_free (name);
21010
21011   /* send it... */
21012   S (mp);
21013   /* Wait for the reply */
21014   W (ret);
21015   return ret;
21016 }
21017
21018 static int
21019 api_dns_resolve_ip (vat_main_t * vam)
21020 {
21021   unformat_input_t *line_input = vam->input;
21022   vl_api_dns_resolve_ip_t *mp;
21023   int is_ip6 = -1;
21024   ip4_address_t addr4;
21025   ip6_address_t addr6;
21026   int ret;
21027
21028   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21029     {
21030       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21031         is_ip6 = 1;
21032       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21033         is_ip6 = 0;
21034       else
21035         break;
21036     }
21037
21038   if (is_ip6 == -1)
21039     {
21040       errmsg ("missing address");
21041       return -99;
21042     }
21043
21044   /* Construct the API message */
21045   M (DNS_RESOLVE_IP, mp);
21046   mp->is_ip6 = is_ip6;
21047   if (is_ip6)
21048     memcpy (mp->address, &addr6, sizeof (addr6));
21049   else
21050     memcpy (mp->address, &addr4, sizeof (addr4));
21051
21052   /* send it... */
21053   S (mp);
21054   /* Wait for the reply */
21055   W (ret);
21056   return ret;
21057 }
21058
21059 static int
21060 api_dns_name_server_add_del (vat_main_t * vam)
21061 {
21062   unformat_input_t *i = vam->input;
21063   vl_api_dns_name_server_add_del_t *mp;
21064   u8 is_add = 1;
21065   ip6_address_t ip6_server;
21066   ip4_address_t ip4_server;
21067   int ip6_set = 0;
21068   int ip4_set = 0;
21069   int ret = 0;
21070
21071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21072     {
21073       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21074         ip6_set = 1;
21075       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21076         ip4_set = 1;
21077       else if (unformat (i, "del"))
21078         is_add = 0;
21079       else
21080         {
21081           clib_warning ("parse error '%U'", format_unformat_error, i);
21082           return -99;
21083         }
21084     }
21085
21086   if (ip4_set && ip6_set)
21087     {
21088       errmsg ("Only one server address allowed per message");
21089       return -99;
21090     }
21091   if ((ip4_set + ip6_set) == 0)
21092     {
21093       errmsg ("Server address required");
21094       return -99;
21095     }
21096
21097   /* Construct the API message */
21098   M (DNS_NAME_SERVER_ADD_DEL, mp);
21099
21100   if (ip6_set)
21101     {
21102       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21103       mp->is_ip6 = 1;
21104     }
21105   else
21106     {
21107       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21108       mp->is_ip6 = 0;
21109     }
21110
21111   mp->is_add = is_add;
21112
21113   /* send it... */
21114   S (mp);
21115
21116   /* Wait for a reply, return good/bad news  */
21117   W (ret);
21118   return ret;
21119 }
21120
21121 static void
21122 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21123 {
21124   vat_main_t *vam = &vat_main;
21125
21126   if (mp->is_ip4)
21127     {
21128       print (vam->ofp,
21129              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21130              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21131              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21132              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21133              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21134              clib_net_to_host_u32 (mp->action_index), mp->tag);
21135     }
21136   else
21137     {
21138       print (vam->ofp,
21139              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21140              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21141              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21142              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21143              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21144              clib_net_to_host_u32 (mp->action_index), mp->tag);
21145     }
21146 }
21147
21148 static void
21149 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21150                                              mp)
21151 {
21152   vat_main_t *vam = &vat_main;
21153   vat_json_node_t *node = NULL;
21154   struct in6_addr ip6;
21155   struct in_addr ip4;
21156
21157   if (VAT_JSON_ARRAY != vam->json_tree.type)
21158     {
21159       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21160       vat_json_init_array (&vam->json_tree);
21161     }
21162   node = vat_json_array_add (&vam->json_tree);
21163   vat_json_init_object (node);
21164
21165   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21166   vat_json_object_add_uint (node, "appns_index",
21167                             clib_net_to_host_u32 (mp->appns_index));
21168   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21169   vat_json_object_add_uint (node, "scope", mp->scope);
21170   vat_json_object_add_uint (node, "action_index",
21171                             clib_net_to_host_u32 (mp->action_index));
21172   vat_json_object_add_uint (node, "lcl_port",
21173                             clib_net_to_host_u16 (mp->lcl_port));
21174   vat_json_object_add_uint (node, "rmt_port",
21175                             clib_net_to_host_u16 (mp->rmt_port));
21176   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21177   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21178   vat_json_object_add_string_copy (node, "tag", mp->tag);
21179   if (mp->is_ip4)
21180     {
21181       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21182       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21183       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21184       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21185     }
21186   else
21187     {
21188       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21189       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21190       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21191       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21192     }
21193 }
21194
21195 static int
21196 api_session_rule_add_del (vat_main_t * vam)
21197 {
21198   vl_api_session_rule_add_del_t *mp;
21199   unformat_input_t *i = vam->input;
21200   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21201   u32 appns_index = 0, scope = 0;
21202   ip4_address_t lcl_ip4, rmt_ip4;
21203   ip6_address_t lcl_ip6, rmt_ip6;
21204   u8 is_ip4 = 1, conn_set = 0;
21205   u8 is_add = 1, *tag = 0;
21206   int ret;
21207
21208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21209     {
21210       if (unformat (i, "del"))
21211         is_add = 0;
21212       else if (unformat (i, "add"))
21213         ;
21214       else if (unformat (i, "proto tcp"))
21215         proto = 0;
21216       else if (unformat (i, "proto udp"))
21217         proto = 1;
21218       else if (unformat (i, "appns %d", &appns_index))
21219         ;
21220       else if (unformat (i, "scope %d", &scope))
21221         ;
21222       else if (unformat (i, "tag %_%v%_", &tag))
21223         ;
21224       else
21225         if (unformat
21226             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21227              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21228              &rmt_port))
21229         {
21230           is_ip4 = 1;
21231           conn_set = 1;
21232         }
21233       else
21234         if (unformat
21235             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21236              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21237              &rmt_port))
21238         {
21239           is_ip4 = 0;
21240           conn_set = 1;
21241         }
21242       else if (unformat (i, "action %d", &action))
21243         ;
21244       else
21245         break;
21246     }
21247   if (proto == ~0 || !conn_set || action == ~0)
21248     {
21249       errmsg ("transport proto, connection and action must be set");
21250       return -99;
21251     }
21252
21253   if (scope > 3)
21254     {
21255       errmsg ("scope should be 0-3");
21256       return -99;
21257     }
21258
21259   M (SESSION_RULE_ADD_DEL, mp);
21260
21261   mp->is_ip4 = is_ip4;
21262   mp->transport_proto = proto;
21263   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21264   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21265   mp->lcl_plen = lcl_plen;
21266   mp->rmt_plen = rmt_plen;
21267   mp->action_index = clib_host_to_net_u32 (action);
21268   mp->appns_index = clib_host_to_net_u32 (appns_index);
21269   mp->scope = scope;
21270   mp->is_add = is_add;
21271   if (is_ip4)
21272     {
21273       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21274       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21275     }
21276   else
21277     {
21278       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21279       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21280     }
21281   if (tag)
21282     {
21283       clib_memcpy (mp->tag, tag, vec_len (tag));
21284       vec_free (tag);
21285     }
21286
21287   S (mp);
21288   W (ret);
21289   return ret;
21290 }
21291
21292 static int
21293 api_session_rules_dump (vat_main_t * vam)
21294 {
21295   vl_api_session_rules_dump_t *mp;
21296   vl_api_control_ping_t *mp_ping;
21297   int ret;
21298
21299   if (!vam->json_output)
21300     {
21301       print (vam->ofp, "%=20s", "Session Rules");
21302     }
21303
21304   M (SESSION_RULES_DUMP, mp);
21305   /* send it... */
21306   S (mp);
21307
21308   /* Use a control ping for synchronization */
21309   MPING (CONTROL_PING, mp_ping);
21310   S (mp_ping);
21311
21312   /* Wait for a reply... */
21313   W (ret);
21314   return ret;
21315 }
21316
21317 static int
21318 api_ip_container_proxy_add_del (vat_main_t * vam)
21319 {
21320   vl_api_ip_container_proxy_add_del_t *mp;
21321   unformat_input_t *i = vam->input;
21322   u32 sw_if_index = ~0;
21323   vl_api_prefix_t pfx = { };
21324   u8 is_add = 1;
21325   int ret;
21326
21327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21328     {
21329       if (unformat (i, "del"))
21330         is_add = 0;
21331       else if (unformat (i, "add"))
21332         ;
21333       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21334         ;
21335       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21336         ;
21337       else
21338         break;
21339     }
21340   if (sw_if_index == ~0 || pfx.len == 0)
21341     {
21342       errmsg ("address and sw_if_index must be set");
21343       return -99;
21344     }
21345
21346   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21347
21348   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21349   mp->is_add = is_add;
21350   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21351
21352   S (mp);
21353   W (ret);
21354   return ret;
21355 }
21356
21357 static int
21358 api_qos_record_enable_disable (vat_main_t * vam)
21359 {
21360   unformat_input_t *i = vam->input;
21361   vl_api_qos_record_enable_disable_t *mp;
21362   u32 sw_if_index, qs = 0xff;
21363   u8 sw_if_index_set = 0;
21364   u8 enable = 1;
21365   int ret;
21366
21367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21368     {
21369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21370         sw_if_index_set = 1;
21371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21372         sw_if_index_set = 1;
21373       else if (unformat (i, "%U", unformat_qos_source, &qs))
21374         ;
21375       else if (unformat (i, "disable"))
21376         enable = 0;
21377       else
21378         {
21379           clib_warning ("parse error '%U'", format_unformat_error, i);
21380           return -99;
21381         }
21382     }
21383
21384   if (sw_if_index_set == 0)
21385     {
21386       errmsg ("missing interface name or sw_if_index");
21387       return -99;
21388     }
21389   if (qs == 0xff)
21390     {
21391       errmsg ("input location must be specified");
21392       return -99;
21393     }
21394
21395   M (QOS_RECORD_ENABLE_DISABLE, mp);
21396
21397   mp->record.sw_if_index = ntohl (sw_if_index);
21398   mp->record.input_source = qs;
21399   mp->enable = enable;
21400
21401   S (mp);
21402   W (ret);
21403   return ret;
21404 }
21405
21406
21407 static int
21408 q_or_quit (vat_main_t * vam)
21409 {
21410 #if VPP_API_TEST_BUILTIN == 0
21411   longjmp (vam->jump_buf, 1);
21412 #endif
21413   return 0;                     /* not so much */
21414 }
21415
21416 static int
21417 q (vat_main_t * vam)
21418 {
21419   return q_or_quit (vam);
21420 }
21421
21422 static int
21423 quit (vat_main_t * vam)
21424 {
21425   return q_or_quit (vam);
21426 }
21427
21428 static int
21429 comment (vat_main_t * vam)
21430 {
21431   return 0;
21432 }
21433
21434 static int
21435 elog_save (vat_main_t * vam)
21436 {
21437 #if VPP_API_TEST_BUILTIN == 0
21438   elog_main_t *em = &vam->elog_main;
21439   unformat_input_t *i = vam->input;
21440   char *file, *chroot_file;
21441   clib_error_t *error;
21442
21443   if (!unformat (i, "%s", &file))
21444     {
21445       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21446       return 0;
21447     }
21448
21449   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21450   if (strstr (file, "..") || index (file, '/'))
21451     {
21452       errmsg ("illegal characters in filename '%s'", file);
21453       return 0;
21454     }
21455
21456   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21457
21458   vec_free (file);
21459
21460   errmsg ("Saving %wd of %wd events to %s",
21461           elog_n_events_in_buffer (em),
21462           elog_buffer_capacity (em), chroot_file);
21463
21464   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21465   vec_free (chroot_file);
21466
21467   if (error)
21468     clib_error_report (error);
21469 #else
21470   errmsg ("Use the vpp event loger...");
21471 #endif
21472
21473   return 0;
21474 }
21475
21476 static int
21477 elog_setup (vat_main_t * vam)
21478 {
21479 #if VPP_API_TEST_BUILTIN == 0
21480   elog_main_t *em = &vam->elog_main;
21481   unformat_input_t *i = vam->input;
21482   u32 nevents = 128 << 10;
21483
21484   (void) unformat (i, "nevents %d", &nevents);
21485
21486   elog_init (em, nevents);
21487   vl_api_set_elog_main (em);
21488   vl_api_set_elog_trace_api_messages (1);
21489   errmsg ("Event logger initialized with %u events", nevents);
21490 #else
21491   errmsg ("Use the vpp event loger...");
21492 #endif
21493   return 0;
21494 }
21495
21496 static int
21497 elog_enable (vat_main_t * vam)
21498 {
21499 #if VPP_API_TEST_BUILTIN == 0
21500   elog_main_t *em = &vam->elog_main;
21501
21502   elog_enable_disable (em, 1 /* enable */ );
21503   vl_api_set_elog_trace_api_messages (1);
21504   errmsg ("Event logger enabled...");
21505 #else
21506   errmsg ("Use the vpp event loger...");
21507 #endif
21508   return 0;
21509 }
21510
21511 static int
21512 elog_disable (vat_main_t * vam)
21513 {
21514 #if VPP_API_TEST_BUILTIN == 0
21515   elog_main_t *em = &vam->elog_main;
21516
21517   elog_enable_disable (em, 0 /* enable */ );
21518   vl_api_set_elog_trace_api_messages (1);
21519   errmsg ("Event logger disabled...");
21520 #else
21521   errmsg ("Use the vpp event loger...");
21522 #endif
21523   return 0;
21524 }
21525
21526 static int
21527 statseg (vat_main_t * vam)
21528 {
21529   ssvm_private_t *ssvmp = &vam->stat_segment;
21530   ssvm_shared_header_t *shared_header = ssvmp->sh;
21531   vlib_counter_t **counters;
21532   u64 thread0_index1_packets;
21533   u64 thread0_index1_bytes;
21534   f64 vector_rate, input_rate;
21535   uword *p;
21536
21537   uword *counter_vector_by_name;
21538   if (vam->stat_segment_lockp == 0)
21539     {
21540       errmsg ("Stat segment not mapped...");
21541       return -99;
21542     }
21543
21544   /* look up "/if/rx for sw_if_index 1 as a test */
21545
21546   clib_spinlock_lock (vam->stat_segment_lockp);
21547
21548   counter_vector_by_name = (uword *) shared_header->opaque[1];
21549
21550   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21551   if (p == 0)
21552     {
21553       clib_spinlock_unlock (vam->stat_segment_lockp);
21554       errmsg ("/if/tx not found?");
21555       return -99;
21556     }
21557
21558   /* Fish per-thread vector of combined counters from shared memory */
21559   counters = (vlib_counter_t **) p[0];
21560
21561   if (vec_len (counters[0]) < 2)
21562     {
21563       clib_spinlock_unlock (vam->stat_segment_lockp);
21564       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21565       return -99;
21566     }
21567
21568   /* Read thread 0 sw_if_index 1 counter */
21569   thread0_index1_packets = counters[0][1].packets;
21570   thread0_index1_bytes = counters[0][1].bytes;
21571
21572   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21573   if (p == 0)
21574     {
21575       clib_spinlock_unlock (vam->stat_segment_lockp);
21576       errmsg ("vector_rate not found?");
21577       return -99;
21578     }
21579
21580   vector_rate = *(f64 *) (p[0]);
21581   p = hash_get_mem (counter_vector_by_name, "input_rate");
21582   if (p == 0)
21583     {
21584       clib_spinlock_unlock (vam->stat_segment_lockp);
21585       errmsg ("input_rate not found?");
21586       return -99;
21587     }
21588   input_rate = *(f64 *) (p[0]);
21589
21590   clib_spinlock_unlock (vam->stat_segment_lockp);
21591
21592   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21593          vector_rate, input_rate);
21594   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21595          thread0_index1_packets, thread0_index1_bytes);
21596
21597   return 0;
21598 }
21599
21600 static int
21601 cmd_cmp (void *a1, void *a2)
21602 {
21603   u8 **c1 = a1;
21604   u8 **c2 = a2;
21605
21606   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21607 }
21608
21609 static int
21610 help (vat_main_t * vam)
21611 {
21612   u8 **cmds = 0;
21613   u8 *name = 0;
21614   hash_pair_t *p;
21615   unformat_input_t *i = vam->input;
21616   int j;
21617
21618   if (unformat (i, "%s", &name))
21619     {
21620       uword *hs;
21621
21622       vec_add1 (name, 0);
21623
21624       hs = hash_get_mem (vam->help_by_name, name);
21625       if (hs)
21626         print (vam->ofp, "usage: %s %s", name, hs[0]);
21627       else
21628         print (vam->ofp, "No such msg / command '%s'", name);
21629       vec_free (name);
21630       return 0;
21631     }
21632
21633   print (vam->ofp, "Help is available for the following:");
21634
21635     /* *INDENT-OFF* */
21636     hash_foreach_pair (p, vam->function_by_name,
21637     ({
21638       vec_add1 (cmds, (u8 *)(p->key));
21639     }));
21640     /* *INDENT-ON* */
21641
21642   vec_sort_with_function (cmds, cmd_cmp);
21643
21644   for (j = 0; j < vec_len (cmds); j++)
21645     print (vam->ofp, "%s", cmds[j]);
21646
21647   vec_free (cmds);
21648   return 0;
21649 }
21650
21651 static int
21652 set (vat_main_t * vam)
21653 {
21654   u8 *name = 0, *value = 0;
21655   unformat_input_t *i = vam->input;
21656
21657   if (unformat (i, "%s", &name))
21658     {
21659       /* The input buffer is a vector, not a string. */
21660       value = vec_dup (i->buffer);
21661       vec_delete (value, i->index, 0);
21662       /* Almost certainly has a trailing newline */
21663       if (value[vec_len (value) - 1] == '\n')
21664         value[vec_len (value) - 1] = 0;
21665       /* Make sure it's a proper string, one way or the other */
21666       vec_add1 (value, 0);
21667       (void) clib_macro_set_value (&vam->macro_main,
21668                                    (char *) name, (char *) value);
21669     }
21670   else
21671     errmsg ("usage: set <name> <value>");
21672
21673   vec_free (name);
21674   vec_free (value);
21675   return 0;
21676 }
21677
21678 static int
21679 unset (vat_main_t * vam)
21680 {
21681   u8 *name = 0;
21682
21683   if (unformat (vam->input, "%s", &name))
21684     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21685       errmsg ("unset: %s wasn't set", name);
21686   vec_free (name);
21687   return 0;
21688 }
21689
21690 typedef struct
21691 {
21692   u8 *name;
21693   u8 *value;
21694 } macro_sort_t;
21695
21696
21697 static int
21698 macro_sort_cmp (void *a1, void *a2)
21699 {
21700   macro_sort_t *s1 = a1;
21701   macro_sort_t *s2 = a2;
21702
21703   return strcmp ((char *) (s1->name), (char *) (s2->name));
21704 }
21705
21706 static int
21707 dump_macro_table (vat_main_t * vam)
21708 {
21709   macro_sort_t *sort_me = 0, *sm;
21710   int i;
21711   hash_pair_t *p;
21712
21713     /* *INDENT-OFF* */
21714     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21715     ({
21716       vec_add2 (sort_me, sm, 1);
21717       sm->name = (u8 *)(p->key);
21718       sm->value = (u8 *) (p->value[0]);
21719     }));
21720     /* *INDENT-ON* */
21721
21722   vec_sort_with_function (sort_me, macro_sort_cmp);
21723
21724   if (vec_len (sort_me))
21725     print (vam->ofp, "%-15s%s", "Name", "Value");
21726   else
21727     print (vam->ofp, "The macro table is empty...");
21728
21729   for (i = 0; i < vec_len (sort_me); i++)
21730     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21731   return 0;
21732 }
21733
21734 static int
21735 dump_node_table (vat_main_t * vam)
21736 {
21737   int i, j;
21738   vlib_node_t *node, *next_node;
21739
21740   if (vec_len (vam->graph_nodes) == 0)
21741     {
21742       print (vam->ofp, "Node table empty, issue get_node_graph...");
21743       return 0;
21744     }
21745
21746   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21747     {
21748       node = vam->graph_nodes[0][i];
21749       print (vam->ofp, "[%d] %s", i, node->name);
21750       for (j = 0; j < vec_len (node->next_nodes); j++)
21751         {
21752           if (node->next_nodes[j] != ~0)
21753             {
21754               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21755               print (vam->ofp, "  [%d] %s", j, next_node->name);
21756             }
21757         }
21758     }
21759   return 0;
21760 }
21761
21762 static int
21763 value_sort_cmp (void *a1, void *a2)
21764 {
21765   name_sort_t *n1 = a1;
21766   name_sort_t *n2 = a2;
21767
21768   if (n1->value < n2->value)
21769     return -1;
21770   if (n1->value > n2->value)
21771     return 1;
21772   return 0;
21773 }
21774
21775
21776 static int
21777 dump_msg_api_table (vat_main_t * vam)
21778 {
21779   api_main_t *am = &api_main;
21780   name_sort_t *nses = 0, *ns;
21781   hash_pair_t *hp;
21782   int i;
21783
21784   /* *INDENT-OFF* */
21785   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21786   ({
21787     vec_add2 (nses, ns, 1);
21788     ns->name = (u8 *)(hp->key);
21789     ns->value = (u32) hp->value[0];
21790   }));
21791   /* *INDENT-ON* */
21792
21793   vec_sort_with_function (nses, value_sort_cmp);
21794
21795   for (i = 0; i < vec_len (nses); i++)
21796     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21797   vec_free (nses);
21798   return 0;
21799 }
21800
21801 static int
21802 get_msg_id (vat_main_t * vam)
21803 {
21804   u8 *name_and_crc;
21805   u32 message_index;
21806
21807   if (unformat (vam->input, "%s", &name_and_crc))
21808     {
21809       message_index = vl_msg_api_get_msg_index (name_and_crc);
21810       if (message_index == ~0)
21811         {
21812           print (vam->ofp, " '%s' not found", name_and_crc);
21813           return 0;
21814         }
21815       print (vam->ofp, " '%s' has message index %d",
21816              name_and_crc, message_index);
21817       return 0;
21818     }
21819   errmsg ("name_and_crc required...");
21820   return 0;
21821 }
21822
21823 static int
21824 search_node_table (vat_main_t * vam)
21825 {
21826   unformat_input_t *line_input = vam->input;
21827   u8 *node_to_find;
21828   int j;
21829   vlib_node_t *node, *next_node;
21830   uword *p;
21831
21832   if (vam->graph_node_index_by_name == 0)
21833     {
21834       print (vam->ofp, "Node table empty, issue get_node_graph...");
21835       return 0;
21836     }
21837
21838   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21839     {
21840       if (unformat (line_input, "%s", &node_to_find))
21841         {
21842           vec_add1 (node_to_find, 0);
21843           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21844           if (p == 0)
21845             {
21846               print (vam->ofp, "%s not found...", node_to_find);
21847               goto out;
21848             }
21849           node = vam->graph_nodes[0][p[0]];
21850           print (vam->ofp, "[%d] %s", p[0], node->name);
21851           for (j = 0; j < vec_len (node->next_nodes); j++)
21852             {
21853               if (node->next_nodes[j] != ~0)
21854                 {
21855                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21856                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21857                 }
21858             }
21859         }
21860
21861       else
21862         {
21863           clib_warning ("parse error '%U'", format_unformat_error,
21864                         line_input);
21865           return -99;
21866         }
21867
21868     out:
21869       vec_free (node_to_find);
21870
21871     }
21872
21873   return 0;
21874 }
21875
21876
21877 static int
21878 script (vat_main_t * vam)
21879 {
21880 #if (VPP_API_TEST_BUILTIN==0)
21881   u8 *s = 0;
21882   char *save_current_file;
21883   unformat_input_t save_input;
21884   jmp_buf save_jump_buf;
21885   u32 save_line_number;
21886
21887   FILE *new_fp, *save_ifp;
21888
21889   if (unformat (vam->input, "%s", &s))
21890     {
21891       new_fp = fopen ((char *) s, "r");
21892       if (new_fp == 0)
21893         {
21894           errmsg ("Couldn't open script file %s", s);
21895           vec_free (s);
21896           return -99;
21897         }
21898     }
21899   else
21900     {
21901       errmsg ("Missing script name");
21902       return -99;
21903     }
21904
21905   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21906   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21907   save_ifp = vam->ifp;
21908   save_line_number = vam->input_line_number;
21909   save_current_file = (char *) vam->current_file;
21910
21911   vam->input_line_number = 0;
21912   vam->ifp = new_fp;
21913   vam->current_file = s;
21914   do_one_file (vam);
21915
21916   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21917   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21918   vam->ifp = save_ifp;
21919   vam->input_line_number = save_line_number;
21920   vam->current_file = (u8 *) save_current_file;
21921   vec_free (s);
21922
21923   return 0;
21924 #else
21925   clib_warning ("use the exec command...");
21926   return -99;
21927 #endif
21928 }
21929
21930 static int
21931 echo (vat_main_t * vam)
21932 {
21933   print (vam->ofp, "%v", vam->input->buffer);
21934   return 0;
21935 }
21936
21937 /* List of API message constructors, CLI names map to api_xxx */
21938 #define foreach_vpe_api_msg                                             \
21939 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21940 _(sw_interface_dump,"")                                                 \
21941 _(sw_interface_set_flags,                                               \
21942   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21943 _(sw_interface_add_del_address,                                         \
21944   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21945 _(sw_interface_set_rx_mode,                                             \
21946   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21947 _(sw_interface_set_rx_placement,                                        \
21948   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21949 _(sw_interface_rx_placement_dump,                                       \
21950   "[<intfc> | sw_if_index <id>]")                                         \
21951 _(sw_interface_set_table,                                               \
21952   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21953 _(sw_interface_set_mpls_enable,                                         \
21954   "<intfc> | sw_if_index [disable | dis]")                              \
21955 _(sw_interface_set_vpath,                                               \
21956   "<intfc> | sw_if_index <id> enable | disable")                        \
21957 _(sw_interface_set_vxlan_bypass,                                        \
21958   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21959 _(sw_interface_set_geneve_bypass,                                       \
21960   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21961 _(sw_interface_set_l2_xconnect,                                         \
21962   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21963   "enable | disable")                                                   \
21964 _(sw_interface_set_l2_bridge,                                           \
21965   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21966   "[shg <split-horizon-group>] [bvi]\n"                                 \
21967   "enable | disable")                                                   \
21968 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21969 _(bridge_domain_add_del,                                                \
21970   "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") \
21971 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21972 _(l2fib_add_del,                                                        \
21973   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21974 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21975 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21976 _(l2_flags,                                                             \
21977   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21978 _(bridge_flags,                                                         \
21979   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21980 _(tap_create_v2,                                                        \
21981   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21982 _(tap_delete_v2,                                                        \
21983   "<vpp-if-name> | sw_if_index <id>")                                   \
21984 _(sw_interface_tap_v2_dump, "")                                         \
21985 _(virtio_pci_create,                                                    \
21986   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21987 _(virtio_pci_delete,                                                    \
21988   "<vpp-if-name> | sw_if_index <id>")                                   \
21989 _(sw_interface_virtio_pci_dump, "")                                     \
21990 _(bond_create,                                                          \
21991   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21992   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21993   "[id <if-id>]")                                                       \
21994 _(bond_delete,                                                          \
21995   "<vpp-if-name> | sw_if_index <id>")                                   \
21996 _(bond_enslave,                                                         \
21997   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21998 _(bond_detach_slave,                                                    \
21999   "sw_if_index <n>")                                                    \
22000 _(sw_interface_bond_dump, "")                                           \
22001 _(sw_interface_slave_dump,                                              \
22002   "<vpp-if-name> | sw_if_index <id>")                                   \
22003 _(ip_table_add_del,                                                     \
22004   "table <n> [ipv6] [add | del]\n")                                     \
22005 _(ip_route_add_del,                                                     \
22006   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22007   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22008   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22009   "[multipath] [count <n>] [del]")                                      \
22010 _(ip_mroute_add_del,                                                    \
22011   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22012   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22013 _(mpls_table_add_del,                                                   \
22014   "table <n> [add | del]\n")                                            \
22015 _(mpls_route_add_del,                                                   \
22016   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22017   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22018   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22019   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22020   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22021   "[count <n>] [del]")                                                  \
22022 _(mpls_ip_bind_unbind,                                                  \
22023   "<label> <addr/len>")                                                 \
22024 _(mpls_tunnel_add_del,                                                  \
22025   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22026   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22027   "[l2-only]  [out-label <n>]")                                         \
22028 _(sr_mpls_policy_add,                                                   \
22029   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22030 _(sr_mpls_policy_del,                                                   \
22031   "bsid <id>")                                                          \
22032 _(bier_table_add_del,                                                   \
22033   "<label> <sub-domain> <set> <bsl> [del]")                             \
22034 _(bier_route_add_del,                                                   \
22035   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22036   "[<intfc> | sw_if_index <id>]"                                        \
22037   "[weight <n>] [del] [multipath]")                                     \
22038 _(proxy_arp_add_del,                                                    \
22039   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22040 _(proxy_arp_intfc_enable_disable,                                       \
22041   "<intfc> | sw_if_index <id> enable | disable")                        \
22042 _(sw_interface_set_unnumbered,                                          \
22043   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22044 _(ip_neighbor_add_del,                                                  \
22045   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22046   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22047 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22048 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22049   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22050   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22051   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22052 _(reset_fib, "vrf <n> [ipv6]")                                          \
22053 _(dhcp_proxy_config,                                                    \
22054   "svr <v46-address> src <v46-address>\n"                               \
22055    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22056 _(dhcp_proxy_set_vss,                                                   \
22057   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22058 _(dhcp_proxy_dump, "ip6")                                               \
22059 _(dhcp_client_config,                                                   \
22060   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22061 _(set_ip_flow_hash,                                                     \
22062   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22063 _(sw_interface_ip6_enable_disable,                                      \
22064   "<intfc> | sw_if_index <id> enable | disable")                        \
22065 _(ip6nd_proxy_add_del,                                                  \
22066   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22067 _(ip6nd_proxy_dump, "")                                                 \
22068 _(sw_interface_ip6nd_ra_prefix,                                         \
22069   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22070   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22071   "[nolink] [isno]")                                                    \
22072 _(sw_interface_ip6nd_ra_config,                                         \
22073   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22074   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22075   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22076 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22077 _(l2_patch_add_del,                                                     \
22078   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22079   "enable | disable")                                                   \
22080 _(sr_localsid_add_del,                                                  \
22081   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22082   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22083 _(classify_add_del_table,                                               \
22084   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22085   " [del] [del-chain] mask <mask-value>\n"                              \
22086   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22087   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22088 _(classify_add_del_session,                                             \
22089   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22090   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22091   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22092   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22093 _(classify_set_interface_ip_table,                                      \
22094   "<intfc> | sw_if_index <nn> table <nn>")                              \
22095 _(classify_set_interface_l2_tables,                                     \
22096   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22097   "  [other-table <nn>]")                                               \
22098 _(get_node_index, "node <node-name")                                    \
22099 _(add_node_next, "node <node-name> next <next-node-name>")              \
22100 _(l2tpv3_create_tunnel,                                                 \
22101   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22102   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22103   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22104 _(l2tpv3_set_tunnel_cookies,                                            \
22105   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22106   "[new_remote_cookie <nn>]\n")                                         \
22107 _(l2tpv3_interface_enable_disable,                                      \
22108   "<intfc> | sw_if_index <nn> enable | disable")                        \
22109 _(l2tpv3_set_lookup_key,                                                \
22110   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22111 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22112 _(vxlan_offload_rx,                                                     \
22113   "hw { <interface name> | hw_if_index <nn>} "                          \
22114   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22115 _(vxlan_add_del_tunnel,                                                 \
22116   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22117   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22118   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22119 _(geneve_add_del_tunnel,                                                \
22120   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22121   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22122   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22123 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22124 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22125 _(gre_tunnel_add_del,                                                   \
22126   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22127   "[teb | erspan <session-id>] [del]")                                  \
22128 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22129 _(l2_fib_clear_table, "")                                               \
22130 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22131 _(l2_interface_vlan_tag_rewrite,                                        \
22132   "<intfc> | sw_if_index <nn> \n"                                       \
22133   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22134   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22135 _(create_vhost_user_if,                                                 \
22136         "socket <filename> [server] [renumber <dev_instance>] "         \
22137         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
22138         "[mac <mac_address>]")                                          \
22139 _(modify_vhost_user_if,                                                 \
22140         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22141         "[server] [renumber <dev_instance>] [gso]")                     \
22142 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22143 _(sw_interface_vhost_user_dump, "")                                     \
22144 _(show_version, "")                                                     \
22145 _(show_threads, "")                                                     \
22146 _(vxlan_gpe_add_del_tunnel,                                             \
22147   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22148   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22149   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22150   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22151 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22152 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22153 _(interface_name_renumber,                                              \
22154   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22155 _(input_acl_set_interface,                                              \
22156   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22157   "  [l2-table <nn>] [del]")                                            \
22158 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22159 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22160   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22161 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22162 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22163 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22164 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22165 _(ip_dump, "ipv4 | ipv6")                                               \
22166 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22167 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22168   "  spid_id <n> ")                                                     \
22169 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22170   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22171   "  integ_alg <alg> integ_key <hex>")                                  \
22172 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22173   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22174   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22175   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22176 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22177   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22178   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22179   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22180   "  [instance <n>]")     \
22181 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22182 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22183 _(delete_loopback,"sw_if_index <nn>")                                   \
22184 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22185 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22186 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22187 _(want_interface_events,  "enable|disable")                             \
22188 _(get_first_msg_id, "client <name>")                                    \
22189 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22190 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22191   "fib-id <nn> [ip4][ip6][default]")                                    \
22192 _(get_node_graph, " ")                                                  \
22193 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22194 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22195 _(ioam_disable, "")                                                     \
22196 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22197                             " sw_if_index <sw_if_index> p <priority> "  \
22198                             "w <weight>] [del]")                        \
22199 _(one_add_del_locator, "locator-set <locator_name> "                    \
22200                         "iface <intf> | sw_if_index <sw_if_index> "     \
22201                         "p <priority> w <weight> [del]")                \
22202 _(one_add_del_local_eid,"vni <vni> eid "                                \
22203                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22204                          "locator-set <locator_name> [del]"             \
22205                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22206 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22207 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22208 _(one_enable_disable, "enable|disable")                                 \
22209 _(one_map_register_enable_disable, "enable|disable")                    \
22210 _(one_map_register_fallback_threshold, "<value>")                       \
22211 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22212 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22213                                "[seid <seid>] "                         \
22214                                "rloc <locator> p <prio> "               \
22215                                "w <weight> [rloc <loc> ... ] "          \
22216                                "action <action> [del-all]")             \
22217 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22218                           "<local-eid>")                                \
22219 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22220 _(one_use_petr, "ip-address> | disable")                                \
22221 _(one_map_request_mode, "src-dst|dst-only")                             \
22222 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22223 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22224 _(one_locator_set_dump, "[local | remote]")                             \
22225 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22226 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22227                        "[local] | [remote]")                            \
22228 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22229 _(one_ndp_bd_get, "")                                                   \
22230 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22231 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22232 _(one_l2_arp_bd_get, "")                                                \
22233 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22234 _(one_stats_enable_disable, "enable|disable")                           \
22235 _(show_one_stats_enable_disable, "")                                    \
22236 _(one_eid_table_vni_dump, "")                                           \
22237 _(one_eid_table_map_dump, "l2|l3")                                      \
22238 _(one_map_resolver_dump, "")                                            \
22239 _(one_map_server_dump, "")                                              \
22240 _(one_adjacencies_get, "vni <vni>")                                     \
22241 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22242 _(show_one_rloc_probe_state, "")                                        \
22243 _(show_one_map_register_state, "")                                      \
22244 _(show_one_status, "")                                                  \
22245 _(one_stats_dump, "")                                                   \
22246 _(one_stats_flush, "")                                                  \
22247 _(one_get_map_request_itr_rlocs, "")                                    \
22248 _(one_map_register_set_ttl, "<ttl>")                                    \
22249 _(one_set_transport_protocol, "udp|api")                                \
22250 _(one_get_transport_protocol, "")                                       \
22251 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22252 _(one_show_xtr_mode, "")                                                \
22253 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22254 _(one_show_pitr_mode, "")                                               \
22255 _(one_enable_disable_petr_mode, "enable|disable")                       \
22256 _(one_show_petr_mode, "")                                               \
22257 _(show_one_nsh_mapping, "")                                             \
22258 _(show_one_pitr, "")                                                    \
22259 _(show_one_use_petr, "")                                                \
22260 _(show_one_map_request_mode, "")                                        \
22261 _(show_one_map_register_ttl, "")                                        \
22262 _(show_one_map_register_fallback_threshold, "")                         \
22263 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22264                             " sw_if_index <sw_if_index> p <priority> "  \
22265                             "w <weight>] [del]")                        \
22266 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22267                         "iface <intf> | sw_if_index <sw_if_index> "     \
22268                         "p <priority> w <weight> [del]")                \
22269 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22270                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22271                          "locator-set <locator_name> [del]"             \
22272                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22273 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22274 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22275 _(lisp_enable_disable, "enable|disable")                                \
22276 _(lisp_map_register_enable_disable, "enable|disable")                   \
22277 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22278 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22279                                "[seid <seid>] "                         \
22280                                "rloc <locator> p <prio> "               \
22281                                "w <weight> [rloc <loc> ... ] "          \
22282                                "action <action> [del-all]")             \
22283 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22284                           "<local-eid>")                                \
22285 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22286 _(lisp_use_petr, "<ip-address> | disable")                              \
22287 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22288 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22289 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22290 _(lisp_locator_set_dump, "[local | remote]")                            \
22291 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22292 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22293                        "[local] | [remote]")                            \
22294 _(lisp_eid_table_vni_dump, "")                                          \
22295 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22296 _(lisp_map_resolver_dump, "")                                           \
22297 _(lisp_map_server_dump, "")                                             \
22298 _(lisp_adjacencies_get, "vni <vni>")                                    \
22299 _(gpe_fwd_entry_vnis_get, "")                                           \
22300 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22301 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22302                                 "[table <table-id>]")                   \
22303 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22304 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22305 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22306 _(gpe_get_encap_mode, "")                                               \
22307 _(lisp_gpe_add_del_iface, "up|down")                                    \
22308 _(lisp_gpe_enable_disable, "enable|disable")                            \
22309 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22310   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22311 _(show_lisp_rloc_probe_state, "")                                       \
22312 _(show_lisp_map_register_state, "")                                     \
22313 _(show_lisp_status, "")                                                 \
22314 _(lisp_get_map_request_itr_rlocs, "")                                   \
22315 _(show_lisp_pitr, "")                                                   \
22316 _(show_lisp_use_petr, "")                                               \
22317 _(show_lisp_map_request_mode, "")                                       \
22318 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22319 _(af_packet_delete, "name <host interface name>")                       \
22320 _(af_packet_dump, "")                                                   \
22321 _(policer_add_del, "name <policer name> <params> [del]")                \
22322 _(policer_dump, "[name <policer name>]")                                \
22323 _(policer_classify_set_interface,                                       \
22324   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22325   "  [l2-table <nn>] [del]")                                            \
22326 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22327 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22328     "[master|slave]")                                                   \
22329 _(netmap_delete, "name <interface name>")                               \
22330 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22331 _(mpls_table_dump, "")                                                  \
22332 _(mpls_route_dump, "table-id <ID>")                                     \
22333 _(classify_table_ids, "")                                               \
22334 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22335 _(classify_table_info, "table_id <nn>")                                 \
22336 _(classify_session_dump, "table_id <nn>")                               \
22337 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22338     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22339     "[template_interval <nn>] [udp_checksum]")                          \
22340 _(ipfix_exporter_dump, "")                                              \
22341 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22342 _(ipfix_classify_stream_dump, "")                                       \
22343 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22344 _(ipfix_classify_table_dump, "")                                        \
22345 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22346 _(sw_interface_span_dump, "[l2]")                                           \
22347 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22348 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22349 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22350 _(pg_enable_disable, "[stream <id>] disable")                           \
22351 _(ip_source_and_port_range_check_add_del,                               \
22352   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22353 _(ip_source_and_port_range_check_interface_add_del,                     \
22354   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22355   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22356 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22357 _(l2_interface_pbb_tag_rewrite,                                         \
22358   "<intfc> | sw_if_index <nn> \n"                                       \
22359   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22360   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22361 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22362 _(flow_classify_set_interface,                                          \
22363   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22364 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22365 _(ip_table_dump, "")                                                    \
22366 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22367 _(ip_mtable_dump, "")                                                   \
22368 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22369 _(feature_enable_disable, "arc_name <arc_name> "                        \
22370   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22371 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22372 "[disable]")                                                            \
22373 _(l2_xconnect_dump, "")                                                 \
22374 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22375 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22376 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22377 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22378 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22379 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22380 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22381   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22382 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22383 _(sock_init_shm, "size <nnn>")                                          \
22384 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22385 _(dns_enable_disable, "[enable][disable]")                              \
22386 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22387 _(dns_resolve_name, "<hostname>")                                       \
22388 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22389 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22390 _(dns_resolve_name, "<hostname>")                                       \
22391 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22392   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22393 _(session_rules_dump, "")                                               \
22394 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22395 _(output_acl_set_interface,                                             \
22396   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22397   "  [l2-table <nn>] [del]")                                            \
22398 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22399
22400 /* List of command functions, CLI names map directly to functions */
22401 #define foreach_cli_function                                    \
22402 _(comment, "usage: comment <ignore-rest-of-line>")              \
22403 _(dump_interface_table, "usage: dump_interface_table")          \
22404 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22405 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22406 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22407 _(dump_macro_table, "usage: dump_macro_table ")                 \
22408 _(dump_node_table, "usage: dump_node_table")                    \
22409 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22410 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22411 _(elog_disable, "usage: elog_disable")                          \
22412 _(elog_enable, "usage: elog_enable")                            \
22413 _(elog_save, "usage: elog_save <filename>")                     \
22414 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22415 _(echo, "usage: echo <message>")                                \
22416 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22417 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22418 _(help, "usage: help")                                          \
22419 _(q, "usage: quit")                                             \
22420 _(quit, "usage: quit")                                          \
22421 _(search_node_table, "usage: search_node_table <name>...")      \
22422 _(set, "usage: set <variable-name> <value>")                    \
22423 _(script, "usage: script <file-name>")                          \
22424 _(statseg, "usage: statseg")                                    \
22425 _(unset, "usage: unset <variable-name>")
22426
22427 #define _(N,n)                                  \
22428     static void vl_api_##n##_t_handler_uni      \
22429     (vl_api_##n##_t * mp)                       \
22430     {                                           \
22431         vat_main_t * vam = &vat_main;           \
22432         if (vam->json_output) {                 \
22433             vl_api_##n##_t_handler_json(mp);    \
22434         } else {                                \
22435             vl_api_##n##_t_handler(mp);         \
22436         }                                       \
22437     }
22438 foreach_vpe_api_reply_msg;
22439 #if VPP_API_TEST_BUILTIN == 0
22440 foreach_standalone_reply_msg;
22441 #endif
22442 #undef _
22443
22444 void
22445 vat_api_hookup (vat_main_t * vam)
22446 {
22447 #define _(N,n)                                                  \
22448     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22449                            vl_api_##n##_t_handler_uni,          \
22450                            vl_noop_handler,                     \
22451                            vl_api_##n##_t_endian,               \
22452                            vl_api_##n##_t_print,                \
22453                            sizeof(vl_api_##n##_t), 1);
22454   foreach_vpe_api_reply_msg;
22455 #if VPP_API_TEST_BUILTIN == 0
22456   foreach_standalone_reply_msg;
22457 #endif
22458 #undef _
22459
22460 #if (VPP_API_TEST_BUILTIN==0)
22461   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22462
22463   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22464
22465   vam->function_by_name = hash_create_string (0, sizeof (uword));
22466
22467   vam->help_by_name = hash_create_string (0, sizeof (uword));
22468 #endif
22469
22470   /* API messages we can send */
22471 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22472   foreach_vpe_api_msg;
22473 #undef _
22474
22475   /* Help strings */
22476 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22477   foreach_vpe_api_msg;
22478 #undef _
22479
22480   /* CLI functions */
22481 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22482   foreach_cli_function;
22483 #undef _
22484
22485   /* Help strings */
22486 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22487   foreach_cli_function;
22488 #undef _
22489 }
22490
22491 #if VPP_API_TEST_BUILTIN
22492 static clib_error_t *
22493 vat_api_hookup_shim (vlib_main_t * vm)
22494 {
22495   vat_api_hookup (&vat_main);
22496   return 0;
22497 }
22498
22499 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22500 #endif
22501
22502 /*
22503  * fd.io coding-style-patch-verification: ON
22504  *
22505  * Local Variables:
22506  * eval: (c-set-style "gnu")
22507  * End:
22508  */