api: enable binary API event logging in vat
[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
7773   clib_memset (mac_address, 0, sizeof (mac_address));
7774   lb = BOND_LB_L2;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7780         mode_is_set = 1;
7781       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7782                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7783         ;
7784       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7785                          mac_address))
7786         custom_mac = 1;
7787       else if (unformat (i, "id %u", &id))
7788         ;
7789       else
7790         break;
7791     }
7792
7793   if (mode_is_set == 0)
7794     {
7795       errmsg ("Missing bond mode. ");
7796       return -99;
7797     }
7798
7799   /* Construct the API message */
7800   M (BOND_CREATE, mp);
7801
7802   mp->use_custom_mac = custom_mac;
7803
7804   mp->mode = mode;
7805   mp->lb = lb;
7806   mp->id = htonl (id);
7807
7808   if (custom_mac)
7809     clib_memcpy (mp->mac_address, mac_address, 6);
7810
7811   /* send it... */
7812   S (mp);
7813
7814   /* Wait for a reply... */
7815   W (ret);
7816   return ret;
7817 }
7818
7819 static int
7820 api_bond_delete (vat_main_t * vam)
7821 {
7822   unformat_input_t *i = vam->input;
7823   vl_api_bond_delete_t *mp;
7824   u32 sw_if_index = ~0;
7825   u8 sw_if_index_set = 0;
7826   int ret;
7827
7828   /* Parse args required to build the message */
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7832         sw_if_index_set = 1;
7833       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7834         sw_if_index_set = 1;
7835       else
7836         break;
7837     }
7838
7839   if (sw_if_index_set == 0)
7840     {
7841       errmsg ("missing vpp interface name. ");
7842       return -99;
7843     }
7844
7845   /* Construct the API message */
7846   M (BOND_DELETE, mp);
7847
7848   mp->sw_if_index = ntohl (sw_if_index);
7849
7850   /* send it... */
7851   S (mp);
7852
7853   /* Wait for a reply... */
7854   W (ret);
7855   return ret;
7856 }
7857
7858 static int
7859 api_bond_enslave (vat_main_t * vam)
7860 {
7861   unformat_input_t *i = vam->input;
7862   vl_api_bond_enslave_t *mp;
7863   u32 bond_sw_if_index;
7864   int ret;
7865   u8 is_passive;
7866   u8 is_long_timeout;
7867   u32 bond_sw_if_index_is_set = 0;
7868   u32 sw_if_index;
7869   u8 sw_if_index_is_set = 0;
7870
7871   /* Parse args required to build the message */
7872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7873     {
7874       if (unformat (i, "sw_if_index %d", &sw_if_index))
7875         sw_if_index_is_set = 1;
7876       else if (unformat (i, "bond %u", &bond_sw_if_index))
7877         bond_sw_if_index_is_set = 1;
7878       else if (unformat (i, "passive %d", &is_passive))
7879         ;
7880       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7881         ;
7882       else
7883         break;
7884     }
7885
7886   if (bond_sw_if_index_is_set == 0)
7887     {
7888       errmsg ("Missing bond sw_if_index. ");
7889       return -99;
7890     }
7891   if (sw_if_index_is_set == 0)
7892     {
7893       errmsg ("Missing slave sw_if_index. ");
7894       return -99;
7895     }
7896
7897   /* Construct the API message */
7898   M (BOND_ENSLAVE, mp);
7899
7900   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7901   mp->sw_if_index = ntohl (sw_if_index);
7902   mp->is_long_timeout = is_long_timeout;
7903   mp->is_passive = is_passive;
7904
7905   /* send it... */
7906   S (mp);
7907
7908   /* Wait for a reply... */
7909   W (ret);
7910   return ret;
7911 }
7912
7913 static int
7914 api_bond_detach_slave (vat_main_t * vam)
7915 {
7916   unformat_input_t *i = vam->input;
7917   vl_api_bond_detach_slave_t *mp;
7918   u32 sw_if_index = ~0;
7919   u8 sw_if_index_set = 0;
7920   int ret;
7921
7922   /* Parse args required to build the message */
7923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7924     {
7925       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7926         sw_if_index_set = 1;
7927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7928         sw_if_index_set = 1;
7929       else
7930         break;
7931     }
7932
7933   if (sw_if_index_set == 0)
7934     {
7935       errmsg ("missing vpp interface name. ");
7936       return -99;
7937     }
7938
7939   /* Construct the API message */
7940   M (BOND_DETACH_SLAVE, mp);
7941
7942   mp->sw_if_index = ntohl (sw_if_index);
7943
7944   /* send it... */
7945   S (mp);
7946
7947   /* Wait for a reply... */
7948   W (ret);
7949   return ret;
7950 }
7951
7952 static int
7953 api_ip_table_add_del (vat_main_t * vam)
7954 {
7955   unformat_input_t *i = vam->input;
7956   vl_api_ip_table_add_del_t *mp;
7957   u32 table_id = ~0;
7958   u8 is_ipv6 = 0;
7959   u8 is_add = 1;
7960   int ret = 0;
7961
7962   /* Parse args required to build the message */
7963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7964     {
7965       if (unformat (i, "ipv6"))
7966         is_ipv6 = 1;
7967       else if (unformat (i, "del"))
7968         is_add = 0;
7969       else if (unformat (i, "add"))
7970         is_add = 1;
7971       else if (unformat (i, "table %d", &table_id))
7972         ;
7973       else
7974         {
7975           clib_warning ("parse error '%U'", format_unformat_error, i);
7976           return -99;
7977         }
7978     }
7979
7980   if (~0 == table_id)
7981     {
7982       errmsg ("missing table-ID");
7983       return -99;
7984     }
7985
7986   /* Construct the API message */
7987   M (IP_TABLE_ADD_DEL, mp);
7988
7989   mp->table.table_id = ntohl (table_id);
7990   mp->table.is_ip6 = is_ipv6;
7991   mp->is_add = is_add;
7992
7993   /* send it... */
7994   S (mp);
7995
7996   /* Wait for a reply... */
7997   W (ret);
7998
7999   return ret;
8000 }
8001
8002 uword
8003 unformat_fib_path (unformat_input_t * input, va_list * args)
8004 {
8005   vat_main_t *vam = va_arg (*args, vat_main_t *);
8006   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8007   u32 weight, preference;
8008   mpls_label_t out_label;
8009
8010   clib_memset (path, 0, sizeof (*path));
8011   path->weight = 1;
8012   path->sw_if_index = ~0;
8013   path->rpf_id = ~0;
8014   path->n_labels = 0;
8015
8016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8017     {
8018       if (unformat (input, "%U %U",
8019                     unformat_vl_api_ip4_address,
8020                     &path->nh.address.ip4,
8021                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8022         {
8023           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8024         }
8025       else if (unformat (input, "%U %U",
8026                          unformat_vl_api_ip6_address,
8027                          &path->nh.address.ip6,
8028                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8029         {
8030           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8031         }
8032       else if (unformat (input, "weight %u", &weight))
8033         {
8034           path->weight = weight;
8035         }
8036       else if (unformat (input, "preference %u", &preference))
8037         {
8038           path->preference = preference;
8039         }
8040       else if (unformat (input, "%U next-hop-table %d",
8041                          unformat_vl_api_ip4_address,
8042                          &path->nh.address.ip4, &path->table_id))
8043         {
8044           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8045         }
8046       else if (unformat (input, "%U next-hop-table %d",
8047                          unformat_vl_api_ip6_address,
8048                          &path->nh.address.ip6, &path->table_id))
8049         {
8050           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8051         }
8052       else if (unformat (input, "%U",
8053                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8054         {
8055           /*
8056            * the recursive next-hops are by default in the default table
8057            */
8058           path->table_id = 0;
8059           path->sw_if_index = ~0;
8060           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8061         }
8062       else if (unformat (input, "%U",
8063                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8064         {
8065           /*
8066            * the recursive next-hops are by default in the default table
8067            */
8068           path->table_id = 0;
8069           path->sw_if_index = ~0;
8070           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8071         }
8072       else if (unformat (input, "resolve-via-host"))
8073         {
8074           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8075         }
8076       else if (unformat (input, "resolve-via-attached"))
8077         {
8078           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8079         }
8080       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8081         {
8082           path->type = FIB_API_PATH_TYPE_LOCAL;
8083           path->sw_if_index = ~0;
8084           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8085         }
8086       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8087         {
8088           path->type = FIB_API_PATH_TYPE_LOCAL;
8089           path->sw_if_index = ~0;
8090           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8091         }
8092       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8093         ;
8094       else if (unformat (input, "via-label %d", &path->nh.via_label))
8095         {
8096           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8097           path->sw_if_index = ~0;
8098         }
8099       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8100         {
8101           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8102           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8103         }
8104       else if (unformat (input, "local"))
8105         {
8106           path->type = FIB_API_PATH_TYPE_LOCAL;
8107         }
8108       else if (unformat (input, "out-labels"))
8109         {
8110           while (unformat (input, "%d", &out_label))
8111             {
8112               path->label_stack[path->n_labels].label = out_label;
8113               path->label_stack[path->n_labels].is_uniform = 0;
8114               path->label_stack[path->n_labels].ttl = 64;
8115               path->n_labels++;
8116             }
8117         }
8118       else if (unformat (input, "via"))
8119         {
8120           /* new path, back up and return */
8121           unformat_put_input (input);
8122           unformat_put_input (input);
8123           unformat_put_input (input);
8124           unformat_put_input (input);
8125           break;
8126         }
8127       else
8128         {
8129           return (0);
8130         }
8131     }
8132
8133   path->proto = ntohl (path->proto);
8134   path->type = ntohl (path->type);
8135   path->flags = ntohl (path->flags);
8136   path->table_id = ntohl (path->table_id);
8137   path->sw_if_index = ntohl (path->sw_if_index);
8138
8139   return (1);
8140 }
8141
8142 static int
8143 api_ip_route_add_del (vat_main_t * vam)
8144 {
8145   unformat_input_t *i = vam->input;
8146   vl_api_ip_route_add_del_t *mp;
8147   u32 vrf_id = 0;
8148   u8 is_add = 1;
8149   u8 is_multipath = 0;
8150   u8 prefix_set = 0;
8151   u8 path_count = 0;
8152   vl_api_prefix_t pfx = { };
8153   vl_api_fib_path_t paths[8];
8154   int count = 1;
8155   int j;
8156   f64 before = 0;
8157   u32 random_add_del = 0;
8158   u32 *random_vector = 0;
8159   u32 random_seed = 0xdeaddabe;
8160
8161   /* Parse args required to build the message */
8162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8163     {
8164       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8165         prefix_set = 1;
8166       else if (unformat (i, "del"))
8167         is_add = 0;
8168       else if (unformat (i, "add"))
8169         is_add = 1;
8170       else if (unformat (i, "vrf %d", &vrf_id))
8171         ;
8172       else if (unformat (i, "count %d", &count))
8173         ;
8174       else if (unformat (i, "random"))
8175         random_add_del = 1;
8176       else if (unformat (i, "multipath"))
8177         is_multipath = 1;
8178       else if (unformat (i, "seed %d", &random_seed))
8179         ;
8180       else
8181         if (unformat
8182             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8183         {
8184           path_count++;
8185           if (8 == path_count)
8186             {
8187               errmsg ("max 8 paths");
8188               return -99;
8189             }
8190         }
8191       else
8192         {
8193           clib_warning ("parse error '%U'", format_unformat_error, i);
8194           return -99;
8195         }
8196     }
8197
8198   if (!path_count)
8199     {
8200       errmsg ("specify a path; via ...");
8201       return -99;
8202     }
8203   if (prefix_set == 0)
8204     {
8205       errmsg ("missing prefix");
8206       return -99;
8207     }
8208
8209   /* Generate a pile of unique, random routes */
8210   if (random_add_del)
8211     {
8212       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8213       u32 this_random_address;
8214       uword *random_hash;
8215
8216       random_hash = hash_create (count, sizeof (uword));
8217
8218       hash_set (random_hash, i->as_u32, 1);
8219       for (j = 0; j <= count; j++)
8220         {
8221           do
8222             {
8223               this_random_address = random_u32 (&random_seed);
8224               this_random_address =
8225                 clib_host_to_net_u32 (this_random_address);
8226             }
8227           while (hash_get (random_hash, this_random_address));
8228           vec_add1 (random_vector, this_random_address);
8229           hash_set (random_hash, this_random_address, 1);
8230         }
8231       hash_free (random_hash);
8232       set_ip4_address (&pfx.address, random_vector[0]);
8233     }
8234
8235   if (count > 1)
8236     {
8237       /* Turn on async mode */
8238       vam->async_mode = 1;
8239       vam->async_errors = 0;
8240       before = vat_time_now (vam);
8241     }
8242
8243   for (j = 0; j < count; j++)
8244     {
8245       /* Construct the API message */
8246       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8247
8248       mp->is_add = is_add;
8249       mp->is_multipath = is_multipath;
8250
8251       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8252       mp->route.table_id = ntohl (vrf_id);
8253       mp->route.n_paths = path_count;
8254
8255       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8256
8257       if (random_add_del)
8258         set_ip4_address (&pfx.address, random_vector[j + 1]);
8259       else
8260         increment_address (&pfx.address);
8261       /* send it... */
8262       S (mp);
8263       /* If we receive SIGTERM, stop now... */
8264       if (vam->do_exit)
8265         break;
8266     }
8267
8268   /* When testing multiple add/del ops, use a control-ping to sync */
8269   if (count > 1)
8270     {
8271       vl_api_control_ping_t *mp_ping;
8272       f64 after;
8273       f64 timeout;
8274
8275       /* Shut off async mode */
8276       vam->async_mode = 0;
8277
8278       MPING (CONTROL_PING, mp_ping);
8279       S (mp_ping);
8280
8281       timeout = vat_time_now (vam) + 1.0;
8282       while (vat_time_now (vam) < timeout)
8283         if (vam->result_ready == 1)
8284           goto out;
8285       vam->retval = -99;
8286
8287     out:
8288       if (vam->retval == -99)
8289         errmsg ("timeout");
8290
8291       if (vam->async_errors > 0)
8292         {
8293           errmsg ("%d asynchronous errors", vam->async_errors);
8294           vam->retval = -98;
8295         }
8296       vam->async_errors = 0;
8297       after = vat_time_now (vam);
8298
8299       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8300       if (j > 0)
8301         count = j;
8302
8303       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8304              count, after - before, count / (after - before));
8305     }
8306   else
8307     {
8308       int ret;
8309
8310       /* Wait for a reply... */
8311       W (ret);
8312       return ret;
8313     }
8314
8315   /* Return the good/bad news */
8316   return (vam->retval);
8317 }
8318
8319 static int
8320 api_ip_mroute_add_del (vat_main_t * vam)
8321 {
8322   unformat_input_t *i = vam->input;
8323   u8 path_set = 0, prefix_set = 0, is_add = 1;
8324   vl_api_ip_mroute_add_del_t *mp;
8325   mfib_entry_flags_t eflags = 0;
8326   vl_api_mfib_path_t path;
8327   vl_api_mprefix_t pfx = { };
8328   u32 vrf_id = 0;
8329   int ret;
8330
8331   /* Parse args required to build the message */
8332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8333     {
8334       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8335         {
8336           prefix_set = 1;
8337           pfx.grp_address_length = htons (pfx.grp_address_length);
8338         }
8339       else if (unformat (i, "del"))
8340         is_add = 0;
8341       else if (unformat (i, "add"))
8342         is_add = 1;
8343       else if (unformat (i, "vrf %d", &vrf_id))
8344         ;
8345       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8346         path.itf_flags = htonl (path.itf_flags);
8347       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8348         ;
8349       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8350         path_set = 1;
8351       else
8352         {
8353           clib_warning ("parse error '%U'", format_unformat_error, i);
8354           return -99;
8355         }
8356     }
8357
8358   if (prefix_set == 0)
8359     {
8360       errmsg ("missing addresses\n");
8361       return -99;
8362     }
8363   if (path_set == 0)
8364     {
8365       errmsg ("missing path\n");
8366       return -99;
8367     }
8368
8369   /* Construct the API message */
8370   M (IP_MROUTE_ADD_DEL, mp);
8371
8372   mp->is_add = is_add;
8373   mp->is_multipath = 1;
8374
8375   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8376   mp->route.table_id = htonl (vrf_id);
8377   mp->route.n_paths = 1;
8378   mp->route.entry_flags = htonl (eflags);
8379
8380   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8381
8382   /* send it... */
8383   S (mp);
8384   /* Wait for a reply... */
8385   W (ret);
8386   return ret;
8387 }
8388
8389 static int
8390 api_mpls_table_add_del (vat_main_t * vam)
8391 {
8392   unformat_input_t *i = vam->input;
8393   vl_api_mpls_table_add_del_t *mp;
8394   u32 table_id = ~0;
8395   u8 is_add = 1;
8396   int ret = 0;
8397
8398   /* Parse args required to build the message */
8399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8400     {
8401       if (unformat (i, "table %d", &table_id))
8402         ;
8403       else if (unformat (i, "del"))
8404         is_add = 0;
8405       else if (unformat (i, "add"))
8406         is_add = 1;
8407       else
8408         {
8409           clib_warning ("parse error '%U'", format_unformat_error, i);
8410           return -99;
8411         }
8412     }
8413
8414   if (~0 == table_id)
8415     {
8416       errmsg ("missing table-ID");
8417       return -99;
8418     }
8419
8420   /* Construct the API message */
8421   M (MPLS_TABLE_ADD_DEL, mp);
8422
8423   mp->mt_table.mt_table_id = ntohl (table_id);
8424   mp->mt_is_add = is_add;
8425
8426   /* send it... */
8427   S (mp);
8428
8429   /* Wait for a reply... */
8430   W (ret);
8431
8432   return ret;
8433 }
8434
8435 static int
8436 api_mpls_route_add_del (vat_main_t * vam)
8437 {
8438   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8439   mpls_label_t local_label = MPLS_LABEL_INVALID;
8440   unformat_input_t *i = vam->input;
8441   vl_api_mpls_route_add_del_t *mp;
8442   vl_api_fib_path_t paths[8];
8443   int count = 1, j;
8444   f64 before = 0;
8445
8446   /* Parse args required to build the message */
8447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8448     {
8449       if (unformat (i, "%d", &local_label))
8450         ;
8451       else if (unformat (i, "eos"))
8452         is_eos = 1;
8453       else if (unformat (i, "non-eos"))
8454         is_eos = 0;
8455       else if (unformat (i, "del"))
8456         is_add = 0;
8457       else if (unformat (i, "add"))
8458         is_add = 1;
8459       else if (unformat (i, "multipath"))
8460         is_multipath = 1;
8461       else if (unformat (i, "count %d", &count))
8462         ;
8463       else
8464         if (unformat
8465             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8466         {
8467           path_count++;
8468           if (8 == path_count)
8469             {
8470               errmsg ("max 8 paths");
8471               return -99;
8472             }
8473         }
8474       else
8475         {
8476           clib_warning ("parse error '%U'", format_unformat_error, i);
8477           return -99;
8478         }
8479     }
8480
8481   if (!path_count)
8482     {
8483       errmsg ("specify a path; via ...");
8484       return -99;
8485     }
8486
8487   if (MPLS_LABEL_INVALID == local_label)
8488     {
8489       errmsg ("missing label");
8490       return -99;
8491     }
8492
8493   if (count > 1)
8494     {
8495       /* Turn on async mode */
8496       vam->async_mode = 1;
8497       vam->async_errors = 0;
8498       before = vat_time_now (vam);
8499     }
8500
8501   for (j = 0; j < count; j++)
8502     {
8503       /* Construct the API message */
8504       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8505
8506       mp->mr_is_add = is_add;
8507       mp->mr_is_multipath = is_multipath;
8508
8509       mp->mr_route.mr_label = local_label;
8510       mp->mr_route.mr_eos = is_eos;
8511       mp->mr_route.mr_table_id = 0;
8512       mp->mr_route.mr_n_paths = path_count;
8513
8514       clib_memcpy (&mp->mr_route.mr_paths, paths,
8515                    sizeof (paths[0]) * path_count);
8516
8517       local_label++;
8518
8519       /* send it... */
8520       S (mp);
8521       /* If we receive SIGTERM, stop now... */
8522       if (vam->do_exit)
8523         break;
8524     }
8525
8526   /* When testing multiple add/del ops, use a control-ping to sync */
8527   if (count > 1)
8528     {
8529       vl_api_control_ping_t *mp_ping;
8530       f64 after;
8531       f64 timeout;
8532
8533       /* Shut off async mode */
8534       vam->async_mode = 0;
8535
8536       MPING (CONTROL_PING, mp_ping);
8537       S (mp_ping);
8538
8539       timeout = vat_time_now (vam) + 1.0;
8540       while (vat_time_now (vam) < timeout)
8541         if (vam->result_ready == 1)
8542           goto out;
8543       vam->retval = -99;
8544
8545     out:
8546       if (vam->retval == -99)
8547         errmsg ("timeout");
8548
8549       if (vam->async_errors > 0)
8550         {
8551           errmsg ("%d asynchronous errors", vam->async_errors);
8552           vam->retval = -98;
8553         }
8554       vam->async_errors = 0;
8555       after = vat_time_now (vam);
8556
8557       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8558       if (j > 0)
8559         count = j;
8560
8561       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8562              count, after - before, count / (after - before));
8563     }
8564   else
8565     {
8566       int ret;
8567
8568       /* Wait for a reply... */
8569       W (ret);
8570       return ret;
8571     }
8572
8573   /* Return the good/bad news */
8574   return (vam->retval);
8575   return (0);
8576 }
8577
8578 static int
8579 api_mpls_ip_bind_unbind (vat_main_t * vam)
8580 {
8581   unformat_input_t *i = vam->input;
8582   vl_api_mpls_ip_bind_unbind_t *mp;
8583   u32 ip_table_id = 0;
8584   u8 is_bind = 1;
8585   vl_api_prefix_t pfx;
8586   u8 prefix_set = 0;
8587   mpls_label_t local_label = MPLS_LABEL_INVALID;
8588   int ret;
8589
8590   /* Parse args required to build the message */
8591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8592     {
8593       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8594         prefix_set = 1;
8595       else if (unformat (i, "%d", &local_label))
8596         ;
8597       else if (unformat (i, "table-id %d", &ip_table_id))
8598         ;
8599       else if (unformat (i, "unbind"))
8600         is_bind = 0;
8601       else if (unformat (i, "bind"))
8602         is_bind = 1;
8603       else
8604         {
8605           clib_warning ("parse error '%U'", format_unformat_error, i);
8606           return -99;
8607         }
8608     }
8609
8610   if (!prefix_set)
8611     {
8612       errmsg ("IP prefix not set");
8613       return -99;
8614     }
8615
8616   if (MPLS_LABEL_INVALID == local_label)
8617     {
8618       errmsg ("missing label");
8619       return -99;
8620     }
8621
8622   /* Construct the API message */
8623   M (MPLS_IP_BIND_UNBIND, mp);
8624
8625   mp->mb_is_bind = is_bind;
8626   mp->mb_ip_table_id = ntohl (ip_table_id);
8627   mp->mb_mpls_table_id = 0;
8628   mp->mb_label = ntohl (local_label);
8629   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8630
8631   /* send it... */
8632   S (mp);
8633
8634   /* Wait for a reply... */
8635   W (ret);
8636   return ret;
8637   return (0);
8638 }
8639
8640 static int
8641 api_sr_mpls_policy_add (vat_main_t * vam)
8642 {
8643   unformat_input_t *i = vam->input;
8644   vl_api_sr_mpls_policy_add_t *mp;
8645   u32 bsid = 0;
8646   u32 weight = 1;
8647   u8 type = 0;
8648   u8 n_segments = 0;
8649   u32 sid;
8650   u32 *segments = NULL;
8651   int ret;
8652
8653   /* Parse args required to build the message */
8654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8655     {
8656       if (unformat (i, "bsid %d", &bsid))
8657         ;
8658       else if (unformat (i, "weight %d", &weight))
8659         ;
8660       else if (unformat (i, "spray"))
8661         type = 1;
8662       else if (unformat (i, "next %d", &sid))
8663         {
8664           n_segments += 1;
8665           vec_add1 (segments, htonl (sid));
8666         }
8667       else
8668         {
8669           clib_warning ("parse error '%U'", format_unformat_error, i);
8670           return -99;
8671         }
8672     }
8673
8674   if (bsid == 0)
8675     {
8676       errmsg ("bsid not set");
8677       return -99;
8678     }
8679
8680   if (n_segments == 0)
8681     {
8682       errmsg ("no sid in segment stack");
8683       return -99;
8684     }
8685
8686   /* Construct the API message */
8687   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8688
8689   mp->bsid = htonl (bsid);
8690   mp->weight = htonl (weight);
8691   mp->type = type;
8692   mp->n_segments = n_segments;
8693   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8694   vec_free (segments);
8695
8696   /* send it... */
8697   S (mp);
8698
8699   /* Wait for a reply... */
8700   W (ret);
8701   return ret;
8702 }
8703
8704 static int
8705 api_sr_mpls_policy_del (vat_main_t * vam)
8706 {
8707   unformat_input_t *i = vam->input;
8708   vl_api_sr_mpls_policy_del_t *mp;
8709   u32 bsid = 0;
8710   int ret;
8711
8712   /* Parse args required to build the message */
8713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8714     {
8715       if (unformat (i, "bsid %d", &bsid))
8716         ;
8717       else
8718         {
8719           clib_warning ("parse error '%U'", format_unformat_error, i);
8720           return -99;
8721         }
8722     }
8723
8724   if (bsid == 0)
8725     {
8726       errmsg ("bsid not set");
8727       return -99;
8728     }
8729
8730   /* Construct the API message */
8731   M (SR_MPLS_POLICY_DEL, mp);
8732
8733   mp->bsid = htonl (bsid);
8734
8735   /* send it... */
8736   S (mp);
8737
8738   /* Wait for a reply... */
8739   W (ret);
8740   return ret;
8741 }
8742
8743 static int
8744 api_bier_table_add_del (vat_main_t * vam)
8745 {
8746   unformat_input_t *i = vam->input;
8747   vl_api_bier_table_add_del_t *mp;
8748   u8 is_add = 1;
8749   u32 set = 0, sub_domain = 0, hdr_len = 3;
8750   mpls_label_t local_label = MPLS_LABEL_INVALID;
8751   int ret;
8752
8753   /* Parse args required to build the message */
8754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8755     {
8756       if (unformat (i, "sub-domain %d", &sub_domain))
8757         ;
8758       else if (unformat (i, "set %d", &set))
8759         ;
8760       else if (unformat (i, "label %d", &local_label))
8761         ;
8762       else if (unformat (i, "hdr-len %d", &hdr_len))
8763         ;
8764       else if (unformat (i, "add"))
8765         is_add = 1;
8766       else if (unformat (i, "del"))
8767         is_add = 0;
8768       else
8769         {
8770           clib_warning ("parse error '%U'", format_unformat_error, i);
8771           return -99;
8772         }
8773     }
8774
8775   if (MPLS_LABEL_INVALID == local_label)
8776     {
8777       errmsg ("missing label\n");
8778       return -99;
8779     }
8780
8781   /* Construct the API message */
8782   M (BIER_TABLE_ADD_DEL, mp);
8783
8784   mp->bt_is_add = is_add;
8785   mp->bt_label = ntohl (local_label);
8786   mp->bt_tbl_id.bt_set = set;
8787   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8788   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8789
8790   /* send it... */
8791   S (mp);
8792
8793   /* Wait for a reply... */
8794   W (ret);
8795
8796   return (ret);
8797 }
8798
8799 static int
8800 api_bier_route_add_del (vat_main_t * vam)
8801 {
8802   unformat_input_t *i = vam->input;
8803   vl_api_bier_route_add_del_t *mp;
8804   u8 is_add = 1;
8805   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8806   ip4_address_t v4_next_hop_address;
8807   ip6_address_t v6_next_hop_address;
8808   u8 next_hop_set = 0;
8809   u8 next_hop_proto_is_ip4 = 1;
8810   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8811   int ret;
8812
8813   /* Parse args required to build the message */
8814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8815     {
8816       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8817         {
8818           next_hop_proto_is_ip4 = 1;
8819           next_hop_set = 1;
8820         }
8821       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8822         {
8823           next_hop_proto_is_ip4 = 0;
8824           next_hop_set = 1;
8825         }
8826       if (unformat (i, "sub-domain %d", &sub_domain))
8827         ;
8828       else if (unformat (i, "set %d", &set))
8829         ;
8830       else if (unformat (i, "hdr-len %d", &hdr_len))
8831         ;
8832       else if (unformat (i, "bp %d", &bp))
8833         ;
8834       else if (unformat (i, "add"))
8835         is_add = 1;
8836       else if (unformat (i, "del"))
8837         is_add = 0;
8838       else if (unformat (i, "out-label %d", &next_hop_out_label))
8839         ;
8840       else
8841         {
8842           clib_warning ("parse error '%U'", format_unformat_error, i);
8843           return -99;
8844         }
8845     }
8846
8847   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8848     {
8849       errmsg ("next hop / label set\n");
8850       return -99;
8851     }
8852   if (0 == bp)
8853     {
8854       errmsg ("bit=position not set\n");
8855       return -99;
8856     }
8857
8858   /* Construct the API message */
8859   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8860
8861   mp->br_is_add = is_add;
8862   mp->br_route.br_tbl_id.bt_set = set;
8863   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8864   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8865   mp->br_route.br_bp = ntohs (bp);
8866   mp->br_route.br_n_paths = 1;
8867   mp->br_route.br_paths[0].n_labels = 1;
8868   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8869   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8870                                     FIB_API_PATH_NH_PROTO_IP4 :
8871                                     FIB_API_PATH_NH_PROTO_IP6);
8872
8873   if (next_hop_proto_is_ip4)
8874     {
8875       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8876                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8877     }
8878   else
8879     {
8880       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8881                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8882     }
8883
8884   /* send it... */
8885   S (mp);
8886
8887   /* Wait for a reply... */
8888   W (ret);
8889
8890   return (ret);
8891 }
8892
8893 static int
8894 api_proxy_arp_add_del (vat_main_t * vam)
8895 {
8896   unformat_input_t *i = vam->input;
8897   vl_api_proxy_arp_add_del_t *mp;
8898   u32 vrf_id = 0;
8899   u8 is_add = 1;
8900   vl_api_ip4_address_t lo, hi;
8901   u8 range_set = 0;
8902   int ret;
8903
8904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8905     {
8906       if (unformat (i, "vrf %d", &vrf_id))
8907         ;
8908       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8909                          unformat_vl_api_ip4_address, &hi))
8910         range_set = 1;
8911       else if (unformat (i, "del"))
8912         is_add = 0;
8913       else
8914         {
8915           clib_warning ("parse error '%U'", format_unformat_error, i);
8916           return -99;
8917         }
8918     }
8919
8920   if (range_set == 0)
8921     {
8922       errmsg ("address range not set");
8923       return -99;
8924     }
8925
8926   M (PROXY_ARP_ADD_DEL, mp);
8927
8928   mp->proxy.table_id = ntohl (vrf_id);
8929   mp->is_add = is_add;
8930   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8931   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8932
8933   S (mp);
8934   W (ret);
8935   return ret;
8936 }
8937
8938 static int
8939 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8940 {
8941   unformat_input_t *i = vam->input;
8942   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8943   u32 sw_if_index;
8944   u8 enable = 1;
8945   u8 sw_if_index_set = 0;
8946   int ret;
8947
8948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8949     {
8950       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8951         sw_if_index_set = 1;
8952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8953         sw_if_index_set = 1;
8954       else if (unformat (i, "enable"))
8955         enable = 1;
8956       else if (unformat (i, "disable"))
8957         enable = 0;
8958       else
8959         {
8960           clib_warning ("parse error '%U'", format_unformat_error, i);
8961           return -99;
8962         }
8963     }
8964
8965   if (sw_if_index_set == 0)
8966     {
8967       errmsg ("missing interface name or sw_if_index");
8968       return -99;
8969     }
8970
8971   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8972
8973   mp->sw_if_index = ntohl (sw_if_index);
8974   mp->enable_disable = enable;
8975
8976   S (mp);
8977   W (ret);
8978   return ret;
8979 }
8980
8981 static int
8982 api_mpls_tunnel_add_del (vat_main_t * vam)
8983 {
8984   unformat_input_t *i = vam->input;
8985   vl_api_mpls_tunnel_add_del_t *mp;
8986
8987   vl_api_fib_path_t paths[8];
8988   u32 sw_if_index = ~0;
8989   u8 path_count = 0;
8990   u8 l2_only = 0;
8991   u8 is_add = 1;
8992   int ret;
8993
8994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8995     {
8996       if (unformat (i, "add"))
8997         is_add = 1;
8998       else
8999         if (unformat
9000             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9001         is_add = 0;
9002       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9003         is_add = 0;
9004       else if (unformat (i, "l2-only"))
9005         l2_only = 1;
9006       else
9007         if (unformat
9008             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9009         {
9010           path_count++;
9011           if (8 == path_count)
9012             {
9013               errmsg ("max 8 paths");
9014               return -99;
9015             }
9016         }
9017       else
9018         {
9019           clib_warning ("parse error '%U'", format_unformat_error, i);
9020           return -99;
9021         }
9022     }
9023
9024   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9025
9026   mp->mt_is_add = is_add;
9027   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9028   mp->mt_tunnel.mt_l2_only = l2_only;
9029   mp->mt_tunnel.mt_is_multicast = 0;
9030   mp->mt_tunnel.mt_n_paths = path_count;
9031
9032   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9033                sizeof (paths[0]) * path_count);
9034
9035   S (mp);
9036   W (ret);
9037   return ret;
9038 }
9039
9040 static int
9041 api_sw_interface_set_unnumbered (vat_main_t * vam)
9042 {
9043   unformat_input_t *i = vam->input;
9044   vl_api_sw_interface_set_unnumbered_t *mp;
9045   u32 sw_if_index;
9046   u32 unnum_sw_index = ~0;
9047   u8 is_add = 1;
9048   u8 sw_if_index_set = 0;
9049   int ret;
9050
9051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9052     {
9053       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9054         sw_if_index_set = 1;
9055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9056         sw_if_index_set = 1;
9057       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9058         ;
9059       else if (unformat (i, "del"))
9060         is_add = 0;
9061       else
9062         {
9063           clib_warning ("parse error '%U'", format_unformat_error, i);
9064           return -99;
9065         }
9066     }
9067
9068   if (sw_if_index_set == 0)
9069     {
9070       errmsg ("missing interface name or sw_if_index");
9071       return -99;
9072     }
9073
9074   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9075
9076   mp->sw_if_index = ntohl (sw_if_index);
9077   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9078   mp->is_add = is_add;
9079
9080   S (mp);
9081   W (ret);
9082   return ret;
9083 }
9084
9085 static int
9086 api_ip_neighbor_add_del (vat_main_t * vam)
9087 {
9088   vl_api_mac_address_t mac_address;
9089   unformat_input_t *i = vam->input;
9090   vl_api_ip_neighbor_add_del_t *mp;
9091   vl_api_address_t ip_address;
9092   u32 sw_if_index;
9093   u8 sw_if_index_set = 0;
9094   u8 is_add = 1;
9095   u8 mac_set = 0;
9096   u8 address_set = 0;
9097   int ret;
9098   ip_neighbor_flags_t flags;
9099
9100   flags = IP_NEIGHBOR_FLAG_NONE;
9101   clib_memset (&ip_address, 0, sizeof (ip_address));
9102   clib_memset (&mac_address, 0, sizeof (mac_address));
9103
9104   /* Parse args required to build the message */
9105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9106     {
9107       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9108         {
9109           mac_set = 1;
9110         }
9111       else if (unformat (i, "del"))
9112         is_add = 0;
9113       else
9114         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9115         sw_if_index_set = 1;
9116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9117         sw_if_index_set = 1;
9118       else if (unformat (i, "static"))
9119         flags |= IP_NEIGHBOR_FLAG_STATIC;
9120       else if (unformat (i, "no-fib-entry"))
9121         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9122       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9123         address_set = 1;
9124       else
9125         {
9126           clib_warning ("parse error '%U'", format_unformat_error, i);
9127           return -99;
9128         }
9129     }
9130
9131   if (sw_if_index_set == 0)
9132     {
9133       errmsg ("missing interface name or sw_if_index");
9134       return -99;
9135     }
9136   if (!address_set)
9137     {
9138       errmsg ("no address set");
9139       return -99;
9140     }
9141
9142   /* Construct the API message */
9143   M (IP_NEIGHBOR_ADD_DEL, mp);
9144
9145   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9146   mp->is_add = is_add;
9147   mp->neighbor.flags = htonl (flags);
9148   if (mac_set)
9149     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9150                  sizeof (mac_address));
9151   if (address_set)
9152     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9153
9154   /* send it... */
9155   S (mp);
9156
9157   /* Wait for a reply, return good/bad news  */
9158   W (ret);
9159   return ret;
9160 }
9161
9162 static int
9163 api_create_vlan_subif (vat_main_t * vam)
9164 {
9165   unformat_input_t *i = vam->input;
9166   vl_api_create_vlan_subif_t *mp;
9167   u32 sw_if_index;
9168   u8 sw_if_index_set = 0;
9169   u32 vlan_id;
9170   u8 vlan_id_set = 0;
9171   int ret;
9172
9173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9174     {
9175       if (unformat (i, "sw_if_index %d", &sw_if_index))
9176         sw_if_index_set = 1;
9177       else
9178         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9179         sw_if_index_set = 1;
9180       else if (unformat (i, "vlan %d", &vlan_id))
9181         vlan_id_set = 1;
9182       else
9183         {
9184           clib_warning ("parse error '%U'", format_unformat_error, i);
9185           return -99;
9186         }
9187     }
9188
9189   if (sw_if_index_set == 0)
9190     {
9191       errmsg ("missing interface name or sw_if_index");
9192       return -99;
9193     }
9194
9195   if (vlan_id_set == 0)
9196     {
9197       errmsg ("missing vlan_id");
9198       return -99;
9199     }
9200   M (CREATE_VLAN_SUBIF, mp);
9201
9202   mp->sw_if_index = ntohl (sw_if_index);
9203   mp->vlan_id = ntohl (vlan_id);
9204
9205   S (mp);
9206   W (ret);
9207   return ret;
9208 }
9209
9210 #define foreach_create_subif_bit                \
9211 _(no_tags)                                      \
9212 _(one_tag)                                      \
9213 _(two_tags)                                     \
9214 _(dot1ad)                                       \
9215 _(exact_match)                                  \
9216 _(default_sub)                                  \
9217 _(outer_vlan_id_any)                            \
9218 _(inner_vlan_id_any)
9219
9220 static int
9221 api_create_subif (vat_main_t * vam)
9222 {
9223   unformat_input_t *i = vam->input;
9224   vl_api_create_subif_t *mp;
9225   u32 sw_if_index;
9226   u8 sw_if_index_set = 0;
9227   u32 sub_id;
9228   u8 sub_id_set = 0;
9229   u32 no_tags = 0;
9230   u32 one_tag = 0;
9231   u32 two_tags = 0;
9232   u32 dot1ad = 0;
9233   u32 exact_match = 0;
9234   u32 default_sub = 0;
9235   u32 outer_vlan_id_any = 0;
9236   u32 inner_vlan_id_any = 0;
9237   u32 tmp;
9238   u16 outer_vlan_id = 0;
9239   u16 inner_vlan_id = 0;
9240   int ret;
9241
9242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9243     {
9244       if (unformat (i, "sw_if_index %d", &sw_if_index))
9245         sw_if_index_set = 1;
9246       else
9247         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9248         sw_if_index_set = 1;
9249       else if (unformat (i, "sub_id %d", &sub_id))
9250         sub_id_set = 1;
9251       else if (unformat (i, "outer_vlan_id %d", &tmp))
9252         outer_vlan_id = tmp;
9253       else if (unformat (i, "inner_vlan_id %d", &tmp))
9254         inner_vlan_id = tmp;
9255
9256 #define _(a) else if (unformat (i, #a)) a = 1 ;
9257       foreach_create_subif_bit
9258 #undef _
9259         else
9260         {
9261           clib_warning ("parse error '%U'", format_unformat_error, i);
9262           return -99;
9263         }
9264     }
9265
9266   if (sw_if_index_set == 0)
9267     {
9268       errmsg ("missing interface name or sw_if_index");
9269       return -99;
9270     }
9271
9272   if (sub_id_set == 0)
9273     {
9274       errmsg ("missing sub_id");
9275       return -99;
9276     }
9277   M (CREATE_SUBIF, mp);
9278
9279   mp->sw_if_index = ntohl (sw_if_index);
9280   mp->sub_id = ntohl (sub_id);
9281
9282 #define _(a) mp->a = a;
9283   foreach_create_subif_bit;
9284 #undef _
9285
9286   mp->outer_vlan_id = ntohs (outer_vlan_id);
9287   mp->inner_vlan_id = ntohs (inner_vlan_id);
9288
9289   S (mp);
9290   W (ret);
9291   return ret;
9292 }
9293
9294 static int
9295 api_reset_fib (vat_main_t * vam)
9296 {
9297   unformat_input_t *i = vam->input;
9298   vl_api_reset_fib_t *mp;
9299   u32 vrf_id = 0;
9300   u8 is_ipv6 = 0;
9301   u8 vrf_id_set = 0;
9302
9303   int ret;
9304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9305     {
9306       if (unformat (i, "vrf %d", &vrf_id))
9307         vrf_id_set = 1;
9308       else if (unformat (i, "ipv6"))
9309         is_ipv6 = 1;
9310       else
9311         {
9312           clib_warning ("parse error '%U'", format_unformat_error, i);
9313           return -99;
9314         }
9315     }
9316
9317   if (vrf_id_set == 0)
9318     {
9319       errmsg ("missing vrf id");
9320       return -99;
9321     }
9322
9323   M (RESET_FIB, mp);
9324
9325   mp->vrf_id = ntohl (vrf_id);
9326   mp->is_ipv6 = is_ipv6;
9327
9328   S (mp);
9329   W (ret);
9330   return ret;
9331 }
9332
9333 static int
9334 api_dhcp_proxy_config (vat_main_t * vam)
9335 {
9336   unformat_input_t *i = vam->input;
9337   vl_api_dhcp_proxy_config_t *mp;
9338   u32 rx_vrf_id = 0;
9339   u32 server_vrf_id = 0;
9340   u8 is_add = 1;
9341   u8 v4_address_set = 0;
9342   u8 v6_address_set = 0;
9343   ip4_address_t v4address;
9344   ip6_address_t v6address;
9345   u8 v4_src_address_set = 0;
9346   u8 v6_src_address_set = 0;
9347   ip4_address_t v4srcaddress;
9348   ip6_address_t v6srcaddress;
9349   int ret;
9350
9351   /* Parse args required to build the message */
9352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9353     {
9354       if (unformat (i, "del"))
9355         is_add = 0;
9356       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9357         ;
9358       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9359         ;
9360       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9361         v4_address_set = 1;
9362       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9363         v6_address_set = 1;
9364       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9365         v4_src_address_set = 1;
9366       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9367         v6_src_address_set = 1;
9368       else
9369         break;
9370     }
9371
9372   if (v4_address_set && v6_address_set)
9373     {
9374       errmsg ("both v4 and v6 server addresses set");
9375       return -99;
9376     }
9377   if (!v4_address_set && !v6_address_set)
9378     {
9379       errmsg ("no server addresses set");
9380       return -99;
9381     }
9382
9383   if (v4_src_address_set && v6_src_address_set)
9384     {
9385       errmsg ("both v4 and v6  src addresses set");
9386       return -99;
9387     }
9388   if (!v4_src_address_set && !v6_src_address_set)
9389     {
9390       errmsg ("no src addresses set");
9391       return -99;
9392     }
9393
9394   if (!(v4_src_address_set && v4_address_set) &&
9395       !(v6_src_address_set && v6_address_set))
9396     {
9397       errmsg ("no matching server and src addresses set");
9398       return -99;
9399     }
9400
9401   /* Construct the API message */
9402   M (DHCP_PROXY_CONFIG, mp);
9403
9404   mp->is_add = is_add;
9405   mp->rx_vrf_id = ntohl (rx_vrf_id);
9406   mp->server_vrf_id = ntohl (server_vrf_id);
9407   if (v6_address_set)
9408     {
9409       mp->is_ipv6 = 1;
9410       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9411       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9412     }
9413   else
9414     {
9415       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9416       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9417     }
9418
9419   /* send it... */
9420   S (mp);
9421
9422   /* Wait for a reply, return good/bad news  */
9423   W (ret);
9424   return ret;
9425 }
9426
9427 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9428 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9429
9430 static void
9431 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9432 {
9433   vat_main_t *vam = &vat_main;
9434   u32 i, count = mp->count;
9435   vl_api_dhcp_server_t *s;
9436
9437   if (mp->is_ipv6)
9438     print (vam->ofp,
9439            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9440            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9441            ntohl (mp->rx_vrf_id),
9442            format_ip6_address, mp->dhcp_src_address,
9443            mp->vss_type, mp->vss_vpn_ascii_id,
9444            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9445   else
9446     print (vam->ofp,
9447            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9448            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9449            ntohl (mp->rx_vrf_id),
9450            format_ip4_address, mp->dhcp_src_address,
9451            mp->vss_type, mp->vss_vpn_ascii_id,
9452            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9453
9454   for (i = 0; i < count; i++)
9455     {
9456       s = &mp->servers[i];
9457
9458       if (mp->is_ipv6)
9459         print (vam->ofp,
9460                " Server Table-ID %d, Server Address %U",
9461                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9462       else
9463         print (vam->ofp,
9464                " Server Table-ID %d, Server Address %U",
9465                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9466     }
9467 }
9468
9469 static void vl_api_dhcp_proxy_details_t_handler_json
9470   (vl_api_dhcp_proxy_details_t * mp)
9471 {
9472   vat_main_t *vam = &vat_main;
9473   vat_json_node_t *node = NULL;
9474   u32 i, count = mp->count;
9475   struct in_addr ip4;
9476   struct in6_addr ip6;
9477   vl_api_dhcp_server_t *s;
9478
9479   if (VAT_JSON_ARRAY != vam->json_tree.type)
9480     {
9481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9482       vat_json_init_array (&vam->json_tree);
9483     }
9484   node = vat_json_array_add (&vam->json_tree);
9485
9486   vat_json_init_object (node);
9487   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9488   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9489                              sizeof (mp->vss_type));
9490   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9491                                    mp->vss_vpn_ascii_id);
9492   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9493   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9494
9495   if (mp->is_ipv6)
9496     {
9497       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9498       vat_json_object_add_ip6 (node, "src_address", ip6);
9499     }
9500   else
9501     {
9502       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9503       vat_json_object_add_ip4 (node, "src_address", ip4);
9504     }
9505
9506   for (i = 0; i < count; i++)
9507     {
9508       s = &mp->servers[i];
9509
9510       vat_json_object_add_uint (node, "server-table-id",
9511                                 ntohl (s->server_vrf_id));
9512
9513       if (mp->is_ipv6)
9514         {
9515           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9516           vat_json_object_add_ip4 (node, "src_address", ip4);
9517         }
9518       else
9519         {
9520           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9521           vat_json_object_add_ip6 (node, "server_address", ip6);
9522         }
9523     }
9524 }
9525
9526 static int
9527 api_dhcp_proxy_dump (vat_main_t * vam)
9528 {
9529   unformat_input_t *i = vam->input;
9530   vl_api_control_ping_t *mp_ping;
9531   vl_api_dhcp_proxy_dump_t *mp;
9532   u8 is_ipv6 = 0;
9533   int ret;
9534
9535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9536     {
9537       if (unformat (i, "ipv6"))
9538         is_ipv6 = 1;
9539       else
9540         {
9541           clib_warning ("parse error '%U'", format_unformat_error, i);
9542           return -99;
9543         }
9544     }
9545
9546   M (DHCP_PROXY_DUMP, mp);
9547
9548   mp->is_ip6 = is_ipv6;
9549   S (mp);
9550
9551   /* Use a control ping for synchronization */
9552   MPING (CONTROL_PING, mp_ping);
9553   S (mp_ping);
9554
9555   W (ret);
9556   return ret;
9557 }
9558
9559 static int
9560 api_dhcp_proxy_set_vss (vat_main_t * vam)
9561 {
9562   unformat_input_t *i = vam->input;
9563   vl_api_dhcp_proxy_set_vss_t *mp;
9564   u8 is_ipv6 = 0;
9565   u8 is_add = 1;
9566   u32 tbl_id = ~0;
9567   u8 vss_type = VSS_TYPE_DEFAULT;
9568   u8 *vpn_ascii_id = 0;
9569   u32 oui = 0;
9570   u32 fib_id = 0;
9571   int ret;
9572
9573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9574     {
9575       if (unformat (i, "tbl_id %d", &tbl_id))
9576         ;
9577       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9578         vss_type = VSS_TYPE_ASCII;
9579       else if (unformat (i, "fib_id %d", &fib_id))
9580         vss_type = VSS_TYPE_VPN_ID;
9581       else if (unformat (i, "oui %d", &oui))
9582         vss_type = VSS_TYPE_VPN_ID;
9583       else if (unformat (i, "ipv6"))
9584         is_ipv6 = 1;
9585       else if (unformat (i, "del"))
9586         is_add = 0;
9587       else
9588         break;
9589     }
9590
9591   if (tbl_id == ~0)
9592     {
9593       errmsg ("missing tbl_id ");
9594       vec_free (vpn_ascii_id);
9595       return -99;
9596     }
9597
9598   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9599     {
9600       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9601       vec_free (vpn_ascii_id);
9602       return -99;
9603     }
9604
9605   M (DHCP_PROXY_SET_VSS, mp);
9606   mp->tbl_id = ntohl (tbl_id);
9607   mp->vss_type = vss_type;
9608   if (vpn_ascii_id)
9609     {
9610       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9611       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9612     }
9613   mp->vpn_index = ntohl (fib_id);
9614   mp->oui = ntohl (oui);
9615   mp->is_ipv6 = is_ipv6;
9616   mp->is_add = is_add;
9617
9618   S (mp);
9619   W (ret);
9620
9621   vec_free (vpn_ascii_id);
9622   return ret;
9623 }
9624
9625 static int
9626 api_dhcp_client_config (vat_main_t * vam)
9627 {
9628   unformat_input_t *i = vam->input;
9629   vl_api_dhcp_client_config_t *mp;
9630   u32 sw_if_index;
9631   u8 sw_if_index_set = 0;
9632   u8 is_add = 1;
9633   u8 *hostname = 0;
9634   u8 disable_event = 0;
9635   int ret;
9636
9637   /* Parse args required to build the message */
9638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9639     {
9640       if (unformat (i, "del"))
9641         is_add = 0;
9642       else
9643         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9644         sw_if_index_set = 1;
9645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9646         sw_if_index_set = 1;
9647       else if (unformat (i, "hostname %s", &hostname))
9648         ;
9649       else if (unformat (i, "disable_event"))
9650         disable_event = 1;
9651       else
9652         break;
9653     }
9654
9655   if (sw_if_index_set == 0)
9656     {
9657       errmsg ("missing interface name or sw_if_index");
9658       return -99;
9659     }
9660
9661   if (vec_len (hostname) > 63)
9662     {
9663       errmsg ("hostname too long");
9664     }
9665   vec_add1 (hostname, 0);
9666
9667   /* Construct the API message */
9668   M (DHCP_CLIENT_CONFIG, mp);
9669
9670   mp->is_add = is_add;
9671   mp->client.sw_if_index = htonl (sw_if_index);
9672   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9673   vec_free (hostname);
9674   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9675   mp->client.pid = htonl (getpid ());
9676
9677   /* send it... */
9678   S (mp);
9679
9680   /* Wait for a reply, return good/bad news  */
9681   W (ret);
9682   return ret;
9683 }
9684
9685 static int
9686 api_set_ip_flow_hash (vat_main_t * vam)
9687 {
9688   unformat_input_t *i = vam->input;
9689   vl_api_set_ip_flow_hash_t *mp;
9690   u32 vrf_id = 0;
9691   u8 is_ipv6 = 0;
9692   u8 vrf_id_set = 0;
9693   u8 src = 0;
9694   u8 dst = 0;
9695   u8 sport = 0;
9696   u8 dport = 0;
9697   u8 proto = 0;
9698   u8 reverse = 0;
9699   int ret;
9700
9701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9702     {
9703       if (unformat (i, "vrf %d", &vrf_id))
9704         vrf_id_set = 1;
9705       else if (unformat (i, "ipv6"))
9706         is_ipv6 = 1;
9707       else if (unformat (i, "src"))
9708         src = 1;
9709       else if (unformat (i, "dst"))
9710         dst = 1;
9711       else if (unformat (i, "sport"))
9712         sport = 1;
9713       else if (unformat (i, "dport"))
9714         dport = 1;
9715       else if (unformat (i, "proto"))
9716         proto = 1;
9717       else if (unformat (i, "reverse"))
9718         reverse = 1;
9719
9720       else
9721         {
9722           clib_warning ("parse error '%U'", format_unformat_error, i);
9723           return -99;
9724         }
9725     }
9726
9727   if (vrf_id_set == 0)
9728     {
9729       errmsg ("missing vrf id");
9730       return -99;
9731     }
9732
9733   M (SET_IP_FLOW_HASH, mp);
9734   mp->src = src;
9735   mp->dst = dst;
9736   mp->sport = sport;
9737   mp->dport = dport;
9738   mp->proto = proto;
9739   mp->reverse = reverse;
9740   mp->vrf_id = ntohl (vrf_id);
9741   mp->is_ipv6 = is_ipv6;
9742
9743   S (mp);
9744   W (ret);
9745   return ret;
9746 }
9747
9748 static int
9749 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9750 {
9751   unformat_input_t *i = vam->input;
9752   vl_api_sw_interface_ip6_enable_disable_t *mp;
9753   u32 sw_if_index;
9754   u8 sw_if_index_set = 0;
9755   u8 enable = 0;
9756   int ret;
9757
9758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9759     {
9760       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9761         sw_if_index_set = 1;
9762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9763         sw_if_index_set = 1;
9764       else if (unformat (i, "enable"))
9765         enable = 1;
9766       else if (unformat (i, "disable"))
9767         enable = 0;
9768       else
9769         {
9770           clib_warning ("parse error '%U'", format_unformat_error, i);
9771           return -99;
9772         }
9773     }
9774
9775   if (sw_if_index_set == 0)
9776     {
9777       errmsg ("missing interface name or sw_if_index");
9778       return -99;
9779     }
9780
9781   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9782
9783   mp->sw_if_index = ntohl (sw_if_index);
9784   mp->enable = enable;
9785
9786   S (mp);
9787   W (ret);
9788   return ret;
9789 }
9790
9791 static int
9792 api_ip6nd_proxy_add_del (vat_main_t * vam)
9793 {
9794   unformat_input_t *i = vam->input;
9795   vl_api_ip6nd_proxy_add_del_t *mp;
9796   u32 sw_if_index = ~0;
9797   u8 v6_address_set = 0;
9798   vl_api_ip6_address_t v6address;
9799   u8 is_del = 0;
9800   int ret;
9801
9802   /* Parse args required to build the message */
9803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9804     {
9805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9806         ;
9807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9808         ;
9809       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9810         v6_address_set = 1;
9811       if (unformat (i, "del"))
9812         is_del = 1;
9813       else
9814         {
9815           clib_warning ("parse error '%U'", format_unformat_error, i);
9816           return -99;
9817         }
9818     }
9819
9820   if (sw_if_index == ~0)
9821     {
9822       errmsg ("missing interface name or sw_if_index");
9823       return -99;
9824     }
9825   if (!v6_address_set)
9826     {
9827       errmsg ("no address set");
9828       return -99;
9829     }
9830
9831   /* Construct the API message */
9832   M (IP6ND_PROXY_ADD_DEL, mp);
9833
9834   mp->is_del = is_del;
9835   mp->sw_if_index = ntohl (sw_if_index);
9836   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9837
9838   /* send it... */
9839   S (mp);
9840
9841   /* Wait for a reply, return good/bad news  */
9842   W (ret);
9843   return ret;
9844 }
9845
9846 static int
9847 api_ip6nd_proxy_dump (vat_main_t * vam)
9848 {
9849   vl_api_ip6nd_proxy_dump_t *mp;
9850   vl_api_control_ping_t *mp_ping;
9851   int ret;
9852
9853   M (IP6ND_PROXY_DUMP, mp);
9854
9855   S (mp);
9856
9857   /* Use a control ping for synchronization */
9858   MPING (CONTROL_PING, mp_ping);
9859   S (mp_ping);
9860
9861   W (ret);
9862   return ret;
9863 }
9864
9865 static void vl_api_ip6nd_proxy_details_t_handler
9866   (vl_api_ip6nd_proxy_details_t * mp)
9867 {
9868   vat_main_t *vam = &vat_main;
9869
9870   print (vam->ofp, "host %U sw_if_index %d",
9871          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9872 }
9873
9874 static void vl_api_ip6nd_proxy_details_t_handler_json
9875   (vl_api_ip6nd_proxy_details_t * mp)
9876 {
9877   vat_main_t *vam = &vat_main;
9878   struct in6_addr ip6;
9879   vat_json_node_t *node = NULL;
9880
9881   if (VAT_JSON_ARRAY != vam->json_tree.type)
9882     {
9883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9884       vat_json_init_array (&vam->json_tree);
9885     }
9886   node = vat_json_array_add (&vam->json_tree);
9887
9888   vat_json_init_object (node);
9889   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9890
9891   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9892   vat_json_object_add_ip6 (node, "host", ip6);
9893 }
9894
9895 static int
9896 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9897 {
9898   unformat_input_t *i = vam->input;
9899   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9900   u32 sw_if_index;
9901   u8 sw_if_index_set = 0;
9902   u8 v6_address_set = 0;
9903   vl_api_prefix_t pfx;
9904   u8 use_default = 0;
9905   u8 no_advertise = 0;
9906   u8 off_link = 0;
9907   u8 no_autoconfig = 0;
9908   u8 no_onlink = 0;
9909   u8 is_no = 0;
9910   u32 val_lifetime = 0;
9911   u32 pref_lifetime = 0;
9912   int ret;
9913
9914   /* Parse args required to build the message */
9915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9916     {
9917       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9918         sw_if_index_set = 1;
9919       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9920         sw_if_index_set = 1;
9921       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9922         v6_address_set = 1;
9923       else if (unformat (i, "val_life %d", &val_lifetime))
9924         ;
9925       else if (unformat (i, "pref_life %d", &pref_lifetime))
9926         ;
9927       else if (unformat (i, "def"))
9928         use_default = 1;
9929       else if (unformat (i, "noadv"))
9930         no_advertise = 1;
9931       else if (unformat (i, "offl"))
9932         off_link = 1;
9933       else if (unformat (i, "noauto"))
9934         no_autoconfig = 1;
9935       else if (unformat (i, "nolink"))
9936         no_onlink = 1;
9937       else if (unformat (i, "isno"))
9938         is_no = 1;
9939       else
9940         {
9941           clib_warning ("parse error '%U'", format_unformat_error, i);
9942           return -99;
9943         }
9944     }
9945
9946   if (sw_if_index_set == 0)
9947     {
9948       errmsg ("missing interface name or sw_if_index");
9949       return -99;
9950     }
9951   if (!v6_address_set)
9952     {
9953       errmsg ("no address set");
9954       return -99;
9955     }
9956
9957   /* Construct the API message */
9958   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9959
9960   mp->sw_if_index = ntohl (sw_if_index);
9961   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9962   mp->use_default = use_default;
9963   mp->no_advertise = no_advertise;
9964   mp->off_link = off_link;
9965   mp->no_autoconfig = no_autoconfig;
9966   mp->no_onlink = no_onlink;
9967   mp->is_no = is_no;
9968   mp->val_lifetime = ntohl (val_lifetime);
9969   mp->pref_lifetime = ntohl (pref_lifetime);
9970
9971   /* send it... */
9972   S (mp);
9973
9974   /* Wait for a reply, return good/bad news  */
9975   W (ret);
9976   return ret;
9977 }
9978
9979 static int
9980 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9981 {
9982   unformat_input_t *i = vam->input;
9983   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9984   u32 sw_if_index;
9985   u8 sw_if_index_set = 0;
9986   u8 suppress = 0;
9987   u8 managed = 0;
9988   u8 other = 0;
9989   u8 ll_option = 0;
9990   u8 send_unicast = 0;
9991   u8 cease = 0;
9992   u8 is_no = 0;
9993   u8 default_router = 0;
9994   u32 max_interval = 0;
9995   u32 min_interval = 0;
9996   u32 lifetime = 0;
9997   u32 initial_count = 0;
9998   u32 initial_interval = 0;
9999   int ret;
10000
10001
10002   /* Parse args required to build the message */
10003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10004     {
10005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10006         sw_if_index_set = 1;
10007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10008         sw_if_index_set = 1;
10009       else if (unformat (i, "maxint %d", &max_interval))
10010         ;
10011       else if (unformat (i, "minint %d", &min_interval))
10012         ;
10013       else if (unformat (i, "life %d", &lifetime))
10014         ;
10015       else if (unformat (i, "count %d", &initial_count))
10016         ;
10017       else if (unformat (i, "interval %d", &initial_interval))
10018         ;
10019       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10020         suppress = 1;
10021       else if (unformat (i, "managed"))
10022         managed = 1;
10023       else if (unformat (i, "other"))
10024         other = 1;
10025       else if (unformat (i, "ll"))
10026         ll_option = 1;
10027       else if (unformat (i, "send"))
10028         send_unicast = 1;
10029       else if (unformat (i, "cease"))
10030         cease = 1;
10031       else if (unformat (i, "isno"))
10032         is_no = 1;
10033       else if (unformat (i, "def"))
10034         default_router = 1;
10035       else
10036         {
10037           clib_warning ("parse error '%U'", format_unformat_error, i);
10038           return -99;
10039         }
10040     }
10041
10042   if (sw_if_index_set == 0)
10043     {
10044       errmsg ("missing interface name or sw_if_index");
10045       return -99;
10046     }
10047
10048   /* Construct the API message */
10049   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10050
10051   mp->sw_if_index = ntohl (sw_if_index);
10052   mp->max_interval = ntohl (max_interval);
10053   mp->min_interval = ntohl (min_interval);
10054   mp->lifetime = ntohl (lifetime);
10055   mp->initial_count = ntohl (initial_count);
10056   mp->initial_interval = ntohl (initial_interval);
10057   mp->suppress = suppress;
10058   mp->managed = managed;
10059   mp->other = other;
10060   mp->ll_option = ll_option;
10061   mp->send_unicast = send_unicast;
10062   mp->cease = cease;
10063   mp->is_no = is_no;
10064   mp->default_router = default_router;
10065
10066   /* send it... */
10067   S (mp);
10068
10069   /* Wait for a reply, return good/bad news  */
10070   W (ret);
10071   return ret;
10072 }
10073
10074 static int
10075 api_set_arp_neighbor_limit (vat_main_t * vam)
10076 {
10077   unformat_input_t *i = vam->input;
10078   vl_api_set_arp_neighbor_limit_t *mp;
10079   u32 arp_nbr_limit;
10080   u8 limit_set = 0;
10081   u8 is_ipv6 = 0;
10082   int ret;
10083
10084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10085     {
10086       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10087         limit_set = 1;
10088       else if (unformat (i, "ipv6"))
10089         is_ipv6 = 1;
10090       else
10091         {
10092           clib_warning ("parse error '%U'", format_unformat_error, i);
10093           return -99;
10094         }
10095     }
10096
10097   if (limit_set == 0)
10098     {
10099       errmsg ("missing limit value");
10100       return -99;
10101     }
10102
10103   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10104
10105   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10106   mp->is_ipv6 = is_ipv6;
10107
10108   S (mp);
10109   W (ret);
10110   return ret;
10111 }
10112
10113 static int
10114 api_l2_patch_add_del (vat_main_t * vam)
10115 {
10116   unformat_input_t *i = vam->input;
10117   vl_api_l2_patch_add_del_t *mp;
10118   u32 rx_sw_if_index;
10119   u8 rx_sw_if_index_set = 0;
10120   u32 tx_sw_if_index;
10121   u8 tx_sw_if_index_set = 0;
10122   u8 is_add = 1;
10123   int ret;
10124
10125   /* Parse args required to build the message */
10126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10127     {
10128       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10129         rx_sw_if_index_set = 1;
10130       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10131         tx_sw_if_index_set = 1;
10132       else if (unformat (i, "rx"))
10133         {
10134           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10135             {
10136               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10137                             &rx_sw_if_index))
10138                 rx_sw_if_index_set = 1;
10139             }
10140           else
10141             break;
10142         }
10143       else if (unformat (i, "tx"))
10144         {
10145           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10146             {
10147               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10148                             &tx_sw_if_index))
10149                 tx_sw_if_index_set = 1;
10150             }
10151           else
10152             break;
10153         }
10154       else if (unformat (i, "del"))
10155         is_add = 0;
10156       else
10157         break;
10158     }
10159
10160   if (rx_sw_if_index_set == 0)
10161     {
10162       errmsg ("missing rx interface name or rx_sw_if_index");
10163       return -99;
10164     }
10165
10166   if (tx_sw_if_index_set == 0)
10167     {
10168       errmsg ("missing tx interface name or tx_sw_if_index");
10169       return -99;
10170     }
10171
10172   M (L2_PATCH_ADD_DEL, mp);
10173
10174   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10175   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10176   mp->is_add = is_add;
10177
10178   S (mp);
10179   W (ret);
10180   return ret;
10181 }
10182
10183 u8 is_del;
10184 u8 localsid_addr[16];
10185 u8 end_psp;
10186 u8 behavior;
10187 u32 sw_if_index;
10188 u32 vlan_index;
10189 u32 fib_table;
10190 u8 nh_addr[16];
10191
10192 static int
10193 api_sr_localsid_add_del (vat_main_t * vam)
10194 {
10195   unformat_input_t *i = vam->input;
10196   vl_api_sr_localsid_add_del_t *mp;
10197
10198   u8 is_del;
10199   ip6_address_t localsid;
10200   u8 end_psp = 0;
10201   u8 behavior = ~0;
10202   u32 sw_if_index;
10203   u32 fib_table = ~(u32) 0;
10204   ip6_address_t nh_addr6;
10205   ip4_address_t nh_addr4;
10206   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10207   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10208
10209   bool nexthop_set = 0;
10210
10211   int ret;
10212
10213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10214     {
10215       if (unformat (i, "del"))
10216         is_del = 1;
10217       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10218       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10219         nexthop_set = 1;
10220       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10221         nexthop_set = 1;
10222       else if (unformat (i, "behavior %u", &behavior));
10223       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10224       else if (unformat (i, "fib-table %u", &fib_table));
10225       else if (unformat (i, "end.psp %u", &behavior));
10226       else
10227         break;
10228     }
10229
10230   M (SR_LOCALSID_ADD_DEL, mp);
10231
10232   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10233   if (nexthop_set)
10234     {
10235       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10236       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10237     }
10238   mp->behavior = behavior;
10239   mp->sw_if_index = ntohl (sw_if_index);
10240   mp->fib_table = ntohl (fib_table);
10241   mp->end_psp = end_psp;
10242   mp->is_del = is_del;
10243
10244   S (mp);
10245   W (ret);
10246   return ret;
10247 }
10248
10249 static int
10250 api_ioam_enable (vat_main_t * vam)
10251 {
10252   unformat_input_t *input = vam->input;
10253   vl_api_ioam_enable_t *mp;
10254   u32 id = 0;
10255   int has_trace_option = 0;
10256   int has_pot_option = 0;
10257   int has_seqno_option = 0;
10258   int has_analyse_option = 0;
10259   int ret;
10260
10261   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10262     {
10263       if (unformat (input, "trace"))
10264         has_trace_option = 1;
10265       else if (unformat (input, "pot"))
10266         has_pot_option = 1;
10267       else if (unformat (input, "seqno"))
10268         has_seqno_option = 1;
10269       else if (unformat (input, "analyse"))
10270         has_analyse_option = 1;
10271       else
10272         break;
10273     }
10274   M (IOAM_ENABLE, mp);
10275   mp->id = htons (id);
10276   mp->seqno = has_seqno_option;
10277   mp->analyse = has_analyse_option;
10278   mp->pot_enable = has_pot_option;
10279   mp->trace_enable = has_trace_option;
10280
10281   S (mp);
10282   W (ret);
10283   return ret;
10284 }
10285
10286
10287 static int
10288 api_ioam_disable (vat_main_t * vam)
10289 {
10290   vl_api_ioam_disable_t *mp;
10291   int ret;
10292
10293   M (IOAM_DISABLE, mp);
10294   S (mp);
10295   W (ret);
10296   return ret;
10297 }
10298
10299 #define foreach_tcp_proto_field                 \
10300 _(src_port)                                     \
10301 _(dst_port)
10302
10303 #define foreach_udp_proto_field                 \
10304 _(src_port)                                     \
10305 _(dst_port)
10306
10307 #define foreach_ip4_proto_field                 \
10308 _(src_address)                                  \
10309 _(dst_address)                                  \
10310 _(tos)                                          \
10311 _(length)                                       \
10312 _(fragment_id)                                  \
10313 _(ttl)                                          \
10314 _(protocol)                                     \
10315 _(checksum)
10316
10317 typedef struct
10318 {
10319   u16 src_port, dst_port;
10320 } tcpudp_header_t;
10321
10322 #if VPP_API_TEST_BUILTIN == 0
10323 uword
10324 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10325 {
10326   u8 **maskp = va_arg (*args, u8 **);
10327   u8 *mask = 0;
10328   u8 found_something = 0;
10329   tcp_header_t *tcp;
10330
10331 #define _(a) u8 a=0;
10332   foreach_tcp_proto_field;
10333 #undef _
10334
10335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10336     {
10337       if (0);
10338 #define _(a) else if (unformat (input, #a)) a=1;
10339       foreach_tcp_proto_field
10340 #undef _
10341         else
10342         break;
10343     }
10344
10345 #define _(a) found_something += a;
10346   foreach_tcp_proto_field;
10347 #undef _
10348
10349   if (found_something == 0)
10350     return 0;
10351
10352   vec_validate (mask, sizeof (*tcp) - 1);
10353
10354   tcp = (tcp_header_t *) mask;
10355
10356 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10357   foreach_tcp_proto_field;
10358 #undef _
10359
10360   *maskp = mask;
10361   return 1;
10362 }
10363
10364 uword
10365 unformat_udp_mask (unformat_input_t * input, va_list * args)
10366 {
10367   u8 **maskp = va_arg (*args, u8 **);
10368   u8 *mask = 0;
10369   u8 found_something = 0;
10370   udp_header_t *udp;
10371
10372 #define _(a) u8 a=0;
10373   foreach_udp_proto_field;
10374 #undef _
10375
10376   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10377     {
10378       if (0);
10379 #define _(a) else if (unformat (input, #a)) a=1;
10380       foreach_udp_proto_field
10381 #undef _
10382         else
10383         break;
10384     }
10385
10386 #define _(a) found_something += a;
10387   foreach_udp_proto_field;
10388 #undef _
10389
10390   if (found_something == 0)
10391     return 0;
10392
10393   vec_validate (mask, sizeof (*udp) - 1);
10394
10395   udp = (udp_header_t *) mask;
10396
10397 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10398   foreach_udp_proto_field;
10399 #undef _
10400
10401   *maskp = mask;
10402   return 1;
10403 }
10404
10405 uword
10406 unformat_l4_mask (unformat_input_t * input, va_list * args)
10407 {
10408   u8 **maskp = va_arg (*args, u8 **);
10409   u16 src_port = 0, dst_port = 0;
10410   tcpudp_header_t *tcpudp;
10411
10412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10413     {
10414       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10415         return 1;
10416       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10417         return 1;
10418       else if (unformat (input, "src_port"))
10419         src_port = 0xFFFF;
10420       else if (unformat (input, "dst_port"))
10421         dst_port = 0xFFFF;
10422       else
10423         return 0;
10424     }
10425
10426   if (!src_port && !dst_port)
10427     return 0;
10428
10429   u8 *mask = 0;
10430   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10431
10432   tcpudp = (tcpudp_header_t *) mask;
10433   tcpudp->src_port = src_port;
10434   tcpudp->dst_port = dst_port;
10435
10436   *maskp = mask;
10437
10438   return 1;
10439 }
10440
10441 uword
10442 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10443 {
10444   u8 **maskp = va_arg (*args, u8 **);
10445   u8 *mask = 0;
10446   u8 found_something = 0;
10447   ip4_header_t *ip;
10448
10449 #define _(a) u8 a=0;
10450   foreach_ip4_proto_field;
10451 #undef _
10452   u8 version = 0;
10453   u8 hdr_length = 0;
10454
10455
10456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10457     {
10458       if (unformat (input, "version"))
10459         version = 1;
10460       else if (unformat (input, "hdr_length"))
10461         hdr_length = 1;
10462       else if (unformat (input, "src"))
10463         src_address = 1;
10464       else if (unformat (input, "dst"))
10465         dst_address = 1;
10466       else if (unformat (input, "proto"))
10467         protocol = 1;
10468
10469 #define _(a) else if (unformat (input, #a)) a=1;
10470       foreach_ip4_proto_field
10471 #undef _
10472         else
10473         break;
10474     }
10475
10476 #define _(a) found_something += a;
10477   foreach_ip4_proto_field;
10478 #undef _
10479
10480   if (found_something == 0)
10481     return 0;
10482
10483   vec_validate (mask, sizeof (*ip) - 1);
10484
10485   ip = (ip4_header_t *) mask;
10486
10487 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10488   foreach_ip4_proto_field;
10489 #undef _
10490
10491   ip->ip_version_and_header_length = 0;
10492
10493   if (version)
10494     ip->ip_version_and_header_length |= 0xF0;
10495
10496   if (hdr_length)
10497     ip->ip_version_and_header_length |= 0x0F;
10498
10499   *maskp = mask;
10500   return 1;
10501 }
10502
10503 #define foreach_ip6_proto_field                 \
10504 _(src_address)                                  \
10505 _(dst_address)                                  \
10506 _(payload_length)                               \
10507 _(hop_limit)                                    \
10508 _(protocol)
10509
10510 uword
10511 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10512 {
10513   u8 **maskp = va_arg (*args, u8 **);
10514   u8 *mask = 0;
10515   u8 found_something = 0;
10516   ip6_header_t *ip;
10517   u32 ip_version_traffic_class_and_flow_label;
10518
10519 #define _(a) u8 a=0;
10520   foreach_ip6_proto_field;
10521 #undef _
10522   u8 version = 0;
10523   u8 traffic_class = 0;
10524   u8 flow_label = 0;
10525
10526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10527     {
10528       if (unformat (input, "version"))
10529         version = 1;
10530       else if (unformat (input, "traffic-class"))
10531         traffic_class = 1;
10532       else if (unformat (input, "flow-label"))
10533         flow_label = 1;
10534       else if (unformat (input, "src"))
10535         src_address = 1;
10536       else if (unformat (input, "dst"))
10537         dst_address = 1;
10538       else if (unformat (input, "proto"))
10539         protocol = 1;
10540
10541 #define _(a) else if (unformat (input, #a)) a=1;
10542       foreach_ip6_proto_field
10543 #undef _
10544         else
10545         break;
10546     }
10547
10548 #define _(a) found_something += a;
10549   foreach_ip6_proto_field;
10550 #undef _
10551
10552   if (found_something == 0)
10553     return 0;
10554
10555   vec_validate (mask, sizeof (*ip) - 1);
10556
10557   ip = (ip6_header_t *) mask;
10558
10559 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10560   foreach_ip6_proto_field;
10561 #undef _
10562
10563   ip_version_traffic_class_and_flow_label = 0;
10564
10565   if (version)
10566     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10567
10568   if (traffic_class)
10569     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10570
10571   if (flow_label)
10572     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10573
10574   ip->ip_version_traffic_class_and_flow_label =
10575     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10576
10577   *maskp = mask;
10578   return 1;
10579 }
10580
10581 uword
10582 unformat_l3_mask (unformat_input_t * input, va_list * args)
10583 {
10584   u8 **maskp = va_arg (*args, u8 **);
10585
10586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10587     {
10588       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10589         return 1;
10590       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10591         return 1;
10592       else
10593         break;
10594     }
10595   return 0;
10596 }
10597
10598 uword
10599 unformat_l2_mask (unformat_input_t * input, va_list * args)
10600 {
10601   u8 **maskp = va_arg (*args, u8 **);
10602   u8 *mask = 0;
10603   u8 src = 0;
10604   u8 dst = 0;
10605   u8 proto = 0;
10606   u8 tag1 = 0;
10607   u8 tag2 = 0;
10608   u8 ignore_tag1 = 0;
10609   u8 ignore_tag2 = 0;
10610   u8 cos1 = 0;
10611   u8 cos2 = 0;
10612   u8 dot1q = 0;
10613   u8 dot1ad = 0;
10614   int len = 14;
10615
10616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10617     {
10618       if (unformat (input, "src"))
10619         src = 1;
10620       else if (unformat (input, "dst"))
10621         dst = 1;
10622       else if (unformat (input, "proto"))
10623         proto = 1;
10624       else if (unformat (input, "tag1"))
10625         tag1 = 1;
10626       else if (unformat (input, "tag2"))
10627         tag2 = 1;
10628       else if (unformat (input, "ignore-tag1"))
10629         ignore_tag1 = 1;
10630       else if (unformat (input, "ignore-tag2"))
10631         ignore_tag2 = 1;
10632       else if (unformat (input, "cos1"))
10633         cos1 = 1;
10634       else if (unformat (input, "cos2"))
10635         cos2 = 1;
10636       else if (unformat (input, "dot1q"))
10637         dot1q = 1;
10638       else if (unformat (input, "dot1ad"))
10639         dot1ad = 1;
10640       else
10641         break;
10642     }
10643   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10644        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10645     return 0;
10646
10647   if (tag1 || ignore_tag1 || cos1 || dot1q)
10648     len = 18;
10649   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10650     len = 22;
10651
10652   vec_validate (mask, len - 1);
10653
10654   if (dst)
10655     clib_memset (mask, 0xff, 6);
10656
10657   if (src)
10658     clib_memset (mask + 6, 0xff, 6);
10659
10660   if (tag2 || dot1ad)
10661     {
10662       /* inner vlan tag */
10663       if (tag2)
10664         {
10665           mask[19] = 0xff;
10666           mask[18] = 0x0f;
10667         }
10668       if (cos2)
10669         mask[18] |= 0xe0;
10670       if (proto)
10671         mask[21] = mask[20] = 0xff;
10672       if (tag1)
10673         {
10674           mask[15] = 0xff;
10675           mask[14] = 0x0f;
10676         }
10677       if (cos1)
10678         mask[14] |= 0xe0;
10679       *maskp = mask;
10680       return 1;
10681     }
10682   if (tag1 | dot1q)
10683     {
10684       if (tag1)
10685         {
10686           mask[15] = 0xff;
10687           mask[14] = 0x0f;
10688         }
10689       if (cos1)
10690         mask[14] |= 0xe0;
10691       if (proto)
10692         mask[16] = mask[17] = 0xff;
10693
10694       *maskp = mask;
10695       return 1;
10696     }
10697   if (cos2)
10698     mask[18] |= 0xe0;
10699   if (cos1)
10700     mask[14] |= 0xe0;
10701   if (proto)
10702     mask[12] = mask[13] = 0xff;
10703
10704   *maskp = mask;
10705   return 1;
10706 }
10707
10708 uword
10709 unformat_classify_mask (unformat_input_t * input, va_list * args)
10710 {
10711   u8 **maskp = va_arg (*args, u8 **);
10712   u32 *skipp = va_arg (*args, u32 *);
10713   u32 *matchp = va_arg (*args, u32 *);
10714   u32 match;
10715   u8 *mask = 0;
10716   u8 *l2 = 0;
10717   u8 *l3 = 0;
10718   u8 *l4 = 0;
10719   int i;
10720
10721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10724         ;
10725       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10726         ;
10727       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10728         ;
10729       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10730         ;
10731       else
10732         break;
10733     }
10734
10735   if (l4 && !l3)
10736     {
10737       vec_free (mask);
10738       vec_free (l2);
10739       vec_free (l4);
10740       return 0;
10741     }
10742
10743   if (mask || l2 || l3 || l4)
10744     {
10745       if (l2 || l3 || l4)
10746         {
10747           /* "With a free Ethernet header in every package" */
10748           if (l2 == 0)
10749             vec_validate (l2, 13);
10750           mask = l2;
10751           if (vec_len (l3))
10752             {
10753               vec_append (mask, l3);
10754               vec_free (l3);
10755             }
10756           if (vec_len (l4))
10757             {
10758               vec_append (mask, l4);
10759               vec_free (l4);
10760             }
10761         }
10762
10763       /* Scan forward looking for the first significant mask octet */
10764       for (i = 0; i < vec_len (mask); i++)
10765         if (mask[i])
10766           break;
10767
10768       /* compute (skip, match) params */
10769       *skipp = i / sizeof (u32x4);
10770       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10771
10772       /* Pad mask to an even multiple of the vector size */
10773       while (vec_len (mask) % sizeof (u32x4))
10774         vec_add1 (mask, 0);
10775
10776       match = vec_len (mask) / sizeof (u32x4);
10777
10778       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10779         {
10780           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10781           if (*tmp || *(tmp + 1))
10782             break;
10783           match--;
10784         }
10785       if (match == 0)
10786         clib_warning ("BUG: match 0");
10787
10788       _vec_len (mask) = match * sizeof (u32x4);
10789
10790       *matchp = match;
10791       *maskp = mask;
10792
10793       return 1;
10794     }
10795
10796   return 0;
10797 }
10798 #endif /* VPP_API_TEST_BUILTIN */
10799
10800 #define foreach_l2_next                         \
10801 _(drop, DROP)                                   \
10802 _(ethernet, ETHERNET_INPUT)                     \
10803 _(ip4, IP4_INPUT)                               \
10804 _(ip6, IP6_INPUT)
10805
10806 uword
10807 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10808 {
10809   u32 *miss_next_indexp = va_arg (*args, u32 *);
10810   u32 next_index = 0;
10811   u32 tmp;
10812
10813 #define _(n,N) \
10814   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10815   foreach_l2_next;
10816 #undef _
10817
10818   if (unformat (input, "%d", &tmp))
10819     {
10820       next_index = tmp;
10821       goto out;
10822     }
10823
10824   return 0;
10825
10826 out:
10827   *miss_next_indexp = next_index;
10828   return 1;
10829 }
10830
10831 #define foreach_ip_next                         \
10832 _(drop, DROP)                                   \
10833 _(local, LOCAL)                                 \
10834 _(rewrite, REWRITE)
10835
10836 uword
10837 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10838 {
10839   u32 *miss_next_indexp = va_arg (*args, u32 *);
10840   u32 next_index = 0;
10841   u32 tmp;
10842
10843 #define _(n,N) \
10844   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10845   foreach_ip_next;
10846 #undef _
10847
10848   if (unformat (input, "%d", &tmp))
10849     {
10850       next_index = tmp;
10851       goto out;
10852     }
10853
10854   return 0;
10855
10856 out:
10857   *miss_next_indexp = next_index;
10858   return 1;
10859 }
10860
10861 #define foreach_acl_next                        \
10862 _(deny, DENY)
10863
10864 uword
10865 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10866 {
10867   u32 *miss_next_indexp = va_arg (*args, u32 *);
10868   u32 next_index = 0;
10869   u32 tmp;
10870
10871 #define _(n,N) \
10872   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10873   foreach_acl_next;
10874 #undef _
10875
10876   if (unformat (input, "permit"))
10877     {
10878       next_index = ~0;
10879       goto out;
10880     }
10881   else if (unformat (input, "%d", &tmp))
10882     {
10883       next_index = tmp;
10884       goto out;
10885     }
10886
10887   return 0;
10888
10889 out:
10890   *miss_next_indexp = next_index;
10891   return 1;
10892 }
10893
10894 uword
10895 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10896 {
10897   u32 *r = va_arg (*args, u32 *);
10898
10899   if (unformat (input, "conform-color"))
10900     *r = POLICE_CONFORM;
10901   else if (unformat (input, "exceed-color"))
10902     *r = POLICE_EXCEED;
10903   else
10904     return 0;
10905
10906   return 1;
10907 }
10908
10909 static int
10910 api_classify_add_del_table (vat_main_t * vam)
10911 {
10912   unformat_input_t *i = vam->input;
10913   vl_api_classify_add_del_table_t *mp;
10914
10915   u32 nbuckets = 2;
10916   u32 skip = ~0;
10917   u32 match = ~0;
10918   int is_add = 1;
10919   int del_chain = 0;
10920   u32 table_index = ~0;
10921   u32 next_table_index = ~0;
10922   u32 miss_next_index = ~0;
10923   u32 memory_size = 32 << 20;
10924   u8 *mask = 0;
10925   u32 current_data_flag = 0;
10926   int current_data_offset = 0;
10927   int ret;
10928
10929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10930     {
10931       if (unformat (i, "del"))
10932         is_add = 0;
10933       else if (unformat (i, "del-chain"))
10934         {
10935           is_add = 0;
10936           del_chain = 1;
10937         }
10938       else if (unformat (i, "buckets %d", &nbuckets))
10939         ;
10940       else if (unformat (i, "memory_size %d", &memory_size))
10941         ;
10942       else if (unformat (i, "skip %d", &skip))
10943         ;
10944       else if (unformat (i, "match %d", &match))
10945         ;
10946       else if (unformat (i, "table %d", &table_index))
10947         ;
10948       else if (unformat (i, "mask %U", unformat_classify_mask,
10949                          &mask, &skip, &match))
10950         ;
10951       else if (unformat (i, "next-table %d", &next_table_index))
10952         ;
10953       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10954                          &miss_next_index))
10955         ;
10956       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10957                          &miss_next_index))
10958         ;
10959       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10960                          &miss_next_index))
10961         ;
10962       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10963         ;
10964       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10965         ;
10966       else
10967         break;
10968     }
10969
10970   if (is_add && mask == 0)
10971     {
10972       errmsg ("Mask required");
10973       return -99;
10974     }
10975
10976   if (is_add && skip == ~0)
10977     {
10978       errmsg ("skip count required");
10979       return -99;
10980     }
10981
10982   if (is_add && match == ~0)
10983     {
10984       errmsg ("match count required");
10985       return -99;
10986     }
10987
10988   if (!is_add && table_index == ~0)
10989     {
10990       errmsg ("table index required for delete");
10991       return -99;
10992     }
10993
10994   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10995
10996   mp->is_add = is_add;
10997   mp->del_chain = del_chain;
10998   mp->table_index = ntohl (table_index);
10999   mp->nbuckets = ntohl (nbuckets);
11000   mp->memory_size = ntohl (memory_size);
11001   mp->skip_n_vectors = ntohl (skip);
11002   mp->match_n_vectors = ntohl (match);
11003   mp->next_table_index = ntohl (next_table_index);
11004   mp->miss_next_index = ntohl (miss_next_index);
11005   mp->current_data_flag = ntohl (current_data_flag);
11006   mp->current_data_offset = ntohl (current_data_offset);
11007   mp->mask_len = ntohl (vec_len (mask));
11008   clib_memcpy (mp->mask, mask, vec_len (mask));
11009
11010   vec_free (mask);
11011
11012   S (mp);
11013   W (ret);
11014   return ret;
11015 }
11016
11017 #if VPP_API_TEST_BUILTIN == 0
11018 uword
11019 unformat_l4_match (unformat_input_t * input, va_list * args)
11020 {
11021   u8 **matchp = va_arg (*args, u8 **);
11022
11023   u8 *proto_header = 0;
11024   int src_port = 0;
11025   int dst_port = 0;
11026
11027   tcpudp_header_t h;
11028
11029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11030     {
11031       if (unformat (input, "src_port %d", &src_port))
11032         ;
11033       else if (unformat (input, "dst_port %d", &dst_port))
11034         ;
11035       else
11036         return 0;
11037     }
11038
11039   h.src_port = clib_host_to_net_u16 (src_port);
11040   h.dst_port = clib_host_to_net_u16 (dst_port);
11041   vec_validate (proto_header, sizeof (h) - 1);
11042   memcpy (proto_header, &h, sizeof (h));
11043
11044   *matchp = proto_header;
11045
11046   return 1;
11047 }
11048
11049 uword
11050 unformat_ip4_match (unformat_input_t * input, va_list * args)
11051 {
11052   u8 **matchp = va_arg (*args, u8 **);
11053   u8 *match = 0;
11054   ip4_header_t *ip;
11055   int version = 0;
11056   u32 version_val;
11057   int hdr_length = 0;
11058   u32 hdr_length_val;
11059   int src = 0, dst = 0;
11060   ip4_address_t src_val, dst_val;
11061   int proto = 0;
11062   u32 proto_val;
11063   int tos = 0;
11064   u32 tos_val;
11065   int length = 0;
11066   u32 length_val;
11067   int fragment_id = 0;
11068   u32 fragment_id_val;
11069   int ttl = 0;
11070   int ttl_val;
11071   int checksum = 0;
11072   u32 checksum_val;
11073
11074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11075     {
11076       if (unformat (input, "version %d", &version_val))
11077         version = 1;
11078       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11079         hdr_length = 1;
11080       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11081         src = 1;
11082       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11083         dst = 1;
11084       else if (unformat (input, "proto %d", &proto_val))
11085         proto = 1;
11086       else if (unformat (input, "tos %d", &tos_val))
11087         tos = 1;
11088       else if (unformat (input, "length %d", &length_val))
11089         length = 1;
11090       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11091         fragment_id = 1;
11092       else if (unformat (input, "ttl %d", &ttl_val))
11093         ttl = 1;
11094       else if (unformat (input, "checksum %d", &checksum_val))
11095         checksum = 1;
11096       else
11097         break;
11098     }
11099
11100   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11101       + ttl + checksum == 0)
11102     return 0;
11103
11104   /*
11105    * Aligned because we use the real comparison functions
11106    */
11107   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11108
11109   ip = (ip4_header_t *) match;
11110
11111   /* These are realistically matched in practice */
11112   if (src)
11113     ip->src_address.as_u32 = src_val.as_u32;
11114
11115   if (dst)
11116     ip->dst_address.as_u32 = dst_val.as_u32;
11117
11118   if (proto)
11119     ip->protocol = proto_val;
11120
11121
11122   /* These are not, but they're included for completeness */
11123   if (version)
11124     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11125
11126   if (hdr_length)
11127     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11128
11129   if (tos)
11130     ip->tos = tos_val;
11131
11132   if (length)
11133     ip->length = clib_host_to_net_u16 (length_val);
11134
11135   if (ttl)
11136     ip->ttl = ttl_val;
11137
11138   if (checksum)
11139     ip->checksum = clib_host_to_net_u16 (checksum_val);
11140
11141   *matchp = match;
11142   return 1;
11143 }
11144
11145 uword
11146 unformat_ip6_match (unformat_input_t * input, va_list * args)
11147 {
11148   u8 **matchp = va_arg (*args, u8 **);
11149   u8 *match = 0;
11150   ip6_header_t *ip;
11151   int version = 0;
11152   u32 version_val;
11153   u8 traffic_class = 0;
11154   u32 traffic_class_val = 0;
11155   u8 flow_label = 0;
11156   u8 flow_label_val;
11157   int src = 0, dst = 0;
11158   ip6_address_t src_val, dst_val;
11159   int proto = 0;
11160   u32 proto_val;
11161   int payload_length = 0;
11162   u32 payload_length_val;
11163   int hop_limit = 0;
11164   int hop_limit_val;
11165   u32 ip_version_traffic_class_and_flow_label;
11166
11167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11168     {
11169       if (unformat (input, "version %d", &version_val))
11170         version = 1;
11171       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11172         traffic_class = 1;
11173       else if (unformat (input, "flow_label %d", &flow_label_val))
11174         flow_label = 1;
11175       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11176         src = 1;
11177       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11178         dst = 1;
11179       else if (unformat (input, "proto %d", &proto_val))
11180         proto = 1;
11181       else if (unformat (input, "payload_length %d", &payload_length_val))
11182         payload_length = 1;
11183       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11184         hop_limit = 1;
11185       else
11186         break;
11187     }
11188
11189   if (version + traffic_class + flow_label + src + dst + proto +
11190       payload_length + hop_limit == 0)
11191     return 0;
11192
11193   /*
11194    * Aligned because we use the real comparison functions
11195    */
11196   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11197
11198   ip = (ip6_header_t *) match;
11199
11200   if (src)
11201     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11202
11203   if (dst)
11204     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11205
11206   if (proto)
11207     ip->protocol = proto_val;
11208
11209   ip_version_traffic_class_and_flow_label = 0;
11210
11211   if (version)
11212     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11213
11214   if (traffic_class)
11215     ip_version_traffic_class_and_flow_label |=
11216       (traffic_class_val & 0xFF) << 20;
11217
11218   if (flow_label)
11219     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11220
11221   ip->ip_version_traffic_class_and_flow_label =
11222     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11223
11224   if (payload_length)
11225     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11226
11227   if (hop_limit)
11228     ip->hop_limit = hop_limit_val;
11229
11230   *matchp = match;
11231   return 1;
11232 }
11233
11234 uword
11235 unformat_l3_match (unformat_input_t * input, va_list * args)
11236 {
11237   u8 **matchp = va_arg (*args, u8 **);
11238
11239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11240     {
11241       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11242         return 1;
11243       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11244         return 1;
11245       else
11246         break;
11247     }
11248   return 0;
11249 }
11250
11251 uword
11252 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11253 {
11254   u8 *tagp = va_arg (*args, u8 *);
11255   u32 tag;
11256
11257   if (unformat (input, "%d", &tag))
11258     {
11259       tagp[0] = (tag >> 8) & 0x0F;
11260       tagp[1] = tag & 0xFF;
11261       return 1;
11262     }
11263
11264   return 0;
11265 }
11266
11267 uword
11268 unformat_l2_match (unformat_input_t * input, va_list * args)
11269 {
11270   u8 **matchp = va_arg (*args, u8 **);
11271   u8 *match = 0;
11272   u8 src = 0;
11273   u8 src_val[6];
11274   u8 dst = 0;
11275   u8 dst_val[6];
11276   u8 proto = 0;
11277   u16 proto_val;
11278   u8 tag1 = 0;
11279   u8 tag1_val[2];
11280   u8 tag2 = 0;
11281   u8 tag2_val[2];
11282   int len = 14;
11283   u8 ignore_tag1 = 0;
11284   u8 ignore_tag2 = 0;
11285   u8 cos1 = 0;
11286   u8 cos2 = 0;
11287   u32 cos1_val = 0;
11288   u32 cos2_val = 0;
11289
11290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11291     {
11292       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11293         src = 1;
11294       else
11295         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11296         dst = 1;
11297       else if (unformat (input, "proto %U",
11298                          unformat_ethernet_type_host_byte_order, &proto_val))
11299         proto = 1;
11300       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11301         tag1 = 1;
11302       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11303         tag2 = 1;
11304       else if (unformat (input, "ignore-tag1"))
11305         ignore_tag1 = 1;
11306       else if (unformat (input, "ignore-tag2"))
11307         ignore_tag2 = 1;
11308       else if (unformat (input, "cos1 %d", &cos1_val))
11309         cos1 = 1;
11310       else if (unformat (input, "cos2 %d", &cos2_val))
11311         cos2 = 1;
11312       else
11313         break;
11314     }
11315   if ((src + dst + proto + tag1 + tag2 +
11316        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11317     return 0;
11318
11319   if (tag1 || ignore_tag1 || cos1)
11320     len = 18;
11321   if (tag2 || ignore_tag2 || cos2)
11322     len = 22;
11323
11324   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11325
11326   if (dst)
11327     clib_memcpy (match, dst_val, 6);
11328
11329   if (src)
11330     clib_memcpy (match + 6, src_val, 6);
11331
11332   if (tag2)
11333     {
11334       /* inner vlan tag */
11335       match[19] = tag2_val[1];
11336       match[18] = tag2_val[0];
11337       if (cos2)
11338         match[18] |= (cos2_val & 0x7) << 5;
11339       if (proto)
11340         {
11341           match[21] = proto_val & 0xff;
11342           match[20] = proto_val >> 8;
11343         }
11344       if (tag1)
11345         {
11346           match[15] = tag1_val[1];
11347           match[14] = tag1_val[0];
11348         }
11349       if (cos1)
11350         match[14] |= (cos1_val & 0x7) << 5;
11351       *matchp = match;
11352       return 1;
11353     }
11354   if (tag1)
11355     {
11356       match[15] = tag1_val[1];
11357       match[14] = tag1_val[0];
11358       if (proto)
11359         {
11360           match[17] = proto_val & 0xff;
11361           match[16] = proto_val >> 8;
11362         }
11363       if (cos1)
11364         match[14] |= (cos1_val & 0x7) << 5;
11365
11366       *matchp = match;
11367       return 1;
11368     }
11369   if (cos2)
11370     match[18] |= (cos2_val & 0x7) << 5;
11371   if (cos1)
11372     match[14] |= (cos1_val & 0x7) << 5;
11373   if (proto)
11374     {
11375       match[13] = proto_val & 0xff;
11376       match[12] = proto_val >> 8;
11377     }
11378
11379   *matchp = match;
11380   return 1;
11381 }
11382
11383 uword
11384 unformat_qos_source (unformat_input_t * input, va_list * args)
11385 {
11386   int *qs = va_arg (*args, int *);
11387
11388   if (unformat (input, "ip"))
11389     *qs = QOS_SOURCE_IP;
11390   else if (unformat (input, "mpls"))
11391     *qs = QOS_SOURCE_MPLS;
11392   else if (unformat (input, "ext"))
11393     *qs = QOS_SOURCE_EXT;
11394   else if (unformat (input, "vlan"))
11395     *qs = QOS_SOURCE_VLAN;
11396   else
11397     return 0;
11398
11399   return 1;
11400 }
11401 #endif
11402
11403 uword
11404 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11405 {
11406   u8 **matchp = va_arg (*args, u8 **);
11407   u32 skip_n_vectors = va_arg (*args, u32);
11408   u32 match_n_vectors = va_arg (*args, u32);
11409
11410   u8 *match = 0;
11411   u8 *l2 = 0;
11412   u8 *l3 = 0;
11413   u8 *l4 = 0;
11414
11415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11416     {
11417       if (unformat (input, "hex %U", unformat_hex_string, &match))
11418         ;
11419       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11420         ;
11421       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11422         ;
11423       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11424         ;
11425       else
11426         break;
11427     }
11428
11429   if (l4 && !l3)
11430     {
11431       vec_free (match);
11432       vec_free (l2);
11433       vec_free (l4);
11434       return 0;
11435     }
11436
11437   if (match || l2 || l3 || l4)
11438     {
11439       if (l2 || l3 || l4)
11440         {
11441           /* "Win a free Ethernet header in every packet" */
11442           if (l2 == 0)
11443             vec_validate_aligned (l2, 13, sizeof (u32x4));
11444           match = l2;
11445           if (vec_len (l3))
11446             {
11447               vec_append_aligned (match, l3, sizeof (u32x4));
11448               vec_free (l3);
11449             }
11450           if (vec_len (l4))
11451             {
11452               vec_append_aligned (match, l4, sizeof (u32x4));
11453               vec_free (l4);
11454             }
11455         }
11456
11457       /* Make sure the vector is big enough even if key is all 0's */
11458       vec_validate_aligned
11459         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11460          sizeof (u32x4));
11461
11462       /* Set size, include skipped vectors */
11463       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11464
11465       *matchp = match;
11466
11467       return 1;
11468     }
11469
11470   return 0;
11471 }
11472
11473 static int
11474 api_classify_add_del_session (vat_main_t * vam)
11475 {
11476   unformat_input_t *i = vam->input;
11477   vl_api_classify_add_del_session_t *mp;
11478   int is_add = 1;
11479   u32 table_index = ~0;
11480   u32 hit_next_index = ~0;
11481   u32 opaque_index = ~0;
11482   u8 *match = 0;
11483   i32 advance = 0;
11484   u32 skip_n_vectors = 0;
11485   u32 match_n_vectors = 0;
11486   u32 action = 0;
11487   u32 metadata = 0;
11488   int ret;
11489
11490   /*
11491    * Warning: you have to supply skip_n and match_n
11492    * because the API client cant simply look at the classify
11493    * table object.
11494    */
11495
11496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11497     {
11498       if (unformat (i, "del"))
11499         is_add = 0;
11500       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11501                          &hit_next_index))
11502         ;
11503       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11504                          &hit_next_index))
11505         ;
11506       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11507                          &hit_next_index))
11508         ;
11509       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11510         ;
11511       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11512         ;
11513       else if (unformat (i, "opaque-index %d", &opaque_index))
11514         ;
11515       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11516         ;
11517       else if (unformat (i, "match_n %d", &match_n_vectors))
11518         ;
11519       else if (unformat (i, "match %U", api_unformat_classify_match,
11520                          &match, skip_n_vectors, match_n_vectors))
11521         ;
11522       else if (unformat (i, "advance %d", &advance))
11523         ;
11524       else if (unformat (i, "table-index %d", &table_index))
11525         ;
11526       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11527         action = 1;
11528       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11529         action = 2;
11530       else if (unformat (i, "action %d", &action))
11531         ;
11532       else if (unformat (i, "metadata %d", &metadata))
11533         ;
11534       else
11535         break;
11536     }
11537
11538   if (table_index == ~0)
11539     {
11540       errmsg ("Table index required");
11541       return -99;
11542     }
11543
11544   if (is_add && match == 0)
11545     {
11546       errmsg ("Match value required");
11547       return -99;
11548     }
11549
11550   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11551
11552   mp->is_add = is_add;
11553   mp->table_index = ntohl (table_index);
11554   mp->hit_next_index = ntohl (hit_next_index);
11555   mp->opaque_index = ntohl (opaque_index);
11556   mp->advance = ntohl (advance);
11557   mp->action = action;
11558   mp->metadata = ntohl (metadata);
11559   mp->match_len = ntohl (vec_len (match));
11560   clib_memcpy (mp->match, match, vec_len (match));
11561   vec_free (match);
11562
11563   S (mp);
11564   W (ret);
11565   return ret;
11566 }
11567
11568 static int
11569 api_classify_set_interface_ip_table (vat_main_t * vam)
11570 {
11571   unformat_input_t *i = vam->input;
11572   vl_api_classify_set_interface_ip_table_t *mp;
11573   u32 sw_if_index;
11574   int sw_if_index_set;
11575   u32 table_index = ~0;
11576   u8 is_ipv6 = 0;
11577   int ret;
11578
11579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11580     {
11581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11582         sw_if_index_set = 1;
11583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11584         sw_if_index_set = 1;
11585       else if (unformat (i, "table %d", &table_index))
11586         ;
11587       else
11588         {
11589           clib_warning ("parse error '%U'", format_unformat_error, i);
11590           return -99;
11591         }
11592     }
11593
11594   if (sw_if_index_set == 0)
11595     {
11596       errmsg ("missing interface name or sw_if_index");
11597       return -99;
11598     }
11599
11600
11601   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11602
11603   mp->sw_if_index = ntohl (sw_if_index);
11604   mp->table_index = ntohl (table_index);
11605   mp->is_ipv6 = is_ipv6;
11606
11607   S (mp);
11608   W (ret);
11609   return ret;
11610 }
11611
11612 static int
11613 api_classify_set_interface_l2_tables (vat_main_t * vam)
11614 {
11615   unformat_input_t *i = vam->input;
11616   vl_api_classify_set_interface_l2_tables_t *mp;
11617   u32 sw_if_index;
11618   int sw_if_index_set;
11619   u32 ip4_table_index = ~0;
11620   u32 ip6_table_index = ~0;
11621   u32 other_table_index = ~0;
11622   u32 is_input = 1;
11623   int ret;
11624
11625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11626     {
11627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11628         sw_if_index_set = 1;
11629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11630         sw_if_index_set = 1;
11631       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11632         ;
11633       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11634         ;
11635       else if (unformat (i, "other-table %d", &other_table_index))
11636         ;
11637       else if (unformat (i, "is-input %d", &is_input))
11638         ;
11639       else
11640         {
11641           clib_warning ("parse error '%U'", format_unformat_error, i);
11642           return -99;
11643         }
11644     }
11645
11646   if (sw_if_index_set == 0)
11647     {
11648       errmsg ("missing interface name or sw_if_index");
11649       return -99;
11650     }
11651
11652
11653   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11654
11655   mp->sw_if_index = ntohl (sw_if_index);
11656   mp->ip4_table_index = ntohl (ip4_table_index);
11657   mp->ip6_table_index = ntohl (ip6_table_index);
11658   mp->other_table_index = ntohl (other_table_index);
11659   mp->is_input = (u8) is_input;
11660
11661   S (mp);
11662   W (ret);
11663   return ret;
11664 }
11665
11666 static int
11667 api_set_ipfix_exporter (vat_main_t * vam)
11668 {
11669   unformat_input_t *i = vam->input;
11670   vl_api_set_ipfix_exporter_t *mp;
11671   ip4_address_t collector_address;
11672   u8 collector_address_set = 0;
11673   u32 collector_port = ~0;
11674   ip4_address_t src_address;
11675   u8 src_address_set = 0;
11676   u32 vrf_id = ~0;
11677   u32 path_mtu = ~0;
11678   u32 template_interval = ~0;
11679   u8 udp_checksum = 0;
11680   int ret;
11681
11682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11683     {
11684       if (unformat (i, "collector_address %U", unformat_ip4_address,
11685                     &collector_address))
11686         collector_address_set = 1;
11687       else if (unformat (i, "collector_port %d", &collector_port))
11688         ;
11689       else if (unformat (i, "src_address %U", unformat_ip4_address,
11690                          &src_address))
11691         src_address_set = 1;
11692       else if (unformat (i, "vrf_id %d", &vrf_id))
11693         ;
11694       else if (unformat (i, "path_mtu %d", &path_mtu))
11695         ;
11696       else if (unformat (i, "template_interval %d", &template_interval))
11697         ;
11698       else if (unformat (i, "udp_checksum"))
11699         udp_checksum = 1;
11700       else
11701         break;
11702     }
11703
11704   if (collector_address_set == 0)
11705     {
11706       errmsg ("collector_address required");
11707       return -99;
11708     }
11709
11710   if (src_address_set == 0)
11711     {
11712       errmsg ("src_address required");
11713       return -99;
11714     }
11715
11716   M (SET_IPFIX_EXPORTER, mp);
11717
11718   memcpy (mp->collector_address, collector_address.data,
11719           sizeof (collector_address.data));
11720   mp->collector_port = htons ((u16) collector_port);
11721   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11722   mp->vrf_id = htonl (vrf_id);
11723   mp->path_mtu = htonl (path_mtu);
11724   mp->template_interval = htonl (template_interval);
11725   mp->udp_checksum = udp_checksum;
11726
11727   S (mp);
11728   W (ret);
11729   return ret;
11730 }
11731
11732 static int
11733 api_set_ipfix_classify_stream (vat_main_t * vam)
11734 {
11735   unformat_input_t *i = vam->input;
11736   vl_api_set_ipfix_classify_stream_t *mp;
11737   u32 domain_id = 0;
11738   u32 src_port = UDP_DST_PORT_ipfix;
11739   int ret;
11740
11741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11742     {
11743       if (unformat (i, "domain %d", &domain_id))
11744         ;
11745       else if (unformat (i, "src_port %d", &src_port))
11746         ;
11747       else
11748         {
11749           errmsg ("unknown input `%U'", format_unformat_error, i);
11750           return -99;
11751         }
11752     }
11753
11754   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11755
11756   mp->domain_id = htonl (domain_id);
11757   mp->src_port = htons ((u16) src_port);
11758
11759   S (mp);
11760   W (ret);
11761   return ret;
11762 }
11763
11764 static int
11765 api_ipfix_classify_table_add_del (vat_main_t * vam)
11766 {
11767   unformat_input_t *i = vam->input;
11768   vl_api_ipfix_classify_table_add_del_t *mp;
11769   int is_add = -1;
11770   u32 classify_table_index = ~0;
11771   u8 ip_version = 0;
11772   u8 transport_protocol = 255;
11773   int ret;
11774
11775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11776     {
11777       if (unformat (i, "add"))
11778         is_add = 1;
11779       else if (unformat (i, "del"))
11780         is_add = 0;
11781       else if (unformat (i, "table %d", &classify_table_index))
11782         ;
11783       else if (unformat (i, "ip4"))
11784         ip_version = 4;
11785       else if (unformat (i, "ip6"))
11786         ip_version = 6;
11787       else if (unformat (i, "tcp"))
11788         transport_protocol = 6;
11789       else if (unformat (i, "udp"))
11790         transport_protocol = 17;
11791       else
11792         {
11793           errmsg ("unknown input `%U'", format_unformat_error, i);
11794           return -99;
11795         }
11796     }
11797
11798   if (is_add == -1)
11799     {
11800       errmsg ("expecting: add|del");
11801       return -99;
11802     }
11803   if (classify_table_index == ~0)
11804     {
11805       errmsg ("classifier table not specified");
11806       return -99;
11807     }
11808   if (ip_version == 0)
11809     {
11810       errmsg ("IP version not specified");
11811       return -99;
11812     }
11813
11814   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11815
11816   mp->is_add = is_add;
11817   mp->table_id = htonl (classify_table_index);
11818   mp->ip_version = ip_version;
11819   mp->transport_protocol = transport_protocol;
11820
11821   S (mp);
11822   W (ret);
11823   return ret;
11824 }
11825
11826 static int
11827 api_get_node_index (vat_main_t * vam)
11828 {
11829   unformat_input_t *i = vam->input;
11830   vl_api_get_node_index_t *mp;
11831   u8 *name = 0;
11832   int ret;
11833
11834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11835     {
11836       if (unformat (i, "node %s", &name))
11837         ;
11838       else
11839         break;
11840     }
11841   if (name == 0)
11842     {
11843       errmsg ("node name required");
11844       return -99;
11845     }
11846   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11847     {
11848       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11849       return -99;
11850     }
11851
11852   M (GET_NODE_INDEX, mp);
11853   clib_memcpy (mp->node_name, name, vec_len (name));
11854   vec_free (name);
11855
11856   S (mp);
11857   W (ret);
11858   return ret;
11859 }
11860
11861 static int
11862 api_get_next_index (vat_main_t * vam)
11863 {
11864   unformat_input_t *i = vam->input;
11865   vl_api_get_next_index_t *mp;
11866   u8 *node_name = 0, *next_node_name = 0;
11867   int ret;
11868
11869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11870     {
11871       if (unformat (i, "node-name %s", &node_name))
11872         ;
11873       else if (unformat (i, "next-node-name %s", &next_node_name))
11874         break;
11875     }
11876
11877   if (node_name == 0)
11878     {
11879       errmsg ("node name required");
11880       return -99;
11881     }
11882   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11883     {
11884       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11885       return -99;
11886     }
11887
11888   if (next_node_name == 0)
11889     {
11890       errmsg ("next node name required");
11891       return -99;
11892     }
11893   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11894     {
11895       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11896       return -99;
11897     }
11898
11899   M (GET_NEXT_INDEX, mp);
11900   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11901   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11902   vec_free (node_name);
11903   vec_free (next_node_name);
11904
11905   S (mp);
11906   W (ret);
11907   return ret;
11908 }
11909
11910 static int
11911 api_add_node_next (vat_main_t * vam)
11912 {
11913   unformat_input_t *i = vam->input;
11914   vl_api_add_node_next_t *mp;
11915   u8 *name = 0;
11916   u8 *next = 0;
11917   int ret;
11918
11919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11920     {
11921       if (unformat (i, "node %s", &name))
11922         ;
11923       else if (unformat (i, "next %s", &next))
11924         ;
11925       else
11926         break;
11927     }
11928   if (name == 0)
11929     {
11930       errmsg ("node name required");
11931       return -99;
11932     }
11933   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11934     {
11935       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11936       return -99;
11937     }
11938   if (next == 0)
11939     {
11940       errmsg ("next node required");
11941       return -99;
11942     }
11943   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11944     {
11945       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11946       return -99;
11947     }
11948
11949   M (ADD_NODE_NEXT, mp);
11950   clib_memcpy (mp->node_name, name, vec_len (name));
11951   clib_memcpy (mp->next_name, next, vec_len (next));
11952   vec_free (name);
11953   vec_free (next);
11954
11955   S (mp);
11956   W (ret);
11957   return ret;
11958 }
11959
11960 static int
11961 api_l2tpv3_create_tunnel (vat_main_t * vam)
11962 {
11963   unformat_input_t *i = vam->input;
11964   ip6_address_t client_address, our_address;
11965   int client_address_set = 0;
11966   int our_address_set = 0;
11967   u32 local_session_id = 0;
11968   u32 remote_session_id = 0;
11969   u64 local_cookie = 0;
11970   u64 remote_cookie = 0;
11971   u8 l2_sublayer_present = 0;
11972   vl_api_l2tpv3_create_tunnel_t *mp;
11973   int ret;
11974
11975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11976     {
11977       if (unformat (i, "client_address %U", unformat_ip6_address,
11978                     &client_address))
11979         client_address_set = 1;
11980       else if (unformat (i, "our_address %U", unformat_ip6_address,
11981                          &our_address))
11982         our_address_set = 1;
11983       else if (unformat (i, "local_session_id %d", &local_session_id))
11984         ;
11985       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11986         ;
11987       else if (unformat (i, "local_cookie %lld", &local_cookie))
11988         ;
11989       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11990         ;
11991       else if (unformat (i, "l2-sublayer-present"))
11992         l2_sublayer_present = 1;
11993       else
11994         break;
11995     }
11996
11997   if (client_address_set == 0)
11998     {
11999       errmsg ("client_address required");
12000       return -99;
12001     }
12002
12003   if (our_address_set == 0)
12004     {
12005       errmsg ("our_address required");
12006       return -99;
12007     }
12008
12009   M (L2TPV3_CREATE_TUNNEL, mp);
12010
12011   clib_memcpy (mp->client_address, client_address.as_u8,
12012                sizeof (mp->client_address));
12013
12014   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12015
12016   mp->local_session_id = ntohl (local_session_id);
12017   mp->remote_session_id = ntohl (remote_session_id);
12018   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12019   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12020   mp->l2_sublayer_present = l2_sublayer_present;
12021   mp->is_ipv6 = 1;
12022
12023   S (mp);
12024   W (ret);
12025   return ret;
12026 }
12027
12028 static int
12029 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12030 {
12031   unformat_input_t *i = vam->input;
12032   u32 sw_if_index;
12033   u8 sw_if_index_set = 0;
12034   u64 new_local_cookie = 0;
12035   u64 new_remote_cookie = 0;
12036   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12037   int ret;
12038
12039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12040     {
12041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12042         sw_if_index_set = 1;
12043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12044         sw_if_index_set = 1;
12045       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12046         ;
12047       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12048         ;
12049       else
12050         break;
12051     }
12052
12053   if (sw_if_index_set == 0)
12054     {
12055       errmsg ("missing interface name or sw_if_index");
12056       return -99;
12057     }
12058
12059   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12060
12061   mp->sw_if_index = ntohl (sw_if_index);
12062   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12063   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12064
12065   S (mp);
12066   W (ret);
12067   return ret;
12068 }
12069
12070 static int
12071 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12072 {
12073   unformat_input_t *i = vam->input;
12074   vl_api_l2tpv3_interface_enable_disable_t *mp;
12075   u32 sw_if_index;
12076   u8 sw_if_index_set = 0;
12077   u8 enable_disable = 1;
12078   int ret;
12079
12080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12081     {
12082       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12083         sw_if_index_set = 1;
12084       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12085         sw_if_index_set = 1;
12086       else if (unformat (i, "enable"))
12087         enable_disable = 1;
12088       else if (unformat (i, "disable"))
12089         enable_disable = 0;
12090       else
12091         break;
12092     }
12093
12094   if (sw_if_index_set == 0)
12095     {
12096       errmsg ("missing interface name or sw_if_index");
12097       return -99;
12098     }
12099
12100   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12101
12102   mp->sw_if_index = ntohl (sw_if_index);
12103   mp->enable_disable = enable_disable;
12104
12105   S (mp);
12106   W (ret);
12107   return ret;
12108 }
12109
12110 static int
12111 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12112 {
12113   unformat_input_t *i = vam->input;
12114   vl_api_l2tpv3_set_lookup_key_t *mp;
12115   u8 key = ~0;
12116   int ret;
12117
12118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12119     {
12120       if (unformat (i, "lookup_v6_src"))
12121         key = L2T_LOOKUP_SRC_ADDRESS;
12122       else if (unformat (i, "lookup_v6_dst"))
12123         key = L2T_LOOKUP_DST_ADDRESS;
12124       else if (unformat (i, "lookup_session_id"))
12125         key = L2T_LOOKUP_SESSION_ID;
12126       else
12127         break;
12128     }
12129
12130   if (key == (u8) ~ 0)
12131     {
12132       errmsg ("l2tp session lookup key unset");
12133       return -99;
12134     }
12135
12136   M (L2TPV3_SET_LOOKUP_KEY, mp);
12137
12138   mp->key = key;
12139
12140   S (mp);
12141   W (ret);
12142   return ret;
12143 }
12144
12145 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12146   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12147 {
12148   vat_main_t *vam = &vat_main;
12149
12150   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12151          format_ip6_address, mp->our_address,
12152          format_ip6_address, mp->client_address,
12153          clib_net_to_host_u32 (mp->sw_if_index));
12154
12155   print (vam->ofp,
12156          "   local cookies %016llx %016llx remote cookie %016llx",
12157          clib_net_to_host_u64 (mp->local_cookie[0]),
12158          clib_net_to_host_u64 (mp->local_cookie[1]),
12159          clib_net_to_host_u64 (mp->remote_cookie));
12160
12161   print (vam->ofp, "   local session-id %d remote session-id %d",
12162          clib_net_to_host_u32 (mp->local_session_id),
12163          clib_net_to_host_u32 (mp->remote_session_id));
12164
12165   print (vam->ofp, "   l2 specific sublayer %s\n",
12166          mp->l2_sublayer_present ? "preset" : "absent");
12167
12168 }
12169
12170 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12171   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12172 {
12173   vat_main_t *vam = &vat_main;
12174   vat_json_node_t *node = NULL;
12175   struct in6_addr addr;
12176
12177   if (VAT_JSON_ARRAY != vam->json_tree.type)
12178     {
12179       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12180       vat_json_init_array (&vam->json_tree);
12181     }
12182   node = vat_json_array_add (&vam->json_tree);
12183
12184   vat_json_init_object (node);
12185
12186   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12187   vat_json_object_add_ip6 (node, "our_address", addr);
12188   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12189   vat_json_object_add_ip6 (node, "client_address", addr);
12190
12191   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12192   vat_json_init_array (lc);
12193   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12194   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12195   vat_json_object_add_uint (node, "remote_cookie",
12196                             clib_net_to_host_u64 (mp->remote_cookie));
12197
12198   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12199   vat_json_object_add_uint (node, "local_session_id",
12200                             clib_net_to_host_u32 (mp->local_session_id));
12201   vat_json_object_add_uint (node, "remote_session_id",
12202                             clib_net_to_host_u32 (mp->remote_session_id));
12203   vat_json_object_add_string_copy (node, "l2_sublayer",
12204                                    mp->l2_sublayer_present ? (u8 *) "present"
12205                                    : (u8 *) "absent");
12206 }
12207
12208 static int
12209 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12210 {
12211   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12212   vl_api_control_ping_t *mp_ping;
12213   int ret;
12214
12215   /* Get list of l2tpv3-tunnel interfaces */
12216   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12217   S (mp);
12218
12219   /* Use a control ping for synchronization */
12220   MPING (CONTROL_PING, mp_ping);
12221   S (mp_ping);
12222
12223   W (ret);
12224   return ret;
12225 }
12226
12227
12228 static void vl_api_sw_interface_tap_v2_details_t_handler
12229   (vl_api_sw_interface_tap_v2_details_t * mp)
12230 {
12231   vat_main_t *vam = &vat_main;
12232
12233   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12234                     mp->host_ip4_prefix_len);
12235   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12236                     mp->host_ip6_prefix_len);
12237
12238   print (vam->ofp,
12239          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12240          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12241          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12242          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12243          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12244
12245   vec_free (ip4);
12246   vec_free (ip6);
12247 }
12248
12249 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12250   (vl_api_sw_interface_tap_v2_details_t * mp)
12251 {
12252   vat_main_t *vam = &vat_main;
12253   vat_json_node_t *node = NULL;
12254
12255   if (VAT_JSON_ARRAY != vam->json_tree.type)
12256     {
12257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12258       vat_json_init_array (&vam->json_tree);
12259     }
12260   node = vat_json_array_add (&vam->json_tree);
12261
12262   vat_json_init_object (node);
12263   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12264   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12265   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12266   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12267   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12268   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12269   vat_json_object_add_string_copy (node, "host_mac_addr",
12270                                    format (0, "%U", format_ethernet_address,
12271                                            &mp->host_mac_addr));
12272   vat_json_object_add_string_copy (node, "host_namespace",
12273                                    mp->host_namespace);
12274   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12275   vat_json_object_add_string_copy (node, "host_ip4_addr",
12276                                    format (0, "%U/%d", format_ip4_address,
12277                                            mp->host_ip4_addr,
12278                                            mp->host_ip4_prefix_len));
12279   vat_json_object_add_string_copy (node, "host_ip6_addr",
12280                                    format (0, "%U/%d", format_ip6_address,
12281                                            mp->host_ip6_addr,
12282                                            mp->host_ip6_prefix_len));
12283
12284 }
12285
12286 static int
12287 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12288 {
12289   vl_api_sw_interface_tap_v2_dump_t *mp;
12290   vl_api_control_ping_t *mp_ping;
12291   int ret;
12292
12293   print (vam->ofp,
12294          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12295          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12296          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12297          "host_ip6_addr");
12298
12299   /* Get list of tap interfaces */
12300   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12301   S (mp);
12302
12303   /* Use a control ping for synchronization */
12304   MPING (CONTROL_PING, mp_ping);
12305   S (mp_ping);
12306
12307   W (ret);
12308   return ret;
12309 }
12310
12311 static void vl_api_sw_interface_virtio_pci_details_t_handler
12312   (vl_api_sw_interface_virtio_pci_details_t * mp)
12313 {
12314   vat_main_t *vam = &vat_main;
12315
12316   typedef union
12317   {
12318     struct
12319     {
12320       u16 domain;
12321       u8 bus;
12322       u8 slot:5;
12323       u8 function:3;
12324     };
12325     u32 as_u32;
12326   } pci_addr_t;
12327   pci_addr_t addr;
12328   addr.as_u32 = ntohl (mp->pci_addr);
12329   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12330                          addr.slot, addr.function);
12331
12332   print (vam->ofp,
12333          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12334          pci_addr, ntohl (mp->sw_if_index),
12335          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12336          format_ethernet_address, mp->mac_addr,
12337          clib_net_to_host_u64 (mp->features));
12338   vec_free (pci_addr);
12339 }
12340
12341 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12342   (vl_api_sw_interface_virtio_pci_details_t * mp)
12343 {
12344   vat_main_t *vam = &vat_main;
12345   vat_json_node_t *node = NULL;
12346
12347   if (VAT_JSON_ARRAY != vam->json_tree.type)
12348     {
12349       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12350       vat_json_init_array (&vam->json_tree);
12351     }
12352   node = vat_json_array_add (&vam->json_tree);
12353
12354   vat_json_init_object (node);
12355   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12356   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12357   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12358   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12359   vat_json_object_add_uint (node, "features",
12360                             clib_net_to_host_u64 (mp->features));
12361   vat_json_object_add_string_copy (node, "mac_addr",
12362                                    format (0, "%U", format_ethernet_address,
12363                                            &mp->mac_addr));
12364 }
12365
12366 static int
12367 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12368 {
12369   vl_api_sw_interface_virtio_pci_dump_t *mp;
12370   vl_api_control_ping_t *mp_ping;
12371   int ret;
12372
12373   print (vam->ofp,
12374          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12375          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12376          "mac_addr", "features");
12377
12378   /* Get list of tap interfaces */
12379   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12380   S (mp);
12381
12382   /* Use a control ping for synchronization */
12383   MPING (CONTROL_PING, mp_ping);
12384   S (mp_ping);
12385
12386   W (ret);
12387   return ret;
12388 }
12389
12390 static int
12391 api_vxlan_offload_rx (vat_main_t * vam)
12392 {
12393   unformat_input_t *line_input = vam->input;
12394   vl_api_vxlan_offload_rx_t *mp;
12395   u32 hw_if_index = ~0, rx_if_index = ~0;
12396   u8 is_add = 1;
12397   int ret;
12398
12399   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12400     {
12401       if (unformat (line_input, "del"))
12402         is_add = 0;
12403       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12404                          &hw_if_index))
12405         ;
12406       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12407         ;
12408       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12409                          &rx_if_index))
12410         ;
12411       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12412         ;
12413       else
12414         {
12415           errmsg ("parse error '%U'", format_unformat_error, line_input);
12416           return -99;
12417         }
12418     }
12419
12420   if (hw_if_index == ~0)
12421     {
12422       errmsg ("no hw interface");
12423       return -99;
12424     }
12425
12426   if (rx_if_index == ~0)
12427     {
12428       errmsg ("no rx tunnel");
12429       return -99;
12430     }
12431
12432   M (VXLAN_OFFLOAD_RX, mp);
12433
12434   mp->hw_if_index = ntohl (hw_if_index);
12435   mp->sw_if_index = ntohl (rx_if_index);
12436   mp->enable = is_add;
12437
12438   S (mp);
12439   W (ret);
12440   return ret;
12441 }
12442
12443 static uword unformat_vxlan_decap_next
12444   (unformat_input_t * input, va_list * args)
12445 {
12446   u32 *result = va_arg (*args, u32 *);
12447   u32 tmp;
12448
12449   if (unformat (input, "l2"))
12450     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12451   else if (unformat (input, "%d", &tmp))
12452     *result = tmp;
12453   else
12454     return 0;
12455   return 1;
12456 }
12457
12458 static int
12459 api_vxlan_add_del_tunnel (vat_main_t * vam)
12460 {
12461   unformat_input_t *line_input = vam->input;
12462   vl_api_vxlan_add_del_tunnel_t *mp;
12463   ip46_address_t src, dst;
12464   u8 is_add = 1;
12465   u8 ipv4_set = 0, ipv6_set = 0;
12466   u8 src_set = 0;
12467   u8 dst_set = 0;
12468   u8 grp_set = 0;
12469   u32 instance = ~0;
12470   u32 mcast_sw_if_index = ~0;
12471   u32 encap_vrf_id = 0;
12472   u32 decap_next_index = ~0;
12473   u32 vni = 0;
12474   int ret;
12475
12476   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12477   clib_memset (&src, 0, sizeof src);
12478   clib_memset (&dst, 0, sizeof dst);
12479
12480   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12481     {
12482       if (unformat (line_input, "del"))
12483         is_add = 0;
12484       else if (unformat (line_input, "instance %d", &instance))
12485         ;
12486       else
12487         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12488         {
12489           ipv4_set = 1;
12490           src_set = 1;
12491         }
12492       else
12493         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12494         {
12495           ipv4_set = 1;
12496           dst_set = 1;
12497         }
12498       else
12499         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12500         {
12501           ipv6_set = 1;
12502           src_set = 1;
12503         }
12504       else
12505         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12506         {
12507           ipv6_set = 1;
12508           dst_set = 1;
12509         }
12510       else if (unformat (line_input, "group %U %U",
12511                          unformat_ip4_address, &dst.ip4,
12512                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12513         {
12514           grp_set = dst_set = 1;
12515           ipv4_set = 1;
12516         }
12517       else if (unformat (line_input, "group %U",
12518                          unformat_ip4_address, &dst.ip4))
12519         {
12520           grp_set = dst_set = 1;
12521           ipv4_set = 1;
12522         }
12523       else if (unformat (line_input, "group %U %U",
12524                          unformat_ip6_address, &dst.ip6,
12525                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12526         {
12527           grp_set = dst_set = 1;
12528           ipv6_set = 1;
12529         }
12530       else if (unformat (line_input, "group %U",
12531                          unformat_ip6_address, &dst.ip6))
12532         {
12533           grp_set = dst_set = 1;
12534           ipv6_set = 1;
12535         }
12536       else
12537         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12538         ;
12539       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12540         ;
12541       else if (unformat (line_input, "decap-next %U",
12542                          unformat_vxlan_decap_next, &decap_next_index))
12543         ;
12544       else if (unformat (line_input, "vni %d", &vni))
12545         ;
12546       else
12547         {
12548           errmsg ("parse error '%U'", format_unformat_error, line_input);
12549           return -99;
12550         }
12551     }
12552
12553   if (src_set == 0)
12554     {
12555       errmsg ("tunnel src address not specified");
12556       return -99;
12557     }
12558   if (dst_set == 0)
12559     {
12560       errmsg ("tunnel dst address not specified");
12561       return -99;
12562     }
12563
12564   if (grp_set && !ip46_address_is_multicast (&dst))
12565     {
12566       errmsg ("tunnel group address not multicast");
12567       return -99;
12568     }
12569   if (grp_set && mcast_sw_if_index == ~0)
12570     {
12571       errmsg ("tunnel nonexistent multicast device");
12572       return -99;
12573     }
12574   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12575     {
12576       errmsg ("tunnel dst address must be unicast");
12577       return -99;
12578     }
12579
12580
12581   if (ipv4_set && ipv6_set)
12582     {
12583       errmsg ("both IPv4 and IPv6 addresses specified");
12584       return -99;
12585     }
12586
12587   if ((vni == 0) || (vni >> 24))
12588     {
12589       errmsg ("vni not specified or out of range");
12590       return -99;
12591     }
12592
12593   M (VXLAN_ADD_DEL_TUNNEL, mp);
12594
12595   if (ipv6_set)
12596     {
12597       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12598       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12599     }
12600   else
12601     {
12602       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12603       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12604     }
12605
12606   mp->instance = htonl (instance);
12607   mp->encap_vrf_id = ntohl (encap_vrf_id);
12608   mp->decap_next_index = ntohl (decap_next_index);
12609   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12610   mp->vni = ntohl (vni);
12611   mp->is_add = is_add;
12612   mp->is_ipv6 = ipv6_set;
12613
12614   S (mp);
12615   W (ret);
12616   return ret;
12617 }
12618
12619 static void vl_api_vxlan_tunnel_details_t_handler
12620   (vl_api_vxlan_tunnel_details_t * mp)
12621 {
12622   vat_main_t *vam = &vat_main;
12623   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12624   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12625
12626   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12627          ntohl (mp->sw_if_index),
12628          ntohl (mp->instance),
12629          format_ip46_address, &src, IP46_TYPE_ANY,
12630          format_ip46_address, &dst, IP46_TYPE_ANY,
12631          ntohl (mp->encap_vrf_id),
12632          ntohl (mp->decap_next_index), ntohl (mp->vni),
12633          ntohl (mp->mcast_sw_if_index));
12634 }
12635
12636 static void vl_api_vxlan_tunnel_details_t_handler_json
12637   (vl_api_vxlan_tunnel_details_t * mp)
12638 {
12639   vat_main_t *vam = &vat_main;
12640   vat_json_node_t *node = NULL;
12641
12642   if (VAT_JSON_ARRAY != vam->json_tree.type)
12643     {
12644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12645       vat_json_init_array (&vam->json_tree);
12646     }
12647   node = vat_json_array_add (&vam->json_tree);
12648
12649   vat_json_init_object (node);
12650   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12651
12652   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12653
12654   if (mp->is_ipv6)
12655     {
12656       struct in6_addr ip6;
12657
12658       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12659       vat_json_object_add_ip6 (node, "src_address", ip6);
12660       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12661       vat_json_object_add_ip6 (node, "dst_address", ip6);
12662     }
12663   else
12664     {
12665       struct in_addr ip4;
12666
12667       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12668       vat_json_object_add_ip4 (node, "src_address", ip4);
12669       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12670       vat_json_object_add_ip4 (node, "dst_address", ip4);
12671     }
12672   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12673   vat_json_object_add_uint (node, "decap_next_index",
12674                             ntohl (mp->decap_next_index));
12675   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12676   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12677   vat_json_object_add_uint (node, "mcast_sw_if_index",
12678                             ntohl (mp->mcast_sw_if_index));
12679 }
12680
12681 static int
12682 api_vxlan_tunnel_dump (vat_main_t * vam)
12683 {
12684   unformat_input_t *i = vam->input;
12685   vl_api_vxlan_tunnel_dump_t *mp;
12686   vl_api_control_ping_t *mp_ping;
12687   u32 sw_if_index;
12688   u8 sw_if_index_set = 0;
12689   int ret;
12690
12691   /* Parse args required to build the message */
12692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12693     {
12694       if (unformat (i, "sw_if_index %d", &sw_if_index))
12695         sw_if_index_set = 1;
12696       else
12697         break;
12698     }
12699
12700   if (sw_if_index_set == 0)
12701     {
12702       sw_if_index = ~0;
12703     }
12704
12705   if (!vam->json_output)
12706     {
12707       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12708              "sw_if_index", "instance", "src_address", "dst_address",
12709              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12710     }
12711
12712   /* Get list of vxlan-tunnel interfaces */
12713   M (VXLAN_TUNNEL_DUMP, mp);
12714
12715   mp->sw_if_index = htonl (sw_if_index);
12716
12717   S (mp);
12718
12719   /* Use a control ping for synchronization */
12720   MPING (CONTROL_PING, mp_ping);
12721   S (mp_ping);
12722
12723   W (ret);
12724   return ret;
12725 }
12726
12727 static uword unformat_geneve_decap_next
12728   (unformat_input_t * input, va_list * args)
12729 {
12730   u32 *result = va_arg (*args, u32 *);
12731   u32 tmp;
12732
12733   if (unformat (input, "l2"))
12734     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12735   else if (unformat (input, "%d", &tmp))
12736     *result = tmp;
12737   else
12738     return 0;
12739   return 1;
12740 }
12741
12742 static int
12743 api_geneve_add_del_tunnel (vat_main_t * vam)
12744 {
12745   unformat_input_t *line_input = vam->input;
12746   vl_api_geneve_add_del_tunnel_t *mp;
12747   ip46_address_t src, dst;
12748   u8 is_add = 1;
12749   u8 ipv4_set = 0, ipv6_set = 0;
12750   u8 src_set = 0;
12751   u8 dst_set = 0;
12752   u8 grp_set = 0;
12753   u32 mcast_sw_if_index = ~0;
12754   u32 encap_vrf_id = 0;
12755   u32 decap_next_index = ~0;
12756   u32 vni = 0;
12757   int ret;
12758
12759   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12760   clib_memset (&src, 0, sizeof src);
12761   clib_memset (&dst, 0, sizeof dst);
12762
12763   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12764     {
12765       if (unformat (line_input, "del"))
12766         is_add = 0;
12767       else
12768         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12769         {
12770           ipv4_set = 1;
12771           src_set = 1;
12772         }
12773       else
12774         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12775         {
12776           ipv4_set = 1;
12777           dst_set = 1;
12778         }
12779       else
12780         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12781         {
12782           ipv6_set = 1;
12783           src_set = 1;
12784         }
12785       else
12786         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12787         {
12788           ipv6_set = 1;
12789           dst_set = 1;
12790         }
12791       else if (unformat (line_input, "group %U %U",
12792                          unformat_ip4_address, &dst.ip4,
12793                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12794         {
12795           grp_set = dst_set = 1;
12796           ipv4_set = 1;
12797         }
12798       else if (unformat (line_input, "group %U",
12799                          unformat_ip4_address, &dst.ip4))
12800         {
12801           grp_set = dst_set = 1;
12802           ipv4_set = 1;
12803         }
12804       else if (unformat (line_input, "group %U %U",
12805                          unformat_ip6_address, &dst.ip6,
12806                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12807         {
12808           grp_set = dst_set = 1;
12809           ipv6_set = 1;
12810         }
12811       else if (unformat (line_input, "group %U",
12812                          unformat_ip6_address, &dst.ip6))
12813         {
12814           grp_set = dst_set = 1;
12815           ipv6_set = 1;
12816         }
12817       else
12818         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12819         ;
12820       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12821         ;
12822       else if (unformat (line_input, "decap-next %U",
12823                          unformat_geneve_decap_next, &decap_next_index))
12824         ;
12825       else if (unformat (line_input, "vni %d", &vni))
12826         ;
12827       else
12828         {
12829           errmsg ("parse error '%U'", format_unformat_error, line_input);
12830           return -99;
12831         }
12832     }
12833
12834   if (src_set == 0)
12835     {
12836       errmsg ("tunnel src address not specified");
12837       return -99;
12838     }
12839   if (dst_set == 0)
12840     {
12841       errmsg ("tunnel dst address not specified");
12842       return -99;
12843     }
12844
12845   if (grp_set && !ip46_address_is_multicast (&dst))
12846     {
12847       errmsg ("tunnel group address not multicast");
12848       return -99;
12849     }
12850   if (grp_set && mcast_sw_if_index == ~0)
12851     {
12852       errmsg ("tunnel nonexistent multicast device");
12853       return -99;
12854     }
12855   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12856     {
12857       errmsg ("tunnel dst address must be unicast");
12858       return -99;
12859     }
12860
12861
12862   if (ipv4_set && ipv6_set)
12863     {
12864       errmsg ("both IPv4 and IPv6 addresses specified");
12865       return -99;
12866     }
12867
12868   if ((vni == 0) || (vni >> 24))
12869     {
12870       errmsg ("vni not specified or out of range");
12871       return -99;
12872     }
12873
12874   M (GENEVE_ADD_DEL_TUNNEL, mp);
12875
12876   if (ipv6_set)
12877     {
12878       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12879       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12880     }
12881   else
12882     {
12883       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12884       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12885     }
12886   mp->encap_vrf_id = ntohl (encap_vrf_id);
12887   mp->decap_next_index = ntohl (decap_next_index);
12888   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12889   mp->vni = ntohl (vni);
12890   mp->is_add = is_add;
12891   mp->is_ipv6 = ipv6_set;
12892
12893   S (mp);
12894   W (ret);
12895   return ret;
12896 }
12897
12898 static void vl_api_geneve_tunnel_details_t_handler
12899   (vl_api_geneve_tunnel_details_t * mp)
12900 {
12901   vat_main_t *vam = &vat_main;
12902   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12903   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12904
12905   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12906          ntohl (mp->sw_if_index),
12907          format_ip46_address, &src, IP46_TYPE_ANY,
12908          format_ip46_address, &dst, IP46_TYPE_ANY,
12909          ntohl (mp->encap_vrf_id),
12910          ntohl (mp->decap_next_index), ntohl (mp->vni),
12911          ntohl (mp->mcast_sw_if_index));
12912 }
12913
12914 static void vl_api_geneve_tunnel_details_t_handler_json
12915   (vl_api_geneve_tunnel_details_t * mp)
12916 {
12917   vat_main_t *vam = &vat_main;
12918   vat_json_node_t *node = NULL;
12919
12920   if (VAT_JSON_ARRAY != vam->json_tree.type)
12921     {
12922       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12923       vat_json_init_array (&vam->json_tree);
12924     }
12925   node = vat_json_array_add (&vam->json_tree);
12926
12927   vat_json_init_object (node);
12928   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12929   if (mp->is_ipv6)
12930     {
12931       struct in6_addr ip6;
12932
12933       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12934       vat_json_object_add_ip6 (node, "src_address", ip6);
12935       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12936       vat_json_object_add_ip6 (node, "dst_address", ip6);
12937     }
12938   else
12939     {
12940       struct in_addr ip4;
12941
12942       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12943       vat_json_object_add_ip4 (node, "src_address", ip4);
12944       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12945       vat_json_object_add_ip4 (node, "dst_address", ip4);
12946     }
12947   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12948   vat_json_object_add_uint (node, "decap_next_index",
12949                             ntohl (mp->decap_next_index));
12950   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12951   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12952   vat_json_object_add_uint (node, "mcast_sw_if_index",
12953                             ntohl (mp->mcast_sw_if_index));
12954 }
12955
12956 static int
12957 api_geneve_tunnel_dump (vat_main_t * vam)
12958 {
12959   unformat_input_t *i = vam->input;
12960   vl_api_geneve_tunnel_dump_t *mp;
12961   vl_api_control_ping_t *mp_ping;
12962   u32 sw_if_index;
12963   u8 sw_if_index_set = 0;
12964   int ret;
12965
12966   /* Parse args required to build the message */
12967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12968     {
12969       if (unformat (i, "sw_if_index %d", &sw_if_index))
12970         sw_if_index_set = 1;
12971       else
12972         break;
12973     }
12974
12975   if (sw_if_index_set == 0)
12976     {
12977       sw_if_index = ~0;
12978     }
12979
12980   if (!vam->json_output)
12981     {
12982       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12983              "sw_if_index", "local_address", "remote_address",
12984              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12985     }
12986
12987   /* Get list of geneve-tunnel interfaces */
12988   M (GENEVE_TUNNEL_DUMP, mp);
12989
12990   mp->sw_if_index = htonl (sw_if_index);
12991
12992   S (mp);
12993
12994   /* Use a control ping for synchronization */
12995   M (CONTROL_PING, mp_ping);
12996   S (mp_ping);
12997
12998   W (ret);
12999   return ret;
13000 }
13001
13002 static int
13003 api_gre_tunnel_add_del (vat_main_t * vam)
13004 {
13005   unformat_input_t *line_input = vam->input;
13006   vl_api_address_t src = { }, dst =
13007   {
13008   };
13009   vl_api_gre_tunnel_add_del_t *mp;
13010   vl_api_gre_tunnel_type_t t_type;
13011   u8 is_add = 1;
13012   u8 src_set = 0;
13013   u8 dst_set = 0;
13014   u32 outer_fib_id = 0;
13015   u32 session_id = 0;
13016   u32 instance = ~0;
13017   int ret;
13018
13019   t_type = GRE_API_TUNNEL_TYPE_L3;
13020
13021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13022     {
13023       if (unformat (line_input, "del"))
13024         is_add = 0;
13025       else if (unformat (line_input, "instance %d", &instance))
13026         ;
13027       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13028         {
13029           src_set = 1;
13030         }
13031       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13032         {
13033           dst_set = 1;
13034         }
13035       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13036         ;
13037       else if (unformat (line_input, "teb"))
13038         t_type = GRE_API_TUNNEL_TYPE_TEB;
13039       else if (unformat (line_input, "erspan %d", &session_id))
13040         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13041       else
13042         {
13043           errmsg ("parse error '%U'", format_unformat_error, line_input);
13044           return -99;
13045         }
13046     }
13047
13048   if (src_set == 0)
13049     {
13050       errmsg ("tunnel src address not specified");
13051       return -99;
13052     }
13053   if (dst_set == 0)
13054     {
13055       errmsg ("tunnel dst address not specified");
13056       return -99;
13057     }
13058
13059   M (GRE_TUNNEL_ADD_DEL, mp);
13060
13061   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13062   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13063
13064   mp->tunnel.instance = htonl (instance);
13065   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13066   mp->is_add = is_add;
13067   mp->tunnel.session_id = htons ((u16) session_id);
13068   mp->tunnel.type = htonl (t_type);
13069
13070   S (mp);
13071   W (ret);
13072   return ret;
13073 }
13074
13075 static void vl_api_gre_tunnel_details_t_handler
13076   (vl_api_gre_tunnel_details_t * mp)
13077 {
13078   vat_main_t *vam = &vat_main;
13079
13080   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13081          ntohl (mp->tunnel.sw_if_index),
13082          ntohl (mp->tunnel.instance),
13083          format_vl_api_address, &mp->tunnel.src,
13084          format_vl_api_address, &mp->tunnel.dst,
13085          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13086          ntohl (mp->tunnel.session_id));
13087 }
13088
13089 static void vl_api_gre_tunnel_details_t_handler_json
13090   (vl_api_gre_tunnel_details_t * mp)
13091 {
13092   vat_main_t *vam = &vat_main;
13093   vat_json_node_t *node = NULL;
13094
13095   if (VAT_JSON_ARRAY != vam->json_tree.type)
13096     {
13097       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13098       vat_json_init_array (&vam->json_tree);
13099     }
13100   node = vat_json_array_add (&vam->json_tree);
13101
13102   vat_json_init_object (node);
13103   vat_json_object_add_uint (node, "sw_if_index",
13104                             ntohl (mp->tunnel.sw_if_index));
13105   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13106
13107   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13108   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13109   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13110   vat_json_object_add_uint (node, "outer_fib_id",
13111                             ntohl (mp->tunnel.outer_fib_id));
13112   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13113 }
13114
13115 static int
13116 api_gre_tunnel_dump (vat_main_t * vam)
13117 {
13118   unformat_input_t *i = vam->input;
13119   vl_api_gre_tunnel_dump_t *mp;
13120   vl_api_control_ping_t *mp_ping;
13121   u32 sw_if_index;
13122   u8 sw_if_index_set = 0;
13123   int ret;
13124
13125   /* Parse args required to build the message */
13126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13127     {
13128       if (unformat (i, "sw_if_index %d", &sw_if_index))
13129         sw_if_index_set = 1;
13130       else
13131         break;
13132     }
13133
13134   if (sw_if_index_set == 0)
13135     {
13136       sw_if_index = ~0;
13137     }
13138
13139   if (!vam->json_output)
13140     {
13141       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13142              "sw_if_index", "instance", "src_address", "dst_address",
13143              "tunnel_type", "outer_fib_id", "session_id");
13144     }
13145
13146   /* Get list of gre-tunnel interfaces */
13147   M (GRE_TUNNEL_DUMP, mp);
13148
13149   mp->sw_if_index = htonl (sw_if_index);
13150
13151   S (mp);
13152
13153   /* Use a control ping for synchronization */
13154   MPING (CONTROL_PING, mp_ping);
13155   S (mp_ping);
13156
13157   W (ret);
13158   return ret;
13159 }
13160
13161 static int
13162 api_l2_fib_clear_table (vat_main_t * vam)
13163 {
13164 //  unformat_input_t * i = vam->input;
13165   vl_api_l2_fib_clear_table_t *mp;
13166   int ret;
13167
13168   M (L2_FIB_CLEAR_TABLE, mp);
13169
13170   S (mp);
13171   W (ret);
13172   return ret;
13173 }
13174
13175 static int
13176 api_l2_interface_efp_filter (vat_main_t * vam)
13177 {
13178   unformat_input_t *i = vam->input;
13179   vl_api_l2_interface_efp_filter_t *mp;
13180   u32 sw_if_index;
13181   u8 enable = 1;
13182   u8 sw_if_index_set = 0;
13183   int ret;
13184
13185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13186     {
13187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13188         sw_if_index_set = 1;
13189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13190         sw_if_index_set = 1;
13191       else if (unformat (i, "enable"))
13192         enable = 1;
13193       else if (unformat (i, "disable"))
13194         enable = 0;
13195       else
13196         {
13197           clib_warning ("parse error '%U'", format_unformat_error, i);
13198           return -99;
13199         }
13200     }
13201
13202   if (sw_if_index_set == 0)
13203     {
13204       errmsg ("missing sw_if_index");
13205       return -99;
13206     }
13207
13208   M (L2_INTERFACE_EFP_FILTER, mp);
13209
13210   mp->sw_if_index = ntohl (sw_if_index);
13211   mp->enable_disable = enable;
13212
13213   S (mp);
13214   W (ret);
13215   return ret;
13216 }
13217
13218 #define foreach_vtr_op                          \
13219 _("disable",  L2_VTR_DISABLED)                  \
13220 _("push-1",  L2_VTR_PUSH_1)                     \
13221 _("push-2",  L2_VTR_PUSH_2)                     \
13222 _("pop-1",  L2_VTR_POP_1)                       \
13223 _("pop-2",  L2_VTR_POP_2)                       \
13224 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13225 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13226 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13227 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13228
13229 static int
13230 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13231 {
13232   unformat_input_t *i = vam->input;
13233   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13234   u32 sw_if_index;
13235   u8 sw_if_index_set = 0;
13236   u8 vtr_op_set = 0;
13237   u32 vtr_op = 0;
13238   u32 push_dot1q = 1;
13239   u32 tag1 = ~0;
13240   u32 tag2 = ~0;
13241   int ret;
13242
13243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13244     {
13245       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13246         sw_if_index_set = 1;
13247       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13248         sw_if_index_set = 1;
13249       else if (unformat (i, "vtr_op %d", &vtr_op))
13250         vtr_op_set = 1;
13251 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13252       foreach_vtr_op
13253 #undef _
13254         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13255         ;
13256       else if (unformat (i, "tag1 %d", &tag1))
13257         ;
13258       else if (unformat (i, "tag2 %d", &tag2))
13259         ;
13260       else
13261         {
13262           clib_warning ("parse error '%U'", format_unformat_error, i);
13263           return -99;
13264         }
13265     }
13266
13267   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13268     {
13269       errmsg ("missing vtr operation or sw_if_index");
13270       return -99;
13271     }
13272
13273   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13274   mp->sw_if_index = ntohl (sw_if_index);
13275   mp->vtr_op = ntohl (vtr_op);
13276   mp->push_dot1q = ntohl (push_dot1q);
13277   mp->tag1 = ntohl (tag1);
13278   mp->tag2 = ntohl (tag2);
13279
13280   S (mp);
13281   W (ret);
13282   return ret;
13283 }
13284
13285 static int
13286 api_create_vhost_user_if (vat_main_t * vam)
13287 {
13288   unformat_input_t *i = vam->input;
13289   vl_api_create_vhost_user_if_t *mp;
13290   u8 *file_name;
13291   u8 is_server = 0;
13292   u8 file_name_set = 0;
13293   u32 custom_dev_instance = ~0;
13294   u8 hwaddr[6];
13295   u8 use_custom_mac = 0;
13296   u8 disable_mrg_rxbuf = 0;
13297   u8 disable_indirect_desc = 0;
13298   u8 *tag = 0;
13299   int ret;
13300
13301   /* Shut up coverity */
13302   clib_memset (hwaddr, 0, sizeof (hwaddr));
13303
13304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13305     {
13306       if (unformat (i, "socket %s", &file_name))
13307         {
13308           file_name_set = 1;
13309         }
13310       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13311         ;
13312       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13313         use_custom_mac = 1;
13314       else if (unformat (i, "server"))
13315         is_server = 1;
13316       else if (unformat (i, "disable_mrg_rxbuf"))
13317         disable_mrg_rxbuf = 1;
13318       else if (unformat (i, "disable_indirect_desc"))
13319         disable_indirect_desc = 1;
13320       else if (unformat (i, "tag %s", &tag))
13321         ;
13322       else
13323         break;
13324     }
13325
13326   if (file_name_set == 0)
13327     {
13328       errmsg ("missing socket file name");
13329       return -99;
13330     }
13331
13332   if (vec_len (file_name) > 255)
13333     {
13334       errmsg ("socket file name too long");
13335       return -99;
13336     }
13337   vec_add1 (file_name, 0);
13338
13339   M (CREATE_VHOST_USER_IF, mp);
13340
13341   mp->is_server = is_server;
13342   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13343   mp->disable_indirect_desc = disable_indirect_desc;
13344   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13345   vec_free (file_name);
13346   if (custom_dev_instance != ~0)
13347     {
13348       mp->renumber = 1;
13349       mp->custom_dev_instance = ntohl (custom_dev_instance);
13350     }
13351
13352   mp->use_custom_mac = use_custom_mac;
13353   clib_memcpy (mp->mac_address, hwaddr, 6);
13354   if (tag)
13355     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13356   vec_free (tag);
13357
13358   S (mp);
13359   W (ret);
13360   return ret;
13361 }
13362
13363 static int
13364 api_modify_vhost_user_if (vat_main_t * vam)
13365 {
13366   unformat_input_t *i = vam->input;
13367   vl_api_modify_vhost_user_if_t *mp;
13368   u8 *file_name;
13369   u8 is_server = 0;
13370   u8 file_name_set = 0;
13371   u32 custom_dev_instance = ~0;
13372   u8 sw_if_index_set = 0;
13373   u32 sw_if_index = (u32) ~ 0;
13374   int ret;
13375
13376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13377     {
13378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13379         sw_if_index_set = 1;
13380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13381         sw_if_index_set = 1;
13382       else if (unformat (i, "socket %s", &file_name))
13383         {
13384           file_name_set = 1;
13385         }
13386       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13387         ;
13388       else if (unformat (i, "server"))
13389         is_server = 1;
13390       else
13391         break;
13392     }
13393
13394   if (sw_if_index_set == 0)
13395     {
13396       errmsg ("missing sw_if_index or interface name");
13397       return -99;
13398     }
13399
13400   if (file_name_set == 0)
13401     {
13402       errmsg ("missing socket file name");
13403       return -99;
13404     }
13405
13406   if (vec_len (file_name) > 255)
13407     {
13408       errmsg ("socket file name too long");
13409       return -99;
13410     }
13411   vec_add1 (file_name, 0);
13412
13413   M (MODIFY_VHOST_USER_IF, mp);
13414
13415   mp->sw_if_index = ntohl (sw_if_index);
13416   mp->is_server = is_server;
13417   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13418   vec_free (file_name);
13419   if (custom_dev_instance != ~0)
13420     {
13421       mp->renumber = 1;
13422       mp->custom_dev_instance = ntohl (custom_dev_instance);
13423     }
13424
13425   S (mp);
13426   W (ret);
13427   return ret;
13428 }
13429
13430 static int
13431 api_delete_vhost_user_if (vat_main_t * vam)
13432 {
13433   unformat_input_t *i = vam->input;
13434   vl_api_delete_vhost_user_if_t *mp;
13435   u32 sw_if_index = ~0;
13436   u8 sw_if_index_set = 0;
13437   int ret;
13438
13439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13440     {
13441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13442         sw_if_index_set = 1;
13443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13444         sw_if_index_set = 1;
13445       else
13446         break;
13447     }
13448
13449   if (sw_if_index_set == 0)
13450     {
13451       errmsg ("missing sw_if_index or interface name");
13452       return -99;
13453     }
13454
13455
13456   M (DELETE_VHOST_USER_IF, mp);
13457
13458   mp->sw_if_index = ntohl (sw_if_index);
13459
13460   S (mp);
13461   W (ret);
13462   return ret;
13463 }
13464
13465 static void vl_api_sw_interface_vhost_user_details_t_handler
13466   (vl_api_sw_interface_vhost_user_details_t * mp)
13467 {
13468   vat_main_t *vam = &vat_main;
13469
13470   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13471          (char *) mp->interface_name,
13472          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13473          clib_net_to_host_u64 (mp->features), mp->is_server,
13474          ntohl (mp->num_regions), (char *) mp->sock_filename);
13475   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13476 }
13477
13478 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13479   (vl_api_sw_interface_vhost_user_details_t * mp)
13480 {
13481   vat_main_t *vam = &vat_main;
13482   vat_json_node_t *node = NULL;
13483
13484   if (VAT_JSON_ARRAY != vam->json_tree.type)
13485     {
13486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13487       vat_json_init_array (&vam->json_tree);
13488     }
13489   node = vat_json_array_add (&vam->json_tree);
13490
13491   vat_json_init_object (node);
13492   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13493   vat_json_object_add_string_copy (node, "interface_name",
13494                                    mp->interface_name);
13495   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13496                             ntohl (mp->virtio_net_hdr_sz));
13497   vat_json_object_add_uint (node, "features",
13498                             clib_net_to_host_u64 (mp->features));
13499   vat_json_object_add_uint (node, "is_server", mp->is_server);
13500   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13501   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13502   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13503 }
13504
13505 static int
13506 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13507 {
13508   vl_api_sw_interface_vhost_user_dump_t *mp;
13509   vl_api_control_ping_t *mp_ping;
13510   int ret;
13511   print (vam->ofp,
13512          "Interface name            idx hdr_sz features server regions filename");
13513
13514   /* Get list of vhost-user interfaces */
13515   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13516   S (mp);
13517
13518   /* Use a control ping for synchronization */
13519   MPING (CONTROL_PING, mp_ping);
13520   S (mp_ping);
13521
13522   W (ret);
13523   return ret;
13524 }
13525
13526 static int
13527 api_show_version (vat_main_t * vam)
13528 {
13529   vl_api_show_version_t *mp;
13530   int ret;
13531
13532   M (SHOW_VERSION, mp);
13533
13534   S (mp);
13535   W (ret);
13536   return ret;
13537 }
13538
13539
13540 static int
13541 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13542 {
13543   unformat_input_t *line_input = vam->input;
13544   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13545   ip4_address_t local4, remote4;
13546   ip6_address_t local6, remote6;
13547   u8 is_add = 1;
13548   u8 ipv4_set = 0, ipv6_set = 0;
13549   u8 local_set = 0;
13550   u8 remote_set = 0;
13551   u8 grp_set = 0;
13552   u32 mcast_sw_if_index = ~0;
13553   u32 encap_vrf_id = 0;
13554   u32 decap_vrf_id = 0;
13555   u8 protocol = ~0;
13556   u32 vni;
13557   u8 vni_set = 0;
13558   int ret;
13559
13560   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13561   clib_memset (&local4, 0, sizeof local4);
13562   clib_memset (&remote4, 0, sizeof remote4);
13563   clib_memset (&local6, 0, sizeof local6);
13564   clib_memset (&remote6, 0, sizeof remote6);
13565
13566   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13567     {
13568       if (unformat (line_input, "del"))
13569         is_add = 0;
13570       else if (unformat (line_input, "local %U",
13571                          unformat_ip4_address, &local4))
13572         {
13573           local_set = 1;
13574           ipv4_set = 1;
13575         }
13576       else if (unformat (line_input, "remote %U",
13577                          unformat_ip4_address, &remote4))
13578         {
13579           remote_set = 1;
13580           ipv4_set = 1;
13581         }
13582       else if (unformat (line_input, "local %U",
13583                          unformat_ip6_address, &local6))
13584         {
13585           local_set = 1;
13586           ipv6_set = 1;
13587         }
13588       else if (unformat (line_input, "remote %U",
13589                          unformat_ip6_address, &remote6))
13590         {
13591           remote_set = 1;
13592           ipv6_set = 1;
13593         }
13594       else if (unformat (line_input, "group %U %U",
13595                          unformat_ip4_address, &remote4,
13596                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13597         {
13598           grp_set = remote_set = 1;
13599           ipv4_set = 1;
13600         }
13601       else if (unformat (line_input, "group %U",
13602                          unformat_ip4_address, &remote4))
13603         {
13604           grp_set = remote_set = 1;
13605           ipv4_set = 1;
13606         }
13607       else if (unformat (line_input, "group %U %U",
13608                          unformat_ip6_address, &remote6,
13609                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13610         {
13611           grp_set = remote_set = 1;
13612           ipv6_set = 1;
13613         }
13614       else if (unformat (line_input, "group %U",
13615                          unformat_ip6_address, &remote6))
13616         {
13617           grp_set = remote_set = 1;
13618           ipv6_set = 1;
13619         }
13620       else
13621         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13622         ;
13623       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13624         ;
13625       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13626         ;
13627       else if (unformat (line_input, "vni %d", &vni))
13628         vni_set = 1;
13629       else if (unformat (line_input, "next-ip4"))
13630         protocol = 1;
13631       else if (unformat (line_input, "next-ip6"))
13632         protocol = 2;
13633       else if (unformat (line_input, "next-ethernet"))
13634         protocol = 3;
13635       else if (unformat (line_input, "next-nsh"))
13636         protocol = 4;
13637       else
13638         {
13639           errmsg ("parse error '%U'", format_unformat_error, line_input);
13640           return -99;
13641         }
13642     }
13643
13644   if (local_set == 0)
13645     {
13646       errmsg ("tunnel local address not specified");
13647       return -99;
13648     }
13649   if (remote_set == 0)
13650     {
13651       errmsg ("tunnel remote address not specified");
13652       return -99;
13653     }
13654   if (grp_set && mcast_sw_if_index == ~0)
13655     {
13656       errmsg ("tunnel nonexistent multicast device");
13657       return -99;
13658     }
13659   if (ipv4_set && ipv6_set)
13660     {
13661       errmsg ("both IPv4 and IPv6 addresses specified");
13662       return -99;
13663     }
13664
13665   if (vni_set == 0)
13666     {
13667       errmsg ("vni not specified");
13668       return -99;
13669     }
13670
13671   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13672
13673
13674   if (ipv6_set)
13675     {
13676       clib_memcpy (&mp->local, &local6, sizeof (local6));
13677       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13678     }
13679   else
13680     {
13681       clib_memcpy (&mp->local, &local4, sizeof (local4));
13682       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13683     }
13684
13685   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13686   mp->encap_vrf_id = ntohl (encap_vrf_id);
13687   mp->decap_vrf_id = ntohl (decap_vrf_id);
13688   mp->protocol = protocol;
13689   mp->vni = ntohl (vni);
13690   mp->is_add = is_add;
13691   mp->is_ipv6 = ipv6_set;
13692
13693   S (mp);
13694   W (ret);
13695   return ret;
13696 }
13697
13698 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13699   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13700 {
13701   vat_main_t *vam = &vat_main;
13702   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13703   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13704
13705   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13706          ntohl (mp->sw_if_index),
13707          format_ip46_address, &local, IP46_TYPE_ANY,
13708          format_ip46_address, &remote, IP46_TYPE_ANY,
13709          ntohl (mp->vni), mp->protocol,
13710          ntohl (mp->mcast_sw_if_index),
13711          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13712 }
13713
13714
13715 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13716   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13717 {
13718   vat_main_t *vam = &vat_main;
13719   vat_json_node_t *node = NULL;
13720   struct in_addr ip4;
13721   struct in6_addr ip6;
13722
13723   if (VAT_JSON_ARRAY != vam->json_tree.type)
13724     {
13725       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13726       vat_json_init_array (&vam->json_tree);
13727     }
13728   node = vat_json_array_add (&vam->json_tree);
13729
13730   vat_json_init_object (node);
13731   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13732   if (mp->is_ipv6)
13733     {
13734       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13735       vat_json_object_add_ip6 (node, "local", ip6);
13736       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13737       vat_json_object_add_ip6 (node, "remote", ip6);
13738     }
13739   else
13740     {
13741       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13742       vat_json_object_add_ip4 (node, "local", ip4);
13743       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13744       vat_json_object_add_ip4 (node, "remote", ip4);
13745     }
13746   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13747   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13748   vat_json_object_add_uint (node, "mcast_sw_if_index",
13749                             ntohl (mp->mcast_sw_if_index));
13750   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13751   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13752   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13753 }
13754
13755 static int
13756 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13757 {
13758   unformat_input_t *i = vam->input;
13759   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13760   vl_api_control_ping_t *mp_ping;
13761   u32 sw_if_index;
13762   u8 sw_if_index_set = 0;
13763   int ret;
13764
13765   /* Parse args required to build the message */
13766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13767     {
13768       if (unformat (i, "sw_if_index %d", &sw_if_index))
13769         sw_if_index_set = 1;
13770       else
13771         break;
13772     }
13773
13774   if (sw_if_index_set == 0)
13775     {
13776       sw_if_index = ~0;
13777     }
13778
13779   if (!vam->json_output)
13780     {
13781       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13782              "sw_if_index", "local", "remote", "vni",
13783              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13784     }
13785
13786   /* Get list of vxlan-tunnel interfaces */
13787   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13788
13789   mp->sw_if_index = htonl (sw_if_index);
13790
13791   S (mp);
13792
13793   /* Use a control ping for synchronization */
13794   MPING (CONTROL_PING, mp_ping);
13795   S (mp_ping);
13796
13797   W (ret);
13798   return ret;
13799 }
13800
13801 static void vl_api_l2_fib_table_details_t_handler
13802   (vl_api_l2_fib_table_details_t * mp)
13803 {
13804   vat_main_t *vam = &vat_main;
13805
13806   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13807          "       %d       %d     %d",
13808          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13809          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13810          mp->bvi_mac);
13811 }
13812
13813 static void vl_api_l2_fib_table_details_t_handler_json
13814   (vl_api_l2_fib_table_details_t * mp)
13815 {
13816   vat_main_t *vam = &vat_main;
13817   vat_json_node_t *node = NULL;
13818
13819   if (VAT_JSON_ARRAY != vam->json_tree.type)
13820     {
13821       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13822       vat_json_init_array (&vam->json_tree);
13823     }
13824   node = vat_json_array_add (&vam->json_tree);
13825
13826   vat_json_init_object (node);
13827   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13828   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13829   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13830   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13831   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13832   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13833 }
13834
13835 static int
13836 api_l2_fib_table_dump (vat_main_t * vam)
13837 {
13838   unformat_input_t *i = vam->input;
13839   vl_api_l2_fib_table_dump_t *mp;
13840   vl_api_control_ping_t *mp_ping;
13841   u32 bd_id;
13842   u8 bd_id_set = 0;
13843   int ret;
13844
13845   /* Parse args required to build the message */
13846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13847     {
13848       if (unformat (i, "bd_id %d", &bd_id))
13849         bd_id_set = 1;
13850       else
13851         break;
13852     }
13853
13854   if (bd_id_set == 0)
13855     {
13856       errmsg ("missing bridge domain");
13857       return -99;
13858     }
13859
13860   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13861
13862   /* Get list of l2 fib entries */
13863   M (L2_FIB_TABLE_DUMP, mp);
13864
13865   mp->bd_id = ntohl (bd_id);
13866   S (mp);
13867
13868   /* Use a control ping for synchronization */
13869   MPING (CONTROL_PING, mp_ping);
13870   S (mp_ping);
13871
13872   W (ret);
13873   return ret;
13874 }
13875
13876
13877 static int
13878 api_interface_name_renumber (vat_main_t * vam)
13879 {
13880   unformat_input_t *line_input = vam->input;
13881   vl_api_interface_name_renumber_t *mp;
13882   u32 sw_if_index = ~0;
13883   u32 new_show_dev_instance = ~0;
13884   int ret;
13885
13886   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13887     {
13888       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13889                     &sw_if_index))
13890         ;
13891       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13892         ;
13893       else if (unformat (line_input, "new_show_dev_instance %d",
13894                          &new_show_dev_instance))
13895         ;
13896       else
13897         break;
13898     }
13899
13900   if (sw_if_index == ~0)
13901     {
13902       errmsg ("missing interface name or sw_if_index");
13903       return -99;
13904     }
13905
13906   if (new_show_dev_instance == ~0)
13907     {
13908       errmsg ("missing new_show_dev_instance");
13909       return -99;
13910     }
13911
13912   M (INTERFACE_NAME_RENUMBER, mp);
13913
13914   mp->sw_if_index = ntohl (sw_if_index);
13915   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13916
13917   S (mp);
13918   W (ret);
13919   return ret;
13920 }
13921
13922 static int
13923 api_ip_probe_neighbor (vat_main_t * vam)
13924 {
13925   unformat_input_t *i = vam->input;
13926   vl_api_ip_probe_neighbor_t *mp;
13927   vl_api_address_t dst_adr = { };
13928   u8 int_set = 0;
13929   u8 adr_set = 0;
13930   u32 sw_if_index;
13931   int ret;
13932
13933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13934     {
13935       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13936         int_set = 1;
13937       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13938         int_set = 1;
13939       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13940         adr_set = 1;
13941       else
13942         break;
13943     }
13944
13945   if (int_set == 0)
13946     {
13947       errmsg ("missing interface");
13948       return -99;
13949     }
13950
13951   if (adr_set == 0)
13952     {
13953       errmsg ("missing addresses");
13954       return -99;
13955     }
13956
13957   M (IP_PROBE_NEIGHBOR, mp);
13958
13959   mp->sw_if_index = ntohl (sw_if_index);
13960   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13961
13962   S (mp);
13963   W (ret);
13964   return ret;
13965 }
13966
13967 static int
13968 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13969 {
13970   unformat_input_t *i = vam->input;
13971   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13972   u8 mode = IP_SCAN_V46_NEIGHBORS;
13973   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13974   int ret;
13975
13976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13977     {
13978       if (unformat (i, "ip4"))
13979         mode = IP_SCAN_V4_NEIGHBORS;
13980       else if (unformat (i, "ip6"))
13981         mode = IP_SCAN_V6_NEIGHBORS;
13982       if (unformat (i, "both"))
13983         mode = IP_SCAN_V46_NEIGHBORS;
13984       else if (unformat (i, "disable"))
13985         mode = IP_SCAN_DISABLED;
13986       else if (unformat (i, "interval %d", &interval))
13987         ;
13988       else if (unformat (i, "max-time %d", &time))
13989         ;
13990       else if (unformat (i, "max-update %d", &update))
13991         ;
13992       else if (unformat (i, "delay %d", &delay))
13993         ;
13994       else if (unformat (i, "stale %d", &stale))
13995         ;
13996       else
13997         break;
13998     }
13999
14000   if (interval > 255)
14001     {
14002       errmsg ("interval cannot exceed 255 minutes.");
14003       return -99;
14004     }
14005   if (time > 255)
14006     {
14007       errmsg ("max-time cannot exceed 255 usec.");
14008       return -99;
14009     }
14010   if (update > 255)
14011     {
14012       errmsg ("max-update cannot exceed 255.");
14013       return -99;
14014     }
14015   if (delay > 255)
14016     {
14017       errmsg ("delay cannot exceed 255 msec.");
14018       return -99;
14019     }
14020   if (stale > 255)
14021     {
14022       errmsg ("stale cannot exceed 255 minutes.");
14023       return -99;
14024     }
14025
14026   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14027   mp->mode = mode;
14028   mp->scan_interval = interval;
14029   mp->max_proc_time = time;
14030   mp->max_update = update;
14031   mp->scan_int_delay = delay;
14032   mp->stale_threshold = stale;
14033
14034   S (mp);
14035   W (ret);
14036   return ret;
14037 }
14038
14039 static int
14040 api_want_ip4_arp_events (vat_main_t * vam)
14041 {
14042   unformat_input_t *line_input = vam->input;
14043   vl_api_want_ip4_arp_events_t *mp;
14044   ip4_address_t address;
14045   int address_set = 0;
14046   u32 enable_disable = 1;
14047   int ret;
14048
14049   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14050     {
14051       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14052         address_set = 1;
14053       else if (unformat (line_input, "del"))
14054         enable_disable = 0;
14055       else
14056         break;
14057     }
14058
14059   if (address_set == 0)
14060     {
14061       errmsg ("missing addresses");
14062       return -99;
14063     }
14064
14065   M (WANT_IP4_ARP_EVENTS, mp);
14066   mp->enable_disable = enable_disable;
14067   mp->pid = htonl (getpid ());
14068   clib_memcpy (mp->ip, &address, sizeof (address));
14069
14070   S (mp);
14071   W (ret);
14072   return ret;
14073 }
14074
14075 static int
14076 api_want_ip6_nd_events (vat_main_t * vam)
14077 {
14078   unformat_input_t *line_input = vam->input;
14079   vl_api_want_ip6_nd_events_t *mp;
14080   vl_api_ip6_address_t address;
14081   int address_set = 0;
14082   u32 enable_disable = 1;
14083   int ret;
14084
14085   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14086     {
14087       if (unformat
14088           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14089         address_set = 1;
14090       else if (unformat (line_input, "del"))
14091         enable_disable = 0;
14092       else
14093         break;
14094     }
14095
14096   if (address_set == 0)
14097     {
14098       errmsg ("missing addresses");
14099       return -99;
14100     }
14101
14102   M (WANT_IP6_ND_EVENTS, mp);
14103   mp->enable_disable = enable_disable;
14104   mp->pid = htonl (getpid ());
14105   clib_memcpy (&mp->ip, &address, sizeof (address));
14106
14107   S (mp);
14108   W (ret);
14109   return ret;
14110 }
14111
14112 static int
14113 api_want_l2_macs_events (vat_main_t * vam)
14114 {
14115   unformat_input_t *line_input = vam->input;
14116   vl_api_want_l2_macs_events_t *mp;
14117   u8 enable_disable = 1;
14118   u32 scan_delay = 0;
14119   u32 max_macs_in_event = 0;
14120   u32 learn_limit = 0;
14121   int ret;
14122
14123   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14124     {
14125       if (unformat (line_input, "learn-limit %d", &learn_limit))
14126         ;
14127       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14128         ;
14129       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14130         ;
14131       else if (unformat (line_input, "disable"))
14132         enable_disable = 0;
14133       else
14134         break;
14135     }
14136
14137   M (WANT_L2_MACS_EVENTS, mp);
14138   mp->enable_disable = enable_disable;
14139   mp->pid = htonl (getpid ());
14140   mp->learn_limit = htonl (learn_limit);
14141   mp->scan_delay = (u8) scan_delay;
14142   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14143   S (mp);
14144   W (ret);
14145   return ret;
14146 }
14147
14148 static int
14149 api_input_acl_set_interface (vat_main_t * vam)
14150 {
14151   unformat_input_t *i = vam->input;
14152   vl_api_input_acl_set_interface_t *mp;
14153   u32 sw_if_index;
14154   int sw_if_index_set;
14155   u32 ip4_table_index = ~0;
14156   u32 ip6_table_index = ~0;
14157   u32 l2_table_index = ~0;
14158   u8 is_add = 1;
14159   int ret;
14160
14161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14162     {
14163       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14164         sw_if_index_set = 1;
14165       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14166         sw_if_index_set = 1;
14167       else if (unformat (i, "del"))
14168         is_add = 0;
14169       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14170         ;
14171       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14172         ;
14173       else if (unformat (i, "l2-table %d", &l2_table_index))
14174         ;
14175       else
14176         {
14177           clib_warning ("parse error '%U'", format_unformat_error, i);
14178           return -99;
14179         }
14180     }
14181
14182   if (sw_if_index_set == 0)
14183     {
14184       errmsg ("missing interface name or sw_if_index");
14185       return -99;
14186     }
14187
14188   M (INPUT_ACL_SET_INTERFACE, mp);
14189
14190   mp->sw_if_index = ntohl (sw_if_index);
14191   mp->ip4_table_index = ntohl (ip4_table_index);
14192   mp->ip6_table_index = ntohl (ip6_table_index);
14193   mp->l2_table_index = ntohl (l2_table_index);
14194   mp->is_add = is_add;
14195
14196   S (mp);
14197   W (ret);
14198   return ret;
14199 }
14200
14201 static int
14202 api_output_acl_set_interface (vat_main_t * vam)
14203 {
14204   unformat_input_t *i = vam->input;
14205   vl_api_output_acl_set_interface_t *mp;
14206   u32 sw_if_index;
14207   int sw_if_index_set;
14208   u32 ip4_table_index = ~0;
14209   u32 ip6_table_index = ~0;
14210   u32 l2_table_index = ~0;
14211   u8 is_add = 1;
14212   int ret;
14213
14214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14215     {
14216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14217         sw_if_index_set = 1;
14218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14219         sw_if_index_set = 1;
14220       else if (unformat (i, "del"))
14221         is_add = 0;
14222       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14223         ;
14224       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14225         ;
14226       else if (unformat (i, "l2-table %d", &l2_table_index))
14227         ;
14228       else
14229         {
14230           clib_warning ("parse error '%U'", format_unformat_error, i);
14231           return -99;
14232         }
14233     }
14234
14235   if (sw_if_index_set == 0)
14236     {
14237       errmsg ("missing interface name or sw_if_index");
14238       return -99;
14239     }
14240
14241   M (OUTPUT_ACL_SET_INTERFACE, mp);
14242
14243   mp->sw_if_index = ntohl (sw_if_index);
14244   mp->ip4_table_index = ntohl (ip4_table_index);
14245   mp->ip6_table_index = ntohl (ip6_table_index);
14246   mp->l2_table_index = ntohl (l2_table_index);
14247   mp->is_add = is_add;
14248
14249   S (mp);
14250   W (ret);
14251   return ret;
14252 }
14253
14254 static int
14255 api_ip_address_dump (vat_main_t * vam)
14256 {
14257   unformat_input_t *i = vam->input;
14258   vl_api_ip_address_dump_t *mp;
14259   vl_api_control_ping_t *mp_ping;
14260   u32 sw_if_index = ~0;
14261   u8 sw_if_index_set = 0;
14262   u8 ipv4_set = 0;
14263   u8 ipv6_set = 0;
14264   int ret;
14265
14266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14267     {
14268       if (unformat (i, "sw_if_index %d", &sw_if_index))
14269         sw_if_index_set = 1;
14270       else
14271         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14272         sw_if_index_set = 1;
14273       else if (unformat (i, "ipv4"))
14274         ipv4_set = 1;
14275       else if (unformat (i, "ipv6"))
14276         ipv6_set = 1;
14277       else
14278         break;
14279     }
14280
14281   if (ipv4_set && ipv6_set)
14282     {
14283       errmsg ("ipv4 and ipv6 flags cannot be both set");
14284       return -99;
14285     }
14286
14287   if ((!ipv4_set) && (!ipv6_set))
14288     {
14289       errmsg ("no ipv4 nor ipv6 flag set");
14290       return -99;
14291     }
14292
14293   if (sw_if_index_set == 0)
14294     {
14295       errmsg ("missing interface name or sw_if_index");
14296       return -99;
14297     }
14298
14299   vam->current_sw_if_index = sw_if_index;
14300   vam->is_ipv6 = ipv6_set;
14301
14302   M (IP_ADDRESS_DUMP, mp);
14303   mp->sw_if_index = ntohl (sw_if_index);
14304   mp->is_ipv6 = ipv6_set;
14305   S (mp);
14306
14307   /* Use a control ping for synchronization */
14308   MPING (CONTROL_PING, mp_ping);
14309   S (mp_ping);
14310
14311   W (ret);
14312   return ret;
14313 }
14314
14315 static int
14316 api_ip_dump (vat_main_t * vam)
14317 {
14318   vl_api_ip_dump_t *mp;
14319   vl_api_control_ping_t *mp_ping;
14320   unformat_input_t *in = vam->input;
14321   int ipv4_set = 0;
14322   int ipv6_set = 0;
14323   int is_ipv6;
14324   int i;
14325   int ret;
14326
14327   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14328     {
14329       if (unformat (in, "ipv4"))
14330         ipv4_set = 1;
14331       else if (unformat (in, "ipv6"))
14332         ipv6_set = 1;
14333       else
14334         break;
14335     }
14336
14337   if (ipv4_set && ipv6_set)
14338     {
14339       errmsg ("ipv4 and ipv6 flags cannot be both set");
14340       return -99;
14341     }
14342
14343   if ((!ipv4_set) && (!ipv6_set))
14344     {
14345       errmsg ("no ipv4 nor ipv6 flag set");
14346       return -99;
14347     }
14348
14349   is_ipv6 = ipv6_set;
14350   vam->is_ipv6 = is_ipv6;
14351
14352   /* free old data */
14353   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14354     {
14355       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14356     }
14357   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14358
14359   M (IP_DUMP, mp);
14360   mp->is_ipv6 = ipv6_set;
14361   S (mp);
14362
14363   /* Use a control ping for synchronization */
14364   MPING (CONTROL_PING, mp_ping);
14365   S (mp_ping);
14366
14367   W (ret);
14368   return ret;
14369 }
14370
14371 static int
14372 api_ipsec_spd_add_del (vat_main_t * vam)
14373 {
14374   unformat_input_t *i = vam->input;
14375   vl_api_ipsec_spd_add_del_t *mp;
14376   u32 spd_id = ~0;
14377   u8 is_add = 1;
14378   int ret;
14379
14380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14381     {
14382       if (unformat (i, "spd_id %d", &spd_id))
14383         ;
14384       else if (unformat (i, "del"))
14385         is_add = 0;
14386       else
14387         {
14388           clib_warning ("parse error '%U'", format_unformat_error, i);
14389           return -99;
14390         }
14391     }
14392   if (spd_id == ~0)
14393     {
14394       errmsg ("spd_id must be set");
14395       return -99;
14396     }
14397
14398   M (IPSEC_SPD_ADD_DEL, mp);
14399
14400   mp->spd_id = ntohl (spd_id);
14401   mp->is_add = is_add;
14402
14403   S (mp);
14404   W (ret);
14405   return ret;
14406 }
14407
14408 static int
14409 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14410 {
14411   unformat_input_t *i = vam->input;
14412   vl_api_ipsec_interface_add_del_spd_t *mp;
14413   u32 sw_if_index;
14414   u8 sw_if_index_set = 0;
14415   u32 spd_id = (u32) ~ 0;
14416   u8 is_add = 1;
14417   int ret;
14418
14419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14420     {
14421       if (unformat (i, "del"))
14422         is_add = 0;
14423       else if (unformat (i, "spd_id %d", &spd_id))
14424         ;
14425       else
14426         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14427         sw_if_index_set = 1;
14428       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14429         sw_if_index_set = 1;
14430       else
14431         {
14432           clib_warning ("parse error '%U'", format_unformat_error, i);
14433           return -99;
14434         }
14435
14436     }
14437
14438   if (spd_id == (u32) ~ 0)
14439     {
14440       errmsg ("spd_id must be set");
14441       return -99;
14442     }
14443
14444   if (sw_if_index_set == 0)
14445     {
14446       errmsg ("missing interface name or sw_if_index");
14447       return -99;
14448     }
14449
14450   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14451
14452   mp->spd_id = ntohl (spd_id);
14453   mp->sw_if_index = ntohl (sw_if_index);
14454   mp->is_add = is_add;
14455
14456   S (mp);
14457   W (ret);
14458   return ret;
14459 }
14460
14461 static int
14462 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14463 {
14464   unformat_input_t *i = vam->input;
14465   vl_api_ipsec_spd_entry_add_del_t *mp;
14466   u8 is_add = 1, is_outbound = 0;
14467   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14468   i32 priority = 0;
14469   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14470   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14471   vl_api_address_t laddr_start = { }, laddr_stop =
14472   {
14473   }, raddr_start =
14474   {
14475   }, raddr_stop =
14476   {
14477   };
14478   int ret;
14479
14480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14481     {
14482       if (unformat (i, "del"))
14483         is_add = 0;
14484       if (unformat (i, "outbound"))
14485         is_outbound = 1;
14486       if (unformat (i, "inbound"))
14487         is_outbound = 0;
14488       else if (unformat (i, "spd_id %d", &spd_id))
14489         ;
14490       else if (unformat (i, "sa_id %d", &sa_id))
14491         ;
14492       else if (unformat (i, "priority %d", &priority))
14493         ;
14494       else if (unformat (i, "protocol %d", &protocol))
14495         ;
14496       else if (unformat (i, "lport_start %d", &lport_start))
14497         ;
14498       else if (unformat (i, "lport_stop %d", &lport_stop))
14499         ;
14500       else if (unformat (i, "rport_start %d", &rport_start))
14501         ;
14502       else if (unformat (i, "rport_stop %d", &rport_stop))
14503         ;
14504       else if (unformat (i, "laddr_start %U",
14505                          unformat_vl_api_address, &laddr_start))
14506         ;
14507       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14508                          &laddr_stop))
14509         ;
14510       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14511                          &raddr_start))
14512         ;
14513       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14514                          &raddr_stop))
14515         ;
14516       else
14517         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14518         {
14519           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14520             {
14521               clib_warning ("unsupported action: 'resolve'");
14522               return -99;
14523             }
14524         }
14525       else
14526         {
14527           clib_warning ("parse error '%U'", format_unformat_error, i);
14528           return -99;
14529         }
14530
14531     }
14532
14533   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14534
14535   mp->is_add = is_add;
14536
14537   mp->entry.spd_id = ntohl (spd_id);
14538   mp->entry.priority = ntohl (priority);
14539   mp->entry.is_outbound = is_outbound;
14540
14541   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14542                sizeof (vl_api_address_t));
14543   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14544                sizeof (vl_api_address_t));
14545   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14546                sizeof (vl_api_address_t));
14547   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14548                sizeof (vl_api_address_t));
14549
14550   mp->entry.protocol = (u8) protocol;
14551   mp->entry.local_port_start = ntohs ((u16) lport_start);
14552   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14553   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14554   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14555   mp->entry.policy = (u8) policy;
14556   mp->entry.sa_id = ntohl (sa_id);
14557
14558   S (mp);
14559   W (ret);
14560   return ret;
14561 }
14562
14563 static int
14564 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14565 {
14566   unformat_input_t *i = vam->input;
14567   vl_api_ipsec_sad_entry_add_del_t *mp;
14568   u32 sad_id = 0, spi = 0;
14569   u8 *ck = 0, *ik = 0;
14570   u8 is_add = 1;
14571
14572   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14573   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14574   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14575   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14576   vl_api_address_t tun_src, tun_dst;
14577   int ret;
14578
14579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14580     {
14581       if (unformat (i, "del"))
14582         is_add = 0;
14583       else if (unformat (i, "sad_id %d", &sad_id))
14584         ;
14585       else if (unformat (i, "spi %d", &spi))
14586         ;
14587       else if (unformat (i, "esp"))
14588         protocol = IPSEC_API_PROTO_ESP;
14589       else
14590         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14591         {
14592           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14593           if (ADDRESS_IP6 == tun_src.af)
14594             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14595         }
14596       else
14597         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14598         {
14599           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14600           if (ADDRESS_IP6 == tun_src.af)
14601             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14602         }
14603       else
14604         if (unformat (i, "crypto_alg %U",
14605                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14606         ;
14607       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14608         ;
14609       else if (unformat (i, "integ_alg %U",
14610                          unformat_ipsec_api_integ_alg, &integ_alg))
14611         ;
14612       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14613         ;
14614       else
14615         {
14616           clib_warning ("parse error '%U'", format_unformat_error, i);
14617           return -99;
14618         }
14619
14620     }
14621
14622   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14623
14624   mp->is_add = is_add;
14625   mp->entry.sad_id = ntohl (sad_id);
14626   mp->entry.protocol = protocol;
14627   mp->entry.spi = ntohl (spi);
14628   mp->entry.flags = flags;
14629
14630   mp->entry.crypto_algorithm = crypto_alg;
14631   mp->entry.integrity_algorithm = integ_alg;
14632   mp->entry.crypto_key.length = vec_len (ck);
14633   mp->entry.integrity_key.length = vec_len (ik);
14634
14635   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14636     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14637
14638   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14639     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14640
14641   if (ck)
14642     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14643   if (ik)
14644     clib_memcpy (mp->entry.integrity_key.data, ik,
14645                  mp->entry.integrity_key.length);
14646
14647   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14648     {
14649       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14650                    sizeof (mp->entry.tunnel_src));
14651       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14652                    sizeof (mp->entry.tunnel_dst));
14653     }
14654
14655   S (mp);
14656   W (ret);
14657   return ret;
14658 }
14659
14660 static int
14661 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14662 {
14663   unformat_input_t *i = vam->input;
14664   vl_api_ipsec_tunnel_if_add_del_t *mp;
14665   u32 local_spi = 0, remote_spi = 0;
14666   u32 crypto_alg = 0, integ_alg = 0;
14667   u8 *lck = NULL, *rck = NULL;
14668   u8 *lik = NULL, *rik = NULL;
14669   vl_api_address_t local_ip = { 0 };
14670   vl_api_address_t remote_ip = { 0 };
14671   f64 before = 0;
14672   u8 is_add = 1;
14673   u8 esn = 0;
14674   u8 anti_replay = 0;
14675   u8 renumber = 0;
14676   u32 instance = ~0;
14677   u32 count = 1, jj;
14678   int ret = -1;
14679
14680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14681     {
14682       if (unformat (i, "del"))
14683         is_add = 0;
14684       else if (unformat (i, "esn"))
14685         esn = 1;
14686       else if (unformat (i, "anti-replay"))
14687         anti_replay = 1;
14688       else if (unformat (i, "count %d", &count))
14689         ;
14690       else if (unformat (i, "local_spi %d", &local_spi))
14691         ;
14692       else if (unformat (i, "remote_spi %d", &remote_spi))
14693         ;
14694       else
14695         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14696         ;
14697       else
14698         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14699         ;
14700       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14701         ;
14702       else
14703         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14704         ;
14705       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14706         ;
14707       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14708         ;
14709       else
14710         if (unformat
14711             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14712         {
14713           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14714             {
14715               errmsg ("unsupported crypto-alg: '%U'\n",
14716                       format_ipsec_crypto_alg, crypto_alg);
14717               return -99;
14718             }
14719         }
14720       else
14721         if (unformat
14722             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14723         {
14724           if (integ_alg >= IPSEC_INTEG_N_ALG)
14725             {
14726               errmsg ("unsupported integ-alg: '%U'\n",
14727                       format_ipsec_integ_alg, integ_alg);
14728               return -99;
14729             }
14730         }
14731       else if (unformat (i, "instance %u", &instance))
14732         renumber = 1;
14733       else
14734         {
14735           errmsg ("parse error '%U'\n", format_unformat_error, i);
14736           return -99;
14737         }
14738     }
14739
14740   if (count > 1)
14741     {
14742       /* Turn on async mode */
14743       vam->async_mode = 1;
14744       vam->async_errors = 0;
14745       before = vat_time_now (vam);
14746     }
14747
14748   for (jj = 0; jj < count; jj++)
14749     {
14750       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14751
14752       mp->is_add = is_add;
14753       mp->esn = esn;
14754       mp->anti_replay = anti_replay;
14755
14756       if (jj > 0)
14757         increment_address (&remote_ip);
14758
14759       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14760       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14761
14762       mp->local_spi = htonl (local_spi + jj);
14763       mp->remote_spi = htonl (remote_spi + jj);
14764       mp->crypto_alg = (u8) crypto_alg;
14765
14766       mp->local_crypto_key_len = 0;
14767       if (lck)
14768         {
14769           mp->local_crypto_key_len = vec_len (lck);
14770           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14771             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14772           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14773         }
14774
14775       mp->remote_crypto_key_len = 0;
14776       if (rck)
14777         {
14778           mp->remote_crypto_key_len = vec_len (rck);
14779           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14780             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14781           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14782         }
14783
14784       mp->integ_alg = (u8) integ_alg;
14785
14786       mp->local_integ_key_len = 0;
14787       if (lik)
14788         {
14789           mp->local_integ_key_len = vec_len (lik);
14790           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14791             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14792           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14793         }
14794
14795       mp->remote_integ_key_len = 0;
14796       if (rik)
14797         {
14798           mp->remote_integ_key_len = vec_len (rik);
14799           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14800             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14801           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14802         }
14803
14804       if (renumber)
14805         {
14806           mp->renumber = renumber;
14807           mp->show_instance = ntohl (instance);
14808         }
14809       S (mp);
14810     }
14811
14812   /* When testing multiple add/del ops, use a control-ping to sync */
14813   if (count > 1)
14814     {
14815       vl_api_control_ping_t *mp_ping;
14816       f64 after;
14817       f64 timeout;
14818
14819       /* Shut off async mode */
14820       vam->async_mode = 0;
14821
14822       MPING (CONTROL_PING, mp_ping);
14823       S (mp_ping);
14824
14825       timeout = vat_time_now (vam) + 1.0;
14826       while (vat_time_now (vam) < timeout)
14827         if (vam->result_ready == 1)
14828           goto out;
14829       vam->retval = -99;
14830
14831     out:
14832       if (vam->retval == -99)
14833         errmsg ("timeout");
14834
14835       if (vam->async_errors > 0)
14836         {
14837           errmsg ("%d asynchronous errors", vam->async_errors);
14838           vam->retval = -98;
14839         }
14840       vam->async_errors = 0;
14841       after = vat_time_now (vam);
14842
14843       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14844       if (jj > 0)
14845         count = jj;
14846
14847       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14848              count, after - before, count / (after - before));
14849     }
14850   else
14851     {
14852       /* Wait for a reply... */
14853       W (ret);
14854       return ret;
14855     }
14856
14857   return ret;
14858 }
14859
14860 static void
14861 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14862 {
14863   vat_main_t *vam = &vat_main;
14864
14865   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14866          "crypto_key %U integ_alg %u integ_key %U flags %x "
14867          "tunnel_src_addr %U tunnel_dst_addr %U "
14868          "salt %u seq_outbound %lu last_seq_inbound %lu "
14869          "replay_window %lu\n",
14870          ntohl (mp->entry.sad_id),
14871          ntohl (mp->sw_if_index),
14872          ntohl (mp->entry.spi),
14873          ntohl (mp->entry.protocol),
14874          ntohl (mp->entry.crypto_algorithm),
14875          format_hex_bytes, mp->entry.crypto_key.data,
14876          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14877          format_hex_bytes, mp->entry.integrity_key.data,
14878          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14879          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14880          &mp->entry.tunnel_dst, ntohl (mp->salt),
14881          clib_net_to_host_u64 (mp->seq_outbound),
14882          clib_net_to_host_u64 (mp->last_seq_inbound),
14883          clib_net_to_host_u64 (mp->replay_window));
14884 }
14885
14886 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14887 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14888
14889 static void vl_api_ipsec_sa_details_t_handler_json
14890   (vl_api_ipsec_sa_details_t * mp)
14891 {
14892   vat_main_t *vam = &vat_main;
14893   vat_json_node_t *node = NULL;
14894   vl_api_ipsec_sad_flags_t flags;
14895
14896   if (VAT_JSON_ARRAY != vam->json_tree.type)
14897     {
14898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14899       vat_json_init_array (&vam->json_tree);
14900     }
14901   node = vat_json_array_add (&vam->json_tree);
14902
14903   vat_json_init_object (node);
14904   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14905   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14906   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14907   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14908   vat_json_object_add_uint (node, "crypto_alg",
14909                             ntohl (mp->entry.crypto_algorithm));
14910   vat_json_object_add_uint (node, "integ_alg",
14911                             ntohl (mp->entry.integrity_algorithm));
14912   flags = ntohl (mp->entry.flags);
14913   vat_json_object_add_uint (node, "use_esn",
14914                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14915   vat_json_object_add_uint (node, "use_anti_replay",
14916                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14917   vat_json_object_add_uint (node, "is_tunnel",
14918                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14919   vat_json_object_add_uint (node, "is_tunnel_ip6",
14920                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14921   vat_json_object_add_uint (node, "udp_encap",
14922                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14923   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14924                              mp->entry.crypto_key.length);
14925   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14926                              mp->entry.integrity_key.length);
14927   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14928   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14929   vat_json_object_add_uint (node, "replay_window",
14930                             clib_net_to_host_u64 (mp->replay_window));
14931 }
14932
14933 static int
14934 api_ipsec_sa_dump (vat_main_t * vam)
14935 {
14936   unformat_input_t *i = vam->input;
14937   vl_api_ipsec_sa_dump_t *mp;
14938   vl_api_control_ping_t *mp_ping;
14939   u32 sa_id = ~0;
14940   int ret;
14941
14942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14943     {
14944       if (unformat (i, "sa_id %d", &sa_id))
14945         ;
14946       else
14947         {
14948           clib_warning ("parse error '%U'", format_unformat_error, i);
14949           return -99;
14950         }
14951     }
14952
14953   M (IPSEC_SA_DUMP, mp);
14954
14955   mp->sa_id = ntohl (sa_id);
14956
14957   S (mp);
14958
14959   /* Use a control ping for synchronization */
14960   M (CONTROL_PING, mp_ping);
14961   S (mp_ping);
14962
14963   W (ret);
14964   return ret;
14965 }
14966
14967 static int
14968 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14969 {
14970   unformat_input_t *i = vam->input;
14971   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14972   u32 sw_if_index = ~0;
14973   u32 sa_id = ~0;
14974   u8 is_outbound = (u8) ~ 0;
14975   int ret;
14976
14977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14978     {
14979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14980         ;
14981       else if (unformat (i, "sa_id %d", &sa_id))
14982         ;
14983       else if (unformat (i, "outbound"))
14984         is_outbound = 1;
14985       else if (unformat (i, "inbound"))
14986         is_outbound = 0;
14987       else
14988         {
14989           clib_warning ("parse error '%U'", format_unformat_error, i);
14990           return -99;
14991         }
14992     }
14993
14994   if (sw_if_index == ~0)
14995     {
14996       errmsg ("interface must be specified");
14997       return -99;
14998     }
14999
15000   if (sa_id == ~0)
15001     {
15002       errmsg ("SA ID must be specified");
15003       return -99;
15004     }
15005
15006   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15007
15008   mp->sw_if_index = htonl (sw_if_index);
15009   mp->sa_id = htonl (sa_id);
15010   mp->is_outbound = is_outbound;
15011
15012   S (mp);
15013   W (ret);
15014
15015   return ret;
15016 }
15017
15018 static int
15019 api_get_first_msg_id (vat_main_t * vam)
15020 {
15021   vl_api_get_first_msg_id_t *mp;
15022   unformat_input_t *i = vam->input;
15023   u8 *name;
15024   u8 name_set = 0;
15025   int ret;
15026
15027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15028     {
15029       if (unformat (i, "client %s", &name))
15030         name_set = 1;
15031       else
15032         break;
15033     }
15034
15035   if (name_set == 0)
15036     {
15037       errmsg ("missing client name");
15038       return -99;
15039     }
15040   vec_add1 (name, 0);
15041
15042   if (vec_len (name) > 63)
15043     {
15044       errmsg ("client name too long");
15045       return -99;
15046     }
15047
15048   M (GET_FIRST_MSG_ID, mp);
15049   clib_memcpy (mp->name, name, vec_len (name));
15050   S (mp);
15051   W (ret);
15052   return ret;
15053 }
15054
15055 static int
15056 api_cop_interface_enable_disable (vat_main_t * vam)
15057 {
15058   unformat_input_t *line_input = vam->input;
15059   vl_api_cop_interface_enable_disable_t *mp;
15060   u32 sw_if_index = ~0;
15061   u8 enable_disable = 1;
15062   int ret;
15063
15064   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15065     {
15066       if (unformat (line_input, "disable"))
15067         enable_disable = 0;
15068       if (unformat (line_input, "enable"))
15069         enable_disable = 1;
15070       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15071                          vam, &sw_if_index))
15072         ;
15073       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15074         ;
15075       else
15076         break;
15077     }
15078
15079   if (sw_if_index == ~0)
15080     {
15081       errmsg ("missing interface name or sw_if_index");
15082       return -99;
15083     }
15084
15085   /* Construct the API message */
15086   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15087   mp->sw_if_index = ntohl (sw_if_index);
15088   mp->enable_disable = enable_disable;
15089
15090   /* send it... */
15091   S (mp);
15092   /* Wait for the reply */
15093   W (ret);
15094   return ret;
15095 }
15096
15097 static int
15098 api_cop_whitelist_enable_disable (vat_main_t * vam)
15099 {
15100   unformat_input_t *line_input = vam->input;
15101   vl_api_cop_whitelist_enable_disable_t *mp;
15102   u32 sw_if_index = ~0;
15103   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15104   u32 fib_id = 0;
15105   int ret;
15106
15107   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15108     {
15109       if (unformat (line_input, "ip4"))
15110         ip4 = 1;
15111       else if (unformat (line_input, "ip6"))
15112         ip6 = 1;
15113       else if (unformat (line_input, "default"))
15114         default_cop = 1;
15115       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15116                          vam, &sw_if_index))
15117         ;
15118       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15119         ;
15120       else if (unformat (line_input, "fib-id %d", &fib_id))
15121         ;
15122       else
15123         break;
15124     }
15125
15126   if (sw_if_index == ~0)
15127     {
15128       errmsg ("missing interface name or sw_if_index");
15129       return -99;
15130     }
15131
15132   /* Construct the API message */
15133   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15134   mp->sw_if_index = ntohl (sw_if_index);
15135   mp->fib_id = ntohl (fib_id);
15136   mp->ip4 = ip4;
15137   mp->ip6 = ip6;
15138   mp->default_cop = default_cop;
15139
15140   /* send it... */
15141   S (mp);
15142   /* Wait for the reply */
15143   W (ret);
15144   return ret;
15145 }
15146
15147 static int
15148 api_get_node_graph (vat_main_t * vam)
15149 {
15150   vl_api_get_node_graph_t *mp;
15151   int ret;
15152
15153   M (GET_NODE_GRAPH, mp);
15154
15155   /* send it... */
15156   S (mp);
15157   /* Wait for the reply */
15158   W (ret);
15159   return ret;
15160 }
15161
15162 /* *INDENT-OFF* */
15163 /** Used for parsing LISP eids */
15164 typedef CLIB_PACKED(struct{
15165   u8 addr[16];   /**< eid address */
15166   u32 len;       /**< prefix length if IP */
15167   u8 type;      /**< type of eid */
15168 }) lisp_eid_vat_t;
15169 /* *INDENT-ON* */
15170
15171 static uword
15172 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15173 {
15174   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15175
15176   clib_memset (a, 0, sizeof (a[0]));
15177
15178   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15179     {
15180       a->type = 0;              /* ipv4 type */
15181     }
15182   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15183     {
15184       a->type = 1;              /* ipv6 type */
15185     }
15186   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15187     {
15188       a->type = 2;              /* mac type */
15189     }
15190   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15191     {
15192       a->type = 3;              /* NSH type */
15193       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15194       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15195     }
15196   else
15197     {
15198       return 0;
15199     }
15200
15201   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15202     {
15203       return 0;
15204     }
15205
15206   return 1;
15207 }
15208
15209 static int
15210 lisp_eid_size_vat (u8 type)
15211 {
15212   switch (type)
15213     {
15214     case 0:
15215       return 4;
15216     case 1:
15217       return 16;
15218     case 2:
15219       return 6;
15220     case 3:
15221       return 5;
15222     }
15223   return 0;
15224 }
15225
15226 static void
15227 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15228 {
15229   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15230 }
15231
15232 static int
15233 api_one_add_del_locator_set (vat_main_t * vam)
15234 {
15235   unformat_input_t *input = vam->input;
15236   vl_api_one_add_del_locator_set_t *mp;
15237   u8 is_add = 1;
15238   u8 *locator_set_name = NULL;
15239   u8 locator_set_name_set = 0;
15240   vl_api_local_locator_t locator, *locators = 0;
15241   u32 sw_if_index, priority, weight;
15242   u32 data_len = 0;
15243
15244   int ret;
15245   /* Parse args required to build the message */
15246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15247     {
15248       if (unformat (input, "del"))
15249         {
15250           is_add = 0;
15251         }
15252       else if (unformat (input, "locator-set %s", &locator_set_name))
15253         {
15254           locator_set_name_set = 1;
15255         }
15256       else if (unformat (input, "sw_if_index %u p %u w %u",
15257                          &sw_if_index, &priority, &weight))
15258         {
15259           locator.sw_if_index = htonl (sw_if_index);
15260           locator.priority = priority;
15261           locator.weight = weight;
15262           vec_add1 (locators, locator);
15263         }
15264       else
15265         if (unformat
15266             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15267              &sw_if_index, &priority, &weight))
15268         {
15269           locator.sw_if_index = htonl (sw_if_index);
15270           locator.priority = priority;
15271           locator.weight = weight;
15272           vec_add1 (locators, locator);
15273         }
15274       else
15275         break;
15276     }
15277
15278   if (locator_set_name_set == 0)
15279     {
15280       errmsg ("missing locator-set name");
15281       vec_free (locators);
15282       return -99;
15283     }
15284
15285   if (vec_len (locator_set_name) > 64)
15286     {
15287       errmsg ("locator-set name too long");
15288       vec_free (locator_set_name);
15289       vec_free (locators);
15290       return -99;
15291     }
15292   vec_add1 (locator_set_name, 0);
15293
15294   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15295
15296   /* Construct the API message */
15297   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15298
15299   mp->is_add = is_add;
15300   clib_memcpy (mp->locator_set_name, locator_set_name,
15301                vec_len (locator_set_name));
15302   vec_free (locator_set_name);
15303
15304   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15305   if (locators)
15306     clib_memcpy (mp->locators, locators, data_len);
15307   vec_free (locators);
15308
15309   /* send it... */
15310   S (mp);
15311
15312   /* Wait for a reply... */
15313   W (ret);
15314   return ret;
15315 }
15316
15317 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15318
15319 static int
15320 api_one_add_del_locator (vat_main_t * vam)
15321 {
15322   unformat_input_t *input = vam->input;
15323   vl_api_one_add_del_locator_t *mp;
15324   u32 tmp_if_index = ~0;
15325   u32 sw_if_index = ~0;
15326   u8 sw_if_index_set = 0;
15327   u8 sw_if_index_if_name_set = 0;
15328   u32 priority = ~0;
15329   u8 priority_set = 0;
15330   u32 weight = ~0;
15331   u8 weight_set = 0;
15332   u8 is_add = 1;
15333   u8 *locator_set_name = NULL;
15334   u8 locator_set_name_set = 0;
15335   int ret;
15336
15337   /* Parse args required to build the message */
15338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15339     {
15340       if (unformat (input, "del"))
15341         {
15342           is_add = 0;
15343         }
15344       else if (unformat (input, "locator-set %s", &locator_set_name))
15345         {
15346           locator_set_name_set = 1;
15347         }
15348       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15349                          &tmp_if_index))
15350         {
15351           sw_if_index_if_name_set = 1;
15352           sw_if_index = tmp_if_index;
15353         }
15354       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15355         {
15356           sw_if_index_set = 1;
15357           sw_if_index = tmp_if_index;
15358         }
15359       else if (unformat (input, "p %d", &priority))
15360         {
15361           priority_set = 1;
15362         }
15363       else if (unformat (input, "w %d", &weight))
15364         {
15365           weight_set = 1;
15366         }
15367       else
15368         break;
15369     }
15370
15371   if (locator_set_name_set == 0)
15372     {
15373       errmsg ("missing locator-set name");
15374       return -99;
15375     }
15376
15377   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15378     {
15379       errmsg ("missing sw_if_index");
15380       vec_free (locator_set_name);
15381       return -99;
15382     }
15383
15384   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15385     {
15386       errmsg ("cannot use both params interface name and sw_if_index");
15387       vec_free (locator_set_name);
15388       return -99;
15389     }
15390
15391   if (priority_set == 0)
15392     {
15393       errmsg ("missing locator-set priority");
15394       vec_free (locator_set_name);
15395       return -99;
15396     }
15397
15398   if (weight_set == 0)
15399     {
15400       errmsg ("missing locator-set weight");
15401       vec_free (locator_set_name);
15402       return -99;
15403     }
15404
15405   if (vec_len (locator_set_name) > 64)
15406     {
15407       errmsg ("locator-set name too long");
15408       vec_free (locator_set_name);
15409       return -99;
15410     }
15411   vec_add1 (locator_set_name, 0);
15412
15413   /* Construct the API message */
15414   M (ONE_ADD_DEL_LOCATOR, mp);
15415
15416   mp->is_add = is_add;
15417   mp->sw_if_index = ntohl (sw_if_index);
15418   mp->priority = priority;
15419   mp->weight = weight;
15420   clib_memcpy (mp->locator_set_name, locator_set_name,
15421                vec_len (locator_set_name));
15422   vec_free (locator_set_name);
15423
15424   /* send it... */
15425   S (mp);
15426
15427   /* Wait for a reply... */
15428   W (ret);
15429   return ret;
15430 }
15431
15432 #define api_lisp_add_del_locator api_one_add_del_locator
15433
15434 uword
15435 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15436 {
15437   u32 *key_id = va_arg (*args, u32 *);
15438   u8 *s = 0;
15439
15440   if (unformat (input, "%s", &s))
15441     {
15442       if (!strcmp ((char *) s, "sha1"))
15443         key_id[0] = HMAC_SHA_1_96;
15444       else if (!strcmp ((char *) s, "sha256"))
15445         key_id[0] = HMAC_SHA_256_128;
15446       else
15447         {
15448           clib_warning ("invalid key_id: '%s'", s);
15449           key_id[0] = HMAC_NO_KEY;
15450         }
15451     }
15452   else
15453     return 0;
15454
15455   vec_free (s);
15456   return 1;
15457 }
15458
15459 static int
15460 api_one_add_del_local_eid (vat_main_t * vam)
15461 {
15462   unformat_input_t *input = vam->input;
15463   vl_api_one_add_del_local_eid_t *mp;
15464   u8 is_add = 1;
15465   u8 eid_set = 0;
15466   lisp_eid_vat_t _eid, *eid = &_eid;
15467   u8 *locator_set_name = 0;
15468   u8 locator_set_name_set = 0;
15469   u32 vni = 0;
15470   u16 key_id = 0;
15471   u8 *key = 0;
15472   int ret;
15473
15474   /* Parse args required to build the message */
15475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15476     {
15477       if (unformat (input, "del"))
15478         {
15479           is_add = 0;
15480         }
15481       else if (unformat (input, "vni %d", &vni))
15482         {
15483           ;
15484         }
15485       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15486         {
15487           eid_set = 1;
15488         }
15489       else if (unformat (input, "locator-set %s", &locator_set_name))
15490         {
15491           locator_set_name_set = 1;
15492         }
15493       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15494         ;
15495       else if (unformat (input, "secret-key %_%v%_", &key))
15496         ;
15497       else
15498         break;
15499     }
15500
15501   if (locator_set_name_set == 0)
15502     {
15503       errmsg ("missing locator-set name");
15504       return -99;
15505     }
15506
15507   if (0 == eid_set)
15508     {
15509       errmsg ("EID address not set!");
15510       vec_free (locator_set_name);
15511       return -99;
15512     }
15513
15514   if (key && (0 == key_id))
15515     {
15516       errmsg ("invalid key_id!");
15517       return -99;
15518     }
15519
15520   if (vec_len (key) > 64)
15521     {
15522       errmsg ("key too long");
15523       vec_free (key);
15524       return -99;
15525     }
15526
15527   if (vec_len (locator_set_name) > 64)
15528     {
15529       errmsg ("locator-set name too long");
15530       vec_free (locator_set_name);
15531       return -99;
15532     }
15533   vec_add1 (locator_set_name, 0);
15534
15535   /* Construct the API message */
15536   M (ONE_ADD_DEL_LOCAL_EID, mp);
15537
15538   mp->is_add = is_add;
15539   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15540   mp->eid_type = eid->type;
15541   mp->prefix_len = eid->len;
15542   mp->vni = clib_host_to_net_u32 (vni);
15543   mp->key_id = clib_host_to_net_u16 (key_id);
15544   clib_memcpy (mp->locator_set_name, locator_set_name,
15545                vec_len (locator_set_name));
15546   clib_memcpy (mp->key, key, vec_len (key));
15547
15548   vec_free (locator_set_name);
15549   vec_free (key);
15550
15551   /* send it... */
15552   S (mp);
15553
15554   /* Wait for a reply... */
15555   W (ret);
15556   return ret;
15557 }
15558
15559 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15560
15561 static int
15562 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15563 {
15564   u32 dp_table = 0, vni = 0;;
15565   unformat_input_t *input = vam->input;
15566   vl_api_gpe_add_del_fwd_entry_t *mp;
15567   u8 is_add = 1;
15568   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15569   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15570   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15571   u32 action = ~0, w;
15572   ip4_address_t rmt_rloc4, lcl_rloc4;
15573   ip6_address_t rmt_rloc6, lcl_rloc6;
15574   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15575   int ret;
15576
15577   clib_memset (&rloc, 0, sizeof (rloc));
15578
15579   /* Parse args required to build the message */
15580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15581     {
15582       if (unformat (input, "del"))
15583         is_add = 0;
15584       else if (unformat (input, "add"))
15585         is_add = 1;
15586       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15587         {
15588           rmt_eid_set = 1;
15589         }
15590       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15591         {
15592           lcl_eid_set = 1;
15593         }
15594       else if (unformat (input, "vrf %d", &dp_table))
15595         ;
15596       else if (unformat (input, "bd %d", &dp_table))
15597         ;
15598       else if (unformat (input, "vni %d", &vni))
15599         ;
15600       else if (unformat (input, "w %d", &w))
15601         {
15602           if (!curr_rloc)
15603             {
15604               errmsg ("No RLOC configured for setting priority/weight!");
15605               return -99;
15606             }
15607           curr_rloc->weight = w;
15608         }
15609       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15610                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15611         {
15612           rloc.is_ip4 = 1;
15613
15614           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15615           rloc.weight = 0;
15616           vec_add1 (lcl_locs, rloc);
15617
15618           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15619           vec_add1 (rmt_locs, rloc);
15620           /* weight saved in rmt loc */
15621           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15622         }
15623       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15624                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15625         {
15626           rloc.is_ip4 = 0;
15627           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15628           rloc.weight = 0;
15629           vec_add1 (lcl_locs, rloc);
15630
15631           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15632           vec_add1 (rmt_locs, rloc);
15633           /* weight saved in rmt loc */
15634           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15635         }
15636       else if (unformat (input, "action %d", &action))
15637         {
15638           ;
15639         }
15640       else
15641         {
15642           clib_warning ("parse error '%U'", format_unformat_error, input);
15643           return -99;
15644         }
15645     }
15646
15647   if (!rmt_eid_set)
15648     {
15649       errmsg ("remote eid addresses not set");
15650       return -99;
15651     }
15652
15653   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15654     {
15655       errmsg ("eid types don't match");
15656       return -99;
15657     }
15658
15659   if (0 == rmt_locs && (u32) ~ 0 == action)
15660     {
15661       errmsg ("action not set for negative mapping");
15662       return -99;
15663     }
15664
15665   /* Construct the API message */
15666   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15667       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15668
15669   mp->is_add = is_add;
15670   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15671   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15672   mp->eid_type = rmt_eid->type;
15673   mp->dp_table = clib_host_to_net_u32 (dp_table);
15674   mp->vni = clib_host_to_net_u32 (vni);
15675   mp->rmt_len = rmt_eid->len;
15676   mp->lcl_len = lcl_eid->len;
15677   mp->action = action;
15678
15679   if (0 != rmt_locs && 0 != lcl_locs)
15680     {
15681       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15682       clib_memcpy (mp->locs, lcl_locs,
15683                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15684
15685       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15686       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15687                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15688     }
15689   vec_free (lcl_locs);
15690   vec_free (rmt_locs);
15691
15692   /* send it... */
15693   S (mp);
15694
15695   /* Wait for a reply... */
15696   W (ret);
15697   return ret;
15698 }
15699
15700 static int
15701 api_one_add_del_map_server (vat_main_t * vam)
15702 {
15703   unformat_input_t *input = vam->input;
15704   vl_api_one_add_del_map_server_t *mp;
15705   u8 is_add = 1;
15706   u8 ipv4_set = 0;
15707   u8 ipv6_set = 0;
15708   ip4_address_t ipv4;
15709   ip6_address_t ipv6;
15710   int ret;
15711
15712   /* Parse args required to build the message */
15713   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15714     {
15715       if (unformat (input, "del"))
15716         {
15717           is_add = 0;
15718         }
15719       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15720         {
15721           ipv4_set = 1;
15722         }
15723       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15724         {
15725           ipv6_set = 1;
15726         }
15727       else
15728         break;
15729     }
15730
15731   if (ipv4_set && ipv6_set)
15732     {
15733       errmsg ("both eid v4 and v6 addresses set");
15734       return -99;
15735     }
15736
15737   if (!ipv4_set && !ipv6_set)
15738     {
15739       errmsg ("eid addresses not set");
15740       return -99;
15741     }
15742
15743   /* Construct the API message */
15744   M (ONE_ADD_DEL_MAP_SERVER, mp);
15745
15746   mp->is_add = is_add;
15747   if (ipv6_set)
15748     {
15749       mp->is_ipv6 = 1;
15750       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15751     }
15752   else
15753     {
15754       mp->is_ipv6 = 0;
15755       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15756     }
15757
15758   /* send it... */
15759   S (mp);
15760
15761   /* Wait for a reply... */
15762   W (ret);
15763   return ret;
15764 }
15765
15766 #define api_lisp_add_del_map_server api_one_add_del_map_server
15767
15768 static int
15769 api_one_add_del_map_resolver (vat_main_t * vam)
15770 {
15771   unformat_input_t *input = vam->input;
15772   vl_api_one_add_del_map_resolver_t *mp;
15773   u8 is_add = 1;
15774   u8 ipv4_set = 0;
15775   u8 ipv6_set = 0;
15776   ip4_address_t ipv4;
15777   ip6_address_t ipv6;
15778   int ret;
15779
15780   /* Parse args required to build the message */
15781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15782     {
15783       if (unformat (input, "del"))
15784         {
15785           is_add = 0;
15786         }
15787       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15788         {
15789           ipv4_set = 1;
15790         }
15791       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15792         {
15793           ipv6_set = 1;
15794         }
15795       else
15796         break;
15797     }
15798
15799   if (ipv4_set && ipv6_set)
15800     {
15801       errmsg ("both eid v4 and v6 addresses set");
15802       return -99;
15803     }
15804
15805   if (!ipv4_set && !ipv6_set)
15806     {
15807       errmsg ("eid addresses not set");
15808       return -99;
15809     }
15810
15811   /* Construct the API message */
15812   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15813
15814   mp->is_add = is_add;
15815   if (ipv6_set)
15816     {
15817       mp->is_ipv6 = 1;
15818       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15819     }
15820   else
15821     {
15822       mp->is_ipv6 = 0;
15823       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15824     }
15825
15826   /* send it... */
15827   S (mp);
15828
15829   /* Wait for a reply... */
15830   W (ret);
15831   return ret;
15832 }
15833
15834 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15835
15836 static int
15837 api_lisp_gpe_enable_disable (vat_main_t * vam)
15838 {
15839   unformat_input_t *input = vam->input;
15840   vl_api_gpe_enable_disable_t *mp;
15841   u8 is_set = 0;
15842   u8 is_en = 1;
15843   int ret;
15844
15845   /* Parse args required to build the message */
15846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15847     {
15848       if (unformat (input, "enable"))
15849         {
15850           is_set = 1;
15851           is_en = 1;
15852         }
15853       else if (unformat (input, "disable"))
15854         {
15855           is_set = 1;
15856           is_en = 0;
15857         }
15858       else
15859         break;
15860     }
15861
15862   if (is_set == 0)
15863     {
15864       errmsg ("Value not set");
15865       return -99;
15866     }
15867
15868   /* Construct the API message */
15869   M (GPE_ENABLE_DISABLE, mp);
15870
15871   mp->is_en = is_en;
15872
15873   /* send it... */
15874   S (mp);
15875
15876   /* Wait for a reply... */
15877   W (ret);
15878   return ret;
15879 }
15880
15881 static int
15882 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15883 {
15884   unformat_input_t *input = vam->input;
15885   vl_api_one_rloc_probe_enable_disable_t *mp;
15886   u8 is_set = 0;
15887   u8 is_en = 0;
15888   int ret;
15889
15890   /* Parse args required to build the message */
15891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15892     {
15893       if (unformat (input, "enable"))
15894         {
15895           is_set = 1;
15896           is_en = 1;
15897         }
15898       else if (unformat (input, "disable"))
15899         is_set = 1;
15900       else
15901         break;
15902     }
15903
15904   if (!is_set)
15905     {
15906       errmsg ("Value not set");
15907       return -99;
15908     }
15909
15910   /* Construct the API message */
15911   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15912
15913   mp->is_enabled = is_en;
15914
15915   /* send it... */
15916   S (mp);
15917
15918   /* Wait for a reply... */
15919   W (ret);
15920   return ret;
15921 }
15922
15923 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15924
15925 static int
15926 api_one_map_register_enable_disable (vat_main_t * vam)
15927 {
15928   unformat_input_t *input = vam->input;
15929   vl_api_one_map_register_enable_disable_t *mp;
15930   u8 is_set = 0;
15931   u8 is_en = 0;
15932   int ret;
15933
15934   /* Parse args required to build the message */
15935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15936     {
15937       if (unformat (input, "enable"))
15938         {
15939           is_set = 1;
15940           is_en = 1;
15941         }
15942       else if (unformat (input, "disable"))
15943         is_set = 1;
15944       else
15945         break;
15946     }
15947
15948   if (!is_set)
15949     {
15950       errmsg ("Value not set");
15951       return -99;
15952     }
15953
15954   /* Construct the API message */
15955   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15956
15957   mp->is_enabled = is_en;
15958
15959   /* send it... */
15960   S (mp);
15961
15962   /* Wait for a reply... */
15963   W (ret);
15964   return ret;
15965 }
15966
15967 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15968
15969 static int
15970 api_one_enable_disable (vat_main_t * vam)
15971 {
15972   unformat_input_t *input = vam->input;
15973   vl_api_one_enable_disable_t *mp;
15974   u8 is_set = 0;
15975   u8 is_en = 0;
15976   int ret;
15977
15978   /* Parse args required to build the message */
15979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15980     {
15981       if (unformat (input, "enable"))
15982         {
15983           is_set = 1;
15984           is_en = 1;
15985         }
15986       else if (unformat (input, "disable"))
15987         {
15988           is_set = 1;
15989         }
15990       else
15991         break;
15992     }
15993
15994   if (!is_set)
15995     {
15996       errmsg ("Value not set");
15997       return -99;
15998     }
15999
16000   /* Construct the API message */
16001   M (ONE_ENABLE_DISABLE, mp);
16002
16003   mp->is_en = is_en;
16004
16005   /* send it... */
16006   S (mp);
16007
16008   /* Wait for a reply... */
16009   W (ret);
16010   return ret;
16011 }
16012
16013 #define api_lisp_enable_disable api_one_enable_disable
16014
16015 static int
16016 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16017 {
16018   unformat_input_t *input = vam->input;
16019   vl_api_one_enable_disable_xtr_mode_t *mp;
16020   u8 is_set = 0;
16021   u8 is_en = 0;
16022   int ret;
16023
16024   /* Parse args required to build the message */
16025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16026     {
16027       if (unformat (input, "enable"))
16028         {
16029           is_set = 1;
16030           is_en = 1;
16031         }
16032       else if (unformat (input, "disable"))
16033         {
16034           is_set = 1;
16035         }
16036       else
16037         break;
16038     }
16039
16040   if (!is_set)
16041     {
16042       errmsg ("Value not set");
16043       return -99;
16044     }
16045
16046   /* Construct the API message */
16047   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16048
16049   mp->is_en = is_en;
16050
16051   /* send it... */
16052   S (mp);
16053
16054   /* Wait for a reply... */
16055   W (ret);
16056   return ret;
16057 }
16058
16059 static int
16060 api_one_show_xtr_mode (vat_main_t * vam)
16061 {
16062   vl_api_one_show_xtr_mode_t *mp;
16063   int ret;
16064
16065   /* Construct the API message */
16066   M (ONE_SHOW_XTR_MODE, mp);
16067
16068   /* send it... */
16069   S (mp);
16070
16071   /* Wait for a reply... */
16072   W (ret);
16073   return ret;
16074 }
16075
16076 static int
16077 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16078 {
16079   unformat_input_t *input = vam->input;
16080   vl_api_one_enable_disable_pitr_mode_t *mp;
16081   u8 is_set = 0;
16082   u8 is_en = 0;
16083   int ret;
16084
16085   /* Parse args required to build the message */
16086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16087     {
16088       if (unformat (input, "enable"))
16089         {
16090           is_set = 1;
16091           is_en = 1;
16092         }
16093       else if (unformat (input, "disable"))
16094         {
16095           is_set = 1;
16096         }
16097       else
16098         break;
16099     }
16100
16101   if (!is_set)
16102     {
16103       errmsg ("Value not set");
16104       return -99;
16105     }
16106
16107   /* Construct the API message */
16108   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16109
16110   mp->is_en = is_en;
16111
16112   /* send it... */
16113   S (mp);
16114
16115   /* Wait for a reply... */
16116   W (ret);
16117   return ret;
16118 }
16119
16120 static int
16121 api_one_show_pitr_mode (vat_main_t * vam)
16122 {
16123   vl_api_one_show_pitr_mode_t *mp;
16124   int ret;
16125
16126   /* Construct the API message */
16127   M (ONE_SHOW_PITR_MODE, mp);
16128
16129   /* send it... */
16130   S (mp);
16131
16132   /* Wait for a reply... */
16133   W (ret);
16134   return ret;
16135 }
16136
16137 static int
16138 api_one_enable_disable_petr_mode (vat_main_t * vam)
16139 {
16140   unformat_input_t *input = vam->input;
16141   vl_api_one_enable_disable_petr_mode_t *mp;
16142   u8 is_set = 0;
16143   u8 is_en = 0;
16144   int ret;
16145
16146   /* Parse args required to build the message */
16147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16148     {
16149       if (unformat (input, "enable"))
16150         {
16151           is_set = 1;
16152           is_en = 1;
16153         }
16154       else if (unformat (input, "disable"))
16155         {
16156           is_set = 1;
16157         }
16158       else
16159         break;
16160     }
16161
16162   if (!is_set)
16163     {
16164       errmsg ("Value not set");
16165       return -99;
16166     }
16167
16168   /* Construct the API message */
16169   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16170
16171   mp->is_en = is_en;
16172
16173   /* send it... */
16174   S (mp);
16175
16176   /* Wait for a reply... */
16177   W (ret);
16178   return ret;
16179 }
16180
16181 static int
16182 api_one_show_petr_mode (vat_main_t * vam)
16183 {
16184   vl_api_one_show_petr_mode_t *mp;
16185   int ret;
16186
16187   /* Construct the API message */
16188   M (ONE_SHOW_PETR_MODE, mp);
16189
16190   /* send it... */
16191   S (mp);
16192
16193   /* Wait for a reply... */
16194   W (ret);
16195   return ret;
16196 }
16197
16198 static int
16199 api_show_one_map_register_state (vat_main_t * vam)
16200 {
16201   vl_api_show_one_map_register_state_t *mp;
16202   int ret;
16203
16204   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16205
16206   /* send */
16207   S (mp);
16208
16209   /* wait for reply */
16210   W (ret);
16211   return ret;
16212 }
16213
16214 #define api_show_lisp_map_register_state api_show_one_map_register_state
16215
16216 static int
16217 api_show_one_rloc_probe_state (vat_main_t * vam)
16218 {
16219   vl_api_show_one_rloc_probe_state_t *mp;
16220   int ret;
16221
16222   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16223
16224   /* send */
16225   S (mp);
16226
16227   /* wait for reply */
16228   W (ret);
16229   return ret;
16230 }
16231
16232 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16233
16234 static int
16235 api_one_add_del_ndp_entry (vat_main_t * vam)
16236 {
16237   vl_api_one_add_del_ndp_entry_t *mp;
16238   unformat_input_t *input = vam->input;
16239   u8 is_add = 1;
16240   u8 mac_set = 0;
16241   u8 bd_set = 0;
16242   u8 ip_set = 0;
16243   u8 mac[6] = { 0, };
16244   u8 ip6[16] = { 0, };
16245   u32 bd = ~0;
16246   int ret;
16247
16248   /* Parse args required to build the message */
16249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16250     {
16251       if (unformat (input, "del"))
16252         is_add = 0;
16253       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16254         mac_set = 1;
16255       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16256         ip_set = 1;
16257       else if (unformat (input, "bd %d", &bd))
16258         bd_set = 1;
16259       else
16260         {
16261           errmsg ("parse error '%U'", format_unformat_error, input);
16262           return -99;
16263         }
16264     }
16265
16266   if (!bd_set || !ip_set || (!mac_set && is_add))
16267     {
16268       errmsg ("Missing BD, IP or MAC!");
16269       return -99;
16270     }
16271
16272   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16273   mp->is_add = is_add;
16274   clib_memcpy (mp->mac, mac, 6);
16275   mp->bd = clib_host_to_net_u32 (bd);
16276   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16277
16278   /* send */
16279   S (mp);
16280
16281   /* wait for reply */
16282   W (ret);
16283   return ret;
16284 }
16285
16286 static int
16287 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16288 {
16289   vl_api_one_add_del_l2_arp_entry_t *mp;
16290   unformat_input_t *input = vam->input;
16291   u8 is_add = 1;
16292   u8 mac_set = 0;
16293   u8 bd_set = 0;
16294   u8 ip_set = 0;
16295   u8 mac[6] = { 0, };
16296   u32 ip4 = 0, bd = ~0;
16297   int ret;
16298
16299   /* Parse args required to build the message */
16300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16301     {
16302       if (unformat (input, "del"))
16303         is_add = 0;
16304       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16305         mac_set = 1;
16306       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16307         ip_set = 1;
16308       else if (unformat (input, "bd %d", &bd))
16309         bd_set = 1;
16310       else
16311         {
16312           errmsg ("parse error '%U'", format_unformat_error, input);
16313           return -99;
16314         }
16315     }
16316
16317   if (!bd_set || !ip_set || (!mac_set && is_add))
16318     {
16319       errmsg ("Missing BD, IP or MAC!");
16320       return -99;
16321     }
16322
16323   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16324   mp->is_add = is_add;
16325   clib_memcpy (mp->mac, mac, 6);
16326   mp->bd = clib_host_to_net_u32 (bd);
16327   mp->ip4 = ip4;
16328
16329   /* send */
16330   S (mp);
16331
16332   /* wait for reply */
16333   W (ret);
16334   return ret;
16335 }
16336
16337 static int
16338 api_one_ndp_bd_get (vat_main_t * vam)
16339 {
16340   vl_api_one_ndp_bd_get_t *mp;
16341   int ret;
16342
16343   M (ONE_NDP_BD_GET, mp);
16344
16345   /* send */
16346   S (mp);
16347
16348   /* wait for reply */
16349   W (ret);
16350   return ret;
16351 }
16352
16353 static int
16354 api_one_ndp_entries_get (vat_main_t * vam)
16355 {
16356   vl_api_one_ndp_entries_get_t *mp;
16357   unformat_input_t *input = vam->input;
16358   u8 bd_set = 0;
16359   u32 bd = ~0;
16360   int ret;
16361
16362   /* Parse args required to build the message */
16363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16364     {
16365       if (unformat (input, "bd %d", &bd))
16366         bd_set = 1;
16367       else
16368         {
16369           errmsg ("parse error '%U'", format_unformat_error, input);
16370           return -99;
16371         }
16372     }
16373
16374   if (!bd_set)
16375     {
16376       errmsg ("Expected bridge domain!");
16377       return -99;
16378     }
16379
16380   M (ONE_NDP_ENTRIES_GET, mp);
16381   mp->bd = clib_host_to_net_u32 (bd);
16382
16383   /* send */
16384   S (mp);
16385
16386   /* wait for reply */
16387   W (ret);
16388   return ret;
16389 }
16390
16391 static int
16392 api_one_l2_arp_bd_get (vat_main_t * vam)
16393 {
16394   vl_api_one_l2_arp_bd_get_t *mp;
16395   int ret;
16396
16397   M (ONE_L2_ARP_BD_GET, mp);
16398
16399   /* send */
16400   S (mp);
16401
16402   /* wait for reply */
16403   W (ret);
16404   return ret;
16405 }
16406
16407 static int
16408 api_one_l2_arp_entries_get (vat_main_t * vam)
16409 {
16410   vl_api_one_l2_arp_entries_get_t *mp;
16411   unformat_input_t *input = vam->input;
16412   u8 bd_set = 0;
16413   u32 bd = ~0;
16414   int ret;
16415
16416   /* Parse args required to build the message */
16417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16418     {
16419       if (unformat (input, "bd %d", &bd))
16420         bd_set = 1;
16421       else
16422         {
16423           errmsg ("parse error '%U'", format_unformat_error, input);
16424           return -99;
16425         }
16426     }
16427
16428   if (!bd_set)
16429     {
16430       errmsg ("Expected bridge domain!");
16431       return -99;
16432     }
16433
16434   M (ONE_L2_ARP_ENTRIES_GET, mp);
16435   mp->bd = clib_host_to_net_u32 (bd);
16436
16437   /* send */
16438   S (mp);
16439
16440   /* wait for reply */
16441   W (ret);
16442   return ret;
16443 }
16444
16445 static int
16446 api_one_stats_enable_disable (vat_main_t * vam)
16447 {
16448   vl_api_one_stats_enable_disable_t *mp;
16449   unformat_input_t *input = vam->input;
16450   u8 is_set = 0;
16451   u8 is_en = 0;
16452   int ret;
16453
16454   /* Parse args required to build the message */
16455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16456     {
16457       if (unformat (input, "enable"))
16458         {
16459           is_set = 1;
16460           is_en = 1;
16461         }
16462       else if (unformat (input, "disable"))
16463         {
16464           is_set = 1;
16465         }
16466       else
16467         break;
16468     }
16469
16470   if (!is_set)
16471     {
16472       errmsg ("Value not set");
16473       return -99;
16474     }
16475
16476   M (ONE_STATS_ENABLE_DISABLE, mp);
16477   mp->is_en = is_en;
16478
16479   /* send */
16480   S (mp);
16481
16482   /* wait for reply */
16483   W (ret);
16484   return ret;
16485 }
16486
16487 static int
16488 api_show_one_stats_enable_disable (vat_main_t * vam)
16489 {
16490   vl_api_show_one_stats_enable_disable_t *mp;
16491   int ret;
16492
16493   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16494
16495   /* send */
16496   S (mp);
16497
16498   /* wait for reply */
16499   W (ret);
16500   return ret;
16501 }
16502
16503 static int
16504 api_show_one_map_request_mode (vat_main_t * vam)
16505 {
16506   vl_api_show_one_map_request_mode_t *mp;
16507   int ret;
16508
16509   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16510
16511   /* send */
16512   S (mp);
16513
16514   /* wait for reply */
16515   W (ret);
16516   return ret;
16517 }
16518
16519 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16520
16521 static int
16522 api_one_map_request_mode (vat_main_t * vam)
16523 {
16524   unformat_input_t *input = vam->input;
16525   vl_api_one_map_request_mode_t *mp;
16526   u8 mode = 0;
16527   int ret;
16528
16529   /* Parse args required to build the message */
16530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16531     {
16532       if (unformat (input, "dst-only"))
16533         mode = 0;
16534       else if (unformat (input, "src-dst"))
16535         mode = 1;
16536       else
16537         {
16538           errmsg ("parse error '%U'", format_unformat_error, input);
16539           return -99;
16540         }
16541     }
16542
16543   M (ONE_MAP_REQUEST_MODE, mp);
16544
16545   mp->mode = mode;
16546
16547   /* send */
16548   S (mp);
16549
16550   /* wait for reply */
16551   W (ret);
16552   return ret;
16553 }
16554
16555 #define api_lisp_map_request_mode api_one_map_request_mode
16556
16557 /**
16558  * Enable/disable ONE proxy ITR.
16559  *
16560  * @param vam vpp API test context
16561  * @return return code
16562  */
16563 static int
16564 api_one_pitr_set_locator_set (vat_main_t * vam)
16565 {
16566   u8 ls_name_set = 0;
16567   unformat_input_t *input = vam->input;
16568   vl_api_one_pitr_set_locator_set_t *mp;
16569   u8 is_add = 1;
16570   u8 *ls_name = 0;
16571   int ret;
16572
16573   /* Parse args required to build the message */
16574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16575     {
16576       if (unformat (input, "del"))
16577         is_add = 0;
16578       else if (unformat (input, "locator-set %s", &ls_name))
16579         ls_name_set = 1;
16580       else
16581         {
16582           errmsg ("parse error '%U'", format_unformat_error, input);
16583           return -99;
16584         }
16585     }
16586
16587   if (!ls_name_set)
16588     {
16589       errmsg ("locator-set name not set!");
16590       return -99;
16591     }
16592
16593   M (ONE_PITR_SET_LOCATOR_SET, mp);
16594
16595   mp->is_add = is_add;
16596   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16597   vec_free (ls_name);
16598
16599   /* send */
16600   S (mp);
16601
16602   /* wait for reply */
16603   W (ret);
16604   return ret;
16605 }
16606
16607 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16608
16609 static int
16610 api_one_nsh_set_locator_set (vat_main_t * vam)
16611 {
16612   u8 ls_name_set = 0;
16613   unformat_input_t *input = vam->input;
16614   vl_api_one_nsh_set_locator_set_t *mp;
16615   u8 is_add = 1;
16616   u8 *ls_name = 0;
16617   int ret;
16618
16619   /* Parse args required to build the message */
16620   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16621     {
16622       if (unformat (input, "del"))
16623         is_add = 0;
16624       else if (unformat (input, "ls %s", &ls_name))
16625         ls_name_set = 1;
16626       else
16627         {
16628           errmsg ("parse error '%U'", format_unformat_error, input);
16629           return -99;
16630         }
16631     }
16632
16633   if (!ls_name_set && is_add)
16634     {
16635       errmsg ("locator-set name not set!");
16636       return -99;
16637     }
16638
16639   M (ONE_NSH_SET_LOCATOR_SET, mp);
16640
16641   mp->is_add = is_add;
16642   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16643   vec_free (ls_name);
16644
16645   /* send */
16646   S (mp);
16647
16648   /* wait for reply */
16649   W (ret);
16650   return ret;
16651 }
16652
16653 static int
16654 api_show_one_pitr (vat_main_t * vam)
16655 {
16656   vl_api_show_one_pitr_t *mp;
16657   int ret;
16658
16659   if (!vam->json_output)
16660     {
16661       print (vam->ofp, "%=20s", "lisp status:");
16662     }
16663
16664   M (SHOW_ONE_PITR, mp);
16665   /* send it... */
16666   S (mp);
16667
16668   /* Wait for a reply... */
16669   W (ret);
16670   return ret;
16671 }
16672
16673 #define api_show_lisp_pitr api_show_one_pitr
16674
16675 static int
16676 api_one_use_petr (vat_main_t * vam)
16677 {
16678   unformat_input_t *input = vam->input;
16679   vl_api_one_use_petr_t *mp;
16680   u8 is_add = 0;
16681   ip_address_t ip;
16682   int ret;
16683
16684   clib_memset (&ip, 0, sizeof (ip));
16685
16686   /* Parse args required to build the message */
16687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16688     {
16689       if (unformat (input, "disable"))
16690         is_add = 0;
16691       else
16692         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16693         {
16694           is_add = 1;
16695           ip_addr_version (&ip) = IP4;
16696         }
16697       else
16698         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16699         {
16700           is_add = 1;
16701           ip_addr_version (&ip) = IP6;
16702         }
16703       else
16704         {
16705           errmsg ("parse error '%U'", format_unformat_error, input);
16706           return -99;
16707         }
16708     }
16709
16710   M (ONE_USE_PETR, mp);
16711
16712   mp->is_add = is_add;
16713   if (is_add)
16714     {
16715       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16716       if (mp->is_ip4)
16717         clib_memcpy (mp->address, &ip, 4);
16718       else
16719         clib_memcpy (mp->address, &ip, 16);
16720     }
16721
16722   /* send */
16723   S (mp);
16724
16725   /* wait for reply */
16726   W (ret);
16727   return ret;
16728 }
16729
16730 #define api_lisp_use_petr api_one_use_petr
16731
16732 static int
16733 api_show_one_nsh_mapping (vat_main_t * vam)
16734 {
16735   vl_api_show_one_use_petr_t *mp;
16736   int ret;
16737
16738   if (!vam->json_output)
16739     {
16740       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16741     }
16742
16743   M (SHOW_ONE_NSH_MAPPING, mp);
16744   /* send it... */
16745   S (mp);
16746
16747   /* Wait for a reply... */
16748   W (ret);
16749   return ret;
16750 }
16751
16752 static int
16753 api_show_one_use_petr (vat_main_t * vam)
16754 {
16755   vl_api_show_one_use_petr_t *mp;
16756   int ret;
16757
16758   if (!vam->json_output)
16759     {
16760       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16761     }
16762
16763   M (SHOW_ONE_USE_PETR, mp);
16764   /* send it... */
16765   S (mp);
16766
16767   /* Wait for a reply... */
16768   W (ret);
16769   return ret;
16770 }
16771
16772 #define api_show_lisp_use_petr api_show_one_use_petr
16773
16774 /**
16775  * Add/delete mapping between vni and vrf
16776  */
16777 static int
16778 api_one_eid_table_add_del_map (vat_main_t * vam)
16779 {
16780   unformat_input_t *input = vam->input;
16781   vl_api_one_eid_table_add_del_map_t *mp;
16782   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16783   u32 vni, vrf, bd_index;
16784   int ret;
16785
16786   /* Parse args required to build the message */
16787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16788     {
16789       if (unformat (input, "del"))
16790         is_add = 0;
16791       else if (unformat (input, "vrf %d", &vrf))
16792         vrf_set = 1;
16793       else if (unformat (input, "bd_index %d", &bd_index))
16794         bd_index_set = 1;
16795       else if (unformat (input, "vni %d", &vni))
16796         vni_set = 1;
16797       else
16798         break;
16799     }
16800
16801   if (!vni_set || (!vrf_set && !bd_index_set))
16802     {
16803       errmsg ("missing arguments!");
16804       return -99;
16805     }
16806
16807   if (vrf_set && bd_index_set)
16808     {
16809       errmsg ("error: both vrf and bd entered!");
16810       return -99;
16811     }
16812
16813   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16814
16815   mp->is_add = is_add;
16816   mp->vni = htonl (vni);
16817   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16818   mp->is_l2 = bd_index_set;
16819
16820   /* send */
16821   S (mp);
16822
16823   /* wait for reply */
16824   W (ret);
16825   return ret;
16826 }
16827
16828 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16829
16830 uword
16831 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16832 {
16833   u32 *action = va_arg (*args, u32 *);
16834   u8 *s = 0;
16835
16836   if (unformat (input, "%s", &s))
16837     {
16838       if (!strcmp ((char *) s, "no-action"))
16839         action[0] = 0;
16840       else if (!strcmp ((char *) s, "natively-forward"))
16841         action[0] = 1;
16842       else if (!strcmp ((char *) s, "send-map-request"))
16843         action[0] = 2;
16844       else if (!strcmp ((char *) s, "drop"))
16845         action[0] = 3;
16846       else
16847         {
16848           clib_warning ("invalid action: '%s'", s);
16849           action[0] = 3;
16850         }
16851     }
16852   else
16853     return 0;
16854
16855   vec_free (s);
16856   return 1;
16857 }
16858
16859 /**
16860  * Add/del remote mapping to/from ONE control plane
16861  *
16862  * @param vam vpp API test context
16863  * @return return code
16864  */
16865 static int
16866 api_one_add_del_remote_mapping (vat_main_t * vam)
16867 {
16868   unformat_input_t *input = vam->input;
16869   vl_api_one_add_del_remote_mapping_t *mp;
16870   u32 vni = 0;
16871   lisp_eid_vat_t _eid, *eid = &_eid;
16872   lisp_eid_vat_t _seid, *seid = &_seid;
16873   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16874   u32 action = ~0, p, w, data_len;
16875   ip4_address_t rloc4;
16876   ip6_address_t rloc6;
16877   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16878   int ret;
16879
16880   clib_memset (&rloc, 0, sizeof (rloc));
16881
16882   /* Parse args required to build the message */
16883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16884     {
16885       if (unformat (input, "del-all"))
16886         {
16887           del_all = 1;
16888         }
16889       else if (unformat (input, "del"))
16890         {
16891           is_add = 0;
16892         }
16893       else if (unformat (input, "add"))
16894         {
16895           is_add = 1;
16896         }
16897       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16898         {
16899           eid_set = 1;
16900         }
16901       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16902         {
16903           seid_set = 1;
16904         }
16905       else if (unformat (input, "vni %d", &vni))
16906         {
16907           ;
16908         }
16909       else if (unformat (input, "p %d w %d", &p, &w))
16910         {
16911           if (!curr_rloc)
16912             {
16913               errmsg ("No RLOC configured for setting priority/weight!");
16914               return -99;
16915             }
16916           curr_rloc->priority = p;
16917           curr_rloc->weight = w;
16918         }
16919       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16920         {
16921           rloc.is_ip4 = 1;
16922           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16923           vec_add1 (rlocs, rloc);
16924           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16925         }
16926       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16927         {
16928           rloc.is_ip4 = 0;
16929           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16930           vec_add1 (rlocs, rloc);
16931           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16932         }
16933       else if (unformat (input, "action %U",
16934                          unformat_negative_mapping_action, &action))
16935         {
16936           ;
16937         }
16938       else
16939         {
16940           clib_warning ("parse error '%U'", format_unformat_error, input);
16941           return -99;
16942         }
16943     }
16944
16945   if (0 == eid_set)
16946     {
16947       errmsg ("missing params!");
16948       return -99;
16949     }
16950
16951   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16952     {
16953       errmsg ("no action set for negative map-reply!");
16954       return -99;
16955     }
16956
16957   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16958
16959   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16960   mp->is_add = is_add;
16961   mp->vni = htonl (vni);
16962   mp->action = (u8) action;
16963   mp->is_src_dst = seid_set;
16964   mp->eid_len = eid->len;
16965   mp->seid_len = seid->len;
16966   mp->del_all = del_all;
16967   mp->eid_type = eid->type;
16968   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16969   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16970
16971   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16972   clib_memcpy (mp->rlocs, rlocs, data_len);
16973   vec_free (rlocs);
16974
16975   /* send it... */
16976   S (mp);
16977
16978   /* Wait for a reply... */
16979   W (ret);
16980   return ret;
16981 }
16982
16983 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16984
16985 /**
16986  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16987  * forwarding entries in data-plane accordingly.
16988  *
16989  * @param vam vpp API test context
16990  * @return return code
16991  */
16992 static int
16993 api_one_add_del_adjacency (vat_main_t * vam)
16994 {
16995   unformat_input_t *input = vam->input;
16996   vl_api_one_add_del_adjacency_t *mp;
16997   u32 vni = 0;
16998   ip4_address_t leid4, reid4;
16999   ip6_address_t leid6, reid6;
17000   u8 reid_mac[6] = { 0 };
17001   u8 leid_mac[6] = { 0 };
17002   u8 reid_type, leid_type;
17003   u32 leid_len = 0, reid_len = 0, len;
17004   u8 is_add = 1;
17005   int ret;
17006
17007   leid_type = reid_type = (u8) ~ 0;
17008
17009   /* Parse args required to build the message */
17010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17011     {
17012       if (unformat (input, "del"))
17013         {
17014           is_add = 0;
17015         }
17016       else if (unformat (input, "add"))
17017         {
17018           is_add = 1;
17019         }
17020       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17021                          &reid4, &len))
17022         {
17023           reid_type = 0;        /* ipv4 */
17024           reid_len = len;
17025         }
17026       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17027                          &reid6, &len))
17028         {
17029           reid_type = 1;        /* ipv6 */
17030           reid_len = len;
17031         }
17032       else if (unformat (input, "reid %U", unformat_ethernet_address,
17033                          reid_mac))
17034         {
17035           reid_type = 2;        /* mac */
17036         }
17037       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17038                          &leid4, &len))
17039         {
17040           leid_type = 0;        /* ipv4 */
17041           leid_len = len;
17042         }
17043       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17044                          &leid6, &len))
17045         {
17046           leid_type = 1;        /* ipv6 */
17047           leid_len = len;
17048         }
17049       else if (unformat (input, "leid %U", unformat_ethernet_address,
17050                          leid_mac))
17051         {
17052           leid_type = 2;        /* mac */
17053         }
17054       else if (unformat (input, "vni %d", &vni))
17055         {
17056           ;
17057         }
17058       else
17059         {
17060           errmsg ("parse error '%U'", format_unformat_error, input);
17061           return -99;
17062         }
17063     }
17064
17065   if ((u8) ~ 0 == reid_type)
17066     {
17067       errmsg ("missing params!");
17068       return -99;
17069     }
17070
17071   if (leid_type != reid_type)
17072     {
17073       errmsg ("remote and local EIDs are of different types!");
17074       return -99;
17075     }
17076
17077   M (ONE_ADD_DEL_ADJACENCY, mp);
17078   mp->is_add = is_add;
17079   mp->vni = htonl (vni);
17080   mp->leid_len = leid_len;
17081   mp->reid_len = reid_len;
17082   mp->eid_type = reid_type;
17083
17084   switch (mp->eid_type)
17085     {
17086     case 0:
17087       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17088       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17089       break;
17090     case 1:
17091       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17092       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17093       break;
17094     case 2:
17095       clib_memcpy (mp->leid, leid_mac, 6);
17096       clib_memcpy (mp->reid, reid_mac, 6);
17097       break;
17098     default:
17099       errmsg ("unknown EID type %d!", mp->eid_type);
17100       return 0;
17101     }
17102
17103   /* send it... */
17104   S (mp);
17105
17106   /* Wait for a reply... */
17107   W (ret);
17108   return ret;
17109 }
17110
17111 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17112
17113 uword
17114 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17115 {
17116   u32 *mode = va_arg (*args, u32 *);
17117
17118   if (unformat (input, "lisp"))
17119     *mode = 0;
17120   else if (unformat (input, "vxlan"))
17121     *mode = 1;
17122   else
17123     return 0;
17124
17125   return 1;
17126 }
17127
17128 static int
17129 api_gpe_get_encap_mode (vat_main_t * vam)
17130 {
17131   vl_api_gpe_get_encap_mode_t *mp;
17132   int ret;
17133
17134   /* Construct the API message */
17135   M (GPE_GET_ENCAP_MODE, mp);
17136
17137   /* send it... */
17138   S (mp);
17139
17140   /* Wait for a reply... */
17141   W (ret);
17142   return ret;
17143 }
17144
17145 static int
17146 api_gpe_set_encap_mode (vat_main_t * vam)
17147 {
17148   unformat_input_t *input = vam->input;
17149   vl_api_gpe_set_encap_mode_t *mp;
17150   int ret;
17151   u32 mode = 0;
17152
17153   /* Parse args required to build the message */
17154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17155     {
17156       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17157         ;
17158       else
17159         break;
17160     }
17161
17162   /* Construct the API message */
17163   M (GPE_SET_ENCAP_MODE, mp);
17164
17165   mp->mode = mode;
17166
17167   /* send it... */
17168   S (mp);
17169
17170   /* Wait for a reply... */
17171   W (ret);
17172   return ret;
17173 }
17174
17175 static int
17176 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17177 {
17178   unformat_input_t *input = vam->input;
17179   vl_api_gpe_add_del_iface_t *mp;
17180   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17181   u32 dp_table = 0, vni = 0;
17182   int ret;
17183
17184   /* Parse args required to build the message */
17185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17186     {
17187       if (unformat (input, "up"))
17188         {
17189           action_set = 1;
17190           is_add = 1;
17191         }
17192       else if (unformat (input, "down"))
17193         {
17194           action_set = 1;
17195           is_add = 0;
17196         }
17197       else if (unformat (input, "table_id %d", &dp_table))
17198         {
17199           dp_table_set = 1;
17200         }
17201       else if (unformat (input, "bd_id %d", &dp_table))
17202         {
17203           dp_table_set = 1;
17204           is_l2 = 1;
17205         }
17206       else if (unformat (input, "vni %d", &vni))
17207         {
17208           vni_set = 1;
17209         }
17210       else
17211         break;
17212     }
17213
17214   if (action_set == 0)
17215     {
17216       errmsg ("Action not set");
17217       return -99;
17218     }
17219   if (dp_table_set == 0 || vni_set == 0)
17220     {
17221       errmsg ("vni and dp_table must be set");
17222       return -99;
17223     }
17224
17225   /* Construct the API message */
17226   M (GPE_ADD_DEL_IFACE, mp);
17227
17228   mp->is_add = is_add;
17229   mp->dp_table = clib_host_to_net_u32 (dp_table);
17230   mp->is_l2 = is_l2;
17231   mp->vni = clib_host_to_net_u32 (vni);
17232
17233   /* send it... */
17234   S (mp);
17235
17236   /* Wait for a reply... */
17237   W (ret);
17238   return ret;
17239 }
17240
17241 static int
17242 api_one_map_register_fallback_threshold (vat_main_t * vam)
17243 {
17244   unformat_input_t *input = vam->input;
17245   vl_api_one_map_register_fallback_threshold_t *mp;
17246   u32 value = 0;
17247   u8 is_set = 0;
17248   int ret;
17249
17250   /* Parse args required to build the message */
17251   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17252     {
17253       if (unformat (input, "%u", &value))
17254         is_set = 1;
17255       else
17256         {
17257           clib_warning ("parse error '%U'", format_unformat_error, input);
17258           return -99;
17259         }
17260     }
17261
17262   if (!is_set)
17263     {
17264       errmsg ("fallback threshold value is missing!");
17265       return -99;
17266     }
17267
17268   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17269   mp->value = clib_host_to_net_u32 (value);
17270
17271   /* send it... */
17272   S (mp);
17273
17274   /* Wait for a reply... */
17275   W (ret);
17276   return ret;
17277 }
17278
17279 static int
17280 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17281 {
17282   vl_api_show_one_map_register_fallback_threshold_t *mp;
17283   int ret;
17284
17285   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17286
17287   /* send it... */
17288   S (mp);
17289
17290   /* Wait for a reply... */
17291   W (ret);
17292   return ret;
17293 }
17294
17295 uword
17296 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17297 {
17298   u32 *proto = va_arg (*args, u32 *);
17299
17300   if (unformat (input, "udp"))
17301     *proto = 1;
17302   else if (unformat (input, "api"))
17303     *proto = 2;
17304   else
17305     return 0;
17306
17307   return 1;
17308 }
17309
17310 static int
17311 api_one_set_transport_protocol (vat_main_t * vam)
17312 {
17313   unformat_input_t *input = vam->input;
17314   vl_api_one_set_transport_protocol_t *mp;
17315   u8 is_set = 0;
17316   u32 protocol = 0;
17317   int ret;
17318
17319   /* Parse args required to build the message */
17320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17321     {
17322       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17323         is_set = 1;
17324       else
17325         {
17326           clib_warning ("parse error '%U'", format_unformat_error, input);
17327           return -99;
17328         }
17329     }
17330
17331   if (!is_set)
17332     {
17333       errmsg ("Transport protocol missing!");
17334       return -99;
17335     }
17336
17337   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17338   mp->protocol = (u8) protocol;
17339
17340   /* send it... */
17341   S (mp);
17342
17343   /* Wait for a reply... */
17344   W (ret);
17345   return ret;
17346 }
17347
17348 static int
17349 api_one_get_transport_protocol (vat_main_t * vam)
17350 {
17351   vl_api_one_get_transport_protocol_t *mp;
17352   int ret;
17353
17354   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17355
17356   /* send it... */
17357   S (mp);
17358
17359   /* Wait for a reply... */
17360   W (ret);
17361   return ret;
17362 }
17363
17364 static int
17365 api_one_map_register_set_ttl (vat_main_t * vam)
17366 {
17367   unformat_input_t *input = vam->input;
17368   vl_api_one_map_register_set_ttl_t *mp;
17369   u32 ttl = 0;
17370   u8 is_set = 0;
17371   int ret;
17372
17373   /* Parse args required to build the message */
17374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17375     {
17376       if (unformat (input, "%u", &ttl))
17377         is_set = 1;
17378       else
17379         {
17380           clib_warning ("parse error '%U'", format_unformat_error, input);
17381           return -99;
17382         }
17383     }
17384
17385   if (!is_set)
17386     {
17387       errmsg ("TTL value missing!");
17388       return -99;
17389     }
17390
17391   M (ONE_MAP_REGISTER_SET_TTL, mp);
17392   mp->ttl = clib_host_to_net_u32 (ttl);
17393
17394   /* send it... */
17395   S (mp);
17396
17397   /* Wait for a reply... */
17398   W (ret);
17399   return ret;
17400 }
17401
17402 static int
17403 api_show_one_map_register_ttl (vat_main_t * vam)
17404 {
17405   vl_api_show_one_map_register_ttl_t *mp;
17406   int ret;
17407
17408   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17409
17410   /* send it... */
17411   S (mp);
17412
17413   /* Wait for a reply... */
17414   W (ret);
17415   return ret;
17416 }
17417
17418 /**
17419  * Add/del map request itr rlocs from ONE control plane and updates
17420  *
17421  * @param vam vpp API test context
17422  * @return return code
17423  */
17424 static int
17425 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17426 {
17427   unformat_input_t *input = vam->input;
17428   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17429   u8 *locator_set_name = 0;
17430   u8 locator_set_name_set = 0;
17431   u8 is_add = 1;
17432   int ret;
17433
17434   /* Parse args required to build the message */
17435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17436     {
17437       if (unformat (input, "del"))
17438         {
17439           is_add = 0;
17440         }
17441       else if (unformat (input, "%_%v%_", &locator_set_name))
17442         {
17443           locator_set_name_set = 1;
17444         }
17445       else
17446         {
17447           clib_warning ("parse error '%U'", format_unformat_error, input);
17448           return -99;
17449         }
17450     }
17451
17452   if (is_add && !locator_set_name_set)
17453     {
17454       errmsg ("itr-rloc is not set!");
17455       return -99;
17456     }
17457
17458   if (is_add && vec_len (locator_set_name) > 64)
17459     {
17460       errmsg ("itr-rloc locator-set name too long");
17461       vec_free (locator_set_name);
17462       return -99;
17463     }
17464
17465   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17466   mp->is_add = is_add;
17467   if (is_add)
17468     {
17469       clib_memcpy (mp->locator_set_name, locator_set_name,
17470                    vec_len (locator_set_name));
17471     }
17472   else
17473     {
17474       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17475     }
17476   vec_free (locator_set_name);
17477
17478   /* send it... */
17479   S (mp);
17480
17481   /* Wait for a reply... */
17482   W (ret);
17483   return ret;
17484 }
17485
17486 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17487
17488 static int
17489 api_one_locator_dump (vat_main_t * vam)
17490 {
17491   unformat_input_t *input = vam->input;
17492   vl_api_one_locator_dump_t *mp;
17493   vl_api_control_ping_t *mp_ping;
17494   u8 is_index_set = 0, is_name_set = 0;
17495   u8 *ls_name = 0;
17496   u32 ls_index = ~0;
17497   int ret;
17498
17499   /* Parse args required to build the message */
17500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17501     {
17502       if (unformat (input, "ls_name %_%v%_", &ls_name))
17503         {
17504           is_name_set = 1;
17505         }
17506       else if (unformat (input, "ls_index %d", &ls_index))
17507         {
17508           is_index_set = 1;
17509         }
17510       else
17511         {
17512           errmsg ("parse error '%U'", format_unformat_error, input);
17513           return -99;
17514         }
17515     }
17516
17517   if (!is_index_set && !is_name_set)
17518     {
17519       errmsg ("error: expected one of index or name!");
17520       return -99;
17521     }
17522
17523   if (is_index_set && is_name_set)
17524     {
17525       errmsg ("error: only one param expected!");
17526       return -99;
17527     }
17528
17529   if (vec_len (ls_name) > 62)
17530     {
17531       errmsg ("error: locator set name too long!");
17532       return -99;
17533     }
17534
17535   if (!vam->json_output)
17536     {
17537       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17538     }
17539
17540   M (ONE_LOCATOR_DUMP, mp);
17541   mp->is_index_set = is_index_set;
17542
17543   if (is_index_set)
17544     mp->ls_index = clib_host_to_net_u32 (ls_index);
17545   else
17546     {
17547       vec_add1 (ls_name, 0);
17548       strncpy ((char *) mp->ls_name, (char *) ls_name,
17549                sizeof (mp->ls_name) - 1);
17550     }
17551
17552   /* send it... */
17553   S (mp);
17554
17555   /* Use a control ping for synchronization */
17556   MPING (CONTROL_PING, mp_ping);
17557   S (mp_ping);
17558
17559   /* Wait for a reply... */
17560   W (ret);
17561   return ret;
17562 }
17563
17564 #define api_lisp_locator_dump api_one_locator_dump
17565
17566 static int
17567 api_one_locator_set_dump (vat_main_t * vam)
17568 {
17569   vl_api_one_locator_set_dump_t *mp;
17570   vl_api_control_ping_t *mp_ping;
17571   unformat_input_t *input = vam->input;
17572   u8 filter = 0;
17573   int ret;
17574
17575   /* Parse args required to build the message */
17576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17577     {
17578       if (unformat (input, "local"))
17579         {
17580           filter = 1;
17581         }
17582       else if (unformat (input, "remote"))
17583         {
17584           filter = 2;
17585         }
17586       else
17587         {
17588           errmsg ("parse error '%U'", format_unformat_error, input);
17589           return -99;
17590         }
17591     }
17592
17593   if (!vam->json_output)
17594     {
17595       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17596     }
17597
17598   M (ONE_LOCATOR_SET_DUMP, mp);
17599
17600   mp->filter = filter;
17601
17602   /* send it... */
17603   S (mp);
17604
17605   /* Use a control ping for synchronization */
17606   MPING (CONTROL_PING, mp_ping);
17607   S (mp_ping);
17608
17609   /* Wait for a reply... */
17610   W (ret);
17611   return ret;
17612 }
17613
17614 #define api_lisp_locator_set_dump api_one_locator_set_dump
17615
17616 static int
17617 api_one_eid_table_map_dump (vat_main_t * vam)
17618 {
17619   u8 is_l2 = 0;
17620   u8 mode_set = 0;
17621   unformat_input_t *input = vam->input;
17622   vl_api_one_eid_table_map_dump_t *mp;
17623   vl_api_control_ping_t *mp_ping;
17624   int ret;
17625
17626   /* Parse args required to build the message */
17627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17628     {
17629       if (unformat (input, "l2"))
17630         {
17631           is_l2 = 1;
17632           mode_set = 1;
17633         }
17634       else if (unformat (input, "l3"))
17635         {
17636           is_l2 = 0;
17637           mode_set = 1;
17638         }
17639       else
17640         {
17641           errmsg ("parse error '%U'", format_unformat_error, input);
17642           return -99;
17643         }
17644     }
17645
17646   if (!mode_set)
17647     {
17648       errmsg ("expected one of 'l2' or 'l3' parameter!");
17649       return -99;
17650     }
17651
17652   if (!vam->json_output)
17653     {
17654       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17655     }
17656
17657   M (ONE_EID_TABLE_MAP_DUMP, mp);
17658   mp->is_l2 = is_l2;
17659
17660   /* send it... */
17661   S (mp);
17662
17663   /* Use a control ping for synchronization */
17664   MPING (CONTROL_PING, mp_ping);
17665   S (mp_ping);
17666
17667   /* Wait for a reply... */
17668   W (ret);
17669   return ret;
17670 }
17671
17672 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17673
17674 static int
17675 api_one_eid_table_vni_dump (vat_main_t * vam)
17676 {
17677   vl_api_one_eid_table_vni_dump_t *mp;
17678   vl_api_control_ping_t *mp_ping;
17679   int ret;
17680
17681   if (!vam->json_output)
17682     {
17683       print (vam->ofp, "VNI");
17684     }
17685
17686   M (ONE_EID_TABLE_VNI_DUMP, mp);
17687
17688   /* send it... */
17689   S (mp);
17690
17691   /* Use a control ping for synchronization */
17692   MPING (CONTROL_PING, mp_ping);
17693   S (mp_ping);
17694
17695   /* Wait for a reply... */
17696   W (ret);
17697   return ret;
17698 }
17699
17700 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17701
17702 static int
17703 api_one_eid_table_dump (vat_main_t * vam)
17704 {
17705   unformat_input_t *i = vam->input;
17706   vl_api_one_eid_table_dump_t *mp;
17707   vl_api_control_ping_t *mp_ping;
17708   struct in_addr ip4;
17709   struct in6_addr ip6;
17710   u8 mac[6];
17711   u8 eid_type = ~0, eid_set = 0;
17712   u32 prefix_length = ~0, t, vni = 0;
17713   u8 filter = 0;
17714   int ret;
17715   lisp_nsh_api_t nsh;
17716
17717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17718     {
17719       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17720         {
17721           eid_set = 1;
17722           eid_type = 0;
17723           prefix_length = t;
17724         }
17725       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17726         {
17727           eid_set = 1;
17728           eid_type = 1;
17729           prefix_length = t;
17730         }
17731       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17732         {
17733           eid_set = 1;
17734           eid_type = 2;
17735         }
17736       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17737         {
17738           eid_set = 1;
17739           eid_type = 3;
17740         }
17741       else if (unformat (i, "vni %d", &t))
17742         {
17743           vni = t;
17744         }
17745       else if (unformat (i, "local"))
17746         {
17747           filter = 1;
17748         }
17749       else if (unformat (i, "remote"))
17750         {
17751           filter = 2;
17752         }
17753       else
17754         {
17755           errmsg ("parse error '%U'", format_unformat_error, i);
17756           return -99;
17757         }
17758     }
17759
17760   if (!vam->json_output)
17761     {
17762       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17763              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17764     }
17765
17766   M (ONE_EID_TABLE_DUMP, mp);
17767
17768   mp->filter = filter;
17769   if (eid_set)
17770     {
17771       mp->eid_set = 1;
17772       mp->vni = htonl (vni);
17773       mp->eid_type = eid_type;
17774       switch (eid_type)
17775         {
17776         case 0:
17777           mp->prefix_length = prefix_length;
17778           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17779           break;
17780         case 1:
17781           mp->prefix_length = prefix_length;
17782           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17783           break;
17784         case 2:
17785           clib_memcpy (mp->eid, mac, sizeof (mac));
17786           break;
17787         case 3:
17788           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17789           break;
17790         default:
17791           errmsg ("unknown EID type %d!", eid_type);
17792           return -99;
17793         }
17794     }
17795
17796   /* send it... */
17797   S (mp);
17798
17799   /* Use a control ping for synchronization */
17800   MPING (CONTROL_PING, mp_ping);
17801   S (mp_ping);
17802
17803   /* Wait for a reply... */
17804   W (ret);
17805   return ret;
17806 }
17807
17808 #define api_lisp_eid_table_dump api_one_eid_table_dump
17809
17810 static int
17811 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17812 {
17813   unformat_input_t *i = vam->input;
17814   vl_api_gpe_fwd_entries_get_t *mp;
17815   u8 vni_set = 0;
17816   u32 vni = ~0;
17817   int ret;
17818
17819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17820     {
17821       if (unformat (i, "vni %d", &vni))
17822         {
17823           vni_set = 1;
17824         }
17825       else
17826         {
17827           errmsg ("parse error '%U'", format_unformat_error, i);
17828           return -99;
17829         }
17830     }
17831
17832   if (!vni_set)
17833     {
17834       errmsg ("vni not set!");
17835       return -99;
17836     }
17837
17838   if (!vam->json_output)
17839     {
17840       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17841              "leid", "reid");
17842     }
17843
17844   M (GPE_FWD_ENTRIES_GET, mp);
17845   mp->vni = clib_host_to_net_u32 (vni);
17846
17847   /* send it... */
17848   S (mp);
17849
17850   /* Wait for a reply... */
17851   W (ret);
17852   return ret;
17853 }
17854
17855 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17856 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17857 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17858 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17859 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17860 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17861 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17862 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17863
17864 static int
17865 api_one_adjacencies_get (vat_main_t * vam)
17866 {
17867   unformat_input_t *i = vam->input;
17868   vl_api_one_adjacencies_get_t *mp;
17869   u8 vni_set = 0;
17870   u32 vni = ~0;
17871   int ret;
17872
17873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17874     {
17875       if (unformat (i, "vni %d", &vni))
17876         {
17877           vni_set = 1;
17878         }
17879       else
17880         {
17881           errmsg ("parse error '%U'", format_unformat_error, i);
17882           return -99;
17883         }
17884     }
17885
17886   if (!vni_set)
17887     {
17888       errmsg ("vni not set!");
17889       return -99;
17890     }
17891
17892   if (!vam->json_output)
17893     {
17894       print (vam->ofp, "%s %40s", "leid", "reid");
17895     }
17896
17897   M (ONE_ADJACENCIES_GET, mp);
17898   mp->vni = clib_host_to_net_u32 (vni);
17899
17900   /* send it... */
17901   S (mp);
17902
17903   /* Wait for a reply... */
17904   W (ret);
17905   return ret;
17906 }
17907
17908 #define api_lisp_adjacencies_get api_one_adjacencies_get
17909
17910 static int
17911 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17912 {
17913   unformat_input_t *i = vam->input;
17914   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17915   int ret;
17916   u8 ip_family_set = 0, is_ip4 = 1;
17917
17918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17919     {
17920       if (unformat (i, "ip4"))
17921         {
17922           ip_family_set = 1;
17923           is_ip4 = 1;
17924         }
17925       else if (unformat (i, "ip6"))
17926         {
17927           ip_family_set = 1;
17928           is_ip4 = 0;
17929         }
17930       else
17931         {
17932           errmsg ("parse error '%U'", format_unformat_error, i);
17933           return -99;
17934         }
17935     }
17936
17937   if (!ip_family_set)
17938     {
17939       errmsg ("ip family not set!");
17940       return -99;
17941     }
17942
17943   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17944   mp->is_ip4 = is_ip4;
17945
17946   /* send it... */
17947   S (mp);
17948
17949   /* Wait for a reply... */
17950   W (ret);
17951   return ret;
17952 }
17953
17954 static int
17955 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17956 {
17957   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17958   int ret;
17959
17960   if (!vam->json_output)
17961     {
17962       print (vam->ofp, "VNIs");
17963     }
17964
17965   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17966
17967   /* send it... */
17968   S (mp);
17969
17970   /* Wait for a reply... */
17971   W (ret);
17972   return ret;
17973 }
17974
17975 static int
17976 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17977 {
17978   unformat_input_t *i = vam->input;
17979   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17980   int ret = 0;
17981   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17982   struct in_addr ip4;
17983   struct in6_addr ip6;
17984   u32 table_id = 0, nh_sw_if_index = ~0;
17985
17986   clib_memset (&ip4, 0, sizeof (ip4));
17987   clib_memset (&ip6, 0, sizeof (ip6));
17988
17989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17990     {
17991       if (unformat (i, "del"))
17992         is_add = 0;
17993       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17994                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17995         {
17996           ip_set = 1;
17997           is_ip4 = 1;
17998         }
17999       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18000                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18001         {
18002           ip_set = 1;
18003           is_ip4 = 0;
18004         }
18005       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18006         {
18007           ip_set = 1;
18008           is_ip4 = 1;
18009           nh_sw_if_index = ~0;
18010         }
18011       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18012         {
18013           ip_set = 1;
18014           is_ip4 = 0;
18015           nh_sw_if_index = ~0;
18016         }
18017       else if (unformat (i, "table %d", &table_id))
18018         ;
18019       else
18020         {
18021           errmsg ("parse error '%U'", format_unformat_error, i);
18022           return -99;
18023         }
18024     }
18025
18026   if (!ip_set)
18027     {
18028       errmsg ("nh addr not set!");
18029       return -99;
18030     }
18031
18032   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18033   mp->is_add = is_add;
18034   mp->table_id = clib_host_to_net_u32 (table_id);
18035   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18036   mp->is_ip4 = is_ip4;
18037   if (is_ip4)
18038     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18039   else
18040     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18041
18042   /* send it... */
18043   S (mp);
18044
18045   /* Wait for a reply... */
18046   W (ret);
18047   return ret;
18048 }
18049
18050 static int
18051 api_one_map_server_dump (vat_main_t * vam)
18052 {
18053   vl_api_one_map_server_dump_t *mp;
18054   vl_api_control_ping_t *mp_ping;
18055   int ret;
18056
18057   if (!vam->json_output)
18058     {
18059       print (vam->ofp, "%=20s", "Map server");
18060     }
18061
18062   M (ONE_MAP_SERVER_DUMP, mp);
18063   /* send it... */
18064   S (mp);
18065
18066   /* Use a control ping for synchronization */
18067   MPING (CONTROL_PING, mp_ping);
18068   S (mp_ping);
18069
18070   /* Wait for a reply... */
18071   W (ret);
18072   return ret;
18073 }
18074
18075 #define api_lisp_map_server_dump api_one_map_server_dump
18076
18077 static int
18078 api_one_map_resolver_dump (vat_main_t * vam)
18079 {
18080   vl_api_one_map_resolver_dump_t *mp;
18081   vl_api_control_ping_t *mp_ping;
18082   int ret;
18083
18084   if (!vam->json_output)
18085     {
18086       print (vam->ofp, "%=20s", "Map resolver");
18087     }
18088
18089   M (ONE_MAP_RESOLVER_DUMP, mp);
18090   /* send it... */
18091   S (mp);
18092
18093   /* Use a control ping for synchronization */
18094   MPING (CONTROL_PING, mp_ping);
18095   S (mp_ping);
18096
18097   /* Wait for a reply... */
18098   W (ret);
18099   return ret;
18100 }
18101
18102 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18103
18104 static int
18105 api_one_stats_flush (vat_main_t * vam)
18106 {
18107   vl_api_one_stats_flush_t *mp;
18108   int ret = 0;
18109
18110   M (ONE_STATS_FLUSH, mp);
18111   S (mp);
18112   W (ret);
18113   return ret;
18114 }
18115
18116 static int
18117 api_one_stats_dump (vat_main_t * vam)
18118 {
18119   vl_api_one_stats_dump_t *mp;
18120   vl_api_control_ping_t *mp_ping;
18121   int ret;
18122
18123   M (ONE_STATS_DUMP, mp);
18124   /* send it... */
18125   S (mp);
18126
18127   /* Use a control ping for synchronization */
18128   MPING (CONTROL_PING, mp_ping);
18129   S (mp_ping);
18130
18131   /* Wait for a reply... */
18132   W (ret);
18133   return ret;
18134 }
18135
18136 static int
18137 api_show_one_status (vat_main_t * vam)
18138 {
18139   vl_api_show_one_status_t *mp;
18140   int ret;
18141
18142   if (!vam->json_output)
18143     {
18144       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18145     }
18146
18147   M (SHOW_ONE_STATUS, mp);
18148   /* send it... */
18149   S (mp);
18150   /* Wait for a reply... */
18151   W (ret);
18152   return ret;
18153 }
18154
18155 #define api_show_lisp_status api_show_one_status
18156
18157 static int
18158 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18159 {
18160   vl_api_gpe_fwd_entry_path_dump_t *mp;
18161   vl_api_control_ping_t *mp_ping;
18162   unformat_input_t *i = vam->input;
18163   u32 fwd_entry_index = ~0;
18164   int ret;
18165
18166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18167     {
18168       if (unformat (i, "index %d", &fwd_entry_index))
18169         ;
18170       else
18171         break;
18172     }
18173
18174   if (~0 == fwd_entry_index)
18175     {
18176       errmsg ("no index specified!");
18177       return -99;
18178     }
18179
18180   if (!vam->json_output)
18181     {
18182       print (vam->ofp, "first line");
18183     }
18184
18185   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18186
18187   /* send it... */
18188   S (mp);
18189   /* Use a control ping for synchronization */
18190   MPING (CONTROL_PING, mp_ping);
18191   S (mp_ping);
18192
18193   /* Wait for a reply... */
18194   W (ret);
18195   return ret;
18196 }
18197
18198 static int
18199 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18200 {
18201   vl_api_one_get_map_request_itr_rlocs_t *mp;
18202   int ret;
18203
18204   if (!vam->json_output)
18205     {
18206       print (vam->ofp, "%=20s", "itr-rlocs:");
18207     }
18208
18209   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18210   /* send it... */
18211   S (mp);
18212   /* Wait for a reply... */
18213   W (ret);
18214   return ret;
18215 }
18216
18217 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18218
18219 static int
18220 api_af_packet_create (vat_main_t * vam)
18221 {
18222   unformat_input_t *i = vam->input;
18223   vl_api_af_packet_create_t *mp;
18224   u8 *host_if_name = 0;
18225   u8 hw_addr[6];
18226   u8 random_hw_addr = 1;
18227   int ret;
18228
18229   clib_memset (hw_addr, 0, sizeof (hw_addr));
18230
18231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18232     {
18233       if (unformat (i, "name %s", &host_if_name))
18234         vec_add1 (host_if_name, 0);
18235       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18236         random_hw_addr = 0;
18237       else
18238         break;
18239     }
18240
18241   if (!vec_len (host_if_name))
18242     {
18243       errmsg ("host-interface name must be specified");
18244       return -99;
18245     }
18246
18247   if (vec_len (host_if_name) > 64)
18248     {
18249       errmsg ("host-interface name too long");
18250       return -99;
18251     }
18252
18253   M (AF_PACKET_CREATE, mp);
18254
18255   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18256   clib_memcpy (mp->hw_addr, hw_addr, 6);
18257   mp->use_random_hw_addr = random_hw_addr;
18258   vec_free (host_if_name);
18259
18260   S (mp);
18261
18262   /* *INDENT-OFF* */
18263   W2 (ret,
18264       ({
18265         if (ret == 0)
18266           fprintf (vam->ofp ? vam->ofp : stderr,
18267                    " new sw_if_index = %d\n", vam->sw_if_index);
18268       }));
18269   /* *INDENT-ON* */
18270   return ret;
18271 }
18272
18273 static int
18274 api_af_packet_delete (vat_main_t * vam)
18275 {
18276   unformat_input_t *i = vam->input;
18277   vl_api_af_packet_delete_t *mp;
18278   u8 *host_if_name = 0;
18279   int ret;
18280
18281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18282     {
18283       if (unformat (i, "name %s", &host_if_name))
18284         vec_add1 (host_if_name, 0);
18285       else
18286         break;
18287     }
18288
18289   if (!vec_len (host_if_name))
18290     {
18291       errmsg ("host-interface name must be specified");
18292       return -99;
18293     }
18294
18295   if (vec_len (host_if_name) > 64)
18296     {
18297       errmsg ("host-interface name too long");
18298       return -99;
18299     }
18300
18301   M (AF_PACKET_DELETE, mp);
18302
18303   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18304   vec_free (host_if_name);
18305
18306   S (mp);
18307   W (ret);
18308   return ret;
18309 }
18310
18311 static void vl_api_af_packet_details_t_handler
18312   (vl_api_af_packet_details_t * mp)
18313 {
18314   vat_main_t *vam = &vat_main;
18315
18316   print (vam->ofp, "%-16s %d",
18317          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18318 }
18319
18320 static void vl_api_af_packet_details_t_handler_json
18321   (vl_api_af_packet_details_t * mp)
18322 {
18323   vat_main_t *vam = &vat_main;
18324   vat_json_node_t *node = NULL;
18325
18326   if (VAT_JSON_ARRAY != vam->json_tree.type)
18327     {
18328       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18329       vat_json_init_array (&vam->json_tree);
18330     }
18331   node = vat_json_array_add (&vam->json_tree);
18332
18333   vat_json_init_object (node);
18334   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18335   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18336 }
18337
18338 static int
18339 api_af_packet_dump (vat_main_t * vam)
18340 {
18341   vl_api_af_packet_dump_t *mp;
18342   vl_api_control_ping_t *mp_ping;
18343   int ret;
18344
18345   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18346   /* Get list of tap interfaces */
18347   M (AF_PACKET_DUMP, mp);
18348   S (mp);
18349
18350   /* Use a control ping for synchronization */
18351   MPING (CONTROL_PING, mp_ping);
18352   S (mp_ping);
18353
18354   W (ret);
18355   return ret;
18356 }
18357
18358 static int
18359 api_policer_add_del (vat_main_t * vam)
18360 {
18361   unformat_input_t *i = vam->input;
18362   vl_api_policer_add_del_t *mp;
18363   u8 is_add = 1;
18364   u8 *name = 0;
18365   u32 cir = 0;
18366   u32 eir = 0;
18367   u64 cb = 0;
18368   u64 eb = 0;
18369   u8 rate_type = 0;
18370   u8 round_type = 0;
18371   u8 type = 0;
18372   u8 color_aware = 0;
18373   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18374   int ret;
18375
18376   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18377   conform_action.dscp = 0;
18378   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18379   exceed_action.dscp = 0;
18380   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18381   violate_action.dscp = 0;
18382
18383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18384     {
18385       if (unformat (i, "del"))
18386         is_add = 0;
18387       else if (unformat (i, "name %s", &name))
18388         vec_add1 (name, 0);
18389       else if (unformat (i, "cir %u", &cir))
18390         ;
18391       else if (unformat (i, "eir %u", &eir))
18392         ;
18393       else if (unformat (i, "cb %u", &cb))
18394         ;
18395       else if (unformat (i, "eb %u", &eb))
18396         ;
18397       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18398                          &rate_type))
18399         ;
18400       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18401                          &round_type))
18402         ;
18403       else if (unformat (i, "type %U", unformat_policer_type, &type))
18404         ;
18405       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18406                          &conform_action))
18407         ;
18408       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18409                          &exceed_action))
18410         ;
18411       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18412                          &violate_action))
18413         ;
18414       else if (unformat (i, "color-aware"))
18415         color_aware = 1;
18416       else
18417         break;
18418     }
18419
18420   if (!vec_len (name))
18421     {
18422       errmsg ("policer name must be specified");
18423       return -99;
18424     }
18425
18426   if (vec_len (name) > 64)
18427     {
18428       errmsg ("policer name too long");
18429       return -99;
18430     }
18431
18432   M (POLICER_ADD_DEL, mp);
18433
18434   clib_memcpy (mp->name, name, vec_len (name));
18435   vec_free (name);
18436   mp->is_add = is_add;
18437   mp->cir = ntohl (cir);
18438   mp->eir = ntohl (eir);
18439   mp->cb = clib_net_to_host_u64 (cb);
18440   mp->eb = clib_net_to_host_u64 (eb);
18441   mp->rate_type = rate_type;
18442   mp->round_type = round_type;
18443   mp->type = type;
18444   mp->conform_action_type = conform_action.action_type;
18445   mp->conform_dscp = conform_action.dscp;
18446   mp->exceed_action_type = exceed_action.action_type;
18447   mp->exceed_dscp = exceed_action.dscp;
18448   mp->violate_action_type = violate_action.action_type;
18449   mp->violate_dscp = violate_action.dscp;
18450   mp->color_aware = color_aware;
18451
18452   S (mp);
18453   W (ret);
18454   return ret;
18455 }
18456
18457 static int
18458 api_policer_dump (vat_main_t * vam)
18459 {
18460   unformat_input_t *i = vam->input;
18461   vl_api_policer_dump_t *mp;
18462   vl_api_control_ping_t *mp_ping;
18463   u8 *match_name = 0;
18464   u8 match_name_valid = 0;
18465   int ret;
18466
18467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18468     {
18469       if (unformat (i, "name %s", &match_name))
18470         {
18471           vec_add1 (match_name, 0);
18472           match_name_valid = 1;
18473         }
18474       else
18475         break;
18476     }
18477
18478   M (POLICER_DUMP, mp);
18479   mp->match_name_valid = match_name_valid;
18480   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18481   vec_free (match_name);
18482   /* send it... */
18483   S (mp);
18484
18485   /* Use a control ping for synchronization */
18486   MPING (CONTROL_PING, mp_ping);
18487   S (mp_ping);
18488
18489   /* Wait for a reply... */
18490   W (ret);
18491   return ret;
18492 }
18493
18494 static int
18495 api_policer_classify_set_interface (vat_main_t * vam)
18496 {
18497   unformat_input_t *i = vam->input;
18498   vl_api_policer_classify_set_interface_t *mp;
18499   u32 sw_if_index;
18500   int sw_if_index_set;
18501   u32 ip4_table_index = ~0;
18502   u32 ip6_table_index = ~0;
18503   u32 l2_table_index = ~0;
18504   u8 is_add = 1;
18505   int ret;
18506
18507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18508     {
18509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18510         sw_if_index_set = 1;
18511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18512         sw_if_index_set = 1;
18513       else if (unformat (i, "del"))
18514         is_add = 0;
18515       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18516         ;
18517       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18518         ;
18519       else if (unformat (i, "l2-table %d", &l2_table_index))
18520         ;
18521       else
18522         {
18523           clib_warning ("parse error '%U'", format_unformat_error, i);
18524           return -99;
18525         }
18526     }
18527
18528   if (sw_if_index_set == 0)
18529     {
18530       errmsg ("missing interface name or sw_if_index");
18531       return -99;
18532     }
18533
18534   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18535
18536   mp->sw_if_index = ntohl (sw_if_index);
18537   mp->ip4_table_index = ntohl (ip4_table_index);
18538   mp->ip6_table_index = ntohl (ip6_table_index);
18539   mp->l2_table_index = ntohl (l2_table_index);
18540   mp->is_add = is_add;
18541
18542   S (mp);
18543   W (ret);
18544   return ret;
18545 }
18546
18547 static int
18548 api_policer_classify_dump (vat_main_t * vam)
18549 {
18550   unformat_input_t *i = vam->input;
18551   vl_api_policer_classify_dump_t *mp;
18552   vl_api_control_ping_t *mp_ping;
18553   u8 type = POLICER_CLASSIFY_N_TABLES;
18554   int ret;
18555
18556   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18557     ;
18558   else
18559     {
18560       errmsg ("classify table type must be specified");
18561       return -99;
18562     }
18563
18564   if (!vam->json_output)
18565     {
18566       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18567     }
18568
18569   M (POLICER_CLASSIFY_DUMP, mp);
18570   mp->type = type;
18571   /* send it... */
18572   S (mp);
18573
18574   /* Use a control ping for synchronization */
18575   MPING (CONTROL_PING, mp_ping);
18576   S (mp_ping);
18577
18578   /* Wait for a reply... */
18579   W (ret);
18580   return ret;
18581 }
18582
18583 static int
18584 api_netmap_create (vat_main_t * vam)
18585 {
18586   unformat_input_t *i = vam->input;
18587   vl_api_netmap_create_t *mp;
18588   u8 *if_name = 0;
18589   u8 hw_addr[6];
18590   u8 random_hw_addr = 1;
18591   u8 is_pipe = 0;
18592   u8 is_master = 0;
18593   int ret;
18594
18595   clib_memset (hw_addr, 0, sizeof (hw_addr));
18596
18597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18598     {
18599       if (unformat (i, "name %s", &if_name))
18600         vec_add1 (if_name, 0);
18601       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18602         random_hw_addr = 0;
18603       else if (unformat (i, "pipe"))
18604         is_pipe = 1;
18605       else if (unformat (i, "master"))
18606         is_master = 1;
18607       else if (unformat (i, "slave"))
18608         is_master = 0;
18609       else
18610         break;
18611     }
18612
18613   if (!vec_len (if_name))
18614     {
18615       errmsg ("interface name must be specified");
18616       return -99;
18617     }
18618
18619   if (vec_len (if_name) > 64)
18620     {
18621       errmsg ("interface name too long");
18622       return -99;
18623     }
18624
18625   M (NETMAP_CREATE, mp);
18626
18627   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18628   clib_memcpy (mp->hw_addr, hw_addr, 6);
18629   mp->use_random_hw_addr = random_hw_addr;
18630   mp->is_pipe = is_pipe;
18631   mp->is_master = is_master;
18632   vec_free (if_name);
18633
18634   S (mp);
18635   W (ret);
18636   return ret;
18637 }
18638
18639 static int
18640 api_netmap_delete (vat_main_t * vam)
18641 {
18642   unformat_input_t *i = vam->input;
18643   vl_api_netmap_delete_t *mp;
18644   u8 *if_name = 0;
18645   int ret;
18646
18647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18648     {
18649       if (unformat (i, "name %s", &if_name))
18650         vec_add1 (if_name, 0);
18651       else
18652         break;
18653     }
18654
18655   if (!vec_len (if_name))
18656     {
18657       errmsg ("interface name must be specified");
18658       return -99;
18659     }
18660
18661   if (vec_len (if_name) > 64)
18662     {
18663       errmsg ("interface name too long");
18664       return -99;
18665     }
18666
18667   M (NETMAP_DELETE, mp);
18668
18669   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18670   vec_free (if_name);
18671
18672   S (mp);
18673   W (ret);
18674   return ret;
18675 }
18676
18677 static u8 *
18678 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18679 {
18680   vl_api_fib_path_nh_proto_t proto =
18681     va_arg (*args, vl_api_fib_path_nh_proto_t);
18682
18683   switch (proto)
18684     {
18685     case FIB_API_PATH_NH_PROTO_IP4:
18686       s = format (s, "ip4");
18687       break;
18688     case FIB_API_PATH_NH_PROTO_IP6:
18689       s = format (s, "ip6");
18690       break;
18691     case FIB_API_PATH_NH_PROTO_MPLS:
18692       s = format (s, "mpls");
18693       break;
18694     case FIB_API_PATH_NH_PROTO_BIER:
18695       s = format (s, "bier");
18696       break;
18697     case FIB_API_PATH_NH_PROTO_ETHERNET:
18698       s = format (s, "ethernet");
18699       break;
18700     }
18701
18702   return (s);
18703 }
18704
18705 static u8 *
18706 format_vl_api_ip_address_union (u8 * s, va_list * args)
18707 {
18708   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18709   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18710
18711   switch (af)
18712     {
18713     case ADDRESS_IP4:
18714       s = format (s, "%U", format_ip4_address, u->ip4);
18715       break;
18716     case ADDRESS_IP6:
18717       s = format (s, "%U", format_ip6_address, u->ip6);
18718       break;
18719     }
18720   return (s);
18721 }
18722
18723 static u8 *
18724 format_vl_api_fib_path_type (u8 * s, va_list * args)
18725 {
18726   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18727
18728   switch (t)
18729     {
18730     case FIB_API_PATH_TYPE_NORMAL:
18731       s = format (s, "normal");
18732       break;
18733     case FIB_API_PATH_TYPE_LOCAL:
18734       s = format (s, "local");
18735       break;
18736     case FIB_API_PATH_TYPE_DROP:
18737       s = format (s, "drop");
18738       break;
18739     case FIB_API_PATH_TYPE_UDP_ENCAP:
18740       s = format (s, "udp-encap");
18741       break;
18742     case FIB_API_PATH_TYPE_BIER_IMP:
18743       s = format (s, "bier-imp");
18744       break;
18745     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18746       s = format (s, "unreach");
18747       break;
18748     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18749       s = format (s, "prohibit");
18750       break;
18751     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18752       s = format (s, "src-lookup");
18753       break;
18754     case FIB_API_PATH_TYPE_DVR:
18755       s = format (s, "dvr");
18756       break;
18757     case FIB_API_PATH_TYPE_INTERFACE_RX:
18758       s = format (s, "interface-rx");
18759       break;
18760     case FIB_API_PATH_TYPE_CLASSIFY:
18761       s = format (s, "classify");
18762       break;
18763     }
18764
18765   return (s);
18766 }
18767
18768 static void
18769 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18770 {
18771   print (vam->ofp,
18772          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18773          ntohl (fp->weight), ntohl (fp->sw_if_index),
18774          format_vl_api_fib_path_type, fp->type,
18775          format_fib_api_path_nh_proto, fp->proto,
18776          format_vl_api_ip_address_union, &fp->nh.address);
18777 }
18778
18779 static void
18780 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18781                                  vl_api_fib_path_t * fp)
18782 {
18783   struct in_addr ip4;
18784   struct in6_addr ip6;
18785
18786   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18787   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18788   vat_json_object_add_uint (node, "type", fp->type);
18789   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18790   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18791     {
18792       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18793       vat_json_object_add_ip4 (node, "next_hop", ip4);
18794     }
18795   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18796     {
18797       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18798       vat_json_object_add_ip6 (node, "next_hop", ip6);
18799     }
18800 }
18801
18802 static void
18803 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18804 {
18805   vat_main_t *vam = &vat_main;
18806   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18807   vl_api_fib_path_t *fp;
18808   i32 i;
18809
18810   print (vam->ofp, "sw_if_index %d via:",
18811          ntohl (mp->mt_tunnel.mt_sw_if_index));
18812   fp = mp->mt_tunnel.mt_paths;
18813   for (i = 0; i < count; i++)
18814     {
18815       vl_api_fib_path_print (vam, fp);
18816       fp++;
18817     }
18818
18819   print (vam->ofp, "");
18820 }
18821
18822 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18823 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18824
18825 static void
18826 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18827 {
18828   vat_main_t *vam = &vat_main;
18829   vat_json_node_t *node = NULL;
18830   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18831   vl_api_fib_path_t *fp;
18832   i32 i;
18833
18834   if (VAT_JSON_ARRAY != vam->json_tree.type)
18835     {
18836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18837       vat_json_init_array (&vam->json_tree);
18838     }
18839   node = vat_json_array_add (&vam->json_tree);
18840
18841   vat_json_init_object (node);
18842   vat_json_object_add_uint (node, "sw_if_index",
18843                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18844
18845   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18846
18847   fp = mp->mt_tunnel.mt_paths;
18848   for (i = 0; i < count; i++)
18849     {
18850       vl_api_mpls_fib_path_json_print (node, fp);
18851       fp++;
18852     }
18853 }
18854
18855 static int
18856 api_mpls_tunnel_dump (vat_main_t * vam)
18857 {
18858   vl_api_mpls_tunnel_dump_t *mp;
18859   vl_api_control_ping_t *mp_ping;
18860   int ret;
18861
18862   M (MPLS_TUNNEL_DUMP, mp);
18863
18864   S (mp);
18865
18866   /* Use a control ping for synchronization */
18867   MPING (CONTROL_PING, mp_ping);
18868   S (mp_ping);
18869
18870   W (ret);
18871   return ret;
18872 }
18873
18874 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18875 #define vl_api_mpls_table_details_t_print vl_noop_handler
18876
18877
18878 static void
18879 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18880 {
18881   vat_main_t *vam = &vat_main;
18882
18883   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18884 }
18885
18886 static void vl_api_mpls_table_details_t_handler_json
18887   (vl_api_mpls_table_details_t * mp)
18888 {
18889   vat_main_t *vam = &vat_main;
18890   vat_json_node_t *node = NULL;
18891
18892   if (VAT_JSON_ARRAY != vam->json_tree.type)
18893     {
18894       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18895       vat_json_init_array (&vam->json_tree);
18896     }
18897   node = vat_json_array_add (&vam->json_tree);
18898
18899   vat_json_init_object (node);
18900   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18901 }
18902
18903 static int
18904 api_mpls_table_dump (vat_main_t * vam)
18905 {
18906   vl_api_mpls_table_dump_t *mp;
18907   vl_api_control_ping_t *mp_ping;
18908   int ret;
18909
18910   M (MPLS_TABLE_DUMP, mp);
18911   S (mp);
18912
18913   /* Use a control ping for synchronization */
18914   MPING (CONTROL_PING, mp_ping);
18915   S (mp_ping);
18916
18917   W (ret);
18918   return ret;
18919 }
18920
18921 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18922 #define vl_api_mpls_route_details_t_print vl_noop_handler
18923
18924 static void
18925 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18926 {
18927   vat_main_t *vam = &vat_main;
18928   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18929   vl_api_fib_path_t *fp;
18930   int i;
18931
18932   print (vam->ofp,
18933          "table-id %d, label %u, ess_bit %u",
18934          ntohl (mp->mr_route.mr_table_id),
18935          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18936   fp = mp->mr_route.mr_paths;
18937   for (i = 0; i < count; i++)
18938     {
18939       vl_api_fib_path_print (vam, fp);
18940       fp++;
18941     }
18942 }
18943
18944 static void vl_api_mpls_route_details_t_handler_json
18945   (vl_api_mpls_route_details_t * mp)
18946 {
18947   vat_main_t *vam = &vat_main;
18948   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18949   vat_json_node_t *node = NULL;
18950   vl_api_fib_path_t *fp;
18951   int i;
18952
18953   if (VAT_JSON_ARRAY != vam->json_tree.type)
18954     {
18955       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18956       vat_json_init_array (&vam->json_tree);
18957     }
18958   node = vat_json_array_add (&vam->json_tree);
18959
18960   vat_json_init_object (node);
18961   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18962   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18963   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18964   vat_json_object_add_uint (node, "path_count", count);
18965   fp = mp->mr_route.mr_paths;
18966   for (i = 0; i < count; i++)
18967     {
18968       vl_api_mpls_fib_path_json_print (node, fp);
18969       fp++;
18970     }
18971 }
18972
18973 static int
18974 api_mpls_route_dump (vat_main_t * vam)
18975 {
18976   unformat_input_t *input = vam->input;
18977   vl_api_mpls_route_dump_t *mp;
18978   vl_api_control_ping_t *mp_ping;
18979   u32 table_id;
18980   int ret;
18981
18982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18983     {
18984       if (unformat (input, "table_id %d", &table_id))
18985         ;
18986       else
18987         break;
18988     }
18989   if (table_id == ~0)
18990     {
18991       errmsg ("missing table id");
18992       return -99;
18993     }
18994
18995   M (MPLS_ROUTE_DUMP, mp);
18996
18997   mp->table.mt_table_id = ntohl (table_id);
18998   S (mp);
18999
19000   /* Use a control ping for synchronization */
19001   MPING (CONTROL_PING, mp_ping);
19002   S (mp_ping);
19003
19004   W (ret);
19005   return ret;
19006 }
19007
19008 #define vl_api_ip_table_details_t_endian vl_noop_handler
19009 #define vl_api_ip_table_details_t_print vl_noop_handler
19010
19011 static void
19012 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19013 {
19014   vat_main_t *vam = &vat_main;
19015
19016   print (vam->ofp,
19017          "%s; table-id %d, prefix %U/%d",
19018          mp->table.name, ntohl (mp->table.table_id));
19019 }
19020
19021
19022 static void vl_api_ip_table_details_t_handler_json
19023   (vl_api_ip_table_details_t * mp)
19024 {
19025   vat_main_t *vam = &vat_main;
19026   vat_json_node_t *node = NULL;
19027
19028   if (VAT_JSON_ARRAY != vam->json_tree.type)
19029     {
19030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19031       vat_json_init_array (&vam->json_tree);
19032     }
19033   node = vat_json_array_add (&vam->json_tree);
19034
19035   vat_json_init_object (node);
19036   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19037 }
19038
19039 static int
19040 api_ip_table_dump (vat_main_t * vam)
19041 {
19042   vl_api_ip_table_dump_t *mp;
19043   vl_api_control_ping_t *mp_ping;
19044   int ret;
19045
19046   M (IP_TABLE_DUMP, mp);
19047   S (mp);
19048
19049   /* Use a control ping for synchronization */
19050   MPING (CONTROL_PING, mp_ping);
19051   S (mp_ping);
19052
19053   W (ret);
19054   return ret;
19055 }
19056
19057 static int
19058 api_ip_mtable_dump (vat_main_t * vam)
19059 {
19060   vl_api_ip_mtable_dump_t *mp;
19061   vl_api_control_ping_t *mp_ping;
19062   int ret;
19063
19064   M (IP_MTABLE_DUMP, mp);
19065   S (mp);
19066
19067   /* Use a control ping for synchronization */
19068   MPING (CONTROL_PING, mp_ping);
19069   S (mp_ping);
19070
19071   W (ret);
19072   return ret;
19073 }
19074
19075 static int
19076 api_ip_mroute_dump (vat_main_t * vam)
19077 {
19078   unformat_input_t *input = vam->input;
19079   vl_api_control_ping_t *mp_ping;
19080   vl_api_ip_mroute_dump_t *mp;
19081   int ret, is_ip6;
19082   u32 table_id;
19083
19084   is_ip6 = 0;
19085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19086     {
19087       if (unformat (input, "table_id %d", &table_id))
19088         ;
19089       else if (unformat (input, "ip6"))
19090         is_ip6 = 1;
19091       else if (unformat (input, "ip4"))
19092         is_ip6 = 0;
19093       else
19094         break;
19095     }
19096   if (table_id == ~0)
19097     {
19098       errmsg ("missing table id");
19099       return -99;
19100     }
19101
19102   M (IP_MROUTE_DUMP, mp);
19103   mp->table.table_id = table_id;
19104   mp->table.is_ip6 = is_ip6;
19105   S (mp);
19106
19107   /* Use a control ping for synchronization */
19108   MPING (CONTROL_PING, mp_ping);
19109   S (mp_ping);
19110
19111   W (ret);
19112   return ret;
19113 }
19114
19115 static void vl_api_ip_neighbor_details_t_handler
19116   (vl_api_ip_neighbor_details_t * mp)
19117 {
19118   vat_main_t *vam = &vat_main;
19119
19120   print (vam->ofp, "%c %U %U",
19121          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19122          format_vl_api_mac_address, &mp->neighbor.mac_address,
19123          format_vl_api_address, &mp->neighbor.ip_address);
19124 }
19125
19126 static void vl_api_ip_neighbor_details_t_handler_json
19127   (vl_api_ip_neighbor_details_t * mp)
19128 {
19129
19130   vat_main_t *vam = &vat_main;
19131   vat_json_node_t *node;
19132
19133   if (VAT_JSON_ARRAY != vam->json_tree.type)
19134     {
19135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19136       vat_json_init_array (&vam->json_tree);
19137     }
19138   node = vat_json_array_add (&vam->json_tree);
19139
19140   vat_json_init_object (node);
19141   vat_json_object_add_string_copy
19142     (node, "flag",
19143      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19144       (u8 *) "static" : (u8 *) "dynamic"));
19145
19146   vat_json_object_add_string_copy (node, "link_layer",
19147                                    format (0, "%U", format_vl_api_mac_address,
19148                                            &mp->neighbor.mac_address));
19149   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19150 }
19151
19152 static int
19153 api_ip_neighbor_dump (vat_main_t * vam)
19154 {
19155   unformat_input_t *i = vam->input;
19156   vl_api_ip_neighbor_dump_t *mp;
19157   vl_api_control_ping_t *mp_ping;
19158   u8 is_ipv6 = 0;
19159   u32 sw_if_index = ~0;
19160   int ret;
19161
19162   /* Parse args required to build the message */
19163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19164     {
19165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19166         ;
19167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19168         ;
19169       else if (unformat (i, "ip6"))
19170         is_ipv6 = 1;
19171       else
19172         break;
19173     }
19174
19175   if (sw_if_index == ~0)
19176     {
19177       errmsg ("missing interface name or sw_if_index");
19178       return -99;
19179     }
19180
19181   M (IP_NEIGHBOR_DUMP, mp);
19182   mp->is_ipv6 = (u8) is_ipv6;
19183   mp->sw_if_index = ntohl (sw_if_index);
19184   S (mp);
19185
19186   /* Use a control ping for synchronization */
19187   MPING (CONTROL_PING, mp_ping);
19188   S (mp_ping);
19189
19190   W (ret);
19191   return ret;
19192 }
19193
19194 #define vl_api_ip_route_details_t_endian vl_noop_handler
19195 #define vl_api_ip_route_details_t_print vl_noop_handler
19196
19197 static void
19198 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19199 {
19200   vat_main_t *vam = &vat_main;
19201   u8 count = mp->route.n_paths;
19202   vl_api_fib_path_t *fp;
19203   int i;
19204
19205   print (vam->ofp,
19206          "table-id %d, prefix %U/%d",
19207          ntohl (mp->route.table_id),
19208          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19209   for (i = 0; i < count; i++)
19210     {
19211       fp = &mp->route.paths[i];
19212
19213       vl_api_fib_path_print (vam, fp);
19214       fp++;
19215     }
19216 }
19217
19218 static void vl_api_ip_route_details_t_handler_json
19219   (vl_api_ip_route_details_t * mp)
19220 {
19221   vat_main_t *vam = &vat_main;
19222   u8 count = mp->route.n_paths;
19223   vat_json_node_t *node = NULL;
19224   struct in_addr ip4;
19225   struct in6_addr ip6;
19226   vl_api_fib_path_t *fp;
19227   int i;
19228
19229   if (VAT_JSON_ARRAY != vam->json_tree.type)
19230     {
19231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19232       vat_json_init_array (&vam->json_tree);
19233     }
19234   node = vat_json_array_add (&vam->json_tree);
19235
19236   vat_json_init_object (node);
19237   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19238   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19239     {
19240       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19241       vat_json_object_add_ip6 (node, "prefix", ip6);
19242     }
19243   else
19244     {
19245       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19246       vat_json_object_add_ip4 (node, "prefix", ip4);
19247     }
19248   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19249   vat_json_object_add_uint (node, "path_count", count);
19250   for (i = 0; i < count; i++)
19251     {
19252       fp = &mp->route.paths[i];
19253       vl_api_mpls_fib_path_json_print (node, fp);
19254     }
19255 }
19256
19257 static int
19258 api_ip_route_dump (vat_main_t * vam)
19259 {
19260   unformat_input_t *input = vam->input;
19261   vl_api_ip_route_dump_t *mp;
19262   vl_api_control_ping_t *mp_ping;
19263   u32 table_id;
19264   u8 is_ip6;
19265   int ret;
19266
19267   is_ip6 = 0;
19268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19269     {
19270       if (unformat (input, "table_id %d", &table_id))
19271         ;
19272       else if (unformat (input, "ip6"))
19273         is_ip6 = 1;
19274       else if (unformat (input, "ip4"))
19275         is_ip6 = 0;
19276       else
19277         break;
19278     }
19279   if (table_id == ~0)
19280     {
19281       errmsg ("missing table id");
19282       return -99;
19283     }
19284
19285   M (IP_ROUTE_DUMP, mp);
19286
19287   mp->table.table_id = table_id;
19288   mp->table.is_ip6 = is_ip6;
19289
19290   S (mp);
19291
19292   /* Use a control ping for synchronization */
19293   MPING (CONTROL_PING, mp_ping);
19294   S (mp_ping);
19295
19296   W (ret);
19297   return ret;
19298 }
19299
19300 int
19301 api_classify_table_ids (vat_main_t * vam)
19302 {
19303   vl_api_classify_table_ids_t *mp;
19304   int ret;
19305
19306   /* Construct the API message */
19307   M (CLASSIFY_TABLE_IDS, mp);
19308   mp->context = 0;
19309
19310   S (mp);
19311   W (ret);
19312   return ret;
19313 }
19314
19315 int
19316 api_classify_table_by_interface (vat_main_t * vam)
19317 {
19318   unformat_input_t *input = vam->input;
19319   vl_api_classify_table_by_interface_t *mp;
19320
19321   u32 sw_if_index = ~0;
19322   int ret;
19323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19324     {
19325       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19326         ;
19327       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19328         ;
19329       else
19330         break;
19331     }
19332   if (sw_if_index == ~0)
19333     {
19334       errmsg ("missing interface name or sw_if_index");
19335       return -99;
19336     }
19337
19338   /* Construct the API message */
19339   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19340   mp->context = 0;
19341   mp->sw_if_index = ntohl (sw_if_index);
19342
19343   S (mp);
19344   W (ret);
19345   return ret;
19346 }
19347
19348 int
19349 api_classify_table_info (vat_main_t * vam)
19350 {
19351   unformat_input_t *input = vam->input;
19352   vl_api_classify_table_info_t *mp;
19353
19354   u32 table_id = ~0;
19355   int ret;
19356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19357     {
19358       if (unformat (input, "table_id %d", &table_id))
19359         ;
19360       else
19361         break;
19362     }
19363   if (table_id == ~0)
19364     {
19365       errmsg ("missing table id");
19366       return -99;
19367     }
19368
19369   /* Construct the API message */
19370   M (CLASSIFY_TABLE_INFO, mp);
19371   mp->context = 0;
19372   mp->table_id = ntohl (table_id);
19373
19374   S (mp);
19375   W (ret);
19376   return ret;
19377 }
19378
19379 int
19380 api_classify_session_dump (vat_main_t * vam)
19381 {
19382   unformat_input_t *input = vam->input;
19383   vl_api_classify_session_dump_t *mp;
19384   vl_api_control_ping_t *mp_ping;
19385
19386   u32 table_id = ~0;
19387   int ret;
19388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19389     {
19390       if (unformat (input, "table_id %d", &table_id))
19391         ;
19392       else
19393         break;
19394     }
19395   if (table_id == ~0)
19396     {
19397       errmsg ("missing table id");
19398       return -99;
19399     }
19400
19401   /* Construct the API message */
19402   M (CLASSIFY_SESSION_DUMP, mp);
19403   mp->context = 0;
19404   mp->table_id = ntohl (table_id);
19405   S (mp);
19406
19407   /* Use a control ping for synchronization */
19408   MPING (CONTROL_PING, mp_ping);
19409   S (mp_ping);
19410
19411   W (ret);
19412   return ret;
19413 }
19414
19415 static void
19416 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19417 {
19418   vat_main_t *vam = &vat_main;
19419
19420   print (vam->ofp, "collector_address %U, collector_port %d, "
19421          "src_address %U, vrf_id %d, path_mtu %u, "
19422          "template_interval %u, udp_checksum %d",
19423          format_ip4_address, mp->collector_address,
19424          ntohs (mp->collector_port),
19425          format_ip4_address, mp->src_address,
19426          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19427          ntohl (mp->template_interval), mp->udp_checksum);
19428
19429   vam->retval = 0;
19430   vam->result_ready = 1;
19431 }
19432
19433 static void
19434   vl_api_ipfix_exporter_details_t_handler_json
19435   (vl_api_ipfix_exporter_details_t * mp)
19436 {
19437   vat_main_t *vam = &vat_main;
19438   vat_json_node_t node;
19439   struct in_addr collector_address;
19440   struct in_addr src_address;
19441
19442   vat_json_init_object (&node);
19443   clib_memcpy (&collector_address, &mp->collector_address,
19444                sizeof (collector_address));
19445   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19446   vat_json_object_add_uint (&node, "collector_port",
19447                             ntohs (mp->collector_port));
19448   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19449   vat_json_object_add_ip4 (&node, "src_address", src_address);
19450   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19451   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19452   vat_json_object_add_uint (&node, "template_interval",
19453                             ntohl (mp->template_interval));
19454   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19455
19456   vat_json_print (vam->ofp, &node);
19457   vat_json_free (&node);
19458   vam->retval = 0;
19459   vam->result_ready = 1;
19460 }
19461
19462 int
19463 api_ipfix_exporter_dump (vat_main_t * vam)
19464 {
19465   vl_api_ipfix_exporter_dump_t *mp;
19466   int ret;
19467
19468   /* Construct the API message */
19469   M (IPFIX_EXPORTER_DUMP, mp);
19470   mp->context = 0;
19471
19472   S (mp);
19473   W (ret);
19474   return ret;
19475 }
19476
19477 static int
19478 api_ipfix_classify_stream_dump (vat_main_t * vam)
19479 {
19480   vl_api_ipfix_classify_stream_dump_t *mp;
19481   int ret;
19482
19483   /* Construct the API message */
19484   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19485   mp->context = 0;
19486
19487   S (mp);
19488   W (ret);
19489   return ret;
19490   /* NOTREACHED */
19491   return 0;
19492 }
19493
19494 static void
19495   vl_api_ipfix_classify_stream_details_t_handler
19496   (vl_api_ipfix_classify_stream_details_t * mp)
19497 {
19498   vat_main_t *vam = &vat_main;
19499   print (vam->ofp, "domain_id %d, src_port %d",
19500          ntohl (mp->domain_id), ntohs (mp->src_port));
19501   vam->retval = 0;
19502   vam->result_ready = 1;
19503 }
19504
19505 static void
19506   vl_api_ipfix_classify_stream_details_t_handler_json
19507   (vl_api_ipfix_classify_stream_details_t * mp)
19508 {
19509   vat_main_t *vam = &vat_main;
19510   vat_json_node_t node;
19511
19512   vat_json_init_object (&node);
19513   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19514   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19515
19516   vat_json_print (vam->ofp, &node);
19517   vat_json_free (&node);
19518   vam->retval = 0;
19519   vam->result_ready = 1;
19520 }
19521
19522 static int
19523 api_ipfix_classify_table_dump (vat_main_t * vam)
19524 {
19525   vl_api_ipfix_classify_table_dump_t *mp;
19526   vl_api_control_ping_t *mp_ping;
19527   int ret;
19528
19529   if (!vam->json_output)
19530     {
19531       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19532              "transport_protocol");
19533     }
19534
19535   /* Construct the API message */
19536   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19537
19538   /* send it... */
19539   S (mp);
19540
19541   /* Use a control ping for synchronization */
19542   MPING (CONTROL_PING, mp_ping);
19543   S (mp_ping);
19544
19545   W (ret);
19546   return ret;
19547 }
19548
19549 static void
19550   vl_api_ipfix_classify_table_details_t_handler
19551   (vl_api_ipfix_classify_table_details_t * mp)
19552 {
19553   vat_main_t *vam = &vat_main;
19554   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19555          mp->transport_protocol);
19556 }
19557
19558 static void
19559   vl_api_ipfix_classify_table_details_t_handler_json
19560   (vl_api_ipfix_classify_table_details_t * mp)
19561 {
19562   vat_json_node_t *node = NULL;
19563   vat_main_t *vam = &vat_main;
19564
19565   if (VAT_JSON_ARRAY != vam->json_tree.type)
19566     {
19567       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19568       vat_json_init_array (&vam->json_tree);
19569     }
19570
19571   node = vat_json_array_add (&vam->json_tree);
19572   vat_json_init_object (node);
19573
19574   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19575   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19576   vat_json_object_add_uint (node, "transport_protocol",
19577                             mp->transport_protocol);
19578 }
19579
19580 static int
19581 api_sw_interface_span_enable_disable (vat_main_t * vam)
19582 {
19583   unformat_input_t *i = vam->input;
19584   vl_api_sw_interface_span_enable_disable_t *mp;
19585   u32 src_sw_if_index = ~0;
19586   u32 dst_sw_if_index = ~0;
19587   u8 state = 3;
19588   int ret;
19589   u8 is_l2 = 0;
19590
19591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19592     {
19593       if (unformat
19594           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19595         ;
19596       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19597         ;
19598       else
19599         if (unformat
19600             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19601         ;
19602       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19603         ;
19604       else if (unformat (i, "disable"))
19605         state = 0;
19606       else if (unformat (i, "rx"))
19607         state = 1;
19608       else if (unformat (i, "tx"))
19609         state = 2;
19610       else if (unformat (i, "both"))
19611         state = 3;
19612       else if (unformat (i, "l2"))
19613         is_l2 = 1;
19614       else
19615         break;
19616     }
19617
19618   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19619
19620   mp->sw_if_index_from = htonl (src_sw_if_index);
19621   mp->sw_if_index_to = htonl (dst_sw_if_index);
19622   mp->state = state;
19623   mp->is_l2 = is_l2;
19624
19625   S (mp);
19626   W (ret);
19627   return ret;
19628 }
19629
19630 static void
19631 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19632                                             * mp)
19633 {
19634   vat_main_t *vam = &vat_main;
19635   u8 *sw_if_from_name = 0;
19636   u8 *sw_if_to_name = 0;
19637   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19638   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19639   char *states[] = { "none", "rx", "tx", "both" };
19640   hash_pair_t *p;
19641
19642   /* *INDENT-OFF* */
19643   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19644   ({
19645     if ((u32) p->value[0] == sw_if_index_from)
19646       {
19647         sw_if_from_name = (u8 *)(p->key);
19648         if (sw_if_to_name)
19649           break;
19650       }
19651     if ((u32) p->value[0] == sw_if_index_to)
19652       {
19653         sw_if_to_name = (u8 *)(p->key);
19654         if (sw_if_from_name)
19655           break;
19656       }
19657   }));
19658   /* *INDENT-ON* */
19659   print (vam->ofp, "%20s => %20s (%s) %s",
19660          sw_if_from_name, sw_if_to_name, states[mp->state],
19661          mp->is_l2 ? "l2" : "device");
19662 }
19663
19664 static void
19665   vl_api_sw_interface_span_details_t_handler_json
19666   (vl_api_sw_interface_span_details_t * mp)
19667 {
19668   vat_main_t *vam = &vat_main;
19669   vat_json_node_t *node = NULL;
19670   u8 *sw_if_from_name = 0;
19671   u8 *sw_if_to_name = 0;
19672   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19673   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19674   hash_pair_t *p;
19675
19676   /* *INDENT-OFF* */
19677   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19678   ({
19679     if ((u32) p->value[0] == sw_if_index_from)
19680       {
19681         sw_if_from_name = (u8 *)(p->key);
19682         if (sw_if_to_name)
19683           break;
19684       }
19685     if ((u32) p->value[0] == sw_if_index_to)
19686       {
19687         sw_if_to_name = (u8 *)(p->key);
19688         if (sw_if_from_name)
19689           break;
19690       }
19691   }));
19692   /* *INDENT-ON* */
19693
19694   if (VAT_JSON_ARRAY != vam->json_tree.type)
19695     {
19696       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19697       vat_json_init_array (&vam->json_tree);
19698     }
19699   node = vat_json_array_add (&vam->json_tree);
19700
19701   vat_json_init_object (node);
19702   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19703   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19704   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19705   if (0 != sw_if_to_name)
19706     {
19707       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19708     }
19709   vat_json_object_add_uint (node, "state", mp->state);
19710   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19711 }
19712
19713 static int
19714 api_sw_interface_span_dump (vat_main_t * vam)
19715 {
19716   unformat_input_t *input = vam->input;
19717   vl_api_sw_interface_span_dump_t *mp;
19718   vl_api_control_ping_t *mp_ping;
19719   u8 is_l2 = 0;
19720   int ret;
19721
19722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19723     {
19724       if (unformat (input, "l2"))
19725         is_l2 = 1;
19726       else
19727         break;
19728     }
19729
19730   M (SW_INTERFACE_SPAN_DUMP, mp);
19731   mp->is_l2 = is_l2;
19732   S (mp);
19733
19734   /* Use a control ping for synchronization */
19735   MPING (CONTROL_PING, mp_ping);
19736   S (mp_ping);
19737
19738   W (ret);
19739   return ret;
19740 }
19741
19742 int
19743 api_pg_create_interface (vat_main_t * vam)
19744 {
19745   unformat_input_t *input = vam->input;
19746   vl_api_pg_create_interface_t *mp;
19747
19748   u32 if_id = ~0;
19749   int ret;
19750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19751     {
19752       if (unformat (input, "if_id %d", &if_id))
19753         ;
19754       else
19755         break;
19756     }
19757   if (if_id == ~0)
19758     {
19759       errmsg ("missing pg interface index");
19760       return -99;
19761     }
19762
19763   /* Construct the API message */
19764   M (PG_CREATE_INTERFACE, mp);
19765   mp->context = 0;
19766   mp->interface_id = ntohl (if_id);
19767
19768   S (mp);
19769   W (ret);
19770   return ret;
19771 }
19772
19773 int
19774 api_pg_capture (vat_main_t * vam)
19775 {
19776   unformat_input_t *input = vam->input;
19777   vl_api_pg_capture_t *mp;
19778
19779   u32 if_id = ~0;
19780   u8 enable = 1;
19781   u32 count = 1;
19782   u8 pcap_file_set = 0;
19783   u8 *pcap_file = 0;
19784   int ret;
19785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19786     {
19787       if (unformat (input, "if_id %d", &if_id))
19788         ;
19789       else if (unformat (input, "pcap %s", &pcap_file))
19790         pcap_file_set = 1;
19791       else if (unformat (input, "count %d", &count))
19792         ;
19793       else if (unformat (input, "disable"))
19794         enable = 0;
19795       else
19796         break;
19797     }
19798   if (if_id == ~0)
19799     {
19800       errmsg ("missing pg interface index");
19801       return -99;
19802     }
19803   if (pcap_file_set > 0)
19804     {
19805       if (vec_len (pcap_file) > 255)
19806         {
19807           errmsg ("pcap file name is too long");
19808           return -99;
19809         }
19810     }
19811
19812   u32 name_len = vec_len (pcap_file);
19813   /* Construct the API message */
19814   M (PG_CAPTURE, mp);
19815   mp->context = 0;
19816   mp->interface_id = ntohl (if_id);
19817   mp->is_enabled = enable;
19818   mp->count = ntohl (count);
19819   mp->pcap_name_length = ntohl (name_len);
19820   if (pcap_file_set != 0)
19821     {
19822       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19823     }
19824   vec_free (pcap_file);
19825
19826   S (mp);
19827   W (ret);
19828   return ret;
19829 }
19830
19831 int
19832 api_pg_enable_disable (vat_main_t * vam)
19833 {
19834   unformat_input_t *input = vam->input;
19835   vl_api_pg_enable_disable_t *mp;
19836
19837   u8 enable = 1;
19838   u8 stream_name_set = 0;
19839   u8 *stream_name = 0;
19840   int ret;
19841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19842     {
19843       if (unformat (input, "stream %s", &stream_name))
19844         stream_name_set = 1;
19845       else if (unformat (input, "disable"))
19846         enable = 0;
19847       else
19848         break;
19849     }
19850
19851   if (stream_name_set > 0)
19852     {
19853       if (vec_len (stream_name) > 255)
19854         {
19855           errmsg ("stream name too long");
19856           return -99;
19857         }
19858     }
19859
19860   u32 name_len = vec_len (stream_name);
19861   /* Construct the API message */
19862   M (PG_ENABLE_DISABLE, mp);
19863   mp->context = 0;
19864   mp->is_enabled = enable;
19865   if (stream_name_set != 0)
19866     {
19867       mp->stream_name_length = ntohl (name_len);
19868       clib_memcpy (mp->stream_name, stream_name, name_len);
19869     }
19870   vec_free (stream_name);
19871
19872   S (mp);
19873   W (ret);
19874   return ret;
19875 }
19876
19877 int
19878 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19879 {
19880   unformat_input_t *input = vam->input;
19881   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19882
19883   u16 *low_ports = 0;
19884   u16 *high_ports = 0;
19885   u16 this_low;
19886   u16 this_hi;
19887   vl_api_prefix_t prefix;
19888   u32 tmp, tmp2;
19889   u8 prefix_set = 0;
19890   u32 vrf_id = ~0;
19891   u8 is_add = 1;
19892   int ret;
19893
19894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19895     {
19896       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19897         prefix_set = 1;
19898       else if (unformat (input, "vrf %d", &vrf_id))
19899         ;
19900       else if (unformat (input, "del"))
19901         is_add = 0;
19902       else if (unformat (input, "port %d", &tmp))
19903         {
19904           if (tmp == 0 || tmp > 65535)
19905             {
19906               errmsg ("port %d out of range", tmp);
19907               return -99;
19908             }
19909           this_low = tmp;
19910           this_hi = this_low + 1;
19911           vec_add1 (low_ports, this_low);
19912           vec_add1 (high_ports, this_hi);
19913         }
19914       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19915         {
19916           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19917             {
19918               errmsg ("incorrect range parameters");
19919               return -99;
19920             }
19921           this_low = tmp;
19922           /* Note: in debug CLI +1 is added to high before
19923              passing to real fn that does "the work"
19924              (ip_source_and_port_range_check_add_del).
19925              This fn is a wrapper around the binary API fn a
19926              control plane will call, which expects this increment
19927              to have occurred. Hence letting the binary API control
19928              plane fn do the increment for consistency between VAT
19929              and other control planes.
19930            */
19931           this_hi = tmp2;
19932           vec_add1 (low_ports, this_low);
19933           vec_add1 (high_ports, this_hi);
19934         }
19935       else
19936         break;
19937     }
19938
19939   if (prefix_set == 0)
19940     {
19941       errmsg ("<address>/<mask> not specified");
19942       return -99;
19943     }
19944
19945   if (vrf_id == ~0)
19946     {
19947       errmsg ("VRF ID required, not specified");
19948       return -99;
19949     }
19950
19951   if (vrf_id == 0)
19952     {
19953       errmsg
19954         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19955       return -99;
19956     }
19957
19958   if (vec_len (low_ports) == 0)
19959     {
19960       errmsg ("At least one port or port range required");
19961       return -99;
19962     }
19963
19964   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19965
19966   mp->is_add = is_add;
19967
19968   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19969
19970   mp->number_of_ranges = vec_len (low_ports);
19971
19972   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19973   vec_free (low_ports);
19974
19975   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19976   vec_free (high_ports);
19977
19978   mp->vrf_id = ntohl (vrf_id);
19979
19980   S (mp);
19981   W (ret);
19982   return ret;
19983 }
19984
19985 int
19986 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19987 {
19988   unformat_input_t *input = vam->input;
19989   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19990   u32 sw_if_index = ~0;
19991   int vrf_set = 0;
19992   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19993   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19994   u8 is_add = 1;
19995   int ret;
19996
19997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19998     {
19999       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20000         ;
20001       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20002         ;
20003       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20004         vrf_set = 1;
20005       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20006         vrf_set = 1;
20007       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20008         vrf_set = 1;
20009       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20010         vrf_set = 1;
20011       else if (unformat (input, "del"))
20012         is_add = 0;
20013       else
20014         break;
20015     }
20016
20017   if (sw_if_index == ~0)
20018     {
20019       errmsg ("Interface required but not specified");
20020       return -99;
20021     }
20022
20023   if (vrf_set == 0)
20024     {
20025       errmsg ("VRF ID required but not specified");
20026       return -99;
20027     }
20028
20029   if (tcp_out_vrf_id == 0
20030       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20031     {
20032       errmsg
20033         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20034       return -99;
20035     }
20036
20037   /* Construct the API message */
20038   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20039
20040   mp->sw_if_index = ntohl (sw_if_index);
20041   mp->is_add = is_add;
20042   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20043   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20044   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20045   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20046
20047   /* send it... */
20048   S (mp);
20049
20050   /* Wait for a reply... */
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static int
20056 api_set_punt (vat_main_t * vam)
20057 {
20058   unformat_input_t *i = vam->input;
20059   vl_api_address_family_t af;
20060   vl_api_set_punt_t *mp;
20061   u32 protocol = ~0;
20062   u32 port = ~0;
20063   int is_add = 1;
20064   int ret;
20065
20066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20067     {
20068       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20069         ;
20070       else if (unformat (i, "protocol %d", &protocol))
20071         ;
20072       else if (unformat (i, "port %d", &port))
20073         ;
20074       else if (unformat (i, "del"))
20075         is_add = 0;
20076       else
20077         {
20078           clib_warning ("parse error '%U'", format_unformat_error, i);
20079           return -99;
20080         }
20081     }
20082
20083   M (SET_PUNT, mp);
20084
20085   mp->is_add = (u8) is_add;
20086   mp->punt.type = PUNT_API_TYPE_L4;
20087   mp->punt.punt.l4.af = af;
20088   mp->punt.punt.l4.protocol = (u8) protocol;
20089   mp->punt.punt.l4.port = htons ((u16) port);
20090
20091   S (mp);
20092   W (ret);
20093   return ret;
20094 }
20095
20096 static int
20097 api_delete_subif (vat_main_t * vam)
20098 {
20099   unformat_input_t *i = vam->input;
20100   vl_api_delete_subif_t *mp;
20101   u32 sw_if_index = ~0;
20102   int ret;
20103
20104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20105     {
20106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20107         ;
20108       if (unformat (i, "sw_if_index %d", &sw_if_index))
20109         ;
20110       else
20111         break;
20112     }
20113
20114   if (sw_if_index == ~0)
20115     {
20116       errmsg ("missing sw_if_index");
20117       return -99;
20118     }
20119
20120   /* Construct the API message */
20121   M (DELETE_SUBIF, mp);
20122   mp->sw_if_index = ntohl (sw_if_index);
20123
20124   S (mp);
20125   W (ret);
20126   return ret;
20127 }
20128
20129 #define foreach_pbb_vtr_op      \
20130 _("disable",  L2_VTR_DISABLED)  \
20131 _("pop",  L2_VTR_POP_2)         \
20132 _("push",  L2_VTR_PUSH_2)
20133
20134 static int
20135 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20136 {
20137   unformat_input_t *i = vam->input;
20138   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20139   u32 sw_if_index = ~0, vtr_op = ~0;
20140   u16 outer_tag = ~0;
20141   u8 dmac[6], smac[6];
20142   u8 dmac_set = 0, smac_set = 0;
20143   u16 vlanid = 0;
20144   u32 sid = ~0;
20145   u32 tmp;
20146   int ret;
20147
20148   /* Shut up coverity */
20149   clib_memset (dmac, 0, sizeof (dmac));
20150   clib_memset (smac, 0, sizeof (smac));
20151
20152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20153     {
20154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20155         ;
20156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20157         ;
20158       else if (unformat (i, "vtr_op %d", &vtr_op))
20159         ;
20160 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20161       foreach_pbb_vtr_op
20162 #undef _
20163         else if (unformat (i, "translate_pbb_stag"))
20164         {
20165           if (unformat (i, "%d", &tmp))
20166             {
20167               vtr_op = L2_VTR_TRANSLATE_2_1;
20168               outer_tag = tmp;
20169             }
20170           else
20171             {
20172               errmsg
20173                 ("translate_pbb_stag operation requires outer tag definition");
20174               return -99;
20175             }
20176         }
20177       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20178         dmac_set++;
20179       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20180         smac_set++;
20181       else if (unformat (i, "sid %d", &sid))
20182         ;
20183       else if (unformat (i, "vlanid %d", &tmp))
20184         vlanid = tmp;
20185       else
20186         {
20187           clib_warning ("parse error '%U'", format_unformat_error, i);
20188           return -99;
20189         }
20190     }
20191
20192   if ((sw_if_index == ~0) || (vtr_op == ~0))
20193     {
20194       errmsg ("missing sw_if_index or vtr operation");
20195       return -99;
20196     }
20197   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20198       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20199     {
20200       errmsg
20201         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20202       return -99;
20203     }
20204
20205   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20206   mp->sw_if_index = ntohl (sw_if_index);
20207   mp->vtr_op = ntohl (vtr_op);
20208   mp->outer_tag = ntohs (outer_tag);
20209   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20210   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20211   mp->b_vlanid = ntohs (vlanid);
20212   mp->i_sid = ntohl (sid);
20213
20214   S (mp);
20215   W (ret);
20216   return ret;
20217 }
20218
20219 static int
20220 api_flow_classify_set_interface (vat_main_t * vam)
20221 {
20222   unformat_input_t *i = vam->input;
20223   vl_api_flow_classify_set_interface_t *mp;
20224   u32 sw_if_index;
20225   int sw_if_index_set;
20226   u32 ip4_table_index = ~0;
20227   u32 ip6_table_index = ~0;
20228   u8 is_add = 1;
20229   int ret;
20230
20231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20232     {
20233       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20234         sw_if_index_set = 1;
20235       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20236         sw_if_index_set = 1;
20237       else if (unformat (i, "del"))
20238         is_add = 0;
20239       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20240         ;
20241       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20242         ;
20243       else
20244         {
20245           clib_warning ("parse error '%U'", format_unformat_error, i);
20246           return -99;
20247         }
20248     }
20249
20250   if (sw_if_index_set == 0)
20251     {
20252       errmsg ("missing interface name or sw_if_index");
20253       return -99;
20254     }
20255
20256   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20257
20258   mp->sw_if_index = ntohl (sw_if_index);
20259   mp->ip4_table_index = ntohl (ip4_table_index);
20260   mp->ip6_table_index = ntohl (ip6_table_index);
20261   mp->is_add = is_add;
20262
20263   S (mp);
20264   W (ret);
20265   return ret;
20266 }
20267
20268 static int
20269 api_flow_classify_dump (vat_main_t * vam)
20270 {
20271   unformat_input_t *i = vam->input;
20272   vl_api_flow_classify_dump_t *mp;
20273   vl_api_control_ping_t *mp_ping;
20274   u8 type = FLOW_CLASSIFY_N_TABLES;
20275   int ret;
20276
20277   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20278     ;
20279   else
20280     {
20281       errmsg ("classify table type must be specified");
20282       return -99;
20283     }
20284
20285   if (!vam->json_output)
20286     {
20287       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20288     }
20289
20290   M (FLOW_CLASSIFY_DUMP, mp);
20291   mp->type = type;
20292   /* send it... */
20293   S (mp);
20294
20295   /* Use a control ping for synchronization */
20296   MPING (CONTROL_PING, mp_ping);
20297   S (mp_ping);
20298
20299   /* Wait for a reply... */
20300   W (ret);
20301   return ret;
20302 }
20303
20304 static int
20305 api_feature_enable_disable (vat_main_t * vam)
20306 {
20307   unformat_input_t *i = vam->input;
20308   vl_api_feature_enable_disable_t *mp;
20309   u8 *arc_name = 0;
20310   u8 *feature_name = 0;
20311   u32 sw_if_index = ~0;
20312   u8 enable = 1;
20313   int ret;
20314
20315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20316     {
20317       if (unformat (i, "arc_name %s", &arc_name))
20318         ;
20319       else if (unformat (i, "feature_name %s", &feature_name))
20320         ;
20321       else
20322         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20323         ;
20324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20325         ;
20326       else if (unformat (i, "disable"))
20327         enable = 0;
20328       else
20329         break;
20330     }
20331
20332   if (arc_name == 0)
20333     {
20334       errmsg ("missing arc name");
20335       return -99;
20336     }
20337   if (vec_len (arc_name) > 63)
20338     {
20339       errmsg ("arc name too long");
20340     }
20341
20342   if (feature_name == 0)
20343     {
20344       errmsg ("missing feature name");
20345       return -99;
20346     }
20347   if (vec_len (feature_name) > 63)
20348     {
20349       errmsg ("feature name too long");
20350     }
20351
20352   if (sw_if_index == ~0)
20353     {
20354       errmsg ("missing interface name or sw_if_index");
20355       return -99;
20356     }
20357
20358   /* Construct the API message */
20359   M (FEATURE_ENABLE_DISABLE, mp);
20360   mp->sw_if_index = ntohl (sw_if_index);
20361   mp->enable = enable;
20362   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20363   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20364   vec_free (arc_name);
20365   vec_free (feature_name);
20366
20367   S (mp);
20368   W (ret);
20369   return ret;
20370 }
20371
20372 static int
20373 api_sw_interface_tag_add_del (vat_main_t * vam)
20374 {
20375   unformat_input_t *i = vam->input;
20376   vl_api_sw_interface_tag_add_del_t *mp;
20377   u32 sw_if_index = ~0;
20378   u8 *tag = 0;
20379   u8 enable = 1;
20380   int ret;
20381
20382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20383     {
20384       if (unformat (i, "tag %s", &tag))
20385         ;
20386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20387         ;
20388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20389         ;
20390       else if (unformat (i, "del"))
20391         enable = 0;
20392       else
20393         break;
20394     }
20395
20396   if (sw_if_index == ~0)
20397     {
20398       errmsg ("missing interface name or sw_if_index");
20399       return -99;
20400     }
20401
20402   if (enable && (tag == 0))
20403     {
20404       errmsg ("no tag specified");
20405       return -99;
20406     }
20407
20408   /* Construct the API message */
20409   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20410   mp->sw_if_index = ntohl (sw_if_index);
20411   mp->is_add = enable;
20412   if (enable)
20413     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20414   vec_free (tag);
20415
20416   S (mp);
20417   W (ret);
20418   return ret;
20419 }
20420
20421 static void vl_api_l2_xconnect_details_t_handler
20422   (vl_api_l2_xconnect_details_t * mp)
20423 {
20424   vat_main_t *vam = &vat_main;
20425
20426   print (vam->ofp, "%15d%15d",
20427          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20428 }
20429
20430 static void vl_api_l2_xconnect_details_t_handler_json
20431   (vl_api_l2_xconnect_details_t * mp)
20432 {
20433   vat_main_t *vam = &vat_main;
20434   vat_json_node_t *node = NULL;
20435
20436   if (VAT_JSON_ARRAY != vam->json_tree.type)
20437     {
20438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20439       vat_json_init_array (&vam->json_tree);
20440     }
20441   node = vat_json_array_add (&vam->json_tree);
20442
20443   vat_json_init_object (node);
20444   vat_json_object_add_uint (node, "rx_sw_if_index",
20445                             ntohl (mp->rx_sw_if_index));
20446   vat_json_object_add_uint (node, "tx_sw_if_index",
20447                             ntohl (mp->tx_sw_if_index));
20448 }
20449
20450 static int
20451 api_l2_xconnect_dump (vat_main_t * vam)
20452 {
20453   vl_api_l2_xconnect_dump_t *mp;
20454   vl_api_control_ping_t *mp_ping;
20455   int ret;
20456
20457   if (!vam->json_output)
20458     {
20459       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20460     }
20461
20462   M (L2_XCONNECT_DUMP, mp);
20463
20464   S (mp);
20465
20466   /* Use a control ping for synchronization */
20467   MPING (CONTROL_PING, mp_ping);
20468   S (mp_ping);
20469
20470   W (ret);
20471   return ret;
20472 }
20473
20474 static int
20475 api_hw_interface_set_mtu (vat_main_t * vam)
20476 {
20477   unformat_input_t *i = vam->input;
20478   vl_api_hw_interface_set_mtu_t *mp;
20479   u32 sw_if_index = ~0;
20480   u32 mtu = 0;
20481   int ret;
20482
20483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20484     {
20485       if (unformat (i, "mtu %d", &mtu))
20486         ;
20487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20488         ;
20489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20490         ;
20491       else
20492         break;
20493     }
20494
20495   if (sw_if_index == ~0)
20496     {
20497       errmsg ("missing interface name or sw_if_index");
20498       return -99;
20499     }
20500
20501   if (mtu == 0)
20502     {
20503       errmsg ("no mtu specified");
20504       return -99;
20505     }
20506
20507   /* Construct the API message */
20508   M (HW_INTERFACE_SET_MTU, mp);
20509   mp->sw_if_index = ntohl (sw_if_index);
20510   mp->mtu = ntohs ((u16) mtu);
20511
20512   S (mp);
20513   W (ret);
20514   return ret;
20515 }
20516
20517 static int
20518 api_p2p_ethernet_add (vat_main_t * vam)
20519 {
20520   unformat_input_t *i = vam->input;
20521   vl_api_p2p_ethernet_add_t *mp;
20522   u32 parent_if_index = ~0;
20523   u32 sub_id = ~0;
20524   u8 remote_mac[6];
20525   u8 mac_set = 0;
20526   int ret;
20527
20528   clib_memset (remote_mac, 0, sizeof (remote_mac));
20529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20530     {
20531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20532         ;
20533       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20534         ;
20535       else
20536         if (unformat
20537             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20538         mac_set++;
20539       else if (unformat (i, "sub_id %d", &sub_id))
20540         ;
20541       else
20542         {
20543           clib_warning ("parse error '%U'", format_unformat_error, i);
20544           return -99;
20545         }
20546     }
20547
20548   if (parent_if_index == ~0)
20549     {
20550       errmsg ("missing interface name or sw_if_index");
20551       return -99;
20552     }
20553   if (mac_set == 0)
20554     {
20555       errmsg ("missing remote mac address");
20556       return -99;
20557     }
20558   if (sub_id == ~0)
20559     {
20560       errmsg ("missing sub-interface id");
20561       return -99;
20562     }
20563
20564   M (P2P_ETHERNET_ADD, mp);
20565   mp->parent_if_index = ntohl (parent_if_index);
20566   mp->subif_id = ntohl (sub_id);
20567   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20568
20569   S (mp);
20570   W (ret);
20571   return ret;
20572 }
20573
20574 static int
20575 api_p2p_ethernet_del (vat_main_t * vam)
20576 {
20577   unformat_input_t *i = vam->input;
20578   vl_api_p2p_ethernet_del_t *mp;
20579   u32 parent_if_index = ~0;
20580   u8 remote_mac[6];
20581   u8 mac_set = 0;
20582   int ret;
20583
20584   clib_memset (remote_mac, 0, sizeof (remote_mac));
20585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20586     {
20587       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20588         ;
20589       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20590         ;
20591       else
20592         if (unformat
20593             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20594         mac_set++;
20595       else
20596         {
20597           clib_warning ("parse error '%U'", format_unformat_error, i);
20598           return -99;
20599         }
20600     }
20601
20602   if (parent_if_index == ~0)
20603     {
20604       errmsg ("missing interface name or sw_if_index");
20605       return -99;
20606     }
20607   if (mac_set == 0)
20608     {
20609       errmsg ("missing remote mac address");
20610       return -99;
20611     }
20612
20613   M (P2P_ETHERNET_DEL, mp);
20614   mp->parent_if_index = ntohl (parent_if_index);
20615   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20616
20617   S (mp);
20618   W (ret);
20619   return ret;
20620 }
20621
20622 static int
20623 api_lldp_config (vat_main_t * vam)
20624 {
20625   unformat_input_t *i = vam->input;
20626   vl_api_lldp_config_t *mp;
20627   int tx_hold = 0;
20628   int tx_interval = 0;
20629   u8 *sys_name = NULL;
20630   int ret;
20631
20632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20633     {
20634       if (unformat (i, "system-name %s", &sys_name))
20635         ;
20636       else if (unformat (i, "tx-hold %d", &tx_hold))
20637         ;
20638       else if (unformat (i, "tx-interval %d", &tx_interval))
20639         ;
20640       else
20641         {
20642           clib_warning ("parse error '%U'", format_unformat_error, i);
20643           return -99;
20644         }
20645     }
20646
20647   vec_add1 (sys_name, 0);
20648
20649   M (LLDP_CONFIG, mp);
20650   mp->tx_hold = htonl (tx_hold);
20651   mp->tx_interval = htonl (tx_interval);
20652   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20653   vec_free (sys_name);
20654
20655   S (mp);
20656   W (ret);
20657   return ret;
20658 }
20659
20660 static int
20661 api_sw_interface_set_lldp (vat_main_t * vam)
20662 {
20663   unformat_input_t *i = vam->input;
20664   vl_api_sw_interface_set_lldp_t *mp;
20665   u32 sw_if_index = ~0;
20666   u32 enable = 1;
20667   u8 *port_desc = NULL, *mgmt_oid = NULL;
20668   ip4_address_t ip4_addr;
20669   ip6_address_t ip6_addr;
20670   int ret;
20671
20672   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20673   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20674
20675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20676     {
20677       if (unformat (i, "disable"))
20678         enable = 0;
20679       else
20680         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20681         ;
20682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20683         ;
20684       else if (unformat (i, "port-desc %s", &port_desc))
20685         ;
20686       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20687         ;
20688       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20689         ;
20690       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20691         ;
20692       else
20693         break;
20694     }
20695
20696   if (sw_if_index == ~0)
20697     {
20698       errmsg ("missing interface name or sw_if_index");
20699       return -99;
20700     }
20701
20702   /* Construct the API message */
20703   vec_add1 (port_desc, 0);
20704   vec_add1 (mgmt_oid, 0);
20705   M (SW_INTERFACE_SET_LLDP, mp);
20706   mp->sw_if_index = ntohl (sw_if_index);
20707   mp->enable = enable;
20708   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20709   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20710   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20711   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20712   vec_free (port_desc);
20713   vec_free (mgmt_oid);
20714
20715   S (mp);
20716   W (ret);
20717   return ret;
20718 }
20719
20720 static int
20721 api_tcp_configure_src_addresses (vat_main_t * vam)
20722 {
20723   vl_api_tcp_configure_src_addresses_t *mp;
20724   unformat_input_t *i = vam->input;
20725   ip4_address_t v4first, v4last;
20726   ip6_address_t v6first, v6last;
20727   u8 range_set = 0;
20728   u32 vrf_id = 0;
20729   int ret;
20730
20731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20732     {
20733       if (unformat (i, "%U - %U",
20734                     unformat_ip4_address, &v4first,
20735                     unformat_ip4_address, &v4last))
20736         {
20737           if (range_set)
20738             {
20739               errmsg ("one range per message (range already set)");
20740               return -99;
20741             }
20742           range_set = 1;
20743         }
20744       else if (unformat (i, "%U - %U",
20745                          unformat_ip6_address, &v6first,
20746                          unformat_ip6_address, &v6last))
20747         {
20748           if (range_set)
20749             {
20750               errmsg ("one range per message (range already set)");
20751               return -99;
20752             }
20753           range_set = 2;
20754         }
20755       else if (unformat (i, "vrf %d", &vrf_id))
20756         ;
20757       else
20758         break;
20759     }
20760
20761   if (range_set == 0)
20762     {
20763       errmsg ("address range not set");
20764       return -99;
20765     }
20766
20767   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20768   mp->vrf_id = ntohl (vrf_id);
20769   /* ipv6? */
20770   if (range_set == 2)
20771     {
20772       mp->is_ipv6 = 1;
20773       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20774       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20775     }
20776   else
20777     {
20778       mp->is_ipv6 = 0;
20779       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20780       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20781     }
20782   S (mp);
20783   W (ret);
20784   return ret;
20785 }
20786
20787 static void vl_api_app_namespace_add_del_reply_t_handler
20788   (vl_api_app_namespace_add_del_reply_t * mp)
20789 {
20790   vat_main_t *vam = &vat_main;
20791   i32 retval = ntohl (mp->retval);
20792   if (vam->async_mode)
20793     {
20794       vam->async_errors += (retval < 0);
20795     }
20796   else
20797     {
20798       vam->retval = retval;
20799       if (retval == 0)
20800         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20801       vam->result_ready = 1;
20802     }
20803 }
20804
20805 static void vl_api_app_namespace_add_del_reply_t_handler_json
20806   (vl_api_app_namespace_add_del_reply_t * mp)
20807 {
20808   vat_main_t *vam = &vat_main;
20809   vat_json_node_t node;
20810
20811   vat_json_init_object (&node);
20812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20813   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20814
20815   vat_json_print (vam->ofp, &node);
20816   vat_json_free (&node);
20817
20818   vam->retval = ntohl (mp->retval);
20819   vam->result_ready = 1;
20820 }
20821
20822 static int
20823 api_app_namespace_add_del (vat_main_t * vam)
20824 {
20825   vl_api_app_namespace_add_del_t *mp;
20826   unformat_input_t *i = vam->input;
20827   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20828   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20829   u64 secret;
20830   int ret;
20831
20832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20833     {
20834       if (unformat (i, "id %_%v%_", &ns_id))
20835         ;
20836       else if (unformat (i, "secret %lu", &secret))
20837         secret_set = 1;
20838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20839         sw_if_index_set = 1;
20840       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20841         ;
20842       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20843         ;
20844       else
20845         break;
20846     }
20847   if (!ns_id || !secret_set || !sw_if_index_set)
20848     {
20849       errmsg ("namespace id, secret and sw_if_index must be set");
20850       return -99;
20851     }
20852   if (vec_len (ns_id) > 64)
20853     {
20854       errmsg ("namespace id too long");
20855       return -99;
20856     }
20857   M (APP_NAMESPACE_ADD_DEL, mp);
20858
20859   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20860   mp->namespace_id_len = vec_len (ns_id);
20861   mp->secret = clib_host_to_net_u64 (secret);
20862   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20863   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20864   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20865   vec_free (ns_id);
20866   S (mp);
20867   W (ret);
20868   return ret;
20869 }
20870
20871 static int
20872 api_sock_init_shm (vat_main_t * vam)
20873 {
20874 #if VPP_API_TEST_BUILTIN == 0
20875   unformat_input_t *i = vam->input;
20876   vl_api_shm_elem_config_t *config = 0;
20877   u64 size = 64 << 20;
20878   int rv;
20879
20880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20881     {
20882       if (unformat (i, "size %U", unformat_memory_size, &size))
20883         ;
20884       else
20885         break;
20886     }
20887
20888   /*
20889    * Canned custom ring allocator config.
20890    * Should probably parse all of this
20891    */
20892   vec_validate (config, 6);
20893   config[0].type = VL_API_VLIB_RING;
20894   config[0].size = 256;
20895   config[0].count = 32;
20896
20897   config[1].type = VL_API_VLIB_RING;
20898   config[1].size = 1024;
20899   config[1].count = 16;
20900
20901   config[2].type = VL_API_VLIB_RING;
20902   config[2].size = 4096;
20903   config[2].count = 2;
20904
20905   config[3].type = VL_API_CLIENT_RING;
20906   config[3].size = 256;
20907   config[3].count = 32;
20908
20909   config[4].type = VL_API_CLIENT_RING;
20910   config[4].size = 1024;
20911   config[4].count = 16;
20912
20913   config[5].type = VL_API_CLIENT_RING;
20914   config[5].size = 4096;
20915   config[5].count = 2;
20916
20917   config[6].type = VL_API_QUEUE;
20918   config[6].count = 128;
20919   config[6].size = sizeof (uword);
20920
20921   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20922   if (!rv)
20923     vam->client_index_invalid = 1;
20924   return rv;
20925 #else
20926   return -99;
20927 #endif
20928 }
20929
20930 static int
20931 api_dns_enable_disable (vat_main_t * vam)
20932 {
20933   unformat_input_t *line_input = vam->input;
20934   vl_api_dns_enable_disable_t *mp;
20935   u8 enable_disable = 1;
20936   int ret;
20937
20938   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20939     {
20940       if (unformat (line_input, "disable"))
20941         enable_disable = 0;
20942       if (unformat (line_input, "enable"))
20943         enable_disable = 1;
20944       else
20945         break;
20946     }
20947
20948   /* Construct the API message */
20949   M (DNS_ENABLE_DISABLE, mp);
20950   mp->enable = enable_disable;
20951
20952   /* send it... */
20953   S (mp);
20954   /* Wait for the reply */
20955   W (ret);
20956   return ret;
20957 }
20958
20959 static int
20960 api_dns_resolve_name (vat_main_t * vam)
20961 {
20962   unformat_input_t *line_input = vam->input;
20963   vl_api_dns_resolve_name_t *mp;
20964   u8 *name = 0;
20965   int ret;
20966
20967   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20968     {
20969       if (unformat (line_input, "%s", &name))
20970         ;
20971       else
20972         break;
20973     }
20974
20975   if (vec_len (name) > 127)
20976     {
20977       errmsg ("name too long");
20978       return -99;
20979     }
20980
20981   /* Construct the API message */
20982   M (DNS_RESOLVE_NAME, mp);
20983   memcpy (mp->name, name, vec_len (name));
20984   vec_free (name);
20985
20986   /* send it... */
20987   S (mp);
20988   /* Wait for the reply */
20989   W (ret);
20990   return ret;
20991 }
20992
20993 static int
20994 api_dns_resolve_ip (vat_main_t * vam)
20995 {
20996   unformat_input_t *line_input = vam->input;
20997   vl_api_dns_resolve_ip_t *mp;
20998   int is_ip6 = -1;
20999   ip4_address_t addr4;
21000   ip6_address_t addr6;
21001   int ret;
21002
21003   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21004     {
21005       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21006         is_ip6 = 1;
21007       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21008         is_ip6 = 0;
21009       else
21010         break;
21011     }
21012
21013   if (is_ip6 == -1)
21014     {
21015       errmsg ("missing address");
21016       return -99;
21017     }
21018
21019   /* Construct the API message */
21020   M (DNS_RESOLVE_IP, mp);
21021   mp->is_ip6 = is_ip6;
21022   if (is_ip6)
21023     memcpy (mp->address, &addr6, sizeof (addr6));
21024   else
21025     memcpy (mp->address, &addr4, sizeof (addr4));
21026
21027   /* send it... */
21028   S (mp);
21029   /* Wait for the reply */
21030   W (ret);
21031   return ret;
21032 }
21033
21034 static int
21035 api_dns_name_server_add_del (vat_main_t * vam)
21036 {
21037   unformat_input_t *i = vam->input;
21038   vl_api_dns_name_server_add_del_t *mp;
21039   u8 is_add = 1;
21040   ip6_address_t ip6_server;
21041   ip4_address_t ip4_server;
21042   int ip6_set = 0;
21043   int ip4_set = 0;
21044   int ret = 0;
21045
21046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21047     {
21048       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21049         ip6_set = 1;
21050       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21051         ip4_set = 1;
21052       else if (unformat (i, "del"))
21053         is_add = 0;
21054       else
21055         {
21056           clib_warning ("parse error '%U'", format_unformat_error, i);
21057           return -99;
21058         }
21059     }
21060
21061   if (ip4_set && ip6_set)
21062     {
21063       errmsg ("Only one server address allowed per message");
21064       return -99;
21065     }
21066   if ((ip4_set + ip6_set) == 0)
21067     {
21068       errmsg ("Server address required");
21069       return -99;
21070     }
21071
21072   /* Construct the API message */
21073   M (DNS_NAME_SERVER_ADD_DEL, mp);
21074
21075   if (ip6_set)
21076     {
21077       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21078       mp->is_ip6 = 1;
21079     }
21080   else
21081     {
21082       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21083       mp->is_ip6 = 0;
21084     }
21085
21086   mp->is_add = is_add;
21087
21088   /* send it... */
21089   S (mp);
21090
21091   /* Wait for a reply, return good/bad news  */
21092   W (ret);
21093   return ret;
21094 }
21095
21096 static void
21097 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21098 {
21099   vat_main_t *vam = &vat_main;
21100
21101   if (mp->is_ip4)
21102     {
21103       print (vam->ofp,
21104              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21105              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21106              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21107              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21108              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21109              clib_net_to_host_u32 (mp->action_index), mp->tag);
21110     }
21111   else
21112     {
21113       print (vam->ofp,
21114              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21115              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21116              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21117              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21118              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21119              clib_net_to_host_u32 (mp->action_index), mp->tag);
21120     }
21121 }
21122
21123 static void
21124 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21125                                              mp)
21126 {
21127   vat_main_t *vam = &vat_main;
21128   vat_json_node_t *node = NULL;
21129   struct in6_addr ip6;
21130   struct in_addr ip4;
21131
21132   if (VAT_JSON_ARRAY != vam->json_tree.type)
21133     {
21134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21135       vat_json_init_array (&vam->json_tree);
21136     }
21137   node = vat_json_array_add (&vam->json_tree);
21138   vat_json_init_object (node);
21139
21140   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21141   vat_json_object_add_uint (node, "appns_index",
21142                             clib_net_to_host_u32 (mp->appns_index));
21143   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21144   vat_json_object_add_uint (node, "scope", mp->scope);
21145   vat_json_object_add_uint (node, "action_index",
21146                             clib_net_to_host_u32 (mp->action_index));
21147   vat_json_object_add_uint (node, "lcl_port",
21148                             clib_net_to_host_u16 (mp->lcl_port));
21149   vat_json_object_add_uint (node, "rmt_port",
21150                             clib_net_to_host_u16 (mp->rmt_port));
21151   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21152   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21153   vat_json_object_add_string_copy (node, "tag", mp->tag);
21154   if (mp->is_ip4)
21155     {
21156       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21157       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21158       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21159       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21160     }
21161   else
21162     {
21163       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21164       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21165       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21166       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21167     }
21168 }
21169
21170 static int
21171 api_session_rule_add_del (vat_main_t * vam)
21172 {
21173   vl_api_session_rule_add_del_t *mp;
21174   unformat_input_t *i = vam->input;
21175   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21176   u32 appns_index = 0, scope = 0;
21177   ip4_address_t lcl_ip4, rmt_ip4;
21178   ip6_address_t lcl_ip6, rmt_ip6;
21179   u8 is_ip4 = 1, conn_set = 0;
21180   u8 is_add = 1, *tag = 0;
21181   int ret;
21182
21183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21184     {
21185       if (unformat (i, "del"))
21186         is_add = 0;
21187       else if (unformat (i, "add"))
21188         ;
21189       else if (unformat (i, "proto tcp"))
21190         proto = 0;
21191       else if (unformat (i, "proto udp"))
21192         proto = 1;
21193       else if (unformat (i, "appns %d", &appns_index))
21194         ;
21195       else if (unformat (i, "scope %d", &scope))
21196         ;
21197       else if (unformat (i, "tag %_%v%_", &tag))
21198         ;
21199       else
21200         if (unformat
21201             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21202              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21203              &rmt_port))
21204         {
21205           is_ip4 = 1;
21206           conn_set = 1;
21207         }
21208       else
21209         if (unformat
21210             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21211              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21212              &rmt_port))
21213         {
21214           is_ip4 = 0;
21215           conn_set = 1;
21216         }
21217       else if (unformat (i, "action %d", &action))
21218         ;
21219       else
21220         break;
21221     }
21222   if (proto == ~0 || !conn_set || action == ~0)
21223     {
21224       errmsg ("transport proto, connection and action must be set");
21225       return -99;
21226     }
21227
21228   if (scope > 3)
21229     {
21230       errmsg ("scope should be 0-3");
21231       return -99;
21232     }
21233
21234   M (SESSION_RULE_ADD_DEL, mp);
21235
21236   mp->is_ip4 = is_ip4;
21237   mp->transport_proto = proto;
21238   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21239   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21240   mp->lcl_plen = lcl_plen;
21241   mp->rmt_plen = rmt_plen;
21242   mp->action_index = clib_host_to_net_u32 (action);
21243   mp->appns_index = clib_host_to_net_u32 (appns_index);
21244   mp->scope = scope;
21245   mp->is_add = is_add;
21246   if (is_ip4)
21247     {
21248       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21249       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21250     }
21251   else
21252     {
21253       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21254       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21255     }
21256   if (tag)
21257     {
21258       clib_memcpy (mp->tag, tag, vec_len (tag));
21259       vec_free (tag);
21260     }
21261
21262   S (mp);
21263   W (ret);
21264   return ret;
21265 }
21266
21267 static int
21268 api_session_rules_dump (vat_main_t * vam)
21269 {
21270   vl_api_session_rules_dump_t *mp;
21271   vl_api_control_ping_t *mp_ping;
21272   int ret;
21273
21274   if (!vam->json_output)
21275     {
21276       print (vam->ofp, "%=20s", "Session Rules");
21277     }
21278
21279   M (SESSION_RULES_DUMP, mp);
21280   /* send it... */
21281   S (mp);
21282
21283   /* Use a control ping for synchronization */
21284   MPING (CONTROL_PING, mp_ping);
21285   S (mp_ping);
21286
21287   /* Wait for a reply... */
21288   W (ret);
21289   return ret;
21290 }
21291
21292 static int
21293 api_ip_container_proxy_add_del (vat_main_t * vam)
21294 {
21295   vl_api_ip_container_proxy_add_del_t *mp;
21296   unformat_input_t *i = vam->input;
21297   u32 sw_if_index = ~0;
21298   vl_api_prefix_t pfx = { };
21299   u8 is_add = 1;
21300   int ret;
21301
21302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21303     {
21304       if (unformat (i, "del"))
21305         is_add = 0;
21306       else if (unformat (i, "add"))
21307         ;
21308       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21309         ;
21310       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21311         ;
21312       else
21313         break;
21314     }
21315   if (sw_if_index == ~0 || pfx.len == 0)
21316     {
21317       errmsg ("address and sw_if_index must be set");
21318       return -99;
21319     }
21320
21321   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21322
21323   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21324   mp->is_add = is_add;
21325   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21326
21327   S (mp);
21328   W (ret);
21329   return ret;
21330 }
21331
21332 static int
21333 api_qos_record_enable_disable (vat_main_t * vam)
21334 {
21335   unformat_input_t *i = vam->input;
21336   vl_api_qos_record_enable_disable_t *mp;
21337   u32 sw_if_index, qs = 0xff;
21338   u8 sw_if_index_set = 0;
21339   u8 enable = 1;
21340   int ret;
21341
21342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21343     {
21344       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21345         sw_if_index_set = 1;
21346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21347         sw_if_index_set = 1;
21348       else if (unformat (i, "%U", unformat_qos_source, &qs))
21349         ;
21350       else if (unformat (i, "disable"))
21351         enable = 0;
21352       else
21353         {
21354           clib_warning ("parse error '%U'", format_unformat_error, i);
21355           return -99;
21356         }
21357     }
21358
21359   if (sw_if_index_set == 0)
21360     {
21361       errmsg ("missing interface name or sw_if_index");
21362       return -99;
21363     }
21364   if (qs == 0xff)
21365     {
21366       errmsg ("input location must be specified");
21367       return -99;
21368     }
21369
21370   M (QOS_RECORD_ENABLE_DISABLE, mp);
21371
21372   mp->sw_if_index = ntohl (sw_if_index);
21373   mp->input_source = qs;
21374   mp->enable = enable;
21375
21376   S (mp);
21377   W (ret);
21378   return ret;
21379 }
21380
21381
21382 static int
21383 q_or_quit (vat_main_t * vam)
21384 {
21385 #if VPP_API_TEST_BUILTIN == 0
21386   longjmp (vam->jump_buf, 1);
21387 #endif
21388   return 0;                     /* not so much */
21389 }
21390
21391 static int
21392 q (vat_main_t * vam)
21393 {
21394   return q_or_quit (vam);
21395 }
21396
21397 static int
21398 quit (vat_main_t * vam)
21399 {
21400   return q_or_quit (vam);
21401 }
21402
21403 static int
21404 comment (vat_main_t * vam)
21405 {
21406   return 0;
21407 }
21408
21409 static int
21410 elog_save (vat_main_t * vam)
21411 {
21412 #if VPP_API_TEST_BUILTIN == 0
21413   elog_main_t *em = &vam->elog_main;
21414   unformat_input_t *i = vam->input;
21415   char *file, *chroot_file;
21416   clib_error_t *error;
21417
21418   if (!unformat (i, "%s", &file))
21419     {
21420       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21421       return 0;
21422     }
21423
21424   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21425   if (strstr (file, "..") || index (file, '/'))
21426     {
21427       errmsg ("illegal characters in filename '%s'", file);
21428       return 0;
21429     }
21430
21431   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21432
21433   vec_free (file);
21434
21435   errmsg ("Saving %wd of %wd events to %s",
21436           elog_n_events_in_buffer (em),
21437           elog_buffer_capacity (em), chroot_file);
21438
21439   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21440   vec_free (chroot_file);
21441
21442   if (error)
21443     clib_error_report (error);
21444 #else
21445   errmsg ("Use the vpp event loger...");
21446 #endif
21447
21448   return 0;
21449 }
21450
21451 static int
21452 elog_setup (vat_main_t * vam)
21453 {
21454 #if VPP_API_TEST_BUILTIN == 0
21455   elog_main_t *em = &vam->elog_main;
21456   unformat_input_t *i = vam->input;
21457   u32 nevents = 128 << 10;
21458
21459   (void) unformat (i, "nevents %d", &nevents);
21460
21461   elog_init (em, nevents);
21462   vl_api_set_elog_main (em);
21463   vl_api_set_elog_trace_api_messages (1);
21464   errmsg ("Event logger initialized with %u events", nevents);
21465 #else
21466   errmsg ("Use the vpp event loger...");
21467 #endif
21468   return 0;
21469 }
21470
21471 static int
21472 elog_enable (vat_main_t * vam)
21473 {
21474 #if VPP_API_TEST_BUILTIN == 0
21475   elog_main_t *em = &vam->elog_main;
21476
21477   elog_enable_disable (em, 1 /* enable */ );
21478   vl_api_set_elog_trace_api_messages (1);
21479   errmsg ("Event logger enabled...");
21480 #else
21481   errmsg ("Use the vpp event loger...");
21482 #endif
21483   return 0;
21484 }
21485
21486 static int
21487 elog_disable (vat_main_t * vam)
21488 {
21489 #if VPP_API_TEST_BUILTIN == 0
21490   elog_main_t *em = &vam->elog_main;
21491
21492   elog_enable_disable (em, 0 /* enable */ );
21493   vl_api_set_elog_trace_api_messages (1);
21494   errmsg ("Event logger disabled...");
21495 #else
21496   errmsg ("Use the vpp event loger...");
21497 #endif
21498   return 0;
21499 }
21500
21501 static int
21502 statseg (vat_main_t * vam)
21503 {
21504   ssvm_private_t *ssvmp = &vam->stat_segment;
21505   ssvm_shared_header_t *shared_header = ssvmp->sh;
21506   vlib_counter_t **counters;
21507   u64 thread0_index1_packets;
21508   u64 thread0_index1_bytes;
21509   f64 vector_rate, input_rate;
21510   uword *p;
21511
21512   uword *counter_vector_by_name;
21513   if (vam->stat_segment_lockp == 0)
21514     {
21515       errmsg ("Stat segment not mapped...");
21516       return -99;
21517     }
21518
21519   /* look up "/if/rx for sw_if_index 1 as a test */
21520
21521   clib_spinlock_lock (vam->stat_segment_lockp);
21522
21523   counter_vector_by_name = (uword *) shared_header->opaque[1];
21524
21525   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21526   if (p == 0)
21527     {
21528       clib_spinlock_unlock (vam->stat_segment_lockp);
21529       errmsg ("/if/tx not found?");
21530       return -99;
21531     }
21532
21533   /* Fish per-thread vector of combined counters from shared memory */
21534   counters = (vlib_counter_t **) p[0];
21535
21536   if (vec_len (counters[0]) < 2)
21537     {
21538       clib_spinlock_unlock (vam->stat_segment_lockp);
21539       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21540       return -99;
21541     }
21542
21543   /* Read thread 0 sw_if_index 1 counter */
21544   thread0_index1_packets = counters[0][1].packets;
21545   thread0_index1_bytes = counters[0][1].bytes;
21546
21547   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21548   if (p == 0)
21549     {
21550       clib_spinlock_unlock (vam->stat_segment_lockp);
21551       errmsg ("vector_rate not found?");
21552       return -99;
21553     }
21554
21555   vector_rate = *(f64 *) (p[0]);
21556   p = hash_get_mem (counter_vector_by_name, "input_rate");
21557   if (p == 0)
21558     {
21559       clib_spinlock_unlock (vam->stat_segment_lockp);
21560       errmsg ("input_rate not found?");
21561       return -99;
21562     }
21563   input_rate = *(f64 *) (p[0]);
21564
21565   clib_spinlock_unlock (vam->stat_segment_lockp);
21566
21567   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21568          vector_rate, input_rate);
21569   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21570          thread0_index1_packets, thread0_index1_bytes);
21571
21572   return 0;
21573 }
21574
21575 static int
21576 cmd_cmp (void *a1, void *a2)
21577 {
21578   u8 **c1 = a1;
21579   u8 **c2 = a2;
21580
21581   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21582 }
21583
21584 static int
21585 help (vat_main_t * vam)
21586 {
21587   u8 **cmds = 0;
21588   u8 *name = 0;
21589   hash_pair_t *p;
21590   unformat_input_t *i = vam->input;
21591   int j;
21592
21593   if (unformat (i, "%s", &name))
21594     {
21595       uword *hs;
21596
21597       vec_add1 (name, 0);
21598
21599       hs = hash_get_mem (vam->help_by_name, name);
21600       if (hs)
21601         print (vam->ofp, "usage: %s %s", name, hs[0]);
21602       else
21603         print (vam->ofp, "No such msg / command '%s'", name);
21604       vec_free (name);
21605       return 0;
21606     }
21607
21608   print (vam->ofp, "Help is available for the following:");
21609
21610     /* *INDENT-OFF* */
21611     hash_foreach_pair (p, vam->function_by_name,
21612     ({
21613       vec_add1 (cmds, (u8 *)(p->key));
21614     }));
21615     /* *INDENT-ON* */
21616
21617   vec_sort_with_function (cmds, cmd_cmp);
21618
21619   for (j = 0; j < vec_len (cmds); j++)
21620     print (vam->ofp, "%s", cmds[j]);
21621
21622   vec_free (cmds);
21623   return 0;
21624 }
21625
21626 static int
21627 set (vat_main_t * vam)
21628 {
21629   u8 *name = 0, *value = 0;
21630   unformat_input_t *i = vam->input;
21631
21632   if (unformat (i, "%s", &name))
21633     {
21634       /* The input buffer is a vector, not a string. */
21635       value = vec_dup (i->buffer);
21636       vec_delete (value, i->index, 0);
21637       /* Almost certainly has a trailing newline */
21638       if (value[vec_len (value) - 1] == '\n')
21639         value[vec_len (value) - 1] = 0;
21640       /* Make sure it's a proper string, one way or the other */
21641       vec_add1 (value, 0);
21642       (void) clib_macro_set_value (&vam->macro_main,
21643                                    (char *) name, (char *) value);
21644     }
21645   else
21646     errmsg ("usage: set <name> <value>");
21647
21648   vec_free (name);
21649   vec_free (value);
21650   return 0;
21651 }
21652
21653 static int
21654 unset (vat_main_t * vam)
21655 {
21656   u8 *name = 0;
21657
21658   if (unformat (vam->input, "%s", &name))
21659     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21660       errmsg ("unset: %s wasn't set", name);
21661   vec_free (name);
21662   return 0;
21663 }
21664
21665 typedef struct
21666 {
21667   u8 *name;
21668   u8 *value;
21669 } macro_sort_t;
21670
21671
21672 static int
21673 macro_sort_cmp (void *a1, void *a2)
21674 {
21675   macro_sort_t *s1 = a1;
21676   macro_sort_t *s2 = a2;
21677
21678   return strcmp ((char *) (s1->name), (char *) (s2->name));
21679 }
21680
21681 static int
21682 dump_macro_table (vat_main_t * vam)
21683 {
21684   macro_sort_t *sort_me = 0, *sm;
21685   int i;
21686   hash_pair_t *p;
21687
21688     /* *INDENT-OFF* */
21689     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21690     ({
21691       vec_add2 (sort_me, sm, 1);
21692       sm->name = (u8 *)(p->key);
21693       sm->value = (u8 *) (p->value[0]);
21694     }));
21695     /* *INDENT-ON* */
21696
21697   vec_sort_with_function (sort_me, macro_sort_cmp);
21698
21699   if (vec_len (sort_me))
21700     print (vam->ofp, "%-15s%s", "Name", "Value");
21701   else
21702     print (vam->ofp, "The macro table is empty...");
21703
21704   for (i = 0; i < vec_len (sort_me); i++)
21705     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21706   return 0;
21707 }
21708
21709 static int
21710 dump_node_table (vat_main_t * vam)
21711 {
21712   int i, j;
21713   vlib_node_t *node, *next_node;
21714
21715   if (vec_len (vam->graph_nodes) == 0)
21716     {
21717       print (vam->ofp, "Node table empty, issue get_node_graph...");
21718       return 0;
21719     }
21720
21721   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21722     {
21723       node = vam->graph_nodes[0][i];
21724       print (vam->ofp, "[%d] %s", i, node->name);
21725       for (j = 0; j < vec_len (node->next_nodes); j++)
21726         {
21727           if (node->next_nodes[j] != ~0)
21728             {
21729               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21730               print (vam->ofp, "  [%d] %s", j, next_node->name);
21731             }
21732         }
21733     }
21734   return 0;
21735 }
21736
21737 static int
21738 value_sort_cmp (void *a1, void *a2)
21739 {
21740   name_sort_t *n1 = a1;
21741   name_sort_t *n2 = a2;
21742
21743   if (n1->value < n2->value)
21744     return -1;
21745   if (n1->value > n2->value)
21746     return 1;
21747   return 0;
21748 }
21749
21750
21751 static int
21752 dump_msg_api_table (vat_main_t * vam)
21753 {
21754   api_main_t *am = &api_main;
21755   name_sort_t *nses = 0, *ns;
21756   hash_pair_t *hp;
21757   int i;
21758
21759   /* *INDENT-OFF* */
21760   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21761   ({
21762     vec_add2 (nses, ns, 1);
21763     ns->name = (u8 *)(hp->key);
21764     ns->value = (u32) hp->value[0];
21765   }));
21766   /* *INDENT-ON* */
21767
21768   vec_sort_with_function (nses, value_sort_cmp);
21769
21770   for (i = 0; i < vec_len (nses); i++)
21771     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21772   vec_free (nses);
21773   return 0;
21774 }
21775
21776 static int
21777 get_msg_id (vat_main_t * vam)
21778 {
21779   u8 *name_and_crc;
21780   u32 message_index;
21781
21782   if (unformat (vam->input, "%s", &name_and_crc))
21783     {
21784       message_index = vl_msg_api_get_msg_index (name_and_crc);
21785       if (message_index == ~0)
21786         {
21787           print (vam->ofp, " '%s' not found", name_and_crc);
21788           return 0;
21789         }
21790       print (vam->ofp, " '%s' has message index %d",
21791              name_and_crc, message_index);
21792       return 0;
21793     }
21794   errmsg ("name_and_crc required...");
21795   return 0;
21796 }
21797
21798 static int
21799 search_node_table (vat_main_t * vam)
21800 {
21801   unformat_input_t *line_input = vam->input;
21802   u8 *node_to_find;
21803   int j;
21804   vlib_node_t *node, *next_node;
21805   uword *p;
21806
21807   if (vam->graph_node_index_by_name == 0)
21808     {
21809       print (vam->ofp, "Node table empty, issue get_node_graph...");
21810       return 0;
21811     }
21812
21813   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21814     {
21815       if (unformat (line_input, "%s", &node_to_find))
21816         {
21817           vec_add1 (node_to_find, 0);
21818           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21819           if (p == 0)
21820             {
21821               print (vam->ofp, "%s not found...", node_to_find);
21822               goto out;
21823             }
21824           node = vam->graph_nodes[0][p[0]];
21825           print (vam->ofp, "[%d] %s", p[0], node->name);
21826           for (j = 0; j < vec_len (node->next_nodes); j++)
21827             {
21828               if (node->next_nodes[j] != ~0)
21829                 {
21830                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21831                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21832                 }
21833             }
21834         }
21835
21836       else
21837         {
21838           clib_warning ("parse error '%U'", format_unformat_error,
21839                         line_input);
21840           return -99;
21841         }
21842
21843     out:
21844       vec_free (node_to_find);
21845
21846     }
21847
21848   return 0;
21849 }
21850
21851
21852 static int
21853 script (vat_main_t * vam)
21854 {
21855 #if (VPP_API_TEST_BUILTIN==0)
21856   u8 *s = 0;
21857   char *save_current_file;
21858   unformat_input_t save_input;
21859   jmp_buf save_jump_buf;
21860   u32 save_line_number;
21861
21862   FILE *new_fp, *save_ifp;
21863
21864   if (unformat (vam->input, "%s", &s))
21865     {
21866       new_fp = fopen ((char *) s, "r");
21867       if (new_fp == 0)
21868         {
21869           errmsg ("Couldn't open script file %s", s);
21870           vec_free (s);
21871           return -99;
21872         }
21873     }
21874   else
21875     {
21876       errmsg ("Missing script name");
21877       return -99;
21878     }
21879
21880   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21881   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21882   save_ifp = vam->ifp;
21883   save_line_number = vam->input_line_number;
21884   save_current_file = (char *) vam->current_file;
21885
21886   vam->input_line_number = 0;
21887   vam->ifp = new_fp;
21888   vam->current_file = s;
21889   do_one_file (vam);
21890
21891   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21892   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21893   vam->ifp = save_ifp;
21894   vam->input_line_number = save_line_number;
21895   vam->current_file = (u8 *) save_current_file;
21896   vec_free (s);
21897
21898   return 0;
21899 #else
21900   clib_warning ("use the exec command...");
21901   return -99;
21902 #endif
21903 }
21904
21905 static int
21906 echo (vat_main_t * vam)
21907 {
21908   print (vam->ofp, "%v", vam->input->buffer);
21909   return 0;
21910 }
21911
21912 /* List of API message constructors, CLI names map to api_xxx */
21913 #define foreach_vpe_api_msg                                             \
21914 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21915 _(sw_interface_dump,"")                                                 \
21916 _(sw_interface_set_flags,                                               \
21917   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21918 _(sw_interface_add_del_address,                                         \
21919   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21920 _(sw_interface_set_rx_mode,                                             \
21921   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21922 _(sw_interface_set_rx_placement,                                        \
21923   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21924 _(sw_interface_rx_placement_dump,                                       \
21925   "[<intfc> | sw_if_index <id>]")                                         \
21926 _(sw_interface_set_table,                                               \
21927   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21928 _(sw_interface_set_mpls_enable,                                         \
21929   "<intfc> | sw_if_index [disable | dis]")                              \
21930 _(sw_interface_set_vpath,                                               \
21931   "<intfc> | sw_if_index <id> enable | disable")                        \
21932 _(sw_interface_set_vxlan_bypass,                                        \
21933   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21934 _(sw_interface_set_geneve_bypass,                                       \
21935   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21936 _(sw_interface_set_l2_xconnect,                                         \
21937   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21938   "enable | disable")                                                   \
21939 _(sw_interface_set_l2_bridge,                                           \
21940   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21941   "[shg <split-horizon-group>] [bvi]\n"                                 \
21942   "enable | disable")                                                   \
21943 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21944 _(bridge_domain_add_del,                                                \
21945   "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") \
21946 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21947 _(l2fib_add_del,                                                        \
21948   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21949 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21950 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21951 _(l2_flags,                                                             \
21952   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21953 _(bridge_flags,                                                         \
21954   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21955 _(tap_create_v2,                                                        \
21956   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21957 _(tap_delete_v2,                                                        \
21958   "<vpp-if-name> | sw_if_index <id>")                                   \
21959 _(sw_interface_tap_v2_dump, "")                                         \
21960 _(virtio_pci_create,                                                    \
21961   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21962 _(virtio_pci_delete,                                                    \
21963   "<vpp-if-name> | sw_if_index <id>")                                   \
21964 _(sw_interface_virtio_pci_dump, "")                                     \
21965 _(bond_create,                                                          \
21966   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21967   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21968   "[id <if-id>]")                                                       \
21969 _(bond_delete,                                                          \
21970   "<vpp-if-name> | sw_if_index <id>")                                   \
21971 _(bond_enslave,                                                         \
21972   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21973 _(bond_detach_slave,                                                    \
21974   "sw_if_index <n>")                                                    \
21975 _(sw_interface_bond_dump, "")                                           \
21976 _(sw_interface_slave_dump,                                              \
21977   "<vpp-if-name> | sw_if_index <id>")                                   \
21978 _(ip_table_add_del,                                                     \
21979   "table <n> [ipv6] [add | del]\n")                                     \
21980 _(ip_route_add_del,                                                     \
21981   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21982   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21983   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21984   "[multipath] [count <n>] [del]")                                      \
21985 _(ip_mroute_add_del,                                                    \
21986   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21987   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21988 _(mpls_table_add_del,                                                   \
21989   "table <n> [add | del]\n")                                            \
21990 _(mpls_route_add_del,                                                   \
21991   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21992   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21993   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21994   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21995   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21996   "[count <n>] [del]")                                                  \
21997 _(mpls_ip_bind_unbind,                                                  \
21998   "<label> <addr/len>")                                                 \
21999 _(mpls_tunnel_add_del,                                                  \
22000   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22001   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22002   "[l2-only]  [out-label <n>]")                                         \
22003 _(sr_mpls_policy_add,                                                   \
22004   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22005 _(sr_mpls_policy_del,                                                   \
22006   "bsid <id>")                                                          \
22007 _(bier_table_add_del,                                                   \
22008   "<label> <sub-domain> <set> <bsl> [del]")                             \
22009 _(bier_route_add_del,                                                   \
22010   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22011   "[<intfc> | sw_if_index <id>]"                                        \
22012   "[weight <n>] [del] [multipath]")                                     \
22013 _(proxy_arp_add_del,                                                    \
22014   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22015 _(proxy_arp_intfc_enable_disable,                                       \
22016   "<intfc> | sw_if_index <id> enable | disable")                        \
22017 _(sw_interface_set_unnumbered,                                          \
22018   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22019 _(ip_neighbor_add_del,                                                  \
22020   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22021   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22022 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22023 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22024   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22025   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22026   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22027 _(reset_fib, "vrf <n> [ipv6]")                                          \
22028 _(dhcp_proxy_config,                                                    \
22029   "svr <v46-address> src <v46-address>\n"                               \
22030    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22031 _(dhcp_proxy_set_vss,                                                   \
22032   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22033 _(dhcp_proxy_dump, "ip6")                                               \
22034 _(dhcp_client_config,                                                   \
22035   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22036 _(set_ip_flow_hash,                                                     \
22037   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22038 _(sw_interface_ip6_enable_disable,                                      \
22039   "<intfc> | sw_if_index <id> enable | disable")                        \
22040 _(ip6nd_proxy_add_del,                                                  \
22041   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22042 _(ip6nd_proxy_dump, "")                                                 \
22043 _(sw_interface_ip6nd_ra_prefix,                                         \
22044   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22045   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22046   "[nolink] [isno]")                                                    \
22047 _(sw_interface_ip6nd_ra_config,                                         \
22048   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22049   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22050   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22051 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22052 _(l2_patch_add_del,                                                     \
22053   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22054   "enable | disable")                                                   \
22055 _(sr_localsid_add_del,                                                  \
22056   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22057   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22058 _(classify_add_del_table,                                               \
22059   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22060   " [del] [del-chain] mask <mask-value>\n"                              \
22061   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22062   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22063 _(classify_add_del_session,                                             \
22064   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22065   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22066   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22067   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22068 _(classify_set_interface_ip_table,                                      \
22069   "<intfc> | sw_if_index <nn> table <nn>")                              \
22070 _(classify_set_interface_l2_tables,                                     \
22071   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22072   "  [other-table <nn>]")                                               \
22073 _(get_node_index, "node <node-name")                                    \
22074 _(add_node_next, "node <node-name> next <next-node-name>")              \
22075 _(l2tpv3_create_tunnel,                                                 \
22076   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22077   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22078   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22079 _(l2tpv3_set_tunnel_cookies,                                            \
22080   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22081   "[new_remote_cookie <nn>]\n")                                         \
22082 _(l2tpv3_interface_enable_disable,                                      \
22083   "<intfc> | sw_if_index <nn> enable | disable")                        \
22084 _(l2tpv3_set_lookup_key,                                                \
22085   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22086 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22087 _(vxlan_offload_rx,                                                     \
22088   "hw { <interface name> | hw_if_index <nn>} "                          \
22089   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22090 _(vxlan_add_del_tunnel,                                                 \
22091   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22092   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22093   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22094 _(geneve_add_del_tunnel,                                                \
22095   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22096   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22097   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22098 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22099 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22100 _(gre_tunnel_add_del,                                                   \
22101   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22102   "[teb | erspan <session-id>] [del]")                                  \
22103 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22104 _(l2_fib_clear_table, "")                                               \
22105 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22106 _(l2_interface_vlan_tag_rewrite,                                        \
22107   "<intfc> | sw_if_index <nn> \n"                                       \
22108   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22109   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22110 _(create_vhost_user_if,                                                 \
22111         "socket <filename> [server] [renumber <dev_instance>] "         \
22112         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22113         "[mac <mac_address>]")                                          \
22114 _(modify_vhost_user_if,                                                 \
22115         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22116         "[server] [renumber <dev_instance>]")                           \
22117 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22118 _(sw_interface_vhost_user_dump, "")                                     \
22119 _(show_version, "")                                                     \
22120 _(show_threads, "")                                                     \
22121 _(vxlan_gpe_add_del_tunnel,                                             \
22122   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22123   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22124   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22125   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22126 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22127 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22128 _(interface_name_renumber,                                              \
22129   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22130 _(input_acl_set_interface,                                              \
22131   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22132   "  [l2-table <nn>] [del]")                                            \
22133 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22134 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22135   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22136 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22137 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22138 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22139 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22140 _(ip_dump, "ipv4 | ipv6")                                               \
22141 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22142 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22143   "  spid_id <n> ")                                                     \
22144 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22145   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22146   "  integ_alg <alg> integ_key <hex>")                                  \
22147 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22148   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22149   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22150   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22151 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22152   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22153   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22154   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22155   "  [instance <n>]")     \
22156 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22157 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22158 _(delete_loopback,"sw_if_index <nn>")                                   \
22159 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22160 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22161 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22162 _(want_interface_events,  "enable|disable")                             \
22163 _(get_first_msg_id, "client <name>")                                    \
22164 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22165 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22166   "fib-id <nn> [ip4][ip6][default]")                                    \
22167 _(get_node_graph, " ")                                                  \
22168 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22169 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22170 _(ioam_disable, "")                                                     \
22171 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22172                             " sw_if_index <sw_if_index> p <priority> "  \
22173                             "w <weight>] [del]")                        \
22174 _(one_add_del_locator, "locator-set <locator_name> "                    \
22175                         "iface <intf> | sw_if_index <sw_if_index> "     \
22176                         "p <priority> w <weight> [del]")                \
22177 _(one_add_del_local_eid,"vni <vni> eid "                                \
22178                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22179                          "locator-set <locator_name> [del]"             \
22180                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22181 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22182 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22183 _(one_enable_disable, "enable|disable")                                 \
22184 _(one_map_register_enable_disable, "enable|disable")                    \
22185 _(one_map_register_fallback_threshold, "<value>")                       \
22186 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22187 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22188                                "[seid <seid>] "                         \
22189                                "rloc <locator> p <prio> "               \
22190                                "w <weight> [rloc <loc> ... ] "          \
22191                                "action <action> [del-all]")             \
22192 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22193                           "<local-eid>")                                \
22194 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22195 _(one_use_petr, "ip-address> | disable")                                \
22196 _(one_map_request_mode, "src-dst|dst-only")                             \
22197 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22198 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22199 _(one_locator_set_dump, "[local | remote]")                             \
22200 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22201 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22202                        "[local] | [remote]")                            \
22203 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22204 _(one_ndp_bd_get, "")                                                   \
22205 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22206 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22207 _(one_l2_arp_bd_get, "")                                                \
22208 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22209 _(one_stats_enable_disable, "enable|disable")                           \
22210 _(show_one_stats_enable_disable, "")                                    \
22211 _(one_eid_table_vni_dump, "")                                           \
22212 _(one_eid_table_map_dump, "l2|l3")                                      \
22213 _(one_map_resolver_dump, "")                                            \
22214 _(one_map_server_dump, "")                                              \
22215 _(one_adjacencies_get, "vni <vni>")                                     \
22216 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22217 _(show_one_rloc_probe_state, "")                                        \
22218 _(show_one_map_register_state, "")                                      \
22219 _(show_one_status, "")                                                  \
22220 _(one_stats_dump, "")                                                   \
22221 _(one_stats_flush, "")                                                  \
22222 _(one_get_map_request_itr_rlocs, "")                                    \
22223 _(one_map_register_set_ttl, "<ttl>")                                    \
22224 _(one_set_transport_protocol, "udp|api")                                \
22225 _(one_get_transport_protocol, "")                                       \
22226 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22227 _(one_show_xtr_mode, "")                                                \
22228 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22229 _(one_show_pitr_mode, "")                                               \
22230 _(one_enable_disable_petr_mode, "enable|disable")                       \
22231 _(one_show_petr_mode, "")                                               \
22232 _(show_one_nsh_mapping, "")                                             \
22233 _(show_one_pitr, "")                                                    \
22234 _(show_one_use_petr, "")                                                \
22235 _(show_one_map_request_mode, "")                                        \
22236 _(show_one_map_register_ttl, "")                                        \
22237 _(show_one_map_register_fallback_threshold, "")                         \
22238 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22239                             " sw_if_index <sw_if_index> p <priority> "  \
22240                             "w <weight>] [del]")                        \
22241 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22242                         "iface <intf> | sw_if_index <sw_if_index> "     \
22243                         "p <priority> w <weight> [del]")                \
22244 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22245                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22246                          "locator-set <locator_name> [del]"             \
22247                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22248 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22249 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22250 _(lisp_enable_disable, "enable|disable")                                \
22251 _(lisp_map_register_enable_disable, "enable|disable")                   \
22252 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22253 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22254                                "[seid <seid>] "                         \
22255                                "rloc <locator> p <prio> "               \
22256                                "w <weight> [rloc <loc> ... ] "          \
22257                                "action <action> [del-all]")             \
22258 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22259                           "<local-eid>")                                \
22260 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22261 _(lisp_use_petr, "<ip-address> | disable")                              \
22262 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22263 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22264 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22265 _(lisp_locator_set_dump, "[local | remote]")                            \
22266 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22267 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22268                        "[local] | [remote]")                            \
22269 _(lisp_eid_table_vni_dump, "")                                          \
22270 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22271 _(lisp_map_resolver_dump, "")                                           \
22272 _(lisp_map_server_dump, "")                                             \
22273 _(lisp_adjacencies_get, "vni <vni>")                                    \
22274 _(gpe_fwd_entry_vnis_get, "")                                           \
22275 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22276 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22277                                 "[table <table-id>]")                   \
22278 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22279 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22280 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22281 _(gpe_get_encap_mode, "")                                               \
22282 _(lisp_gpe_add_del_iface, "up|down")                                    \
22283 _(lisp_gpe_enable_disable, "enable|disable")                            \
22284 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22285   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22286 _(show_lisp_rloc_probe_state, "")                                       \
22287 _(show_lisp_map_register_state, "")                                     \
22288 _(show_lisp_status, "")                                                 \
22289 _(lisp_get_map_request_itr_rlocs, "")                                   \
22290 _(show_lisp_pitr, "")                                                   \
22291 _(show_lisp_use_petr, "")                                               \
22292 _(show_lisp_map_request_mode, "")                                       \
22293 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22294 _(af_packet_delete, "name <host interface name>")                       \
22295 _(af_packet_dump, "")                                                   \
22296 _(policer_add_del, "name <policer name> <params> [del]")                \
22297 _(policer_dump, "[name <policer name>]")                                \
22298 _(policer_classify_set_interface,                                       \
22299   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22300   "  [l2-table <nn>] [del]")                                            \
22301 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22302 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22303     "[master|slave]")                                                   \
22304 _(netmap_delete, "name <interface name>")                               \
22305 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22306 _(mpls_table_dump, "")                                                  \
22307 _(mpls_route_dump, "table-id <ID>")                                     \
22308 _(classify_table_ids, "")                                               \
22309 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22310 _(classify_table_info, "table_id <nn>")                                 \
22311 _(classify_session_dump, "table_id <nn>")                               \
22312 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22313     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22314     "[template_interval <nn>] [udp_checksum]")                          \
22315 _(ipfix_exporter_dump, "")                                              \
22316 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22317 _(ipfix_classify_stream_dump, "")                                       \
22318 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22319 _(ipfix_classify_table_dump, "")                                        \
22320 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22321 _(sw_interface_span_dump, "[l2]")                                           \
22322 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22323 _(pg_create_interface, "if_id <nn>")                                    \
22324 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22325 _(pg_enable_disable, "[stream <id>] disable")                           \
22326 _(ip_source_and_port_range_check_add_del,                               \
22327   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22328 _(ip_source_and_port_range_check_interface_add_del,                     \
22329   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22330   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22331 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22332 _(l2_interface_pbb_tag_rewrite,                                         \
22333   "<intfc> | sw_if_index <nn> \n"                                       \
22334   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22335   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22336 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22337 _(flow_classify_set_interface,                                          \
22338   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22339 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22340 _(ip_table_dump, "")                                                    \
22341 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22342 _(ip_mtable_dump, "")                                                   \
22343 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22344 _(feature_enable_disable, "arc_name <arc_name> "                        \
22345   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22346 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22347 "[disable]")                                                            \
22348 _(l2_xconnect_dump, "")                                                 \
22349 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22350 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22351 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22352 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22353 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22354 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22355 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22356   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22357 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22358 _(sock_init_shm, "size <nnn>")                                          \
22359 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22360 _(dns_enable_disable, "[enable][disable]")                              \
22361 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22362 _(dns_resolve_name, "<hostname>")                                       \
22363 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22364 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22365 _(dns_resolve_name, "<hostname>")                                       \
22366 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22367   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22368 _(session_rules_dump, "")                                               \
22369 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22370 _(output_acl_set_interface,                                             \
22371   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22372   "  [l2-table <nn>] [del]")                                            \
22373 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22374
22375 /* List of command functions, CLI names map directly to functions */
22376 #define foreach_cli_function                                    \
22377 _(comment, "usage: comment <ignore-rest-of-line>")              \
22378 _(dump_interface_table, "usage: dump_interface_table")          \
22379 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22380 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22381 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22382 _(dump_macro_table, "usage: dump_macro_table ")                 \
22383 _(dump_node_table, "usage: dump_node_table")                    \
22384 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22385 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22386 _(elog_disable, "usage: elog_disable")                          \
22387 _(elog_enable, "usage: elog_enable")                            \
22388 _(elog_save, "usage: elog_save <filename>")                     \
22389 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22390 _(echo, "usage: echo <message>")                                \
22391 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22392 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22393 _(help, "usage: help")                                          \
22394 _(q, "usage: quit")                                             \
22395 _(quit, "usage: quit")                                          \
22396 _(search_node_table, "usage: search_node_table <name>...")      \
22397 _(set, "usage: set <variable-name> <value>")                    \
22398 _(script, "usage: script <file-name>")                          \
22399 _(statseg, "usage: statseg")                                    \
22400 _(unset, "usage: unset <variable-name>")
22401
22402 #define _(N,n)                                  \
22403     static void vl_api_##n##_t_handler_uni      \
22404     (vl_api_##n##_t * mp)                       \
22405     {                                           \
22406         vat_main_t * vam = &vat_main;           \
22407         if (vam->json_output) {                 \
22408             vl_api_##n##_t_handler_json(mp);    \
22409         } else {                                \
22410             vl_api_##n##_t_handler(mp);         \
22411         }                                       \
22412     }
22413 foreach_vpe_api_reply_msg;
22414 #if VPP_API_TEST_BUILTIN == 0
22415 foreach_standalone_reply_msg;
22416 #endif
22417 #undef _
22418
22419 void
22420 vat_api_hookup (vat_main_t * vam)
22421 {
22422 #define _(N,n)                                                  \
22423     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22424                            vl_api_##n##_t_handler_uni,          \
22425                            vl_noop_handler,                     \
22426                            vl_api_##n##_t_endian,               \
22427                            vl_api_##n##_t_print,                \
22428                            sizeof(vl_api_##n##_t), 1);
22429   foreach_vpe_api_reply_msg;
22430 #if VPP_API_TEST_BUILTIN == 0
22431   foreach_standalone_reply_msg;
22432 #endif
22433 #undef _
22434
22435 #if (VPP_API_TEST_BUILTIN==0)
22436   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22437
22438   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22439
22440   vam->function_by_name = hash_create_string (0, sizeof (uword));
22441
22442   vam->help_by_name = hash_create_string (0, sizeof (uword));
22443 #endif
22444
22445   /* API messages we can send */
22446 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22447   foreach_vpe_api_msg;
22448 #undef _
22449
22450   /* Help strings */
22451 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22452   foreach_vpe_api_msg;
22453 #undef _
22454
22455   /* CLI functions */
22456 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22457   foreach_cli_function;
22458 #undef _
22459
22460   /* Help strings */
22461 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22462   foreach_cli_function;
22463 #undef _
22464 }
22465
22466 #if VPP_API_TEST_BUILTIN
22467 static clib_error_t *
22468 vat_api_hookup_shim (vlib_main_t * vm)
22469 {
22470   vat_api_hookup (&vat_main);
22471   return 0;
22472 }
22473
22474 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22475 #endif
22476
22477 /*
22478  * fd.io coding-style-patch-verification: ON
22479  *
22480  * Local Variables:
22481  * eval: (c-set-style "gnu")
22482  * End:
22483  */