bonding: add weight support for active-backup mode
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 void vl_api_set_elog_main (elog_main_t * m);
89 int vl_api_set_elog_trace_api_messages (int enable);
90
91 #if VPP_API_TEST_BUILTIN == 0
92 #include <netdb.h>
93
94 u32
95 vl (void *p)
96 {
97   return vec_len (p);
98 }
99
100 int
101 vat_socket_connect (vat_main_t * vam)
102 {
103   int rv;
104   vam->socket_client_main = &socket_client_main;
105   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
106                                       "vpp_api_test",
107                                       0 /* default socket rx, tx buffer */ )))
108     return rv;
109   /* vpp expects the client index in network order */
110   vam->my_client_index = htonl (socket_client_main.client_index);
111   return 0;
112 }
113 #else /* vpp built-in case, we don't do sockets... */
114 int
115 vat_socket_connect (vat_main_t * vam)
116 {
117   return 0;
118 }
119
120 int
121 vl_socket_client_read (int wait)
122 {
123   return -1;
124 };
125
126 int
127 vl_socket_client_write ()
128 {
129   return -1;
130 };
131
132 void *
133 vl_socket_client_msg_alloc (int nbytes)
134 {
135   return 0;
136 }
137 #endif
138
139
140 f64
141 vat_time_now (vat_main_t * vam)
142 {
143 #if VPP_API_TEST_BUILTIN
144   return vlib_time_now (vam->vlib_main);
145 #else
146   return clib_time_now (&vam->clib_time);
147 #endif
148 }
149
150 void
151 errmsg (char *fmt, ...)
152 {
153   vat_main_t *vam = &vat_main;
154   va_list va;
155   u8 *s;
156
157   va_start (va, fmt);
158   s = va_format (0, fmt, &va);
159   va_end (va);
160
161   vec_add1 (s, 0);
162
163 #if VPP_API_TEST_BUILTIN
164   vlib_cli_output (vam->vlib_main, (char *) s);
165 #else
166   {
167     if (vam->ifp != stdin)
168       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
169                vam->input_line_number);
170     else
171       fformat (vam->ofp, "%s\n", (char *) s);
172     fflush (vam->ofp);
173   }
174 #endif
175
176   vec_free (s);
177 }
178
179 #if VPP_API_TEST_BUILTIN == 0
180 static uword
181 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
182 {
183   vat_main_t *vam = va_arg (*args, vat_main_t *);
184   u32 *result = va_arg (*args, u32 *);
185   u8 *if_name;
186   uword *p;
187
188   if (!unformat (input, "%s", &if_name))
189     return 0;
190
191   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
192   if (p == 0)
193     return 0;
194   *result = p[0];
195   return 1;
196 }
197
198 static uword
199 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
200 {
201   return 0;
202 }
203
204 /* Parse an IP4 address %d.%d.%d.%d. */
205 uword
206 unformat_ip4_address (unformat_input_t * input, va_list * args)
207 {
208   u8 *result = va_arg (*args, u8 *);
209   unsigned a[4];
210
211   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
212     return 0;
213
214   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
215     return 0;
216
217   result[0] = a[0];
218   result[1] = a[1];
219   result[2] = a[2];
220   result[3] = a[3];
221
222   return 1;
223 }
224
225 uword
226 unformat_ethernet_address (unformat_input_t * input, va_list * args)
227 {
228   u8 *result = va_arg (*args, u8 *);
229   u32 i, a[6];
230
231   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
232                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
233     return 0;
234
235   /* Check range. */
236   for (i = 0; i < 6; i++)
237     if (a[i] >= (1 << 8))
238       return 0;
239
240   for (i = 0; i < 6; i++)
241     result[i] = a[i];
242
243   return 1;
244 }
245
246 /* Returns ethernet type as an int in host byte order. */
247 uword
248 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
249                                         va_list * args)
250 {
251   u16 *result = va_arg (*args, u16 *);
252   int type;
253
254   /* Numeric type. */
255   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
256     {
257       if (type >= (1 << 16))
258         return 0;
259       *result = type;
260       return 1;
261     }
262   return 0;
263 }
264
265 /* Parse an IP6 address. */
266 uword
267 unformat_ip6_address (unformat_input_t * input, va_list * args)
268 {
269   ip6_address_t *result = va_arg (*args, ip6_address_t *);
270   u16 hex_quads[8];
271   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
272   uword c, n_colon, double_colon_index;
273
274   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
275   double_colon_index = ARRAY_LEN (hex_quads);
276   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
277     {
278       hex_digit = 16;
279       if (c >= '0' && c <= '9')
280         hex_digit = c - '0';
281       else if (c >= 'a' && c <= 'f')
282         hex_digit = c + 10 - 'a';
283       else if (c >= 'A' && c <= 'F')
284         hex_digit = c + 10 - 'A';
285       else if (c == ':' && n_colon < 2)
286         n_colon++;
287       else
288         {
289           unformat_put_input (input);
290           break;
291         }
292
293       /* Too many hex quads. */
294       if (n_hex_quads >= ARRAY_LEN (hex_quads))
295         return 0;
296
297       if (hex_digit < 16)
298         {
299           hex_quad = (hex_quad << 4) | hex_digit;
300
301           /* Hex quad must fit in 16 bits. */
302           if (n_hex_digits >= 4)
303             return 0;
304
305           n_colon = 0;
306           n_hex_digits++;
307         }
308
309       /* Save position of :: */
310       if (n_colon == 2)
311         {
312           /* More than one :: ? */
313           if (double_colon_index < ARRAY_LEN (hex_quads))
314             return 0;
315           double_colon_index = n_hex_quads;
316         }
317
318       if (n_colon > 0 && n_hex_digits > 0)
319         {
320           hex_quads[n_hex_quads++] = hex_quad;
321           hex_quad = 0;
322           n_hex_digits = 0;
323         }
324     }
325
326   if (n_hex_digits > 0)
327     hex_quads[n_hex_quads++] = hex_quad;
328
329   {
330     word i;
331
332     /* Expand :: to appropriate number of zero hex quads. */
333     if (double_colon_index < ARRAY_LEN (hex_quads))
334       {
335         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
336
337         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
338           hex_quads[n_zero + i] = hex_quads[i];
339
340         for (i = 0; i < n_zero; i++)
341           hex_quads[double_colon_index + i] = 0;
342
343         n_hex_quads = ARRAY_LEN (hex_quads);
344       }
345
346     /* Too few hex quads given. */
347     if (n_hex_quads < ARRAY_LEN (hex_quads))
348       return 0;
349
350     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
351       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
352
353     return 1;
354   }
355 }
356
357 uword
358 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
359 {
360   u32 *r = va_arg (*args, u32 *);
361
362   if (0);
363 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
364   foreach_ipsec_policy_action
365 #undef _
366     else
367     return 0;
368   return 1;
369 }
370
371 u8 *
372 format_ipsec_crypto_alg (u8 * s, va_list * args)
373 {
374   u32 i = va_arg (*args, u32);
375   u8 *t = 0;
376
377   switch (i)
378     {
379 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
380       foreach_ipsec_crypto_alg
381 #undef _
382     default:
383       return format (s, "unknown");
384     }
385   return format (s, "%s", t);
386 }
387
388 u8 *
389 format_ipsec_integ_alg (u8 * s, va_list * args)
390 {
391   u32 i = va_arg (*args, u32);
392   u8 *t = 0;
393
394   switch (i)
395     {
396 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
397       foreach_ipsec_integ_alg
398 #undef _
399     default:
400       return format (s, "unknown");
401     }
402   return format (s, "%s", t);
403 }
404
405 #else /* VPP_API_TEST_BUILTIN == 1 */
406 static uword
407 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
408 {
409   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
410   vnet_main_t *vnm = vnet_get_main ();
411   u32 *result = va_arg (*args, u32 *);
412
413   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
414 }
415
416 static uword
417 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
418 {
419   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
420   vnet_main_t *vnm = vnet_get_main ();
421   u32 *result = va_arg (*args, u32 *);
422
423   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
424 }
425
426 #endif /* VPP_API_TEST_BUILTIN */
427
428 uword
429 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
435   foreach_ipsec_crypto_alg
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
444 {
445   u32 *r = va_arg (*args, u32 *);
446
447   if (0);
448 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
449   foreach_ipsec_integ_alg
450 #undef _
451     else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
458 {
459   u8 *r = va_arg (*args, u8 *);
460
461   if (unformat (input, "kbps"))
462     *r = SSE2_QOS_RATE_KBPS;
463   else if (unformat (input, "pps"))
464     *r = SSE2_QOS_RATE_PPS;
465   else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_round_type (unformat_input_t * input, va_list * args)
472 {
473   u8 *r = va_arg (*args, u8 *);
474
475   if (unformat (input, "closest"))
476     *r = SSE2_QOS_ROUND_TO_CLOSEST;
477   else if (unformat (input, "up"))
478     *r = SSE2_QOS_ROUND_TO_UP;
479   else if (unformat (input, "down"))
480     *r = SSE2_QOS_ROUND_TO_DOWN;
481   else
482     return 0;
483   return 1;
484 }
485
486 static uword
487 unformat_policer_type (unformat_input_t * input, va_list * args)
488 {
489   u8 *r = va_arg (*args, u8 *);
490
491   if (unformat (input, "1r2c"))
492     *r = SSE2_QOS_POLICER_TYPE_1R2C;
493   else if (unformat (input, "1r3c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
495   else if (unformat (input, "2r3c-2698"))
496     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
497   else if (unformat (input, "2r3c-4115"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
499   else if (unformat (input, "2r3c-mef5cf1"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
501   else
502     return 0;
503   return 1;
504 }
505
506 static uword
507 unformat_dscp (unformat_input_t * input, va_list * va)
508 {
509   u8 *r = va_arg (*va, u8 *);
510
511   if (0);
512 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
513   foreach_vnet_dscp
514 #undef _
515     else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_action_type (unformat_input_t * input, va_list * va)
522 {
523   sse2_qos_pol_action_params_st *a
524     = va_arg (*va, sse2_qos_pol_action_params_st *);
525
526   if (unformat (input, "drop"))
527     a->action_type = SSE2_QOS_ACTION_DROP;
528   else if (unformat (input, "transmit"))
529     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
530   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
531     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
532   else
533     return 0;
534   return 1;
535 }
536
537 static uword
538 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
539 {
540   u32 *r = va_arg (*va, u32 *);
541   u32 tid;
542
543   if (unformat (input, "ip4"))
544     tid = POLICER_CLASSIFY_TABLE_IP4;
545   else if (unformat (input, "ip6"))
546     tid = POLICER_CLASSIFY_TABLE_IP6;
547   else if (unformat (input, "l2"))
548     tid = POLICER_CLASSIFY_TABLE_L2;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static uword
557 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
558 {
559   u32 *r = va_arg (*va, u32 *);
560   u32 tid;
561
562   if (unformat (input, "ip4"))
563     tid = FLOW_CLASSIFY_TABLE_IP4;
564   else if (unformat (input, "ip6"))
565     tid = FLOW_CLASSIFY_TABLE_IP6;
566   else
567     return 0;
568
569   *r = tid;
570   return 1;
571 }
572
573 #if (VPP_API_TEST_BUILTIN==0)
574
575 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
576 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
577 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
578 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
579
580 uword
581 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
582 {
583   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
584   mfib_itf_attribute_t attr;
585
586   old = *iflags;
587   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
588   {
589     if (unformat (input, mfib_itf_flag_long_names[attr]))
590       *iflags |= (1 << attr);
591   }
592   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
593   {
594     if (unformat (input, mfib_itf_flag_names[attr]))
595       *iflags |= (1 << attr);
596   }
597
598   return (old == *iflags ? 0 : 1);
599 }
600
601 uword
602 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
603 {
604   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
605   mfib_entry_attribute_t attr;
606
607   old = *eflags;
608   FOR_EACH_MFIB_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_flag_long_names[attr]))
611       *eflags |= (1 << attr);
612   }
613   FOR_EACH_MFIB_ATTRIBUTE (attr)
614   {
615     if (unformat (input, mfib_flag_names[attr]))
616       *eflags |= (1 << attr);
617   }
618
619   return (old == *eflags ? 0 : 1);
620 }
621
622 u8 *
623 format_ip4_address (u8 * s, va_list * args)
624 {
625   u8 *a = va_arg (*args, u8 *);
626   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
627 }
628
629 u8 *
630 format_ip6_address (u8 * s, va_list * args)
631 {
632   ip6_address_t *a = va_arg (*args, ip6_address_t *);
633   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
634
635   i_max_n_zero = ARRAY_LEN (a->as_u16);
636   max_n_zeros = 0;
637   i_first_zero = i_max_n_zero;
638   n_zeros = 0;
639   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
640     {
641       u32 is_zero = a->as_u16[i] == 0;
642       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
643         {
644           i_first_zero = i;
645           n_zeros = 0;
646         }
647       n_zeros += is_zero;
648       if ((!is_zero && n_zeros > max_n_zeros)
649           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
650         {
651           i_max_n_zero = i_first_zero;
652           max_n_zeros = n_zeros;
653           i_first_zero = ARRAY_LEN (a->as_u16);
654           n_zeros = 0;
655         }
656     }
657
658   last_double_colon = 0;
659   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
660     {
661       if (i == i_max_n_zero && max_n_zeros > 1)
662         {
663           s = format (s, "::");
664           i += max_n_zeros - 1;
665           last_double_colon = 1;
666         }
667       else
668         {
669           s = format (s, "%s%x",
670                       (last_double_colon || i == 0) ? "" : ":",
671                       clib_net_to_host_u16 (a->as_u16[i]));
672           last_double_colon = 0;
673         }
674     }
675
676   return s;
677 }
678
679 /* Format an IP46 address. */
680 u8 *
681 format_ip46_address (u8 * s, va_list * args)
682 {
683   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
684   ip46_type_t type = va_arg (*args, ip46_type_t);
685   int is_ip4 = 1;
686
687   switch (type)
688     {
689     case IP46_TYPE_ANY:
690       is_ip4 = ip46_address_is_ip4 (ip46);
691       break;
692     case IP46_TYPE_IP4:
693       is_ip4 = 1;
694       break;
695     case IP46_TYPE_IP6:
696       is_ip4 = 0;
697       break;
698     }
699
700   return is_ip4 ?
701     format (s, "%U", format_ip4_address, &ip46->ip4) :
702     format (s, "%U", format_ip6_address, &ip46->ip6);
703 }
704
705 u8 *
706 format_ethernet_address (u8 * s, va_list * args)
707 {
708   u8 *a = va_arg (*args, u8 *);
709
710   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
711                  a[0], a[1], a[2], a[3], a[4], a[5]);
712 }
713 #endif
714
715 static void
716 increment_v4_address (vl_api_ip4_address_t * i)
717 {
718   ip4_address_t *a = (ip4_address_t *) i;
719   u32 v;
720
721   v = ntohl (a->as_u32) + 1;
722   a->as_u32 = ntohl (v);
723 }
724
725 static void
726 increment_v6_address (vl_api_ip6_address_t * i)
727 {
728   ip6_address_t *a = (ip6_address_t *) i;
729   u64 v0, v1;
730
731   v0 = clib_net_to_host_u64 (a->as_u64[0]);
732   v1 = clib_net_to_host_u64 (a->as_u64[1]);
733
734   v1 += 1;
735   if (v1 == 0)
736     v0 += 1;
737   a->as_u64[0] = clib_net_to_host_u64 (v0);
738   a->as_u64[1] = clib_net_to_host_u64 (v1);
739 }
740
741 static void
742 increment_address (vl_api_address_t * a)
743 {
744   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
745     increment_v4_address (&a->un.ip4);
746   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
747     increment_v6_address (&a->un.ip6);
748 }
749
750 static void
751 set_ip4_address (vl_api_address_t * a, u32 v)
752 {
753   if (a->af == ADDRESS_IP4)
754     {
755       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
756       i->as_u32 = v;
757     }
758 }
759
760 static void
761 increment_mac_address (u8 * mac)
762 {
763   u64 tmp = *((u64 *) mac);
764   tmp = clib_net_to_host_u64 (tmp);
765   tmp += 1 << 16;               /* skip unused (least significant) octets */
766   tmp = clib_host_to_net_u64 (tmp);
767
768   clib_memcpy (mac, &tmp, 6);
769 }
770
771 static void
772 vat_json_object_add_address (vat_json_node_t * node,
773                              const char *str, const vl_api_address_t * addr)
774 {
775   if (ADDRESS_IP6 == addr->af)
776     {
777       struct in6_addr ip6;
778
779       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
780       vat_json_object_add_ip6 (node, str, ip6);
781     }
782   else
783     {
784       struct in_addr ip4;
785
786       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
787       vat_json_object_add_ip4 (node, str, ip4);
788     }
789 }
790
791 static void
792 vat_json_object_add_prefix (vat_json_node_t * node,
793                             const vl_api_prefix_t * prefix)
794 {
795   vat_json_object_add_uint (node, "len", prefix->len);
796   vat_json_object_add_address (node, "address", &prefix->address);
797 }
798
799 static void vl_api_create_loopback_reply_t_handler
800   (vl_api_create_loopback_reply_t * mp)
801 {
802   vat_main_t *vam = &vat_main;
803   i32 retval = ntohl (mp->retval);
804
805   vam->retval = retval;
806   vam->regenerate_interface_table = 1;
807   vam->sw_if_index = ntohl (mp->sw_if_index);
808   vam->result_ready = 1;
809 }
810
811 static void vl_api_create_loopback_reply_t_handler_json
812   (vl_api_create_loopback_reply_t * mp)
813 {
814   vat_main_t *vam = &vat_main;
815   vat_json_node_t node;
816
817   vat_json_init_object (&node);
818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
820
821   vat_json_print (vam->ofp, &node);
822   vat_json_free (&node);
823   vam->retval = ntohl (mp->retval);
824   vam->result_ready = 1;
825 }
826
827 static void vl_api_create_loopback_instance_reply_t_handler
828   (vl_api_create_loopback_instance_reply_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   i32 retval = ntohl (mp->retval);
832
833   vam->retval = retval;
834   vam->regenerate_interface_table = 1;
835   vam->sw_if_index = ntohl (mp->sw_if_index);
836   vam->result_ready = 1;
837 }
838
839 static void vl_api_create_loopback_instance_reply_t_handler_json
840   (vl_api_create_loopback_instance_reply_t * mp)
841 {
842   vat_main_t *vam = &vat_main;
843   vat_json_node_t node;
844
845   vat_json_init_object (&node);
846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
848
849   vat_json_print (vam->ofp, &node);
850   vat_json_free (&node);
851   vam->retval = ntohl (mp->retval);
852   vam->result_ready = 1;
853 }
854
855 static void vl_api_af_packet_create_reply_t_handler
856   (vl_api_af_packet_create_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->regenerate_interface_table = 1;
863   vam->sw_if_index = ntohl (mp->sw_if_index);
864   vam->result_ready = 1;
865 }
866
867 static void vl_api_af_packet_create_reply_t_handler_json
868   (vl_api_af_packet_create_reply_t * mp)
869 {
870   vat_main_t *vam = &vat_main;
871   vat_json_node_t node;
872
873   vat_json_init_object (&node);
874   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
875   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
876
877   vat_json_print (vam->ofp, &node);
878   vat_json_free (&node);
879
880   vam->retval = ntohl (mp->retval);
881   vam->result_ready = 1;
882 }
883
884 static void vl_api_create_vlan_subif_reply_t_handler
885   (vl_api_create_vlan_subif_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   i32 retval = ntohl (mp->retval);
889
890   vam->retval = retval;
891   vam->regenerate_interface_table = 1;
892   vam->sw_if_index = ntohl (mp->sw_if_index);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_create_vlan_subif_reply_t_handler_json
897   (vl_api_create_vlan_subif_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_create_subif_reply_t_handler
914   (vl_api_create_subif_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918
919   vam->retval = retval;
920   vam->regenerate_interface_table = 1;
921   vam->sw_if_index = ntohl (mp->sw_if_index);
922   vam->result_ready = 1;
923 }
924
925 static void vl_api_create_subif_reply_t_handler_json
926   (vl_api_create_subif_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_interface_name_renumber_reply_t_handler
943   (vl_api_interface_name_renumber_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947
948   vam->retval = retval;
949   vam->regenerate_interface_table = 1;
950   vam->result_ready = 1;
951 }
952
953 static void vl_api_interface_name_renumber_reply_t_handler_json
954   (vl_api_interface_name_renumber_reply_t * mp)
955 {
956   vat_main_t *vam = &vat_main;
957   vat_json_node_t node;
958
959   vat_json_init_object (&node);
960   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
961
962   vat_json_print (vam->ofp, &node);
963   vat_json_free (&node);
964
965   vam->retval = ntohl (mp->retval);
966   vam->result_ready = 1;
967 }
968
969 /*
970  * Special-case: build the interface table, maintain
971  * the next loopback sw_if_index vbl.
972  */
973 static void vl_api_sw_interface_details_t_handler
974   (vl_api_sw_interface_details_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   u8 *s = format (0, "%s%c", mp->interface_name, 0);
978
979   hash_set_mem (vam->sw_if_index_by_interface_name, s,
980                 ntohl (mp->sw_if_index));
981
982   /* In sub interface case, fill the sub interface table entry */
983   if (mp->sw_if_index != mp->sup_sw_if_index)
984     {
985       sw_interface_subif_t *sub = NULL;
986
987       vec_add2 (vam->sw_if_subif_table, sub, 1);
988
989       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
990       strncpy ((char *) sub->interface_name, (char *) s,
991                vec_len (sub->interface_name));
992       sub->sw_if_index = ntohl (mp->sw_if_index);
993       sub->sub_id = ntohl (mp->sub_id);
994
995       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
996
997       sub->sub_number_of_tags = mp->sub_number_of_tags;
998       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
999       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1000
1001       /* vlan tag rewrite */
1002       sub->vtr_op = ntohl (mp->vtr_op);
1003       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1004       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1005       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1006     }
1007 }
1008
1009 static void vl_api_sw_interface_details_t_handler_json
1010   (vl_api_sw_interface_details_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t *node = NULL;
1014
1015   if (VAT_JSON_ARRAY != vam->json_tree.type)
1016     {
1017       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1018       vat_json_init_array (&vam->json_tree);
1019     }
1020   node = vat_json_array_add (&vam->json_tree);
1021
1022   vat_json_init_object (node);
1023   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1024   vat_json_object_add_uint (node, "sup_sw_if_index",
1025                             ntohl (mp->sup_sw_if_index));
1026   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1027                              sizeof (mp->l2_address));
1028   vat_json_object_add_string_copy (node, "interface_name",
1029                                    mp->interface_name);
1030   vat_json_object_add_uint (node, "flags", mp->flags);
1031   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1032   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1033   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1034   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1035   vat_json_object_add_uint (node, "sub_number_of_tags",
1036                             mp->sub_number_of_tags);
1037   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1038                             ntohs (mp->sub_outer_vlan_id));
1039   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1040                             ntohs (mp->sub_inner_vlan_id));
1041   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1042   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1043   vat_json_object_add_uint (node, "vtr_push_dot1q",
1044                             ntohl (mp->vtr_push_dot1q));
1045   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1046   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1047   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1048     {
1049       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1050                                        format (0, "%U",
1051                                                format_ethernet_address,
1052                                                &mp->b_dmac));
1053       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1054                                        format (0, "%U",
1055                                                format_ethernet_address,
1056                                                &mp->b_smac));
1057       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1058       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1059     }
1060 }
1061
1062 #if VPP_API_TEST_BUILTIN == 0
1063 static void vl_api_sw_interface_event_t_handler
1064   (vl_api_sw_interface_event_t * mp)
1065 {
1066   vat_main_t *vam = &vat_main;
1067   if (vam->interface_event_display)
1068     errmsg ("interface flags: sw_if_index %d %s %s",
1069             ntohl (mp->sw_if_index),
1070             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1071             "admin-up" : "admin-down",
1072             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1073             "link-up" : "link-down");
1074 }
1075 #endif
1076
1077 __clib_unused static void
1078 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1079 {
1080   /* JSON output not supported */
1081 }
1082
1083 static void
1084 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1085 {
1086   vat_main_t *vam = &vat_main;
1087   i32 retval = ntohl (mp->retval);
1088
1089   vam->retval = retval;
1090   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1091   vam->result_ready = 1;
1092 }
1093
1094 static void
1095 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1096 {
1097   vat_main_t *vam = &vat_main;
1098   vat_json_node_t node;
1099   api_main_t *am = &api_main;
1100   void *oldheap;
1101   u8 *reply;
1102
1103   vat_json_init_object (&node);
1104   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1105   vat_json_object_add_uint (&node, "reply_in_shmem",
1106                             ntohl (mp->reply_in_shmem));
1107   /* Toss the shared-memory original... */
1108   pthread_mutex_lock (&am->vlib_rp->mutex);
1109   oldheap = svm_push_data_heap (am->vlib_rp);
1110
1111   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1112   vec_free (reply);
1113
1114   svm_pop_heap (oldheap);
1115   pthread_mutex_unlock (&am->vlib_rp->mutex);
1116
1117   vat_json_print (vam->ofp, &node);
1118   vat_json_free (&node);
1119
1120   vam->retval = ntohl (mp->retval);
1121   vam->result_ready = 1;
1122 }
1123
1124 static void
1125 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1126 {
1127   vat_main_t *vam = &vat_main;
1128   i32 retval = ntohl (mp->retval);
1129   u32 length = vl_api_string_len (&mp->reply);
1130
1131   vec_reset_length (vam->cmd_reply);
1132
1133   vam->retval = retval;
1134   if (retval == 0)
1135     {
1136       vec_validate (vam->cmd_reply, length);
1137       clib_memcpy ((char *) (vam->cmd_reply),
1138                    vl_api_from_api_string (&mp->reply), length);
1139       vam->cmd_reply[length] = 0;
1140     }
1141   vam->result_ready = 1;
1142 }
1143
1144 static void
1145 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   vat_json_node_t node;
1149
1150   vec_reset_length (vam->cmd_reply);
1151
1152   vat_json_init_object (&node);
1153   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1154   vat_json_object_add_string_copy (&node, "reply",
1155                                    vl_api_from_api_string (&mp->reply));
1156
1157   vat_json_print (vam->ofp, &node);
1158   vat_json_free (&node);
1159
1160   vam->retval = ntohl (mp->retval);
1161   vam->result_ready = 1;
1162 }
1163
1164 static void vl_api_classify_add_del_table_reply_t_handler
1165   (vl_api_classify_add_del_table_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   i32 retval = ntohl (mp->retval);
1169   if (vam->async_mode)
1170     {
1171       vam->async_errors += (retval < 0);
1172     }
1173   else
1174     {
1175       vam->retval = retval;
1176       if (retval == 0 &&
1177           ((mp->new_table_index != 0xFFFFFFFF) ||
1178            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1179            (mp->match_n_vectors != 0xFFFFFFFF)))
1180         /*
1181          * Note: this is just barely thread-safe, depends on
1182          * the main thread spinning waiting for an answer...
1183          */
1184         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1185                 ntohl (mp->new_table_index),
1186                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1187       vam->result_ready = 1;
1188     }
1189 }
1190
1191 static void vl_api_classify_add_del_table_reply_t_handler_json
1192   (vl_api_classify_add_del_table_reply_t * mp)
1193 {
1194   vat_main_t *vam = &vat_main;
1195   vat_json_node_t node;
1196
1197   vat_json_init_object (&node);
1198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1199   vat_json_object_add_uint (&node, "new_table_index",
1200                             ntohl (mp->new_table_index));
1201   vat_json_object_add_uint (&node, "skip_n_vectors",
1202                             ntohl (mp->skip_n_vectors));
1203   vat_json_object_add_uint (&node, "match_n_vectors",
1204                             ntohl (mp->match_n_vectors));
1205
1206   vat_json_print (vam->ofp, &node);
1207   vat_json_free (&node);
1208
1209   vam->retval = ntohl (mp->retval);
1210   vam->result_ready = 1;
1211 }
1212
1213 static void vl_api_get_node_index_reply_t_handler
1214   (vl_api_get_node_index_reply_t * mp)
1215 {
1216   vat_main_t *vam = &vat_main;
1217   i32 retval = ntohl (mp->retval);
1218   if (vam->async_mode)
1219     {
1220       vam->async_errors += (retval < 0);
1221     }
1222   else
1223     {
1224       vam->retval = retval;
1225       if (retval == 0)
1226         errmsg ("node index %d", ntohl (mp->node_index));
1227       vam->result_ready = 1;
1228     }
1229 }
1230
1231 static void vl_api_get_node_index_reply_t_handler_json
1232   (vl_api_get_node_index_reply_t * mp)
1233 {
1234   vat_main_t *vam = &vat_main;
1235   vat_json_node_t node;
1236
1237   vat_json_init_object (&node);
1238   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1239   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1240
1241   vat_json_print (vam->ofp, &node);
1242   vat_json_free (&node);
1243
1244   vam->retval = ntohl (mp->retval);
1245   vam->result_ready = 1;
1246 }
1247
1248 static void vl_api_get_next_index_reply_t_handler
1249   (vl_api_get_next_index_reply_t * mp)
1250 {
1251   vat_main_t *vam = &vat_main;
1252   i32 retval = ntohl (mp->retval);
1253   if (vam->async_mode)
1254     {
1255       vam->async_errors += (retval < 0);
1256     }
1257   else
1258     {
1259       vam->retval = retval;
1260       if (retval == 0)
1261         errmsg ("next node index %d", ntohl (mp->next_index));
1262       vam->result_ready = 1;
1263     }
1264 }
1265
1266 static void vl_api_get_next_index_reply_t_handler_json
1267   (vl_api_get_next_index_reply_t * mp)
1268 {
1269   vat_main_t *vam = &vat_main;
1270   vat_json_node_t node;
1271
1272   vat_json_init_object (&node);
1273   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1274   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1275
1276   vat_json_print (vam->ofp, &node);
1277   vat_json_free (&node);
1278
1279   vam->retval = ntohl (mp->retval);
1280   vam->result_ready = 1;
1281 }
1282
1283 static void vl_api_add_node_next_reply_t_handler
1284   (vl_api_add_node_next_reply_t * mp)
1285 {
1286   vat_main_t *vam = &vat_main;
1287   i32 retval = ntohl (mp->retval);
1288   if (vam->async_mode)
1289     {
1290       vam->async_errors += (retval < 0);
1291     }
1292   else
1293     {
1294       vam->retval = retval;
1295       if (retval == 0)
1296         errmsg ("next index %d", ntohl (mp->next_index));
1297       vam->result_ready = 1;
1298     }
1299 }
1300
1301 static void vl_api_add_node_next_reply_t_handler_json
1302   (vl_api_add_node_next_reply_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t node;
1306
1307   vat_json_init_object (&node);
1308   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1309   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1310
1311   vat_json_print (vam->ofp, &node);
1312   vat_json_free (&node);
1313
1314   vam->retval = ntohl (mp->retval);
1315   vam->result_ready = 1;
1316 }
1317
1318 static void vl_api_show_version_reply_t_handler
1319   (vl_api_show_version_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323
1324   if (retval >= 0)
1325     {
1326       errmsg ("        program: %s", mp->program);
1327       errmsg ("        version: %s", mp->version);
1328       errmsg ("     build date: %s", mp->build_date);
1329       errmsg ("build directory: %s", mp->build_directory);
1330     }
1331   vam->retval = retval;
1332   vam->result_ready = 1;
1333 }
1334
1335 static void vl_api_show_version_reply_t_handler_json
1336   (vl_api_show_version_reply_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   vat_json_node_t node;
1340
1341   vat_json_init_object (&node);
1342   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1343   vat_json_object_add_string_copy (&node, "program", mp->program);
1344   vat_json_object_add_string_copy (&node, "version", mp->version);
1345   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1346   vat_json_object_add_string_copy (&node, "build_directory",
1347                                    mp->build_directory);
1348
1349   vat_json_print (vam->ofp, &node);
1350   vat_json_free (&node);
1351
1352   vam->retval = ntohl (mp->retval);
1353   vam->result_ready = 1;
1354 }
1355
1356 static void vl_api_show_threads_reply_t_handler
1357   (vl_api_show_threads_reply_t * mp)
1358 {
1359   vat_main_t *vam = &vat_main;
1360   i32 retval = ntohl (mp->retval);
1361   int i, count = 0;
1362
1363   if (retval >= 0)
1364     count = ntohl (mp->count);
1365
1366   for (i = 0; i < count; i++)
1367     print (vam->ofp,
1368            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1369            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1370            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1371            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1372            ntohl (mp->thread_data[i].cpu_socket));
1373
1374   vam->retval = retval;
1375   vam->result_ready = 1;
1376 }
1377
1378 static void vl_api_show_threads_reply_t_handler_json
1379   (vl_api_show_threads_reply_t * mp)
1380 {
1381   vat_main_t *vam = &vat_main;
1382   vat_json_node_t node;
1383   vl_api_thread_data_t *td;
1384   i32 retval = ntohl (mp->retval);
1385   int i, count = 0;
1386
1387   if (retval >= 0)
1388     count = ntohl (mp->count);
1389
1390   vat_json_init_object (&node);
1391   vat_json_object_add_int (&node, "retval", retval);
1392   vat_json_object_add_uint (&node, "count", count);
1393
1394   for (i = 0; i < count; i++)
1395     {
1396       td = &mp->thread_data[i];
1397       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1398       vat_json_object_add_string_copy (&node, "name", td->name);
1399       vat_json_object_add_string_copy (&node, "type", td->type);
1400       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1401       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1402       vat_json_object_add_int (&node, "core", ntohl (td->id));
1403       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1404     }
1405
1406   vat_json_print (vam->ofp, &node);
1407   vat_json_free (&node);
1408
1409   vam->retval = retval;
1410   vam->result_ready = 1;
1411 }
1412
1413 static int
1414 api_show_threads (vat_main_t * vam)
1415 {
1416   vl_api_show_threads_t *mp;
1417   int ret;
1418
1419   print (vam->ofp,
1420          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1421          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1422
1423   M (SHOW_THREADS, mp);
1424
1425   S (mp);
1426   W (ret);
1427   return ret;
1428 }
1429
1430 static void
1431 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1432 {
1433   u32 sw_if_index = ntohl (mp->sw_if_index);
1434   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1435           mp->mac_ip ? "mac/ip binding" : "address resolution",
1436           ntohl (mp->pid), format_ip4_address, mp->ip,
1437           format_vl_api_mac_address, &mp->mac, sw_if_index);
1438 }
1439
1440 static void
1441 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1442 {
1443   /* JSON output not supported */
1444 }
1445
1446 static void
1447 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1448 {
1449   u32 sw_if_index = ntohl (mp->sw_if_index);
1450   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1451           mp->mac_ip ? "mac/ip binding" : "address resolution",
1452           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1453           format_vl_api_mac_address, mp->mac, sw_if_index);
1454 }
1455
1456 static void
1457 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1458 {
1459   /* JSON output not supported */
1460 }
1461
1462 static void
1463 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1464 {
1465   u32 n_macs = ntohl (mp->n_macs);
1466   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1467           ntohl (mp->pid), mp->client_index, n_macs);
1468   int i;
1469   for (i = 0; i < n_macs; i++)
1470     {
1471       vl_api_mac_entry_t *mac = &mp->mac[i];
1472       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1473               i + 1, ntohl (mac->sw_if_index),
1474               format_ethernet_address, mac->mac_addr, mac->action);
1475       if (i == 1000)
1476         break;
1477     }
1478 }
1479
1480 static void
1481 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1482 {
1483   /* JSON output not supported */
1484 }
1485
1486 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1487 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1488
1489 /*
1490  * Special-case: build the bridge domain table, maintain
1491  * the next bd id vbl.
1492  */
1493 static void vl_api_bridge_domain_details_t_handler
1494   (vl_api_bridge_domain_details_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1498   int i;
1499
1500   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1501          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1502
1503   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1504          ntohl (mp->bd_id), mp->learn, mp->forward,
1505          mp->flood, ntohl (mp->bvi_sw_if_index),
1506          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1507
1508   if (n_sw_ifs)
1509     {
1510       vl_api_bridge_domain_sw_if_t *sw_ifs;
1511       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1512              "Interface Name");
1513
1514       sw_ifs = mp->sw_if_details;
1515       for (i = 0; i < n_sw_ifs; i++)
1516         {
1517           u8 *sw_if_name = 0;
1518           u32 sw_if_index;
1519           hash_pair_t *p;
1520
1521           sw_if_index = ntohl (sw_ifs->sw_if_index);
1522
1523           /* *INDENT-OFF* */
1524           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1525                              ({
1526                                if ((u32) p->value[0] == sw_if_index)
1527                                  {
1528                                    sw_if_name = (u8 *)(p->key);
1529                                    break;
1530                                  }
1531                              }));
1532           /* *INDENT-ON* */
1533           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1534                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1535                  "sw_if_index not found!");
1536
1537           sw_ifs++;
1538         }
1539     }
1540 }
1541
1542 static void vl_api_bridge_domain_details_t_handler_json
1543   (vl_api_bridge_domain_details_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t *node, *array = NULL;
1547   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1548
1549   if (VAT_JSON_ARRAY != vam->json_tree.type)
1550     {
1551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1552       vat_json_init_array (&vam->json_tree);
1553     }
1554   node = vat_json_array_add (&vam->json_tree);
1555
1556   vat_json_init_object (node);
1557   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1558   vat_json_object_add_uint (node, "flood", mp->flood);
1559   vat_json_object_add_uint (node, "forward", mp->forward);
1560   vat_json_object_add_uint (node, "learn", mp->learn);
1561   vat_json_object_add_uint (node, "bvi_sw_if_index",
1562                             ntohl (mp->bvi_sw_if_index));
1563   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1564   array = vat_json_object_add (node, "sw_if");
1565   vat_json_init_array (array);
1566
1567
1568
1569   if (n_sw_ifs)
1570     {
1571       vl_api_bridge_domain_sw_if_t *sw_ifs;
1572       int i;
1573
1574       sw_ifs = mp->sw_if_details;
1575       for (i = 0; i < n_sw_ifs; i++)
1576         {
1577           node = vat_json_array_add (array);
1578           vat_json_init_object (node);
1579           vat_json_object_add_uint (node, "sw_if_index",
1580                                     ntohl (sw_ifs->sw_if_index));
1581           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1582           sw_ifs++;
1583         }
1584     }
1585 }
1586
1587 static void vl_api_control_ping_reply_t_handler
1588   (vl_api_control_ping_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->result_ready = 1;
1600     }
1601   if (vam->socket_client_main)
1602     vam->socket_client_main->control_pings_outstanding--;
1603 }
1604
1605 static void vl_api_control_ping_reply_t_handler_json
1606   (vl_api_control_ping_reply_t * mp)
1607 {
1608   vat_main_t *vam = &vat_main;
1609   i32 retval = ntohl (mp->retval);
1610
1611   if (VAT_JSON_NONE != vam->json_tree.type)
1612     {
1613       vat_json_print (vam->ofp, &vam->json_tree);
1614       vat_json_free (&vam->json_tree);
1615       vam->json_tree.type = VAT_JSON_NONE;
1616     }
1617   else
1618     {
1619       /* just print [] */
1620       vat_json_init_array (&vam->json_tree);
1621       vat_json_print (vam->ofp, &vam->json_tree);
1622       vam->json_tree.type = VAT_JSON_NONE;
1623     }
1624
1625   vam->retval = retval;
1626   vam->result_ready = 1;
1627 }
1628
1629 static void
1630   vl_api_bridge_domain_set_mac_age_reply_t_handler
1631   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   i32 retval = ntohl (mp->retval);
1635   if (vam->async_mode)
1636     {
1637       vam->async_errors += (retval < 0);
1638     }
1639   else
1640     {
1641       vam->retval = retval;
1642       vam->result_ready = 1;
1643     }
1644 }
1645
1646 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1647   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1648 {
1649   vat_main_t *vam = &vat_main;
1650   vat_json_node_t node;
1651
1652   vat_json_init_object (&node);
1653   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1654
1655   vat_json_print (vam->ofp, &node);
1656   vat_json_free (&node);
1657
1658   vam->retval = ntohl (mp->retval);
1659   vam->result_ready = 1;
1660 }
1661
1662 static void
1663 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   i32 retval = ntohl (mp->retval);
1667   if (vam->async_mode)
1668     {
1669       vam->async_errors += (retval < 0);
1670     }
1671   else
1672     {
1673       vam->retval = retval;
1674       vam->result_ready = 1;
1675     }
1676 }
1677
1678 static void vl_api_l2_flags_reply_t_handler_json
1679   (vl_api_l2_flags_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   vat_json_node_t node;
1683
1684   vat_json_init_object (&node);
1685   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1686   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1687                             ntohl (mp->resulting_feature_bitmap));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_bridge_flags_reply_t_handler
1697   (vl_api_bridge_flags_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->result_ready = 1;
1709     }
1710 }
1711
1712 static void vl_api_bridge_flags_reply_t_handler_json
1713   (vl_api_bridge_flags_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   vat_json_node_t node;
1717
1718   vat_json_init_object (&node);
1719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1720   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1721                             ntohl (mp->resulting_feature_bitmap));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728 }
1729
1730 static void
1731 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   i32 retval = ntohl (mp->retval);
1735   if (vam->async_mode)
1736     {
1737       vam->async_errors += (retval < 0);
1738     }
1739   else
1740     {
1741       vam->retval = retval;
1742       vam->sw_if_index = ntohl (mp->sw_if_index);
1743       vam->result_ready = 1;
1744     }
1745
1746 }
1747
1748 static void vl_api_tap_create_v2_reply_t_handler_json
1749   (vl_api_tap_create_v2_reply_t * mp)
1750 {
1751   vat_main_t *vam = &vat_main;
1752   vat_json_node_t node;
1753
1754   vat_json_init_object (&node);
1755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1756   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763
1764 }
1765
1766 static void
1767 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1768 {
1769   vat_main_t *vam = &vat_main;
1770   i32 retval = ntohl (mp->retval);
1771   if (vam->async_mode)
1772     {
1773       vam->async_errors += (retval < 0);
1774     }
1775   else
1776     {
1777       vam->retval = retval;
1778       vam->result_ready = 1;
1779     }
1780 }
1781
1782 static void vl_api_tap_delete_v2_reply_t_handler_json
1783   (vl_api_tap_delete_v2_reply_t * mp)
1784 {
1785   vat_main_t *vam = &vat_main;
1786   vat_json_node_t node;
1787
1788   vat_json_init_object (&node);
1789   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void
1799 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1800                                           mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_virtio_pci_create_reply_t_handler_json
1817   (vl_api_virtio_pci_create_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831
1832 }
1833
1834 static void
1835 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1836                                           mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   i32 retval = ntohl (mp->retval);
1840   if (vam->async_mode)
1841     {
1842       vam->async_errors += (retval < 0);
1843     }
1844   else
1845     {
1846       vam->retval = retval;
1847       vam->result_ready = 1;
1848     }
1849 }
1850
1851 static void vl_api_virtio_pci_delete_reply_t_handler_json
1852   (vl_api_virtio_pci_delete_reply_t * mp)
1853 {
1854   vat_main_t *vam = &vat_main;
1855   vat_json_node_t node;
1856
1857   vat_json_init_object (&node);
1858   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1859
1860   vat_json_print (vam->ofp, &node);
1861   vat_json_free (&node);
1862
1863   vam->retval = ntohl (mp->retval);
1864   vam->result_ready = 1;
1865 }
1866
1867 static void
1868 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   i32 retval = ntohl (mp->retval);
1872
1873   if (vam->async_mode)
1874     {
1875       vam->async_errors += (retval < 0);
1876     }
1877   else
1878     {
1879       vam->retval = retval;
1880       vam->sw_if_index = ntohl (mp->sw_if_index);
1881       vam->result_ready = 1;
1882     }
1883 }
1884
1885 static void vl_api_bond_create_reply_t_handler_json
1886   (vl_api_bond_create_reply_t * mp)
1887 {
1888   vat_main_t *vam = &vat_main;
1889   vat_json_node_t node;
1890
1891   vat_json_init_object (&node);
1892   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1893   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1894
1895   vat_json_print (vam->ofp, &node);
1896   vat_json_free (&node);
1897
1898   vam->retval = ntohl (mp->retval);
1899   vam->result_ready = 1;
1900 }
1901
1902 static void
1903 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1904 {
1905   vat_main_t *vam = &vat_main;
1906   i32 retval = ntohl (mp->retval);
1907
1908   if (vam->async_mode)
1909     {
1910       vam->async_errors += (retval < 0);
1911     }
1912   else
1913     {
1914       vam->retval = retval;
1915       vam->result_ready = 1;
1916     }
1917 }
1918
1919 static void vl_api_bond_delete_reply_t_handler_json
1920   (vl_api_bond_delete_reply_t * mp)
1921 {
1922   vat_main_t *vam = &vat_main;
1923   vat_json_node_t node;
1924
1925   vat_json_init_object (&node);
1926   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1927
1928   vat_json_print (vam->ofp, &node);
1929   vat_json_free (&node);
1930
1931   vam->retval = ntohl (mp->retval);
1932   vam->result_ready = 1;
1933 }
1934
1935 static void
1936 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1937 {
1938   vat_main_t *vam = &vat_main;
1939   i32 retval = ntohl (mp->retval);
1940
1941   if (vam->async_mode)
1942     {
1943       vam->async_errors += (retval < 0);
1944     }
1945   else
1946     {
1947       vam->retval = retval;
1948       vam->result_ready = 1;
1949     }
1950 }
1951
1952 static void vl_api_bond_enslave_reply_t_handler_json
1953   (vl_api_bond_enslave_reply_t * mp)
1954 {
1955   vat_main_t *vam = &vat_main;
1956   vat_json_node_t node;
1957
1958   vat_json_init_object (&node);
1959   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1960
1961   vat_json_print (vam->ofp, &node);
1962   vat_json_free (&node);
1963
1964   vam->retval = ntohl (mp->retval);
1965   vam->result_ready = 1;
1966 }
1967
1968 static void
1969 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1970                                           mp)
1971 {
1972   vat_main_t *vam = &vat_main;
1973   i32 retval = ntohl (mp->retval);
1974
1975   if (vam->async_mode)
1976     {
1977       vam->async_errors += (retval < 0);
1978     }
1979   else
1980     {
1981       vam->retval = retval;
1982       vam->result_ready = 1;
1983     }
1984 }
1985
1986 static void vl_api_bond_detach_slave_reply_t_handler_json
1987   (vl_api_bond_detach_slave_reply_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   vat_json_node_t node;
1991
1992   vat_json_init_object (&node);
1993   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1994
1995   vat_json_print (vam->ofp, &node);
1996   vat_json_free (&node);
1997
1998   vam->retval = ntohl (mp->retval);
1999   vam->result_ready = 1;
2000 }
2001
2002 static int
2003 api_sw_interface_set_bond_weight (vat_main_t * vam)
2004 {
2005   unformat_input_t *i = vam->input;
2006   vl_api_sw_interface_set_bond_weight_t *mp;
2007   u32 sw_if_index = ~0;
2008   u32 weight = 0;
2009   u8 weight_enter = 0;
2010   int ret;
2011
2012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2013     {
2014       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2015         ;
2016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2017         ;
2018       else if (unformat (i, "weight %u", &weight))
2019         weight_enter = 1;
2020       else
2021         break;
2022     }
2023
2024   if (sw_if_index == ~0)
2025     {
2026       errmsg ("missing interface name or sw_if_index");
2027       return -99;
2028     }
2029   if (weight_enter == 0)
2030     {
2031       errmsg ("missing valid weight");
2032       return -99;
2033     }
2034
2035   /* Construct the API message */
2036   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2037   mp->sw_if_index = ntohl (sw_if_index);
2038   mp->weight = ntohl (weight);
2039
2040   S (mp);
2041   W (ret);
2042   return ret;
2043 }
2044
2045 static void vl_api_sw_interface_bond_details_t_handler
2046   (vl_api_sw_interface_bond_details_t * mp)
2047 {
2048   vat_main_t *vam = &vat_main;
2049
2050   print (vam->ofp,
2051          "%-16s %-12d %-12U %-13U %-14u %-14u",
2052          mp->interface_name, ntohl (mp->sw_if_index),
2053          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2054          ntohl (mp->active_slaves), ntohl (mp->slaves));
2055 }
2056
2057 static void vl_api_sw_interface_bond_details_t_handler_json
2058   (vl_api_sw_interface_bond_details_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vat_json_node_t *node = NULL;
2062
2063   if (VAT_JSON_ARRAY != vam->json_tree.type)
2064     {
2065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2066       vat_json_init_array (&vam->json_tree);
2067     }
2068   node = vat_json_array_add (&vam->json_tree);
2069
2070   vat_json_init_object (node);
2071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2072   vat_json_object_add_string_copy (node, "interface_name",
2073                                    mp->interface_name);
2074   vat_json_object_add_uint (node, "mode", mp->mode);
2075   vat_json_object_add_uint (node, "load_balance", mp->lb);
2076   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2077   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2078 }
2079
2080 static int
2081 api_sw_interface_bond_dump (vat_main_t * vam)
2082 {
2083   vl_api_sw_interface_bond_dump_t *mp;
2084   vl_api_control_ping_t *mp_ping;
2085   int ret;
2086
2087   print (vam->ofp,
2088          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2089          "interface name", "sw_if_index", "mode", "load balance",
2090          "active slaves", "slaves");
2091
2092   /* Get list of bond interfaces */
2093   M (SW_INTERFACE_BOND_DUMP, mp);
2094   S (mp);
2095
2096   /* Use a control ping for synchronization */
2097   MPING (CONTROL_PING, mp_ping);
2098   S (mp_ping);
2099
2100   W (ret);
2101   return ret;
2102 }
2103
2104 static void vl_api_sw_interface_slave_details_t_handler
2105   (vl_api_sw_interface_slave_details_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108
2109   print (vam->ofp,
2110          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2111          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2112          ntohl (mp->weight), mp->is_local_numa);
2113 }
2114
2115 static void vl_api_sw_interface_slave_details_t_handler_json
2116   (vl_api_sw_interface_slave_details_t * mp)
2117 {
2118   vat_main_t *vam = &vat_main;
2119   vat_json_node_t *node = NULL;
2120
2121   if (VAT_JSON_ARRAY != vam->json_tree.type)
2122     {
2123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2124       vat_json_init_array (&vam->json_tree);
2125     }
2126   node = vat_json_array_add (&vam->json_tree);
2127
2128   vat_json_init_object (node);
2129   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2130   vat_json_object_add_string_copy (node, "interface_name",
2131                                    mp->interface_name);
2132   vat_json_object_add_uint (node, "passive", mp->is_passive);
2133   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2134   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2135   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2136 }
2137
2138 static int
2139 api_sw_interface_slave_dump (vat_main_t * vam)
2140 {
2141   unformat_input_t *i = vam->input;
2142   vl_api_sw_interface_slave_dump_t *mp;
2143   vl_api_control_ping_t *mp_ping;
2144   u32 sw_if_index = ~0;
2145   u8 sw_if_index_set = 0;
2146   int ret;
2147
2148   /* Parse args required to build the message */
2149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2150     {
2151       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2152         sw_if_index_set = 1;
2153       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2154         sw_if_index_set = 1;
2155       else
2156         break;
2157     }
2158
2159   if (sw_if_index_set == 0)
2160     {
2161       errmsg ("missing vpp interface name. ");
2162       return -99;
2163     }
2164
2165   print (vam->ofp,
2166          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2167          "slave interface name", "sw_if_index", "passive", "long_timeout",
2168          "weight", "local numa");
2169
2170   /* Get list of bond interfaces */
2171   M (SW_INTERFACE_SLAVE_DUMP, mp);
2172   mp->sw_if_index = ntohl (sw_if_index);
2173   S (mp);
2174
2175   /* Use a control ping for synchronization */
2176   MPING (CONTROL_PING, mp_ping);
2177   S (mp_ping);
2178
2179   W (ret);
2180   return ret;
2181 }
2182
2183 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2184   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2185 {
2186   vat_main_t *vam = &vat_main;
2187   i32 retval = ntohl (mp->retval);
2188   if (vam->async_mode)
2189     {
2190       vam->async_errors += (retval < 0);
2191     }
2192   else
2193     {
2194       vam->retval = retval;
2195       vam->sw_if_index = ntohl (mp->sw_if_index);
2196       vam->result_ready = 1;
2197     }
2198   vam->regenerate_interface_table = 1;
2199 }
2200
2201 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2202   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2203 {
2204   vat_main_t *vam = &vat_main;
2205   vat_json_node_t node;
2206
2207   vat_json_init_object (&node);
2208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2209   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2210                             ntohl (mp->sw_if_index));
2211
2212   vat_json_print (vam->ofp, &node);
2213   vat_json_free (&node);
2214
2215   vam->retval = ntohl (mp->retval);
2216   vam->result_ready = 1;
2217 }
2218
2219 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2220   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2221 {
2222   vat_main_t *vam = &vat_main;
2223   i32 retval = ntohl (mp->retval);
2224   if (vam->async_mode)
2225     {
2226       vam->async_errors += (retval < 0);
2227     }
2228   else
2229     {
2230       vam->retval = retval;
2231       vam->sw_if_index = ntohl (mp->sw_if_index);
2232       vam->result_ready = 1;
2233     }
2234 }
2235
2236 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2237   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2238 {
2239   vat_main_t *vam = &vat_main;
2240   vat_json_node_t node;
2241
2242   vat_json_init_object (&node);
2243   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2244   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2245
2246   vat_json_print (vam->ofp, &node);
2247   vat_json_free (&node);
2248
2249   vam->retval = ntohl (mp->retval);
2250   vam->result_ready = 1;
2251 }
2252
2253 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2254   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   i32 retval = ntohl (mp->retval);
2258   if (vam->async_mode)
2259     {
2260       vam->async_errors += (retval < 0);
2261     }
2262   else
2263     {
2264       vam->retval = retval;
2265       vam->result_ready = 1;
2266     }
2267 }
2268
2269 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2270   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2271 {
2272   vat_main_t *vam = &vat_main;
2273   vat_json_node_t node;
2274
2275   vat_json_init_object (&node);
2276   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2277   vat_json_object_add_uint (&node, "fwd_entry_index",
2278                             clib_net_to_host_u32 (mp->fwd_entry_index));
2279
2280   vat_json_print (vam->ofp, &node);
2281   vat_json_free (&node);
2282
2283   vam->retval = ntohl (mp->retval);
2284   vam->result_ready = 1;
2285 }
2286
2287 u8 *
2288 format_lisp_transport_protocol (u8 * s, va_list * args)
2289 {
2290   u32 proto = va_arg (*args, u32);
2291
2292   switch (proto)
2293     {
2294     case 1:
2295       return format (s, "udp");
2296     case 2:
2297       return format (s, "api");
2298     default:
2299       return 0;
2300     }
2301   return 0;
2302 }
2303
2304 static void vl_api_one_get_transport_protocol_reply_t_handler
2305   (vl_api_one_get_transport_protocol_reply_t * mp)
2306 {
2307   vat_main_t *vam = &vat_main;
2308   i32 retval = ntohl (mp->retval);
2309   if (vam->async_mode)
2310     {
2311       vam->async_errors += (retval < 0);
2312     }
2313   else
2314     {
2315       u32 proto = mp->protocol;
2316       print (vam->ofp, "Transport protocol: %U",
2317              format_lisp_transport_protocol, proto);
2318       vam->retval = retval;
2319       vam->result_ready = 1;
2320     }
2321 }
2322
2323 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2324   (vl_api_one_get_transport_protocol_reply_t * mp)
2325 {
2326   vat_main_t *vam = &vat_main;
2327   vat_json_node_t node;
2328   u8 *s;
2329
2330   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2331   vec_add1 (s, 0);
2332
2333   vat_json_init_object (&node);
2334   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2335   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2336
2337   vec_free (s);
2338   vat_json_print (vam->ofp, &node);
2339   vat_json_free (&node);
2340
2341   vam->retval = ntohl (mp->retval);
2342   vam->result_ready = 1;
2343 }
2344
2345 static void vl_api_one_add_del_locator_set_reply_t_handler
2346   (vl_api_one_add_del_locator_set_reply_t * mp)
2347 {
2348   vat_main_t *vam = &vat_main;
2349   i32 retval = ntohl (mp->retval);
2350   if (vam->async_mode)
2351     {
2352       vam->async_errors += (retval < 0);
2353     }
2354   else
2355     {
2356       vam->retval = retval;
2357       vam->result_ready = 1;
2358     }
2359 }
2360
2361 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2362   (vl_api_one_add_del_locator_set_reply_t * mp)
2363 {
2364   vat_main_t *vam = &vat_main;
2365   vat_json_node_t node;
2366
2367   vat_json_init_object (&node);
2368   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2369   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2370
2371   vat_json_print (vam->ofp, &node);
2372   vat_json_free (&node);
2373
2374   vam->retval = ntohl (mp->retval);
2375   vam->result_ready = 1;
2376 }
2377
2378 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2379   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2380 {
2381   vat_main_t *vam = &vat_main;
2382   i32 retval = ntohl (mp->retval);
2383   if (vam->async_mode)
2384     {
2385       vam->async_errors += (retval < 0);
2386     }
2387   else
2388     {
2389       vam->retval = retval;
2390       vam->sw_if_index = ntohl (mp->sw_if_index);
2391       vam->result_ready = 1;
2392     }
2393   vam->regenerate_interface_table = 1;
2394 }
2395
2396 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2397   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400   vat_json_node_t node;
2401
2402   vat_json_init_object (&node);
2403   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2404   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2405
2406   vat_json_print (vam->ofp, &node);
2407   vat_json_free (&node);
2408
2409   vam->retval = ntohl (mp->retval);
2410   vam->result_ready = 1;
2411 }
2412
2413 static void vl_api_vxlan_offload_rx_reply_t_handler
2414   (vl_api_vxlan_offload_rx_reply_t * mp)
2415 {
2416   vat_main_t *vam = &vat_main;
2417   i32 retval = ntohl (mp->retval);
2418   if (vam->async_mode)
2419     {
2420       vam->async_errors += (retval < 0);
2421     }
2422   else
2423     {
2424       vam->retval = retval;
2425       vam->result_ready = 1;
2426     }
2427 }
2428
2429 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2430   (vl_api_vxlan_offload_rx_reply_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t node;
2434
2435   vat_json_init_object (&node);
2436   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2437
2438   vat_json_print (vam->ofp, &node);
2439   vat_json_free (&node);
2440
2441   vam->retval = ntohl (mp->retval);
2442   vam->result_ready = 1;
2443 }
2444
2445 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2446   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449   i32 retval = ntohl (mp->retval);
2450   if (vam->async_mode)
2451     {
2452       vam->async_errors += (retval < 0);
2453     }
2454   else
2455     {
2456       vam->retval = retval;
2457       vam->sw_if_index = ntohl (mp->sw_if_index);
2458       vam->result_ready = 1;
2459     }
2460 }
2461
2462 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2463   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2464 {
2465   vat_main_t *vam = &vat_main;
2466   vat_json_node_t node;
2467
2468   vat_json_init_object (&node);
2469   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2470   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2471
2472   vat_json_print (vam->ofp, &node);
2473   vat_json_free (&node);
2474
2475   vam->retval = ntohl (mp->retval);
2476   vam->result_ready = 1;
2477 }
2478
2479 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2480   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2481 {
2482   vat_main_t *vam = &vat_main;
2483   i32 retval = ntohl (mp->retval);
2484   if (vam->async_mode)
2485     {
2486       vam->async_errors += (retval < 0);
2487     }
2488   else
2489     {
2490       vam->retval = retval;
2491       vam->sw_if_index = ntohl (mp->sw_if_index);
2492       vam->result_ready = 1;
2493     }
2494   vam->regenerate_interface_table = 1;
2495 }
2496
2497 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2498   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2499 {
2500   vat_main_t *vam = &vat_main;
2501   vat_json_node_t node;
2502
2503   vat_json_init_object (&node);
2504   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2505   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2506
2507   vat_json_print (vam->ofp, &node);
2508   vat_json_free (&node);
2509
2510   vam->retval = ntohl (mp->retval);
2511   vam->result_ready = 1;
2512 }
2513
2514 static void vl_api_gre_tunnel_add_del_reply_t_handler
2515   (vl_api_gre_tunnel_add_del_reply_t * mp)
2516 {
2517   vat_main_t *vam = &vat_main;
2518   i32 retval = ntohl (mp->retval);
2519   if (vam->async_mode)
2520     {
2521       vam->async_errors += (retval < 0);
2522     }
2523   else
2524     {
2525       vam->retval = retval;
2526       vam->sw_if_index = ntohl (mp->sw_if_index);
2527       vam->result_ready = 1;
2528     }
2529 }
2530
2531 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2532   (vl_api_gre_tunnel_add_del_reply_t * mp)
2533 {
2534   vat_main_t *vam = &vat_main;
2535   vat_json_node_t node;
2536
2537   vat_json_init_object (&node);
2538   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2539   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2540
2541   vat_json_print (vam->ofp, &node);
2542   vat_json_free (&node);
2543
2544   vam->retval = ntohl (mp->retval);
2545   vam->result_ready = 1;
2546 }
2547
2548 static void vl_api_create_vhost_user_if_reply_t_handler
2549   (vl_api_create_vhost_user_if_reply_t * mp)
2550 {
2551   vat_main_t *vam = &vat_main;
2552   i32 retval = ntohl (mp->retval);
2553   if (vam->async_mode)
2554     {
2555       vam->async_errors += (retval < 0);
2556     }
2557   else
2558     {
2559       vam->retval = retval;
2560       vam->sw_if_index = ntohl (mp->sw_if_index);
2561       vam->result_ready = 1;
2562     }
2563   vam->regenerate_interface_table = 1;
2564 }
2565
2566 static void vl_api_create_vhost_user_if_reply_t_handler_json
2567   (vl_api_create_vhost_user_if_reply_t * mp)
2568 {
2569   vat_main_t *vam = &vat_main;
2570   vat_json_node_t node;
2571
2572   vat_json_init_object (&node);
2573   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2574   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2575
2576   vat_json_print (vam->ofp, &node);
2577   vat_json_free (&node);
2578
2579   vam->retval = ntohl (mp->retval);
2580   vam->result_ready = 1;
2581 }
2582
2583 static void vl_api_ip_address_details_t_handler
2584   (vl_api_ip_address_details_t * mp)
2585 {
2586   vat_main_t *vam = &vat_main;
2587   static ip_address_details_t empty_ip_address_details = { {0} };
2588   ip_address_details_t *address = NULL;
2589   ip_details_t *current_ip_details = NULL;
2590   ip_details_t *details = NULL;
2591
2592   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2593
2594   if (!details || vam->current_sw_if_index >= vec_len (details)
2595       || !details[vam->current_sw_if_index].present)
2596     {
2597       errmsg ("ip address details arrived but not stored");
2598       errmsg ("ip_dump should be called first");
2599       return;
2600     }
2601
2602   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2603
2604 #define addresses (current_ip_details->addr)
2605
2606   vec_validate_init_empty (addresses, vec_len (addresses),
2607                            empty_ip_address_details);
2608
2609   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2610
2611   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2612   address->prefix_length = mp->prefix.len;
2613 #undef addresses
2614 }
2615
2616 static void vl_api_ip_address_details_t_handler_json
2617   (vl_api_ip_address_details_t * mp)
2618 {
2619   vat_main_t *vam = &vat_main;
2620   vat_json_node_t *node = NULL;
2621
2622   if (VAT_JSON_ARRAY != vam->json_tree.type)
2623     {
2624       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2625       vat_json_init_array (&vam->json_tree);
2626     }
2627   node = vat_json_array_add (&vam->json_tree);
2628
2629   vat_json_init_object (node);
2630   vat_json_object_add_prefix (node, &mp->prefix);
2631 }
2632
2633 static void
2634 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2635 {
2636   vat_main_t *vam = &vat_main;
2637   static ip_details_t empty_ip_details = { 0 };
2638   ip_details_t *ip = NULL;
2639   u32 sw_if_index = ~0;
2640
2641   sw_if_index = ntohl (mp->sw_if_index);
2642
2643   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2644                            sw_if_index, empty_ip_details);
2645
2646   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2647                          sw_if_index);
2648
2649   ip->present = 1;
2650 }
2651
2652 static void
2653 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2654 {
2655   vat_main_t *vam = &vat_main;
2656
2657   if (VAT_JSON_ARRAY != vam->json_tree.type)
2658     {
2659       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2660       vat_json_init_array (&vam->json_tree);
2661     }
2662   vat_json_array_add_uint (&vam->json_tree,
2663                            clib_net_to_host_u32 (mp->sw_if_index));
2664 }
2665
2666 static void
2667 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2668 {
2669   u8 *s, i;
2670
2671   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2672               "host_mac %U router_addr %U",
2673               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2674               mp->lease.hostname,
2675               format_ip4_address, mp->lease.host_address,
2676               format_ethernet_address, mp->lease.host_mac,
2677               format_ip4_address, mp->lease.router_address);
2678
2679   for (i = 0; i < mp->lease.count; i++)
2680     s =
2681       format (s, " domain_server_addr %U", format_ip4_address,
2682               mp->lease.domain_server[i].address);
2683
2684   errmsg ((char *) s);
2685   vec_free (s);
2686 }
2687
2688 static void vl_api_dhcp_compl_event_t_handler_json
2689   (vl_api_dhcp_compl_event_t * mp)
2690 {
2691   /* JSON output not supported */
2692 }
2693
2694 static void vl_api_get_first_msg_id_reply_t_handler
2695   (vl_api_get_first_msg_id_reply_t * mp)
2696 {
2697   vat_main_t *vam = &vat_main;
2698   i32 retval = ntohl (mp->retval);
2699
2700   if (vam->async_mode)
2701     {
2702       vam->async_errors += (retval < 0);
2703     }
2704   else
2705     {
2706       vam->retval = retval;
2707       vam->result_ready = 1;
2708     }
2709   if (retval >= 0)
2710     {
2711       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2712     }
2713 }
2714
2715 static void vl_api_get_first_msg_id_reply_t_handler_json
2716   (vl_api_get_first_msg_id_reply_t * mp)
2717 {
2718   vat_main_t *vam = &vat_main;
2719   vat_json_node_t node;
2720
2721   vat_json_init_object (&node);
2722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2723   vat_json_object_add_uint (&node, "first_msg_id",
2724                             (uint) ntohs (mp->first_msg_id));
2725
2726   vat_json_print (vam->ofp, &node);
2727   vat_json_free (&node);
2728
2729   vam->retval = ntohl (mp->retval);
2730   vam->result_ready = 1;
2731 }
2732
2733 static void vl_api_get_node_graph_reply_t_handler
2734   (vl_api_get_node_graph_reply_t * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   api_main_t *am = &api_main;
2738   i32 retval = ntohl (mp->retval);
2739   u8 *pvt_copy, *reply;
2740   void *oldheap;
2741   vlib_node_t *node;
2742   int i;
2743
2744   if (vam->async_mode)
2745     {
2746       vam->async_errors += (retval < 0);
2747     }
2748   else
2749     {
2750       vam->retval = retval;
2751       vam->result_ready = 1;
2752     }
2753
2754   /* "Should never happen..." */
2755   if (retval != 0)
2756     return;
2757
2758   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2759   pvt_copy = vec_dup (reply);
2760
2761   /* Toss the shared-memory original... */
2762   pthread_mutex_lock (&am->vlib_rp->mutex);
2763   oldheap = svm_push_data_heap (am->vlib_rp);
2764
2765   vec_free (reply);
2766
2767   svm_pop_heap (oldheap);
2768   pthread_mutex_unlock (&am->vlib_rp->mutex);
2769
2770   if (vam->graph_nodes)
2771     {
2772       hash_free (vam->graph_node_index_by_name);
2773
2774       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2775         {
2776           node = vam->graph_nodes[0][i];
2777           vec_free (node->name);
2778           vec_free (node->next_nodes);
2779           vec_free (node);
2780         }
2781       vec_free (vam->graph_nodes[0]);
2782       vec_free (vam->graph_nodes);
2783     }
2784
2785   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2786   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2787   vec_free (pvt_copy);
2788
2789   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2790     {
2791       node = vam->graph_nodes[0][i];
2792       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2793     }
2794 }
2795
2796 static void vl_api_get_node_graph_reply_t_handler_json
2797   (vl_api_get_node_graph_reply_t * mp)
2798 {
2799   vat_main_t *vam = &vat_main;
2800   api_main_t *am = &api_main;
2801   void *oldheap;
2802   vat_json_node_t node;
2803   u8 *reply;
2804
2805   /* $$$$ make this real? */
2806   vat_json_init_object (&node);
2807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2808   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2809
2810   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2811
2812   /* Toss the shared-memory original... */
2813   pthread_mutex_lock (&am->vlib_rp->mutex);
2814   oldheap = svm_push_data_heap (am->vlib_rp);
2815
2816   vec_free (reply);
2817
2818   svm_pop_heap (oldheap);
2819   pthread_mutex_unlock (&am->vlib_rp->mutex);
2820
2821   vat_json_print (vam->ofp, &node);
2822   vat_json_free (&node);
2823
2824   vam->retval = ntohl (mp->retval);
2825   vam->result_ready = 1;
2826 }
2827
2828 static void
2829 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2830 {
2831   vat_main_t *vam = &vat_main;
2832   u8 *s = 0;
2833
2834   if (mp->local)
2835     {
2836       s = format (s, "%=16d%=16d%=16d",
2837                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2838     }
2839   else
2840     {
2841       s = format (s, "%=16U%=16d%=16d",
2842                   mp->is_ipv6 ? format_ip6_address :
2843                   format_ip4_address,
2844                   mp->ip_address, mp->priority, mp->weight);
2845     }
2846
2847   print (vam->ofp, "%v", s);
2848   vec_free (s);
2849 }
2850
2851 static void
2852 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2853 {
2854   vat_main_t *vam = &vat_main;
2855   vat_json_node_t *node = NULL;
2856   struct in6_addr ip6;
2857   struct in_addr ip4;
2858
2859   if (VAT_JSON_ARRAY != vam->json_tree.type)
2860     {
2861       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2862       vat_json_init_array (&vam->json_tree);
2863     }
2864   node = vat_json_array_add (&vam->json_tree);
2865   vat_json_init_object (node);
2866
2867   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2868   vat_json_object_add_uint (node, "priority", mp->priority);
2869   vat_json_object_add_uint (node, "weight", mp->weight);
2870
2871   if (mp->local)
2872     vat_json_object_add_uint (node, "sw_if_index",
2873                               clib_net_to_host_u32 (mp->sw_if_index));
2874   else
2875     {
2876       if (mp->is_ipv6)
2877         {
2878           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2879           vat_json_object_add_ip6 (node, "address", ip6);
2880         }
2881       else
2882         {
2883           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2884           vat_json_object_add_ip4 (node, "address", ip4);
2885         }
2886     }
2887 }
2888
2889 static void
2890 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2891                                           mp)
2892 {
2893   vat_main_t *vam = &vat_main;
2894   u8 *ls_name = 0;
2895
2896   ls_name = format (0, "%s", mp->ls_name);
2897
2898   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2899          ls_name);
2900   vec_free (ls_name);
2901 }
2902
2903 static void
2904   vl_api_one_locator_set_details_t_handler_json
2905   (vl_api_one_locator_set_details_t * mp)
2906 {
2907   vat_main_t *vam = &vat_main;
2908   vat_json_node_t *node = 0;
2909   u8 *ls_name = 0;
2910
2911   ls_name = format (0, "%s", mp->ls_name);
2912   vec_add1 (ls_name, 0);
2913
2914   if (VAT_JSON_ARRAY != vam->json_tree.type)
2915     {
2916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2917       vat_json_init_array (&vam->json_tree);
2918     }
2919   node = vat_json_array_add (&vam->json_tree);
2920
2921   vat_json_init_object (node);
2922   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2923   vat_json_object_add_uint (node, "ls_index",
2924                             clib_net_to_host_u32 (mp->ls_index));
2925   vec_free (ls_name);
2926 }
2927
2928 typedef struct
2929 {
2930   u32 spi;
2931   u8 si;
2932 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2933
2934 uword
2935 unformat_nsh_address (unformat_input_t * input, va_list * args)
2936 {
2937   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2938   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2939 }
2940
2941 u8 *
2942 format_nsh_address_vat (u8 * s, va_list * args)
2943 {
2944   nsh_t *a = va_arg (*args, nsh_t *);
2945   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2946 }
2947
2948 static u8 *
2949 format_lisp_flat_eid (u8 * s, va_list * args)
2950 {
2951   u32 type = va_arg (*args, u32);
2952   u8 *eid = va_arg (*args, u8 *);
2953   u32 eid_len = va_arg (*args, u32);
2954
2955   switch (type)
2956     {
2957     case 0:
2958       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2959     case 1:
2960       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2961     case 2:
2962       return format (s, "%U", format_ethernet_address, eid);
2963     case 3:
2964       return format (s, "%U", format_nsh_address_vat, eid);
2965     }
2966   return 0;
2967 }
2968
2969 static u8 *
2970 format_lisp_eid_vat (u8 * s, va_list * args)
2971 {
2972   u32 type = va_arg (*args, u32);
2973   u8 *eid = va_arg (*args, u8 *);
2974   u32 eid_len = va_arg (*args, u32);
2975   u8 *seid = va_arg (*args, u8 *);
2976   u32 seid_len = va_arg (*args, u32);
2977   u32 is_src_dst = va_arg (*args, u32);
2978
2979   if (is_src_dst)
2980     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2981
2982   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2983
2984   return s;
2985 }
2986
2987 static void
2988 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2989 {
2990   vat_main_t *vam = &vat_main;
2991   u8 *s = 0, *eid = 0;
2992
2993   if (~0 == mp->locator_set_index)
2994     s = format (0, "action: %d", mp->action);
2995   else
2996     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2997
2998   eid = format (0, "%U", format_lisp_eid_vat,
2999                 mp->eid_type,
3000                 mp->eid,
3001                 mp->eid_prefix_len,
3002                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3003   vec_add1 (eid, 0);
3004
3005   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3006          clib_net_to_host_u32 (mp->vni),
3007          eid,
3008          mp->is_local ? "local" : "remote",
3009          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3010          clib_net_to_host_u16 (mp->key_id), mp->key);
3011
3012   vec_free (s);
3013   vec_free (eid);
3014 }
3015
3016 static void
3017 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3018                                              * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   vat_json_node_t *node = 0;
3022   u8 *eid = 0;
3023
3024   if (VAT_JSON_ARRAY != vam->json_tree.type)
3025     {
3026       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3027       vat_json_init_array (&vam->json_tree);
3028     }
3029   node = vat_json_array_add (&vam->json_tree);
3030
3031   vat_json_init_object (node);
3032   if (~0 == mp->locator_set_index)
3033     vat_json_object_add_uint (node, "action", mp->action);
3034   else
3035     vat_json_object_add_uint (node, "locator_set_index",
3036                               clib_net_to_host_u32 (mp->locator_set_index));
3037
3038   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3039   if (mp->eid_type == 3)
3040     {
3041       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3042       vat_json_init_object (nsh_json);
3043       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3044       vat_json_object_add_uint (nsh_json, "spi",
3045                                 clib_net_to_host_u32 (nsh->spi));
3046       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3047     }
3048   else
3049     {
3050       eid = format (0, "%U", format_lisp_eid_vat,
3051                     mp->eid_type,
3052                     mp->eid,
3053                     mp->eid_prefix_len,
3054                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3055       vec_add1 (eid, 0);
3056       vat_json_object_add_string_copy (node, "eid", eid);
3057       vec_free (eid);
3058     }
3059   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3060   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3061   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3062
3063   if (mp->key_id)
3064     {
3065       vat_json_object_add_uint (node, "key_id",
3066                                 clib_net_to_host_u16 (mp->key_id));
3067       vat_json_object_add_string_copy (node, "key", mp->key);
3068     }
3069 }
3070
3071 static void
3072 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3073 {
3074   vat_main_t *vam = &vat_main;
3075   u8 *seid = 0, *deid = 0;
3076   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3077
3078   deid = format (0, "%U", format_lisp_eid_vat,
3079                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3080
3081   seid = format (0, "%U", format_lisp_eid_vat,
3082                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3083
3084   vec_add1 (deid, 0);
3085   vec_add1 (seid, 0);
3086
3087   if (mp->is_ip4)
3088     format_ip_address_fcn = format_ip4_address;
3089   else
3090     format_ip_address_fcn = format_ip6_address;
3091
3092
3093   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3094          clib_net_to_host_u32 (mp->vni),
3095          seid, deid,
3096          format_ip_address_fcn, mp->lloc,
3097          format_ip_address_fcn, mp->rloc,
3098          clib_net_to_host_u32 (mp->pkt_count),
3099          clib_net_to_host_u32 (mp->bytes));
3100
3101   vec_free (deid);
3102   vec_free (seid);
3103 }
3104
3105 static void
3106 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3107 {
3108   struct in6_addr ip6;
3109   struct in_addr ip4;
3110   vat_main_t *vam = &vat_main;
3111   vat_json_node_t *node = 0;
3112   u8 *deid = 0, *seid = 0;
3113
3114   if (VAT_JSON_ARRAY != vam->json_tree.type)
3115     {
3116       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3117       vat_json_init_array (&vam->json_tree);
3118     }
3119   node = vat_json_array_add (&vam->json_tree);
3120
3121   vat_json_init_object (node);
3122   deid = format (0, "%U", format_lisp_eid_vat,
3123                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3124
3125   seid = format (0, "%U", format_lisp_eid_vat,
3126                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3127
3128   vec_add1 (deid, 0);
3129   vec_add1 (seid, 0);
3130
3131   vat_json_object_add_string_copy (node, "seid", seid);
3132   vat_json_object_add_string_copy (node, "deid", deid);
3133   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3134
3135   if (mp->is_ip4)
3136     {
3137       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3138       vat_json_object_add_ip4 (node, "lloc", ip4);
3139       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3140       vat_json_object_add_ip4 (node, "rloc", ip4);
3141     }
3142   else
3143     {
3144       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3145       vat_json_object_add_ip6 (node, "lloc", ip6);
3146       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3147       vat_json_object_add_ip6 (node, "rloc", ip6);
3148     }
3149   vat_json_object_add_uint (node, "pkt_count",
3150                             clib_net_to_host_u32 (mp->pkt_count));
3151   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3152
3153   vec_free (deid);
3154   vec_free (seid);
3155 }
3156
3157 static void
3158   vl_api_one_eid_table_map_details_t_handler
3159   (vl_api_one_eid_table_map_details_t * mp)
3160 {
3161   vat_main_t *vam = &vat_main;
3162
3163   u8 *line = format (0, "%=10d%=10d",
3164                      clib_net_to_host_u32 (mp->vni),
3165                      clib_net_to_host_u32 (mp->dp_table));
3166   print (vam->ofp, "%v", line);
3167   vec_free (line);
3168 }
3169
3170 static void
3171   vl_api_one_eid_table_map_details_t_handler_json
3172   (vl_api_one_eid_table_map_details_t * mp)
3173 {
3174   vat_main_t *vam = &vat_main;
3175   vat_json_node_t *node = NULL;
3176
3177   if (VAT_JSON_ARRAY != vam->json_tree.type)
3178     {
3179       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3180       vat_json_init_array (&vam->json_tree);
3181     }
3182   node = vat_json_array_add (&vam->json_tree);
3183   vat_json_init_object (node);
3184   vat_json_object_add_uint (node, "dp_table",
3185                             clib_net_to_host_u32 (mp->dp_table));
3186   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3187 }
3188
3189 static void
3190   vl_api_one_eid_table_vni_details_t_handler
3191   (vl_api_one_eid_table_vni_details_t * mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194
3195   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3196   print (vam->ofp, "%v", line);
3197   vec_free (line);
3198 }
3199
3200 static void
3201   vl_api_one_eid_table_vni_details_t_handler_json
3202   (vl_api_one_eid_table_vni_details_t * mp)
3203 {
3204   vat_main_t *vam = &vat_main;
3205   vat_json_node_t *node = NULL;
3206
3207   if (VAT_JSON_ARRAY != vam->json_tree.type)
3208     {
3209       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3210       vat_json_init_array (&vam->json_tree);
3211     }
3212   node = vat_json_array_add (&vam->json_tree);
3213   vat_json_init_object (node);
3214   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3215 }
3216
3217 static void
3218   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3219   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222   int retval = clib_net_to_host_u32 (mp->retval);
3223
3224   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3225   print (vam->ofp, "fallback threshold value: %d", mp->value);
3226
3227   vam->retval = retval;
3228   vam->result_ready = 1;
3229 }
3230
3231 static void
3232   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3233   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3234 {
3235   vat_main_t *vam = &vat_main;
3236   vat_json_node_t _node, *node = &_node;
3237   int retval = clib_net_to_host_u32 (mp->retval);
3238
3239   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3240   vat_json_init_object (node);
3241   vat_json_object_add_uint (node, "value", mp->value);
3242
3243   vat_json_print (vam->ofp, node);
3244   vat_json_free (node);
3245
3246   vam->retval = retval;
3247   vam->result_ready = 1;
3248 }
3249
3250 static void
3251   vl_api_show_one_map_register_state_reply_t_handler
3252   (vl_api_show_one_map_register_state_reply_t * mp)
3253 {
3254   vat_main_t *vam = &vat_main;
3255   int retval = clib_net_to_host_u32 (mp->retval);
3256
3257   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3258
3259   vam->retval = retval;
3260   vam->result_ready = 1;
3261 }
3262
3263 static void
3264   vl_api_show_one_map_register_state_reply_t_handler_json
3265   (vl_api_show_one_map_register_state_reply_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268   vat_json_node_t _node, *node = &_node;
3269   int retval = clib_net_to_host_u32 (mp->retval);
3270
3271   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3272
3273   vat_json_init_object (node);
3274   vat_json_object_add_string_copy (node, "state", s);
3275
3276   vat_json_print (vam->ofp, node);
3277   vat_json_free (node);
3278
3279   vam->retval = retval;
3280   vam->result_ready = 1;
3281   vec_free (s);
3282 }
3283
3284 static void
3285   vl_api_show_one_rloc_probe_state_reply_t_handler
3286   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3287 {
3288   vat_main_t *vam = &vat_main;
3289   int retval = clib_net_to_host_u32 (mp->retval);
3290
3291   if (retval)
3292     goto end;
3293
3294   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3295 end:
3296   vam->retval = retval;
3297   vam->result_ready = 1;
3298 }
3299
3300 static void
3301   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3302   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305   vat_json_node_t _node, *node = &_node;
3306   int retval = clib_net_to_host_u32 (mp->retval);
3307
3308   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3309   vat_json_init_object (node);
3310   vat_json_object_add_string_copy (node, "state", s);
3311
3312   vat_json_print (vam->ofp, node);
3313   vat_json_free (node);
3314
3315   vam->retval = retval;
3316   vam->result_ready = 1;
3317   vec_free (s);
3318 }
3319
3320 static void
3321   vl_api_show_one_stats_enable_disable_reply_t_handler
3322   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3323 {
3324   vat_main_t *vam = &vat_main;
3325   int retval = clib_net_to_host_u32 (mp->retval);
3326
3327   if (retval)
3328     goto end;
3329
3330   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3331 end:
3332   vam->retval = retval;
3333   vam->result_ready = 1;
3334 }
3335
3336 static void
3337   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3338   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   vat_json_node_t _node, *node = &_node;
3342   int retval = clib_net_to_host_u32 (mp->retval);
3343
3344   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3345   vat_json_init_object (node);
3346   vat_json_object_add_string_copy (node, "state", s);
3347
3348   vat_json_print (vam->ofp, node);
3349   vat_json_free (node);
3350
3351   vam->retval = retval;
3352   vam->result_ready = 1;
3353   vec_free (s);
3354 }
3355
3356 static void
3357 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3358 {
3359   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3360   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3361   e->vni = clib_net_to_host_u32 (e->vni);
3362 }
3363
3364 static void
3365   gpe_fwd_entries_get_reply_t_net_to_host
3366   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3367 {
3368   u32 i;
3369
3370   mp->count = clib_net_to_host_u32 (mp->count);
3371   for (i = 0; i < mp->count; i++)
3372     {
3373       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3374     }
3375 }
3376
3377 static u8 *
3378 format_gpe_encap_mode (u8 * s, va_list * args)
3379 {
3380   u32 mode = va_arg (*args, u32);
3381
3382   switch (mode)
3383     {
3384     case 0:
3385       return format (s, "lisp");
3386     case 1:
3387       return format (s, "vxlan");
3388     }
3389   return 0;
3390 }
3391
3392 static void
3393   vl_api_gpe_get_encap_mode_reply_t_handler
3394   (vl_api_gpe_get_encap_mode_reply_t * mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397
3398   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3399   vam->retval = ntohl (mp->retval);
3400   vam->result_ready = 1;
3401 }
3402
3403 static void
3404   vl_api_gpe_get_encap_mode_reply_t_handler_json
3405   (vl_api_gpe_get_encap_mode_reply_t * mp)
3406 {
3407   vat_main_t *vam = &vat_main;
3408   vat_json_node_t node;
3409
3410   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3411   vec_add1 (encap_mode, 0);
3412
3413   vat_json_init_object (&node);
3414   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3415
3416   vec_free (encap_mode);
3417   vat_json_print (vam->ofp, &node);
3418   vat_json_free (&node);
3419
3420   vam->retval = ntohl (mp->retval);
3421   vam->result_ready = 1;
3422 }
3423
3424 static void
3425   vl_api_gpe_fwd_entry_path_details_t_handler
3426   (vl_api_gpe_fwd_entry_path_details_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3430
3431   if (mp->lcl_loc.is_ip4)
3432     format_ip_address_fcn = format_ip4_address;
3433   else
3434     format_ip_address_fcn = format_ip6_address;
3435
3436   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3437          format_ip_address_fcn, &mp->lcl_loc,
3438          format_ip_address_fcn, &mp->rmt_loc);
3439 }
3440
3441 static void
3442 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3443 {
3444   struct in6_addr ip6;
3445   struct in_addr ip4;
3446
3447   if (loc->is_ip4)
3448     {
3449       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3450       vat_json_object_add_ip4 (n, "address", ip4);
3451     }
3452   else
3453     {
3454       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3455       vat_json_object_add_ip6 (n, "address", ip6);
3456     }
3457   vat_json_object_add_uint (n, "weight", loc->weight);
3458 }
3459
3460 static void
3461   vl_api_gpe_fwd_entry_path_details_t_handler_json
3462   (vl_api_gpe_fwd_entry_path_details_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465   vat_json_node_t *node = NULL;
3466   vat_json_node_t *loc_node;
3467
3468   if (VAT_JSON_ARRAY != vam->json_tree.type)
3469     {
3470       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3471       vat_json_init_array (&vam->json_tree);
3472     }
3473   node = vat_json_array_add (&vam->json_tree);
3474   vat_json_init_object (node);
3475
3476   loc_node = vat_json_object_add (node, "local_locator");
3477   vat_json_init_object (loc_node);
3478   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3479
3480   loc_node = vat_json_object_add (node, "remote_locator");
3481   vat_json_init_object (loc_node);
3482   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3483 }
3484
3485 static void
3486   vl_api_gpe_fwd_entries_get_reply_t_handler
3487   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3488 {
3489   vat_main_t *vam = &vat_main;
3490   u32 i;
3491   int retval = clib_net_to_host_u32 (mp->retval);
3492   vl_api_gpe_fwd_entry_t *e;
3493
3494   if (retval)
3495     goto end;
3496
3497   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3498
3499   for (i = 0; i < mp->count; i++)
3500     {
3501       e = &mp->entries[i];
3502       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3503              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3504              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3505     }
3506
3507 end:
3508   vam->retval = retval;
3509   vam->result_ready = 1;
3510 }
3511
3512 static void
3513   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3514   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3515 {
3516   u8 *s = 0;
3517   vat_main_t *vam = &vat_main;
3518   vat_json_node_t *e = 0, root;
3519   u32 i;
3520   int retval = clib_net_to_host_u32 (mp->retval);
3521   vl_api_gpe_fwd_entry_t *fwd;
3522
3523   if (retval)
3524     goto end;
3525
3526   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3527   vat_json_init_array (&root);
3528
3529   for (i = 0; i < mp->count; i++)
3530     {
3531       e = vat_json_array_add (&root);
3532       fwd = &mp->entries[i];
3533
3534       vat_json_init_object (e);
3535       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3536       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3537       vat_json_object_add_int (e, "vni", fwd->vni);
3538       vat_json_object_add_int (e, "action", fwd->action);
3539
3540       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3541                   fwd->leid_prefix_len);
3542       vec_add1 (s, 0);
3543       vat_json_object_add_string_copy (e, "leid", s);
3544       vec_free (s);
3545
3546       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3547                   fwd->reid_prefix_len);
3548       vec_add1 (s, 0);
3549       vat_json_object_add_string_copy (e, "reid", s);
3550       vec_free (s);
3551     }
3552
3553   vat_json_print (vam->ofp, &root);
3554   vat_json_free (&root);
3555
3556 end:
3557   vam->retval = retval;
3558   vam->result_ready = 1;
3559 }
3560
3561 static void
3562   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3563   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3564 {
3565   vat_main_t *vam = &vat_main;
3566   u32 i, n;
3567   int retval = clib_net_to_host_u32 (mp->retval);
3568   vl_api_gpe_native_fwd_rpath_t *r;
3569
3570   if (retval)
3571     goto end;
3572
3573   n = clib_net_to_host_u32 (mp->count);
3574
3575   for (i = 0; i < n; i++)
3576     {
3577       r = &mp->entries[i];
3578       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3579              clib_net_to_host_u32 (r->fib_index),
3580              clib_net_to_host_u32 (r->nh_sw_if_index),
3581              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3582     }
3583
3584 end:
3585   vam->retval = retval;
3586   vam->result_ready = 1;
3587 }
3588
3589 static void
3590   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3591   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3592 {
3593   vat_main_t *vam = &vat_main;
3594   vat_json_node_t root, *e;
3595   u32 i, n;
3596   int retval = clib_net_to_host_u32 (mp->retval);
3597   vl_api_gpe_native_fwd_rpath_t *r;
3598   u8 *s;
3599
3600   if (retval)
3601     goto end;
3602
3603   n = clib_net_to_host_u32 (mp->count);
3604   vat_json_init_array (&root);
3605
3606   for (i = 0; i < n; i++)
3607     {
3608       e = vat_json_array_add (&root);
3609       vat_json_init_object (e);
3610       r = &mp->entries[i];
3611       s =
3612         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3613                 r->nh_addr);
3614       vec_add1 (s, 0);
3615       vat_json_object_add_string_copy (e, "ip4", s);
3616       vec_free (s);
3617
3618       vat_json_object_add_uint (e, "fib_index",
3619                                 clib_net_to_host_u32 (r->fib_index));
3620       vat_json_object_add_uint (e, "nh_sw_if_index",
3621                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3622     }
3623
3624   vat_json_print (vam->ofp, &root);
3625   vat_json_free (&root);
3626
3627 end:
3628   vam->retval = retval;
3629   vam->result_ready = 1;
3630 }
3631
3632 static void
3633   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3634   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3635 {
3636   vat_main_t *vam = &vat_main;
3637   u32 i, n;
3638   int retval = clib_net_to_host_u32 (mp->retval);
3639
3640   if (retval)
3641     goto end;
3642
3643   n = clib_net_to_host_u32 (mp->count);
3644
3645   for (i = 0; i < n; i++)
3646     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3647
3648 end:
3649   vam->retval = retval;
3650   vam->result_ready = 1;
3651 }
3652
3653 static void
3654   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3655   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3656 {
3657   vat_main_t *vam = &vat_main;
3658   vat_json_node_t root;
3659   u32 i, n;
3660   int retval = clib_net_to_host_u32 (mp->retval);
3661
3662   if (retval)
3663     goto end;
3664
3665   n = clib_net_to_host_u32 (mp->count);
3666   vat_json_init_array (&root);
3667
3668   for (i = 0; i < n; i++)
3669     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3670
3671   vat_json_print (vam->ofp, &root);
3672   vat_json_free (&root);
3673
3674 end:
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_one_ndp_entries_get_reply_t_handler
3681   (vl_api_one_ndp_entries_get_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686
3687   if (retval)
3688     goto end;
3689
3690   n = clib_net_to_host_u32 (mp->count);
3691
3692   for (i = 0; i < n; i++)
3693     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3694            format_ethernet_address, mp->entries[i].mac);
3695
3696 end:
3697   vam->retval = retval;
3698   vam->result_ready = 1;
3699 }
3700
3701 static void
3702   vl_api_one_ndp_entries_get_reply_t_handler_json
3703   (vl_api_one_ndp_entries_get_reply_t * mp)
3704 {
3705   u8 *s = 0;
3706   vat_main_t *vam = &vat_main;
3707   vat_json_node_t *e = 0, root;
3708   u32 i, n;
3709   int retval = clib_net_to_host_u32 (mp->retval);
3710   vl_api_one_ndp_entry_t *arp_entry;
3711
3712   if (retval)
3713     goto end;
3714
3715   n = clib_net_to_host_u32 (mp->count);
3716   vat_json_init_array (&root);
3717
3718   for (i = 0; i < n; i++)
3719     {
3720       e = vat_json_array_add (&root);
3721       arp_entry = &mp->entries[i];
3722
3723       vat_json_init_object (e);
3724       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3725       vec_add1 (s, 0);
3726
3727       vat_json_object_add_string_copy (e, "mac", s);
3728       vec_free (s);
3729
3730       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3731       vec_add1 (s, 0);
3732       vat_json_object_add_string_copy (e, "ip6", s);
3733       vec_free (s);
3734     }
3735
3736   vat_json_print (vam->ofp, &root);
3737   vat_json_free (&root);
3738
3739 end:
3740   vam->retval = retval;
3741   vam->result_ready = 1;
3742 }
3743
3744 static void
3745   vl_api_one_l2_arp_entries_get_reply_t_handler
3746   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3747 {
3748   vat_main_t *vam = &vat_main;
3749   u32 i, n;
3750   int retval = clib_net_to_host_u32 (mp->retval);
3751
3752   if (retval)
3753     goto end;
3754
3755   n = clib_net_to_host_u32 (mp->count);
3756
3757   for (i = 0; i < n; i++)
3758     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3759            format_ethernet_address, mp->entries[i].mac);
3760
3761 end:
3762   vam->retval = retval;
3763   vam->result_ready = 1;
3764 }
3765
3766 static void
3767   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3768   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3769 {
3770   u8 *s = 0;
3771   vat_main_t *vam = &vat_main;
3772   vat_json_node_t *e = 0, root;
3773   u32 i, n;
3774   int retval = clib_net_to_host_u32 (mp->retval);
3775   vl_api_one_l2_arp_entry_t *arp_entry;
3776
3777   if (retval)
3778     goto end;
3779
3780   n = clib_net_to_host_u32 (mp->count);
3781   vat_json_init_array (&root);
3782
3783   for (i = 0; i < n; i++)
3784     {
3785       e = vat_json_array_add (&root);
3786       arp_entry = &mp->entries[i];
3787
3788       vat_json_init_object (e);
3789       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3790       vec_add1 (s, 0);
3791
3792       vat_json_object_add_string_copy (e, "mac", s);
3793       vec_free (s);
3794
3795       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3796       vec_add1 (s, 0);
3797       vat_json_object_add_string_copy (e, "ip4", s);
3798       vec_free (s);
3799     }
3800
3801   vat_json_print (vam->ofp, &root);
3802   vat_json_free (&root);
3803
3804 end:
3805   vam->retval = retval;
3806   vam->result_ready = 1;
3807 }
3808
3809 static void
3810 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3811 {
3812   vat_main_t *vam = &vat_main;
3813   u32 i, n;
3814   int retval = clib_net_to_host_u32 (mp->retval);
3815
3816   if (retval)
3817     goto end;
3818
3819   n = clib_net_to_host_u32 (mp->count);
3820
3821   for (i = 0; i < n; i++)
3822     {
3823       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3824     }
3825
3826 end:
3827   vam->retval = retval;
3828   vam->result_ready = 1;
3829 }
3830
3831 static void
3832   vl_api_one_ndp_bd_get_reply_t_handler_json
3833   (vl_api_one_ndp_bd_get_reply_t * mp)
3834 {
3835   vat_main_t *vam = &vat_main;
3836   vat_json_node_t root;
3837   u32 i, n;
3838   int retval = clib_net_to_host_u32 (mp->retval);
3839
3840   if (retval)
3841     goto end;
3842
3843   n = clib_net_to_host_u32 (mp->count);
3844   vat_json_init_array (&root);
3845
3846   for (i = 0; i < n; i++)
3847     {
3848       vat_json_array_add_uint (&root,
3849                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3850     }
3851
3852   vat_json_print (vam->ofp, &root);
3853   vat_json_free (&root);
3854
3855 end:
3856   vam->retval = retval;
3857   vam->result_ready = 1;
3858 }
3859
3860 static void
3861   vl_api_one_l2_arp_bd_get_reply_t_handler
3862   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3863 {
3864   vat_main_t *vam = &vat_main;
3865   u32 i, n;
3866   int retval = clib_net_to_host_u32 (mp->retval);
3867
3868   if (retval)
3869     goto end;
3870
3871   n = clib_net_to_host_u32 (mp->count);
3872
3873   for (i = 0; i < n; i++)
3874     {
3875       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3876     }
3877
3878 end:
3879   vam->retval = retval;
3880   vam->result_ready = 1;
3881 }
3882
3883 static void
3884   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3885   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3886 {
3887   vat_main_t *vam = &vat_main;
3888   vat_json_node_t root;
3889   u32 i, n;
3890   int retval = clib_net_to_host_u32 (mp->retval);
3891
3892   if (retval)
3893     goto end;
3894
3895   n = clib_net_to_host_u32 (mp->count);
3896   vat_json_init_array (&root);
3897
3898   for (i = 0; i < n; i++)
3899     {
3900       vat_json_array_add_uint (&root,
3901                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3902     }
3903
3904   vat_json_print (vam->ofp, &root);
3905   vat_json_free (&root);
3906
3907 end:
3908   vam->retval = retval;
3909   vam->result_ready = 1;
3910 }
3911
3912 static void
3913   vl_api_one_adjacencies_get_reply_t_handler
3914   (vl_api_one_adjacencies_get_reply_t * mp)
3915 {
3916   vat_main_t *vam = &vat_main;
3917   u32 i, n;
3918   int retval = clib_net_to_host_u32 (mp->retval);
3919   vl_api_one_adjacency_t *a;
3920
3921   if (retval)
3922     goto end;
3923
3924   n = clib_net_to_host_u32 (mp->count);
3925
3926   for (i = 0; i < n; i++)
3927     {
3928       a = &mp->adjacencies[i];
3929       print (vam->ofp, "%U %40U",
3930              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3931              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3932     }
3933
3934 end:
3935   vam->retval = retval;
3936   vam->result_ready = 1;
3937 }
3938
3939 static void
3940   vl_api_one_adjacencies_get_reply_t_handler_json
3941   (vl_api_one_adjacencies_get_reply_t * mp)
3942 {
3943   u8 *s = 0;
3944   vat_main_t *vam = &vat_main;
3945   vat_json_node_t *e = 0, root;
3946   u32 i, n;
3947   int retval = clib_net_to_host_u32 (mp->retval);
3948   vl_api_one_adjacency_t *a;
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       e = vat_json_array_add (&root);
3959       a = &mp->adjacencies[i];
3960
3961       vat_json_init_object (e);
3962       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3963                   a->leid_prefix_len);
3964       vec_add1 (s, 0);
3965       vat_json_object_add_string_copy (e, "leid", s);
3966       vec_free (s);
3967
3968       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3969                   a->reid_prefix_len);
3970       vec_add1 (s, 0);
3971       vat_json_object_add_string_copy (e, "reid", s);
3972       vec_free (s);
3973     }
3974
3975   vat_json_print (vam->ofp, &root);
3976   vat_json_free (&root);
3977
3978 end:
3979   vam->retval = retval;
3980   vam->result_ready = 1;
3981 }
3982
3983 static void
3984 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3985 {
3986   vat_main_t *vam = &vat_main;
3987
3988   print (vam->ofp, "%=20U",
3989          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3990          mp->ip_address);
3991 }
3992
3993 static void
3994   vl_api_one_map_server_details_t_handler_json
3995   (vl_api_one_map_server_details_t * mp)
3996 {
3997   vat_main_t *vam = &vat_main;
3998   vat_json_node_t *node = NULL;
3999   struct in6_addr ip6;
4000   struct in_addr ip4;
4001
4002   if (VAT_JSON_ARRAY != vam->json_tree.type)
4003     {
4004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4005       vat_json_init_array (&vam->json_tree);
4006     }
4007   node = vat_json_array_add (&vam->json_tree);
4008
4009   vat_json_init_object (node);
4010   if (mp->is_ipv6)
4011     {
4012       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4013       vat_json_object_add_ip6 (node, "map-server", ip6);
4014     }
4015   else
4016     {
4017       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4018       vat_json_object_add_ip4 (node, "map-server", ip4);
4019     }
4020 }
4021
4022 static void
4023 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4024                                            * mp)
4025 {
4026   vat_main_t *vam = &vat_main;
4027
4028   print (vam->ofp, "%=20U",
4029          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4030          mp->ip_address);
4031 }
4032
4033 static void
4034   vl_api_one_map_resolver_details_t_handler_json
4035   (vl_api_one_map_resolver_details_t * mp)
4036 {
4037   vat_main_t *vam = &vat_main;
4038   vat_json_node_t *node = NULL;
4039   struct in6_addr ip6;
4040   struct in_addr ip4;
4041
4042   if (VAT_JSON_ARRAY != vam->json_tree.type)
4043     {
4044       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4045       vat_json_init_array (&vam->json_tree);
4046     }
4047   node = vat_json_array_add (&vam->json_tree);
4048
4049   vat_json_init_object (node);
4050   if (mp->is_ipv6)
4051     {
4052       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4053       vat_json_object_add_ip6 (node, "map resolver", ip6);
4054     }
4055   else
4056     {
4057       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4058       vat_json_object_add_ip4 (node, "map resolver", ip4);
4059     }
4060 }
4061
4062 static void
4063 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4064 {
4065   vat_main_t *vam = &vat_main;
4066   i32 retval = ntohl (mp->retval);
4067
4068   if (0 <= retval)
4069     {
4070       print (vam->ofp, "feature: %s\ngpe: %s",
4071              mp->feature_status ? "enabled" : "disabled",
4072              mp->gpe_status ? "enabled" : "disabled");
4073     }
4074
4075   vam->retval = retval;
4076   vam->result_ready = 1;
4077 }
4078
4079 static void
4080   vl_api_show_one_status_reply_t_handler_json
4081   (vl_api_show_one_status_reply_t * mp)
4082 {
4083   vat_main_t *vam = &vat_main;
4084   vat_json_node_t node;
4085   u8 *gpe_status = NULL;
4086   u8 *feature_status = NULL;
4087
4088   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4089   feature_status = format (0, "%s",
4090                            mp->feature_status ? "enabled" : "disabled");
4091   vec_add1 (gpe_status, 0);
4092   vec_add1 (feature_status, 0);
4093
4094   vat_json_init_object (&node);
4095   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4096   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4097
4098   vec_free (gpe_status);
4099   vec_free (feature_status);
4100
4101   vat_json_print (vam->ofp, &node);
4102   vat_json_free (&node);
4103
4104   vam->retval = ntohl (mp->retval);
4105   vam->result_ready = 1;
4106 }
4107
4108 static void
4109   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4110   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4111 {
4112   vat_main_t *vam = &vat_main;
4113   i32 retval = ntohl (mp->retval);
4114
4115   if (retval >= 0)
4116     {
4117       print (vam->ofp, "%=20s", mp->locator_set_name);
4118     }
4119
4120   vam->retval = retval;
4121   vam->result_ready = 1;
4122 }
4123
4124 static void
4125   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4126   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4127 {
4128   vat_main_t *vam = &vat_main;
4129   vat_json_node_t *node = NULL;
4130
4131   if (VAT_JSON_ARRAY != vam->json_tree.type)
4132     {
4133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4134       vat_json_init_array (&vam->json_tree);
4135     }
4136   node = vat_json_array_add (&vam->json_tree);
4137
4138   vat_json_init_object (node);
4139   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4140
4141   vat_json_print (vam->ofp, node);
4142   vat_json_free (node);
4143
4144   vam->retval = ntohl (mp->retval);
4145   vam->result_ready = 1;
4146 }
4147
4148 static u8 *
4149 format_lisp_map_request_mode (u8 * s, va_list * args)
4150 {
4151   u32 mode = va_arg (*args, u32);
4152
4153   switch (mode)
4154     {
4155     case 0:
4156       return format (0, "dst-only");
4157     case 1:
4158       return format (0, "src-dst");
4159     }
4160   return 0;
4161 }
4162
4163 static void
4164   vl_api_show_one_map_request_mode_reply_t_handler
4165   (vl_api_show_one_map_request_mode_reply_t * mp)
4166 {
4167   vat_main_t *vam = &vat_main;
4168   i32 retval = ntohl (mp->retval);
4169
4170   if (0 <= retval)
4171     {
4172       u32 mode = mp->mode;
4173       print (vam->ofp, "map_request_mode: %U",
4174              format_lisp_map_request_mode, mode);
4175     }
4176
4177   vam->retval = retval;
4178   vam->result_ready = 1;
4179 }
4180
4181 static void
4182   vl_api_show_one_map_request_mode_reply_t_handler_json
4183   (vl_api_show_one_map_request_mode_reply_t * mp)
4184 {
4185   vat_main_t *vam = &vat_main;
4186   vat_json_node_t node;
4187   u8 *s = 0;
4188   u32 mode;
4189
4190   mode = mp->mode;
4191   s = format (0, "%U", format_lisp_map_request_mode, mode);
4192   vec_add1 (s, 0);
4193
4194   vat_json_init_object (&node);
4195   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4196   vat_json_print (vam->ofp, &node);
4197   vat_json_free (&node);
4198
4199   vec_free (s);
4200   vam->retval = ntohl (mp->retval);
4201   vam->result_ready = 1;
4202 }
4203
4204 static void
4205   vl_api_one_show_xtr_mode_reply_t_handler
4206   (vl_api_one_show_xtr_mode_reply_t * mp)
4207 {
4208   vat_main_t *vam = &vat_main;
4209   i32 retval = ntohl (mp->retval);
4210
4211   if (0 <= retval)
4212     {
4213       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4214     }
4215
4216   vam->retval = retval;
4217   vam->result_ready = 1;
4218 }
4219
4220 static void
4221   vl_api_one_show_xtr_mode_reply_t_handler_json
4222   (vl_api_one_show_xtr_mode_reply_t * mp)
4223 {
4224   vat_main_t *vam = &vat_main;
4225   vat_json_node_t node;
4226   u8 *status = 0;
4227
4228   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4229   vec_add1 (status, 0);
4230
4231   vat_json_init_object (&node);
4232   vat_json_object_add_string_copy (&node, "status", status);
4233
4234   vec_free (status);
4235
4236   vat_json_print (vam->ofp, &node);
4237   vat_json_free (&node);
4238
4239   vam->retval = ntohl (mp->retval);
4240   vam->result_ready = 1;
4241 }
4242
4243 static void
4244   vl_api_one_show_pitr_mode_reply_t_handler
4245   (vl_api_one_show_pitr_mode_reply_t * mp)
4246 {
4247   vat_main_t *vam = &vat_main;
4248   i32 retval = ntohl (mp->retval);
4249
4250   if (0 <= retval)
4251     {
4252       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4253     }
4254
4255   vam->retval = retval;
4256   vam->result_ready = 1;
4257 }
4258
4259 static void
4260   vl_api_one_show_pitr_mode_reply_t_handler_json
4261   (vl_api_one_show_pitr_mode_reply_t * mp)
4262 {
4263   vat_main_t *vam = &vat_main;
4264   vat_json_node_t node;
4265   u8 *status = 0;
4266
4267   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4268   vec_add1 (status, 0);
4269
4270   vat_json_init_object (&node);
4271   vat_json_object_add_string_copy (&node, "status", status);
4272
4273   vec_free (status);
4274
4275   vat_json_print (vam->ofp, &node);
4276   vat_json_free (&node);
4277
4278   vam->retval = ntohl (mp->retval);
4279   vam->result_ready = 1;
4280 }
4281
4282 static void
4283   vl_api_one_show_petr_mode_reply_t_handler
4284   (vl_api_one_show_petr_mode_reply_t * mp)
4285 {
4286   vat_main_t *vam = &vat_main;
4287   i32 retval = ntohl (mp->retval);
4288
4289   if (0 <= retval)
4290     {
4291       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4292     }
4293
4294   vam->retval = retval;
4295   vam->result_ready = 1;
4296 }
4297
4298 static void
4299   vl_api_one_show_petr_mode_reply_t_handler_json
4300   (vl_api_one_show_petr_mode_reply_t * mp)
4301 {
4302   vat_main_t *vam = &vat_main;
4303   vat_json_node_t node;
4304   u8 *status = 0;
4305
4306   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4307   vec_add1 (status, 0);
4308
4309   vat_json_init_object (&node);
4310   vat_json_object_add_string_copy (&node, "status", status);
4311
4312   vec_free (status);
4313
4314   vat_json_print (vam->ofp, &node);
4315   vat_json_free (&node);
4316
4317   vam->retval = ntohl (mp->retval);
4318   vam->result_ready = 1;
4319 }
4320
4321 static void
4322   vl_api_show_one_use_petr_reply_t_handler
4323   (vl_api_show_one_use_petr_reply_t * mp)
4324 {
4325   vat_main_t *vam = &vat_main;
4326   i32 retval = ntohl (mp->retval);
4327
4328   if (0 <= retval)
4329     {
4330       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4331       if (mp->status)
4332         {
4333           print (vam->ofp, "Proxy-ETR address; %U",
4334                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4335                  mp->address);
4336         }
4337     }
4338
4339   vam->retval = retval;
4340   vam->result_ready = 1;
4341 }
4342
4343 static void
4344   vl_api_show_one_use_petr_reply_t_handler_json
4345   (vl_api_show_one_use_petr_reply_t * mp)
4346 {
4347   vat_main_t *vam = &vat_main;
4348   vat_json_node_t node;
4349   u8 *status = 0;
4350   struct in_addr ip4;
4351   struct in6_addr ip6;
4352
4353   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4354   vec_add1 (status, 0);
4355
4356   vat_json_init_object (&node);
4357   vat_json_object_add_string_copy (&node, "status", status);
4358   if (mp->status)
4359     {
4360       if (mp->is_ip4)
4361         {
4362           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4363           vat_json_object_add_ip6 (&node, "address", ip6);
4364         }
4365       else
4366         {
4367           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4368           vat_json_object_add_ip4 (&node, "address", ip4);
4369         }
4370     }
4371
4372   vec_free (status);
4373
4374   vat_json_print (vam->ofp, &node);
4375   vat_json_free (&node);
4376
4377   vam->retval = ntohl (mp->retval);
4378   vam->result_ready = 1;
4379 }
4380
4381 static void
4382   vl_api_show_one_nsh_mapping_reply_t_handler
4383   (vl_api_show_one_nsh_mapping_reply_t * mp)
4384 {
4385   vat_main_t *vam = &vat_main;
4386   i32 retval = ntohl (mp->retval);
4387
4388   if (0 <= retval)
4389     {
4390       print (vam->ofp, "%-20s%-16s",
4391              mp->is_set ? "set" : "not-set",
4392              mp->is_set ? (char *) mp->locator_set_name : "");
4393     }
4394
4395   vam->retval = retval;
4396   vam->result_ready = 1;
4397 }
4398
4399 static void
4400   vl_api_show_one_nsh_mapping_reply_t_handler_json
4401   (vl_api_show_one_nsh_mapping_reply_t * mp)
4402 {
4403   vat_main_t *vam = &vat_main;
4404   vat_json_node_t node;
4405   u8 *status = 0;
4406
4407   status = format (0, "%s", mp->is_set ? "yes" : "no");
4408   vec_add1 (status, 0);
4409
4410   vat_json_init_object (&node);
4411   vat_json_object_add_string_copy (&node, "is_set", status);
4412   if (mp->is_set)
4413     {
4414       vat_json_object_add_string_copy (&node, "locator_set",
4415                                        mp->locator_set_name);
4416     }
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_show_one_map_register_ttl_reply_t_handler
4429   (vl_api_show_one_map_register_ttl_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4435
4436   if (0 <= retval)
4437     {
4438       print (vam->ofp, "ttl: %u", mp->ttl);
4439     }
4440
4441   vam->retval = retval;
4442   vam->result_ready = 1;
4443 }
4444
4445 static void
4446   vl_api_show_one_map_register_ttl_reply_t_handler_json
4447   (vl_api_show_one_map_register_ttl_reply_t * mp)
4448 {
4449   vat_main_t *vam = &vat_main;
4450   vat_json_node_t node;
4451
4452   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4453   vat_json_init_object (&node);
4454   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4455
4456   vat_json_print (vam->ofp, &node);
4457   vat_json_free (&node);
4458
4459   vam->retval = ntohl (mp->retval);
4460   vam->result_ready = 1;
4461 }
4462
4463 static void
4464 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4465 {
4466   vat_main_t *vam = &vat_main;
4467   i32 retval = ntohl (mp->retval);
4468
4469   if (0 <= retval)
4470     {
4471       print (vam->ofp, "%-20s%-16s",
4472              mp->status ? "enabled" : "disabled",
4473              mp->status ? (char *) mp->locator_set_name : "");
4474     }
4475
4476   vam->retval = retval;
4477   vam->result_ready = 1;
4478 }
4479
4480 static void
4481 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4482 {
4483   vat_main_t *vam = &vat_main;
4484   vat_json_node_t node;
4485   u8 *status = 0;
4486
4487   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4488   vec_add1 (status, 0);
4489
4490   vat_json_init_object (&node);
4491   vat_json_object_add_string_copy (&node, "status", status);
4492   if (mp->status)
4493     {
4494       vat_json_object_add_string_copy (&node, "locator_set",
4495                                        mp->locator_set_name);
4496     }
4497
4498   vec_free (status);
4499
4500   vat_json_print (vam->ofp, &node);
4501   vat_json_free (&node);
4502
4503   vam->retval = ntohl (mp->retval);
4504   vam->result_ready = 1;
4505 }
4506
4507 static u8 *
4508 format_policer_type (u8 * s, va_list * va)
4509 {
4510   u32 i = va_arg (*va, u32);
4511
4512   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4513     s = format (s, "1r2c");
4514   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4515     s = format (s, "1r3c");
4516   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4517     s = format (s, "2r3c-2698");
4518   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4519     s = format (s, "2r3c-4115");
4520   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4521     s = format (s, "2r3c-mef5cf1");
4522   else
4523     s = format (s, "ILLEGAL");
4524   return s;
4525 }
4526
4527 static u8 *
4528 format_policer_rate_type (u8 * s, va_list * va)
4529 {
4530   u32 i = va_arg (*va, u32);
4531
4532   if (i == SSE2_QOS_RATE_KBPS)
4533     s = format (s, "kbps");
4534   else if (i == SSE2_QOS_RATE_PPS)
4535     s = format (s, "pps");
4536   else
4537     s = format (s, "ILLEGAL");
4538   return s;
4539 }
4540
4541 static u8 *
4542 format_policer_round_type (u8 * s, va_list * va)
4543 {
4544   u32 i = va_arg (*va, u32);
4545
4546   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4547     s = format (s, "closest");
4548   else if (i == SSE2_QOS_ROUND_TO_UP)
4549     s = format (s, "up");
4550   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4551     s = format (s, "down");
4552   else
4553     s = format (s, "ILLEGAL");
4554   return s;
4555 }
4556
4557 static u8 *
4558 format_policer_action_type (u8 * s, va_list * va)
4559 {
4560   u32 i = va_arg (*va, u32);
4561
4562   if (i == SSE2_QOS_ACTION_DROP)
4563     s = format (s, "drop");
4564   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4565     s = format (s, "transmit");
4566   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4567     s = format (s, "mark-and-transmit");
4568   else
4569     s = format (s, "ILLEGAL");
4570   return s;
4571 }
4572
4573 static u8 *
4574 format_dscp (u8 * s, va_list * va)
4575 {
4576   u32 i = va_arg (*va, u32);
4577   char *t = 0;
4578
4579   switch (i)
4580     {
4581 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4582       foreach_vnet_dscp
4583 #undef _
4584     default:
4585       return format (s, "ILLEGAL");
4586     }
4587   s = format (s, "%s", t);
4588   return s;
4589 }
4590
4591 static void
4592 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4593 {
4594   vat_main_t *vam = &vat_main;
4595   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4596
4597   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4598     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4599   else
4600     conform_dscp_str = format (0, "");
4601
4602   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4603     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4604   else
4605     exceed_dscp_str = format (0, "");
4606
4607   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4608     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4609   else
4610     violate_dscp_str = format (0, "");
4611
4612   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4613          "rate type %U, round type %U, %s rate, %s color-aware, "
4614          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4615          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4616          "conform action %U%s, exceed action %U%s, violate action %U%s",
4617          mp->name,
4618          format_policer_type, mp->type,
4619          ntohl (mp->cir),
4620          ntohl (mp->eir),
4621          clib_net_to_host_u64 (mp->cb),
4622          clib_net_to_host_u64 (mp->eb),
4623          format_policer_rate_type, mp->rate_type,
4624          format_policer_round_type, mp->round_type,
4625          mp->single_rate ? "single" : "dual",
4626          mp->color_aware ? "is" : "not",
4627          ntohl (mp->cir_tokens_per_period),
4628          ntohl (mp->pir_tokens_per_period),
4629          ntohl (mp->scale),
4630          ntohl (mp->current_limit),
4631          ntohl (mp->current_bucket),
4632          ntohl (mp->extended_limit),
4633          ntohl (mp->extended_bucket),
4634          clib_net_to_host_u64 (mp->last_update_time),
4635          format_policer_action_type, mp->conform_action_type,
4636          conform_dscp_str,
4637          format_policer_action_type, mp->exceed_action_type,
4638          exceed_dscp_str,
4639          format_policer_action_type, mp->violate_action_type,
4640          violate_dscp_str);
4641
4642   vec_free (conform_dscp_str);
4643   vec_free (exceed_dscp_str);
4644   vec_free (violate_dscp_str);
4645 }
4646
4647 static void vl_api_policer_details_t_handler_json
4648   (vl_api_policer_details_t * mp)
4649 {
4650   vat_main_t *vam = &vat_main;
4651   vat_json_node_t *node;
4652   u8 *rate_type_str, *round_type_str, *type_str;
4653   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4654
4655   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4656   round_type_str =
4657     format (0, "%U", format_policer_round_type, mp->round_type);
4658   type_str = format (0, "%U", format_policer_type, mp->type);
4659   conform_action_str = format (0, "%U", format_policer_action_type,
4660                                mp->conform_action_type);
4661   exceed_action_str = format (0, "%U", format_policer_action_type,
4662                               mp->exceed_action_type);
4663   violate_action_str = format (0, "%U", format_policer_action_type,
4664                                mp->violate_action_type);
4665
4666   if (VAT_JSON_ARRAY != vam->json_tree.type)
4667     {
4668       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4669       vat_json_init_array (&vam->json_tree);
4670     }
4671   node = vat_json_array_add (&vam->json_tree);
4672
4673   vat_json_init_object (node);
4674   vat_json_object_add_string_copy (node, "name", mp->name);
4675   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4676   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4677   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4678   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4679   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4680   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4681   vat_json_object_add_string_copy (node, "type", type_str);
4682   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4683   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4684   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4685   vat_json_object_add_uint (node, "cir_tokens_per_period",
4686                             ntohl (mp->cir_tokens_per_period));
4687   vat_json_object_add_uint (node, "eir_tokens_per_period",
4688                             ntohl (mp->pir_tokens_per_period));
4689   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4690   vat_json_object_add_uint (node, "current_bucket",
4691                             ntohl (mp->current_bucket));
4692   vat_json_object_add_uint (node, "extended_limit",
4693                             ntohl (mp->extended_limit));
4694   vat_json_object_add_uint (node, "extended_bucket",
4695                             ntohl (mp->extended_bucket));
4696   vat_json_object_add_uint (node, "last_update_time",
4697                             ntohl (mp->last_update_time));
4698   vat_json_object_add_string_copy (node, "conform_action",
4699                                    conform_action_str);
4700   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4701     {
4702       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4703       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4704       vec_free (dscp_str);
4705     }
4706   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4707   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4708     {
4709       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4710       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4711       vec_free (dscp_str);
4712     }
4713   vat_json_object_add_string_copy (node, "violate_action",
4714                                    violate_action_str);
4715   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4716     {
4717       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4718       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4719       vec_free (dscp_str);
4720     }
4721
4722   vec_free (rate_type_str);
4723   vec_free (round_type_str);
4724   vec_free (type_str);
4725   vec_free (conform_action_str);
4726   vec_free (exceed_action_str);
4727   vec_free (violate_action_str);
4728 }
4729
4730 static void
4731 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4732                                            mp)
4733 {
4734   vat_main_t *vam = &vat_main;
4735   int i, count = ntohl (mp->count);
4736
4737   if (count > 0)
4738     print (vam->ofp, "classify table ids (%d) : ", count);
4739   for (i = 0; i < count; i++)
4740     {
4741       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4742       print (vam->ofp, (i < count - 1) ? "," : "");
4743     }
4744   vam->retval = ntohl (mp->retval);
4745   vam->result_ready = 1;
4746 }
4747
4748 static void
4749   vl_api_classify_table_ids_reply_t_handler_json
4750   (vl_api_classify_table_ids_reply_t * mp)
4751 {
4752   vat_main_t *vam = &vat_main;
4753   int i, count = ntohl (mp->count);
4754
4755   if (count > 0)
4756     {
4757       vat_json_node_t node;
4758
4759       vat_json_init_object (&node);
4760       for (i = 0; i < count; i++)
4761         {
4762           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4763         }
4764       vat_json_print (vam->ofp, &node);
4765       vat_json_free (&node);
4766     }
4767   vam->retval = ntohl (mp->retval);
4768   vam->result_ready = 1;
4769 }
4770
4771 static void
4772   vl_api_classify_table_by_interface_reply_t_handler
4773   (vl_api_classify_table_by_interface_reply_t * mp)
4774 {
4775   vat_main_t *vam = &vat_main;
4776   u32 table_id;
4777
4778   table_id = ntohl (mp->l2_table_id);
4779   if (table_id != ~0)
4780     print (vam->ofp, "l2 table id : %d", table_id);
4781   else
4782     print (vam->ofp, "l2 table id : No input ACL tables configured");
4783   table_id = ntohl (mp->ip4_table_id);
4784   if (table_id != ~0)
4785     print (vam->ofp, "ip4 table id : %d", table_id);
4786   else
4787     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4788   table_id = ntohl (mp->ip6_table_id);
4789   if (table_id != ~0)
4790     print (vam->ofp, "ip6 table id : %d", table_id);
4791   else
4792     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4793   vam->retval = ntohl (mp->retval);
4794   vam->result_ready = 1;
4795 }
4796
4797 static void
4798   vl_api_classify_table_by_interface_reply_t_handler_json
4799   (vl_api_classify_table_by_interface_reply_t * mp)
4800 {
4801   vat_main_t *vam = &vat_main;
4802   vat_json_node_t node;
4803
4804   vat_json_init_object (&node);
4805
4806   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4807   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4808   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4809
4810   vat_json_print (vam->ofp, &node);
4811   vat_json_free (&node);
4812
4813   vam->retval = ntohl (mp->retval);
4814   vam->result_ready = 1;
4815 }
4816
4817 static void vl_api_policer_add_del_reply_t_handler
4818   (vl_api_policer_add_del_reply_t * mp)
4819 {
4820   vat_main_t *vam = &vat_main;
4821   i32 retval = ntohl (mp->retval);
4822   if (vam->async_mode)
4823     {
4824       vam->async_errors += (retval < 0);
4825     }
4826   else
4827     {
4828       vam->retval = retval;
4829       vam->result_ready = 1;
4830       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4831         /*
4832          * Note: this is just barely thread-safe, depends on
4833          * the main thread spinning waiting for an answer...
4834          */
4835         errmsg ("policer index %d", ntohl (mp->policer_index));
4836     }
4837 }
4838
4839 static void vl_api_policer_add_del_reply_t_handler_json
4840   (vl_api_policer_add_del_reply_t * mp)
4841 {
4842   vat_main_t *vam = &vat_main;
4843   vat_json_node_t node;
4844
4845   vat_json_init_object (&node);
4846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4847   vat_json_object_add_uint (&node, "policer_index",
4848                             ntohl (mp->policer_index));
4849
4850   vat_json_print (vam->ofp, &node);
4851   vat_json_free (&node);
4852
4853   vam->retval = ntohl (mp->retval);
4854   vam->result_ready = 1;
4855 }
4856
4857 /* Format hex dump. */
4858 u8 *
4859 format_hex_bytes (u8 * s, va_list * va)
4860 {
4861   u8 *bytes = va_arg (*va, u8 *);
4862   int n_bytes = va_arg (*va, int);
4863   uword i;
4864
4865   /* Print short or long form depending on byte count. */
4866   uword short_form = n_bytes <= 32;
4867   u32 indent = format_get_indent (s);
4868
4869   if (n_bytes == 0)
4870     return s;
4871
4872   for (i = 0; i < n_bytes; i++)
4873     {
4874       if (!short_form && (i % 32) == 0)
4875         s = format (s, "%08x: ", i);
4876       s = format (s, "%02x", bytes[i]);
4877       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4878         s = format (s, "\n%U", format_white_space, indent);
4879     }
4880
4881   return s;
4882 }
4883
4884 static void
4885 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4886                                             * mp)
4887 {
4888   vat_main_t *vam = &vat_main;
4889   i32 retval = ntohl (mp->retval);
4890   if (retval == 0)
4891     {
4892       print (vam->ofp, "classify table info :");
4893       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4894              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4895              ntohl (mp->miss_next_index));
4896       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4897              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4898              ntohl (mp->match_n_vectors));
4899       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4900              ntohl (mp->mask_length));
4901     }
4902   vam->retval = retval;
4903   vam->result_ready = 1;
4904 }
4905
4906 static void
4907   vl_api_classify_table_info_reply_t_handler_json
4908   (vl_api_classify_table_info_reply_t * mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911   vat_json_node_t node;
4912
4913   i32 retval = ntohl (mp->retval);
4914   if (retval == 0)
4915     {
4916       vat_json_init_object (&node);
4917
4918       vat_json_object_add_int (&node, "sessions",
4919                                ntohl (mp->active_sessions));
4920       vat_json_object_add_int (&node, "nexttbl",
4921                                ntohl (mp->next_table_index));
4922       vat_json_object_add_int (&node, "nextnode",
4923                                ntohl (mp->miss_next_index));
4924       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4925       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4926       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4927       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4928                       ntohl (mp->mask_length), 0);
4929       vat_json_object_add_string_copy (&node, "mask", s);
4930
4931       vat_json_print (vam->ofp, &node);
4932       vat_json_free (&node);
4933     }
4934   vam->retval = ntohl (mp->retval);
4935   vam->result_ready = 1;
4936 }
4937
4938 static void
4939 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4940                                            mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943
4944   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4945          ntohl (mp->hit_next_index), ntohl (mp->advance),
4946          ntohl (mp->opaque_index));
4947   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4948          ntohl (mp->match_length));
4949 }
4950
4951 static void
4952   vl_api_classify_session_details_t_handler_json
4953   (vl_api_classify_session_details_t * mp)
4954 {
4955   vat_main_t *vam = &vat_main;
4956   vat_json_node_t *node = NULL;
4957
4958   if (VAT_JSON_ARRAY != vam->json_tree.type)
4959     {
4960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4961       vat_json_init_array (&vam->json_tree);
4962     }
4963   node = vat_json_array_add (&vam->json_tree);
4964
4965   vat_json_init_object (node);
4966   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4967   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4968   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4969   u8 *s =
4970     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4971             0);
4972   vat_json_object_add_string_copy (node, "match", s);
4973 }
4974
4975 static void vl_api_pg_create_interface_reply_t_handler
4976   (vl_api_pg_create_interface_reply_t * mp)
4977 {
4978   vat_main_t *vam = &vat_main;
4979
4980   vam->retval = ntohl (mp->retval);
4981   vam->result_ready = 1;
4982 }
4983
4984 static void vl_api_pg_create_interface_reply_t_handler_json
4985   (vl_api_pg_create_interface_reply_t * mp)
4986 {
4987   vat_main_t *vam = &vat_main;
4988   vat_json_node_t node;
4989
4990   i32 retval = ntohl (mp->retval);
4991   if (retval == 0)
4992     {
4993       vat_json_init_object (&node);
4994
4995       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4996
4997       vat_json_print (vam->ofp, &node);
4998       vat_json_free (&node);
4999     }
5000   vam->retval = ntohl (mp->retval);
5001   vam->result_ready = 1;
5002 }
5003
5004 static void vl_api_policer_classify_details_t_handler
5005   (vl_api_policer_classify_details_t * mp)
5006 {
5007   vat_main_t *vam = &vat_main;
5008
5009   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5010          ntohl (mp->table_index));
5011 }
5012
5013 static void vl_api_policer_classify_details_t_handler_json
5014   (vl_api_policer_classify_details_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017   vat_json_node_t *node;
5018
5019   if (VAT_JSON_ARRAY != vam->json_tree.type)
5020     {
5021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5022       vat_json_init_array (&vam->json_tree);
5023     }
5024   node = vat_json_array_add (&vam->json_tree);
5025
5026   vat_json_init_object (node);
5027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5028   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5029 }
5030
5031 static void vl_api_flow_classify_details_t_handler
5032   (vl_api_flow_classify_details_t * mp)
5033 {
5034   vat_main_t *vam = &vat_main;
5035
5036   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5037          ntohl (mp->table_index));
5038 }
5039
5040 static void vl_api_flow_classify_details_t_handler_json
5041   (vl_api_flow_classify_details_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   vat_json_node_t *node;
5045
5046   if (VAT_JSON_ARRAY != vam->json_tree.type)
5047     {
5048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5049       vat_json_init_array (&vam->json_tree);
5050     }
5051   node = vat_json_array_add (&vam->json_tree);
5052
5053   vat_json_init_object (node);
5054   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5055   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5056 }
5057
5058 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5059 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5060 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5061 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5062 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5063 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5064 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5065 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5066 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5067 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5068
5069 /*
5070  * Generate boilerplate reply handlers, which
5071  * dig the return value out of the xxx_reply_t API message,
5072  * stick it into vam->retval, and set vam->result_ready
5073  *
5074  * Could also do this by pointing N message decode slots at
5075  * a single function, but that could break in subtle ways.
5076  */
5077
5078 #define foreach_standard_reply_retval_handler           \
5079 _(sw_interface_set_flags_reply)                         \
5080 _(sw_interface_add_del_address_reply)                   \
5081 _(sw_interface_set_rx_mode_reply)                       \
5082 _(sw_interface_set_rx_placement_reply)                  \
5083 _(sw_interface_set_table_reply)                         \
5084 _(sw_interface_set_mpls_enable_reply)                   \
5085 _(sw_interface_set_vpath_reply)                         \
5086 _(sw_interface_set_vxlan_bypass_reply)                  \
5087 _(sw_interface_set_geneve_bypass_reply)                 \
5088 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5089 _(sw_interface_set_l2_bridge_reply)                     \
5090 _(sw_interface_set_bond_weight_reply)                   \
5091 _(bridge_domain_add_del_reply)                          \
5092 _(sw_interface_set_l2_xconnect_reply)                   \
5093 _(l2fib_add_del_reply)                                  \
5094 _(l2fib_flush_int_reply)                                \
5095 _(l2fib_flush_bd_reply)                                 \
5096 _(ip_route_add_del_reply)                               \
5097 _(ip_table_add_del_reply)                               \
5098 _(ip_mroute_add_del_reply)                              \
5099 _(mpls_route_add_del_reply)                             \
5100 _(mpls_table_add_del_reply)                             \
5101 _(mpls_ip_bind_unbind_reply)                            \
5102 _(bier_route_add_del_reply)                             \
5103 _(bier_table_add_del_reply)                             \
5104 _(proxy_arp_add_del_reply)                              \
5105 _(proxy_arp_intfc_enable_disable_reply)                 \
5106 _(sw_interface_set_unnumbered_reply)                    \
5107 _(ip_neighbor_add_del_reply)                            \
5108 _(reset_fib_reply)                                      \
5109 _(dhcp_proxy_config_reply)                              \
5110 _(dhcp_proxy_set_vss_reply)                             \
5111 _(dhcp_client_config_reply)                             \
5112 _(set_ip_flow_hash_reply)                               \
5113 _(sw_interface_ip6_enable_disable_reply)                \
5114 _(ip6nd_proxy_add_del_reply)                            \
5115 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5116 _(sw_interface_ip6nd_ra_config_reply)                   \
5117 _(set_arp_neighbor_limit_reply)                         \
5118 _(l2_patch_add_del_reply)                               \
5119 _(sr_mpls_policy_add_reply)                             \
5120 _(sr_mpls_policy_mod_reply)                             \
5121 _(sr_mpls_policy_del_reply)                             \
5122 _(sr_policy_add_reply)                                  \
5123 _(sr_policy_mod_reply)                                  \
5124 _(sr_policy_del_reply)                                  \
5125 _(sr_localsid_add_del_reply)                            \
5126 _(sr_steering_add_del_reply)                            \
5127 _(classify_add_del_session_reply)                       \
5128 _(classify_set_interface_ip_table_reply)                \
5129 _(classify_set_interface_l2_tables_reply)               \
5130 _(l2tpv3_set_tunnel_cookies_reply)                      \
5131 _(l2tpv3_interface_enable_disable_reply)                \
5132 _(l2tpv3_set_lookup_key_reply)                          \
5133 _(l2_fib_clear_table_reply)                             \
5134 _(l2_interface_efp_filter_reply)                        \
5135 _(l2_interface_vlan_tag_rewrite_reply)                  \
5136 _(modify_vhost_user_if_reply)                           \
5137 _(delete_vhost_user_if_reply)                           \
5138 _(ip_probe_neighbor_reply)                              \
5139 _(ip_scan_neighbor_enable_disable_reply)                \
5140 _(want_ip4_arp_events_reply)                            \
5141 _(want_ip6_nd_events_reply)                             \
5142 _(want_l2_macs_events_reply)                            \
5143 _(input_acl_set_interface_reply)                        \
5144 _(ipsec_spd_add_del_reply)                              \
5145 _(ipsec_interface_add_del_spd_reply)                    \
5146 _(ipsec_spd_entry_add_del_reply)                        \
5147 _(ipsec_sad_entry_add_del_reply)                        \
5148 _(ipsec_tunnel_if_add_del_reply)                        \
5149 _(ipsec_tunnel_if_set_sa_reply)                         \
5150 _(delete_loopback_reply)                                \
5151 _(bd_ip_mac_add_del_reply)                              \
5152 _(bd_ip_mac_flush_reply)                                \
5153 _(want_interface_events_reply)                          \
5154 _(cop_interface_enable_disable_reply)                   \
5155 _(cop_whitelist_enable_disable_reply)                   \
5156 _(sw_interface_clear_stats_reply)                       \
5157 _(ioam_enable_reply)                                    \
5158 _(ioam_disable_reply)                                   \
5159 _(one_add_del_locator_reply)                            \
5160 _(one_add_del_local_eid_reply)                          \
5161 _(one_add_del_remote_mapping_reply)                     \
5162 _(one_add_del_adjacency_reply)                          \
5163 _(one_add_del_map_resolver_reply)                       \
5164 _(one_add_del_map_server_reply)                         \
5165 _(one_enable_disable_reply)                             \
5166 _(one_rloc_probe_enable_disable_reply)                  \
5167 _(one_map_register_enable_disable_reply)                \
5168 _(one_map_register_set_ttl_reply)                       \
5169 _(one_set_transport_protocol_reply)                     \
5170 _(one_map_register_fallback_threshold_reply)            \
5171 _(one_pitr_set_locator_set_reply)                       \
5172 _(one_map_request_mode_reply)                           \
5173 _(one_add_del_map_request_itr_rlocs_reply)              \
5174 _(one_eid_table_add_del_map_reply)                      \
5175 _(one_use_petr_reply)                                   \
5176 _(one_stats_enable_disable_reply)                       \
5177 _(one_add_del_l2_arp_entry_reply)                       \
5178 _(one_add_del_ndp_entry_reply)                          \
5179 _(one_stats_flush_reply)                                \
5180 _(one_enable_disable_xtr_mode_reply)                    \
5181 _(one_enable_disable_pitr_mode_reply)                   \
5182 _(one_enable_disable_petr_mode_reply)                   \
5183 _(gpe_enable_disable_reply)                             \
5184 _(gpe_set_encap_mode_reply)                             \
5185 _(gpe_add_del_iface_reply)                              \
5186 _(gpe_add_del_native_fwd_rpath_reply)                   \
5187 _(af_packet_delete_reply)                               \
5188 _(policer_classify_set_interface_reply)                 \
5189 _(netmap_create_reply)                                  \
5190 _(netmap_delete_reply)                                  \
5191 _(set_ipfix_exporter_reply)                             \
5192 _(set_ipfix_classify_stream_reply)                      \
5193 _(ipfix_classify_table_add_del_reply)                   \
5194 _(flow_classify_set_interface_reply)                    \
5195 _(sw_interface_span_enable_disable_reply)               \
5196 _(pg_capture_reply)                                     \
5197 _(pg_enable_disable_reply)                              \
5198 _(ip_source_and_port_range_check_add_del_reply)         \
5199 _(ip_source_and_port_range_check_interface_add_del_reply)\
5200 _(delete_subif_reply)                                   \
5201 _(l2_interface_pbb_tag_rewrite_reply)                   \
5202 _(set_punt_reply)                                       \
5203 _(feature_enable_disable_reply)                         \
5204 _(sw_interface_tag_add_del_reply)                       \
5205 _(hw_interface_set_mtu_reply)                           \
5206 _(p2p_ethernet_add_reply)                               \
5207 _(p2p_ethernet_del_reply)                               \
5208 _(lldp_config_reply)                                    \
5209 _(sw_interface_set_lldp_reply)                          \
5210 _(tcp_configure_src_addresses_reply)                    \
5211 _(session_rule_add_del_reply)                           \
5212 _(ip_container_proxy_add_del_reply)                     \
5213 _(output_acl_set_interface_reply)                       \
5214 _(qos_record_enable_disable_reply)
5215
5216 #define _(n)                                    \
5217     static void vl_api_##n##_t_handler          \
5218     (vl_api_##n##_t * mp)                       \
5219     {                                           \
5220         vat_main_t * vam = &vat_main;           \
5221         i32 retval = ntohl(mp->retval);         \
5222         if (vam->async_mode) {                  \
5223             vam->async_errors += (retval < 0);  \
5224         } else {                                \
5225             vam->retval = retval;               \
5226             vam->result_ready = 1;              \
5227         }                                       \
5228     }
5229 foreach_standard_reply_retval_handler;
5230 #undef _
5231
5232 #define _(n)                                    \
5233     static void vl_api_##n##_t_handler_json     \
5234     (vl_api_##n##_t * mp)                       \
5235     {                                           \
5236         vat_main_t * vam = &vat_main;           \
5237         vat_json_node_t node;                   \
5238         vat_json_init_object(&node);            \
5239         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5240         vat_json_print(vam->ofp, &node);        \
5241         vam->retval = ntohl(mp->retval);        \
5242         vam->result_ready = 1;                  \
5243     }
5244 foreach_standard_reply_retval_handler;
5245 #undef _
5246
5247 /*
5248  * Table of message reply handlers, must include boilerplate handlers
5249  * we just generated
5250  */
5251
5252 #define foreach_vpe_api_reply_msg                                       \
5253 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5254 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5255 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5256 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5257 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5258 _(CLI_REPLY, cli_reply)                                                 \
5259 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5260 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5261   sw_interface_add_del_address_reply)                                   \
5262 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5263 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5264 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5265 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5266 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5267 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5268 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5269 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5270 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5271 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5272   sw_interface_set_l2_xconnect_reply)                                   \
5273 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5274   sw_interface_set_l2_bridge_reply)                                     \
5275 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5276 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5277 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5278 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5279 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5280 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5281 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5282 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5283 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5284 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5285 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5286 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5287 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5288 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5289 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5290 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5291 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5292 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5293 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5294 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5295 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5296 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5297 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5298 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5299 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5300 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5301 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5302 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5303 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5304 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5305 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5306   proxy_arp_intfc_enable_disable_reply)                                 \
5307 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5308 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5309   sw_interface_set_unnumbered_reply)                                    \
5310 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5311 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5312 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5313 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5314 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5315 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5316 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5317 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5318 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5319 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5320   sw_interface_ip6_enable_disable_reply)                                \
5321 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5322 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5323 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5324   sw_interface_ip6nd_ra_prefix_reply)                                   \
5325 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5326   sw_interface_ip6nd_ra_config_reply)                                   \
5327 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5328 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5329 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5330 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5331 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5332 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5333 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5334 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5335 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5336 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5337 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5338 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5339 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5340 classify_set_interface_ip_table_reply)                                  \
5341 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5342   classify_set_interface_l2_tables_reply)                               \
5343 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5344 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5345 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5346 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5347 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5348   l2tpv3_interface_enable_disable_reply)                                \
5349 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5350 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5351 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5352 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5353 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5354 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5355 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5356 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5357 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5358 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5359 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5360 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5361 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5362 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5363 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5364 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5365 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5366 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5367 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5368 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5369 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5370 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5371 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5372 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5373 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5374 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5375 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5376 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5377 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5378 _(L2_MACS_EVENT, l2_macs_event)                                         \
5379 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5380 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5381 _(IP_DETAILS, ip_details)                                               \
5382 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5383 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5384 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5385 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5386 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5387 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5388 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5389 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5390 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5391 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5392 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5393 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5394 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5395 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5396 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5397 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5398 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5399 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5400 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5401 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5402 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5403 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5404 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5405 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5406 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5407 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5408 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5409 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5410 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5411   one_map_register_enable_disable_reply)                                \
5412 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5413 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5414 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5415 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5416   one_map_register_fallback_threshold_reply)                            \
5417 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5418   one_rloc_probe_enable_disable_reply)                                  \
5419 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5420 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5421 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5422 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5423 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5424 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5425 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5426 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5427 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5428 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5429 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5430 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5431 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5432 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5433 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5434 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5435   show_one_stats_enable_disable_reply)                                  \
5436 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5437 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5438 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5439 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5440 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5441 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5442 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5443 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5444   one_enable_disable_pitr_mode_reply)                                   \
5445 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5446   one_enable_disable_petr_mode_reply)                                   \
5447 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5448 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5449 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5450 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5451 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5452 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5453 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5454 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5455 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5456 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5457 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5458 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5459   gpe_add_del_native_fwd_rpath_reply)                                   \
5460 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5461   gpe_fwd_entry_path_details)                                           \
5462 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5463 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5464   one_add_del_map_request_itr_rlocs_reply)                              \
5465 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5466   one_get_map_request_itr_rlocs_reply)                                  \
5467 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5468 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5469 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5470 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5471 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5472 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5473   show_one_map_register_state_reply)                                    \
5474 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5475 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5476   show_one_map_register_fallback_threshold_reply)                       \
5477 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5478 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5479 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5480 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5481 _(POLICER_DETAILS, policer_details)                                     \
5482 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5483 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5484 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5485 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5486 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5487 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5488 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5489 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5490 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5491 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5492 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5493 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5494 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5495 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5496 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5497 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5498 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5499 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5500 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5501 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5502 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5503 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5504 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5505 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5506 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5507 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5508  ip_source_and_port_range_check_add_del_reply)                          \
5509 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5510  ip_source_and_port_range_check_interface_add_del_reply)                \
5511 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5512 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5513 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5514 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5515 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5516 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5517 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5518 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5519 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5520 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5521 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5522 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5523 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5524 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5525 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5526 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5527 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5528 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5529 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5530 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5531 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5532 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5533
5534 #define foreach_standalone_reply_msg                                    \
5535 _(SW_INTERFACE_EVENT, sw_interface_event)
5536
5537 typedef struct
5538 {
5539   u8 *name;
5540   u32 value;
5541 } name_sort_t;
5542
5543 #define STR_VTR_OP_CASE(op)     \
5544     case L2_VTR_ ## op:         \
5545         return "" # op;
5546
5547 static const char *
5548 str_vtr_op (u32 vtr_op)
5549 {
5550   switch (vtr_op)
5551     {
5552       STR_VTR_OP_CASE (DISABLED);
5553       STR_VTR_OP_CASE (PUSH_1);
5554       STR_VTR_OP_CASE (PUSH_2);
5555       STR_VTR_OP_CASE (POP_1);
5556       STR_VTR_OP_CASE (POP_2);
5557       STR_VTR_OP_CASE (TRANSLATE_1_1);
5558       STR_VTR_OP_CASE (TRANSLATE_1_2);
5559       STR_VTR_OP_CASE (TRANSLATE_2_1);
5560       STR_VTR_OP_CASE (TRANSLATE_2_2);
5561     }
5562
5563   return "UNKNOWN";
5564 }
5565
5566 static int
5567 dump_sub_interface_table (vat_main_t * vam)
5568 {
5569   const sw_interface_subif_t *sub = NULL;
5570
5571   if (vam->json_output)
5572     {
5573       clib_warning
5574         ("JSON output supported only for VPE API calls and dump_stats_table");
5575       return -99;
5576     }
5577
5578   print (vam->ofp,
5579          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5580          "Interface", "sw_if_index",
5581          "sub id", "dot1ad", "tags", "outer id",
5582          "inner id", "exact", "default", "outer any", "inner any");
5583
5584   vec_foreach (sub, vam->sw_if_subif_table)
5585   {
5586     print (vam->ofp,
5587            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5588            sub->interface_name,
5589            sub->sw_if_index,
5590            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5591            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5592            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5593            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5594     if (sub->vtr_op != L2_VTR_DISABLED)
5595       {
5596         print (vam->ofp,
5597                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5598                "tag1: %d tag2: %d ]",
5599                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5600                sub->vtr_tag1, sub->vtr_tag2);
5601       }
5602   }
5603
5604   return 0;
5605 }
5606
5607 static int
5608 name_sort_cmp (void *a1, void *a2)
5609 {
5610   name_sort_t *n1 = a1;
5611   name_sort_t *n2 = a2;
5612
5613   return strcmp ((char *) n1->name, (char *) n2->name);
5614 }
5615
5616 static int
5617 dump_interface_table (vat_main_t * vam)
5618 {
5619   hash_pair_t *p;
5620   name_sort_t *nses = 0, *ns;
5621
5622   if (vam->json_output)
5623     {
5624       clib_warning
5625         ("JSON output supported only for VPE API calls and dump_stats_table");
5626       return -99;
5627     }
5628
5629   /* *INDENT-OFF* */
5630   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5631   ({
5632     vec_add2 (nses, ns, 1);
5633     ns->name = (u8 *)(p->key);
5634     ns->value = (u32) p->value[0];
5635   }));
5636   /* *INDENT-ON* */
5637
5638   vec_sort_with_function (nses, name_sort_cmp);
5639
5640   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5641   vec_foreach (ns, nses)
5642   {
5643     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5644   }
5645   vec_free (nses);
5646   return 0;
5647 }
5648
5649 static int
5650 dump_ip_table (vat_main_t * vam, int is_ipv6)
5651 {
5652   const ip_details_t *det = NULL;
5653   const ip_address_details_t *address = NULL;
5654   u32 i = ~0;
5655
5656   print (vam->ofp, "%-12s", "sw_if_index");
5657
5658   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5659   {
5660     i++;
5661     if (!det->present)
5662       {
5663         continue;
5664       }
5665     print (vam->ofp, "%-12d", i);
5666     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5667     if (!det->addr)
5668       {
5669         continue;
5670       }
5671     vec_foreach (address, det->addr)
5672     {
5673       print (vam->ofp,
5674              "            %-30U%-13d",
5675              is_ipv6 ? format_ip6_address : format_ip4_address,
5676              address->ip, address->prefix_length);
5677     }
5678   }
5679
5680   return 0;
5681 }
5682
5683 static int
5684 dump_ipv4_table (vat_main_t * vam)
5685 {
5686   if (vam->json_output)
5687     {
5688       clib_warning
5689         ("JSON output supported only for VPE API calls and dump_stats_table");
5690       return -99;
5691     }
5692
5693   return dump_ip_table (vam, 0);
5694 }
5695
5696 static int
5697 dump_ipv6_table (vat_main_t * vam)
5698 {
5699   if (vam->json_output)
5700     {
5701       clib_warning
5702         ("JSON output supported only for VPE API calls and dump_stats_table");
5703       return -99;
5704     }
5705
5706   return dump_ip_table (vam, 1);
5707 }
5708
5709 /*
5710  * Pass CLI buffers directly in the CLI_INBAND API message,
5711  * instead of an additional shared memory area.
5712  */
5713 static int
5714 exec_inband (vat_main_t * vam)
5715 {
5716   vl_api_cli_inband_t *mp;
5717   unformat_input_t *i = vam->input;
5718   int ret;
5719
5720   if (vec_len (i->buffer) == 0)
5721     return -1;
5722
5723   if (vam->exec_mode == 0 && unformat (i, "mode"))
5724     {
5725       vam->exec_mode = 1;
5726       return 0;
5727     }
5728   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5729     {
5730       vam->exec_mode = 0;
5731       return 0;
5732     }
5733
5734   /*
5735    * In order for the CLI command to work, it
5736    * must be a vector ending in \n, not a C-string ending
5737    * in \n\0.
5738    */
5739   u32 len = vec_len (vam->input->buffer);
5740   M2 (CLI_INBAND, mp, len);
5741   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5742
5743   S (mp);
5744   W (ret);
5745   /* json responses may or may not include a useful reply... */
5746   if (vec_len (vam->cmd_reply))
5747     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5748   return ret;
5749 }
5750
5751 int
5752 exec (vat_main_t * vam)
5753 {
5754   return exec_inband (vam);
5755 }
5756
5757 static int
5758 api_create_loopback (vat_main_t * vam)
5759 {
5760   unformat_input_t *i = vam->input;
5761   vl_api_create_loopback_t *mp;
5762   vl_api_create_loopback_instance_t *mp_lbi;
5763   u8 mac_address[6];
5764   u8 mac_set = 0;
5765   u8 is_specified = 0;
5766   u32 user_instance = 0;
5767   int ret;
5768
5769   clib_memset (mac_address, 0, sizeof (mac_address));
5770
5771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5772     {
5773       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5774         mac_set = 1;
5775       if (unformat (i, "instance %d", &user_instance))
5776         is_specified = 1;
5777       else
5778         break;
5779     }
5780
5781   if (is_specified)
5782     {
5783       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5784       mp_lbi->is_specified = is_specified;
5785       if (is_specified)
5786         mp_lbi->user_instance = htonl (user_instance);
5787       if (mac_set)
5788         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5789       S (mp_lbi);
5790     }
5791   else
5792     {
5793       /* Construct the API message */
5794       M (CREATE_LOOPBACK, mp);
5795       if (mac_set)
5796         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5797       S (mp);
5798     }
5799
5800   W (ret);
5801   return ret;
5802 }
5803
5804 static int
5805 api_delete_loopback (vat_main_t * vam)
5806 {
5807   unformat_input_t *i = vam->input;
5808   vl_api_delete_loopback_t *mp;
5809   u32 sw_if_index = ~0;
5810   int ret;
5811
5812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5813     {
5814       if (unformat (i, "sw_if_index %d", &sw_if_index))
5815         ;
5816       else
5817         break;
5818     }
5819
5820   if (sw_if_index == ~0)
5821     {
5822       errmsg ("missing sw_if_index");
5823       return -99;
5824     }
5825
5826   /* Construct the API message */
5827   M (DELETE_LOOPBACK, mp);
5828   mp->sw_if_index = ntohl (sw_if_index);
5829
5830   S (mp);
5831   W (ret);
5832   return ret;
5833 }
5834
5835 static int
5836 api_want_interface_events (vat_main_t * vam)
5837 {
5838   unformat_input_t *i = vam->input;
5839   vl_api_want_interface_events_t *mp;
5840   int enable = -1;
5841   int ret;
5842
5843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5844     {
5845       if (unformat (i, "enable"))
5846         enable = 1;
5847       else if (unformat (i, "disable"))
5848         enable = 0;
5849       else
5850         break;
5851     }
5852
5853   if (enable == -1)
5854     {
5855       errmsg ("missing enable|disable");
5856       return -99;
5857     }
5858
5859   M (WANT_INTERFACE_EVENTS, mp);
5860   mp->enable_disable = enable;
5861
5862   vam->interface_event_display = enable;
5863
5864   S (mp);
5865   W (ret);
5866   return ret;
5867 }
5868
5869
5870 /* Note: non-static, called once to set up the initial intfc table */
5871 int
5872 api_sw_interface_dump (vat_main_t * vam)
5873 {
5874   vl_api_sw_interface_dump_t *mp;
5875   vl_api_control_ping_t *mp_ping;
5876   hash_pair_t *p;
5877   name_sort_t *nses = 0, *ns;
5878   sw_interface_subif_t *sub = NULL;
5879   int ret;
5880
5881   /* Toss the old name table */
5882   /* *INDENT-OFF* */
5883   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5884   ({
5885     vec_add2 (nses, ns, 1);
5886     ns->name = (u8 *)(p->key);
5887     ns->value = (u32) p->value[0];
5888   }));
5889   /* *INDENT-ON* */
5890
5891   hash_free (vam->sw_if_index_by_interface_name);
5892
5893   vec_foreach (ns, nses) vec_free (ns->name);
5894
5895   vec_free (nses);
5896
5897   vec_foreach (sub, vam->sw_if_subif_table)
5898   {
5899     vec_free (sub->interface_name);
5900   }
5901   vec_free (vam->sw_if_subif_table);
5902
5903   /* recreate the interface name hash table */
5904   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5905
5906   /*
5907    * Ask for all interface names. Otherwise, the epic catalog of
5908    * name filters becomes ridiculously long, and vat ends up needing
5909    * to be taught about new interface types.
5910    */
5911   M (SW_INTERFACE_DUMP, mp);
5912   S (mp);
5913
5914   /* Use a control ping for synchronization */
5915   MPING (CONTROL_PING, mp_ping);
5916   S (mp_ping);
5917
5918   W (ret);
5919   return ret;
5920 }
5921
5922 static int
5923 api_sw_interface_set_flags (vat_main_t * vam)
5924 {
5925   unformat_input_t *i = vam->input;
5926   vl_api_sw_interface_set_flags_t *mp;
5927   u32 sw_if_index;
5928   u8 sw_if_index_set = 0;
5929   u8 admin_up = 0;
5930   int ret;
5931
5932   /* Parse args required to build the message */
5933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5934     {
5935       if (unformat (i, "admin-up"))
5936         admin_up = 1;
5937       else if (unformat (i, "admin-down"))
5938         admin_up = 0;
5939       else
5940         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5941         sw_if_index_set = 1;
5942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5943         sw_if_index_set = 1;
5944       else
5945         break;
5946     }
5947
5948   if (sw_if_index_set == 0)
5949     {
5950       errmsg ("missing interface name or sw_if_index");
5951       return -99;
5952     }
5953
5954   /* Construct the API message */
5955   M (SW_INTERFACE_SET_FLAGS, mp);
5956   mp->sw_if_index = ntohl (sw_if_index);
5957   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5958
5959   /* send it... */
5960   S (mp);
5961
5962   /* Wait for a reply, return the good/bad news... */
5963   W (ret);
5964   return ret;
5965 }
5966
5967 static int
5968 api_sw_interface_set_rx_mode (vat_main_t * vam)
5969 {
5970   unformat_input_t *i = vam->input;
5971   vl_api_sw_interface_set_rx_mode_t *mp;
5972   u32 sw_if_index;
5973   u8 sw_if_index_set = 0;
5974   int ret;
5975   u8 queue_id_valid = 0;
5976   u32 queue_id;
5977   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5978
5979   /* Parse args required to build the message */
5980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5981     {
5982       if (unformat (i, "queue %d", &queue_id))
5983         queue_id_valid = 1;
5984       else if (unformat (i, "polling"))
5985         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5986       else if (unformat (i, "interrupt"))
5987         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5988       else if (unformat (i, "adaptive"))
5989         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5990       else
5991         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5992         sw_if_index_set = 1;
5993       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5994         sw_if_index_set = 1;
5995       else
5996         break;
5997     }
5998
5999   if (sw_if_index_set == 0)
6000     {
6001       errmsg ("missing interface name or sw_if_index");
6002       return -99;
6003     }
6004   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6005     {
6006       errmsg ("missing rx-mode");
6007       return -99;
6008     }
6009
6010   /* Construct the API message */
6011   M (SW_INTERFACE_SET_RX_MODE, mp);
6012   mp->sw_if_index = ntohl (sw_if_index);
6013   mp->mode = (vl_api_rx_mode_t) mode;
6014   mp->queue_id_valid = queue_id_valid;
6015   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6016
6017   /* send it... */
6018   S (mp);
6019
6020   /* Wait for a reply, return the good/bad news... */
6021   W (ret);
6022   return ret;
6023 }
6024
6025 static int
6026 api_sw_interface_set_rx_placement (vat_main_t * vam)
6027 {
6028   unformat_input_t *i = vam->input;
6029   vl_api_sw_interface_set_rx_placement_t *mp;
6030   u32 sw_if_index;
6031   u8 sw_if_index_set = 0;
6032   int ret;
6033   u8 is_main = 0;
6034   u32 queue_id, thread_index;
6035
6036   /* Parse args required to build the message */
6037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6038     {
6039       if (unformat (i, "queue %d", &queue_id))
6040         ;
6041       else if (unformat (i, "main"))
6042         is_main = 1;
6043       else if (unformat (i, "worker %d", &thread_index))
6044         ;
6045       else
6046         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6047         sw_if_index_set = 1;
6048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6049         sw_if_index_set = 1;
6050       else
6051         break;
6052     }
6053
6054   if (sw_if_index_set == 0)
6055     {
6056       errmsg ("missing interface name or sw_if_index");
6057       return -99;
6058     }
6059
6060   if (is_main)
6061     thread_index = 0;
6062   /* Construct the API message */
6063   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6064   mp->sw_if_index = ntohl (sw_if_index);
6065   mp->worker_id = ntohl (thread_index);
6066   mp->queue_id = ntohl (queue_id);
6067   mp->is_main = is_main;
6068
6069   /* send it... */
6070   S (mp);
6071   /* Wait for a reply, return the good/bad news... */
6072   W (ret);
6073   return ret;
6074 }
6075
6076 static void vl_api_sw_interface_rx_placement_details_t_handler
6077   (vl_api_sw_interface_rx_placement_details_t * mp)
6078 {
6079   vat_main_t *vam = &vat_main;
6080   u32 worker_id = ntohl (mp->worker_id);
6081
6082   print (vam->ofp,
6083          "\n%-11d %-11s %-6d %-5d %-9s",
6084          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6085          worker_id, ntohl (mp->queue_id),
6086          (mp->mode ==
6087           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6088 }
6089
6090 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6091   (vl_api_sw_interface_rx_placement_details_t * mp)
6092 {
6093   vat_main_t *vam = &vat_main;
6094   vat_json_node_t *node = NULL;
6095
6096   if (VAT_JSON_ARRAY != vam->json_tree.type)
6097     {
6098       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6099       vat_json_init_array (&vam->json_tree);
6100     }
6101   node = vat_json_array_add (&vam->json_tree);
6102
6103   vat_json_init_object (node);
6104   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6105   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6106   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6107   vat_json_object_add_uint (node, "mode", mp->mode);
6108 }
6109
6110 static int
6111 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6112 {
6113   unformat_input_t *i = vam->input;
6114   vl_api_sw_interface_rx_placement_dump_t *mp;
6115   vl_api_control_ping_t *mp_ping;
6116   int ret;
6117   u32 sw_if_index;
6118   u8 sw_if_index_set = 0;
6119
6120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6121     {
6122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6123         sw_if_index_set++;
6124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6125         sw_if_index_set++;
6126       else
6127         break;
6128     }
6129
6130   print (vam->ofp,
6131          "\n%-11s %-11s %-6s %-5s %-4s",
6132          "sw_if_index", "main/worker", "thread", "queue", "mode");
6133
6134   /* Dump Interface rx placement */
6135   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6136
6137   if (sw_if_index_set)
6138     mp->sw_if_index = htonl (sw_if_index);
6139   else
6140     mp->sw_if_index = ~0;
6141
6142   S (mp);
6143
6144   /* Use a control ping for synchronization */
6145   MPING (CONTROL_PING, mp_ping);
6146   S (mp_ping);
6147
6148   W (ret);
6149   return ret;
6150 }
6151
6152 static int
6153 api_sw_interface_clear_stats (vat_main_t * vam)
6154 {
6155   unformat_input_t *i = vam->input;
6156   vl_api_sw_interface_clear_stats_t *mp;
6157   u32 sw_if_index;
6158   u8 sw_if_index_set = 0;
6159   int ret;
6160
6161   /* Parse args required to build the message */
6162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6163     {
6164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6165         sw_if_index_set = 1;
6166       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6167         sw_if_index_set = 1;
6168       else
6169         break;
6170     }
6171
6172   /* Construct the API message */
6173   M (SW_INTERFACE_CLEAR_STATS, mp);
6174
6175   if (sw_if_index_set == 1)
6176     mp->sw_if_index = ntohl (sw_if_index);
6177   else
6178     mp->sw_if_index = ~0;
6179
6180   /* send it... */
6181   S (mp);
6182
6183   /* Wait for a reply, return the good/bad news... */
6184   W (ret);
6185   return ret;
6186 }
6187
6188 static int
6189 api_sw_interface_add_del_address (vat_main_t * vam)
6190 {
6191   unformat_input_t *i = vam->input;
6192   vl_api_sw_interface_add_del_address_t *mp;
6193   u32 sw_if_index;
6194   u8 sw_if_index_set = 0;
6195   u8 is_add = 1, del_all = 0;
6196   u32 address_length = 0;
6197   u8 v4_address_set = 0;
6198   u8 v6_address_set = 0;
6199   ip4_address_t v4address;
6200   ip6_address_t v6address;
6201   int ret;
6202
6203   /* Parse args required to build the message */
6204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6205     {
6206       if (unformat (i, "del-all"))
6207         del_all = 1;
6208       else if (unformat (i, "del"))
6209         is_add = 0;
6210       else
6211         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6212         sw_if_index_set = 1;
6213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6214         sw_if_index_set = 1;
6215       else if (unformat (i, "%U/%d",
6216                          unformat_ip4_address, &v4address, &address_length))
6217         v4_address_set = 1;
6218       else if (unformat (i, "%U/%d",
6219                          unformat_ip6_address, &v6address, &address_length))
6220         v6_address_set = 1;
6221       else
6222         break;
6223     }
6224
6225   if (sw_if_index_set == 0)
6226     {
6227       errmsg ("missing interface name or sw_if_index");
6228       return -99;
6229     }
6230   if (v4_address_set && v6_address_set)
6231     {
6232       errmsg ("both v4 and v6 addresses set");
6233       return -99;
6234     }
6235   if (!v4_address_set && !v6_address_set && !del_all)
6236     {
6237       errmsg ("no addresses set");
6238       return -99;
6239     }
6240
6241   /* Construct the API message */
6242   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6243
6244   mp->sw_if_index = ntohl (sw_if_index);
6245   mp->is_add = is_add;
6246   mp->del_all = del_all;
6247   if (v6_address_set)
6248     {
6249       mp->prefix.address.af = ADDRESS_IP6;
6250       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6251     }
6252   else
6253     {
6254       mp->prefix.address.af = ADDRESS_IP4;
6255       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6256     }
6257   mp->prefix.len = address_length;
6258
6259   /* send it... */
6260   S (mp);
6261
6262   /* Wait for a reply, return good/bad news  */
6263   W (ret);
6264   return ret;
6265 }
6266
6267 static int
6268 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6269 {
6270   unformat_input_t *i = vam->input;
6271   vl_api_sw_interface_set_mpls_enable_t *mp;
6272   u32 sw_if_index;
6273   u8 sw_if_index_set = 0;
6274   u8 enable = 1;
6275   int ret;
6276
6277   /* Parse args required to build the message */
6278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6279     {
6280       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6281         sw_if_index_set = 1;
6282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6283         sw_if_index_set = 1;
6284       else if (unformat (i, "disable"))
6285         enable = 0;
6286       else if (unformat (i, "dis"))
6287         enable = 0;
6288       else
6289         break;
6290     }
6291
6292   if (sw_if_index_set == 0)
6293     {
6294       errmsg ("missing interface name or sw_if_index");
6295       return -99;
6296     }
6297
6298   /* Construct the API message */
6299   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6300
6301   mp->sw_if_index = ntohl (sw_if_index);
6302   mp->enable = enable;
6303
6304   /* send it... */
6305   S (mp);
6306
6307   /* Wait for a reply... */
6308   W (ret);
6309   return ret;
6310 }
6311
6312 static int
6313 api_sw_interface_set_table (vat_main_t * vam)
6314 {
6315   unformat_input_t *i = vam->input;
6316   vl_api_sw_interface_set_table_t *mp;
6317   u32 sw_if_index, vrf_id = 0;
6318   u8 sw_if_index_set = 0;
6319   u8 is_ipv6 = 0;
6320   int ret;
6321
6322   /* Parse args required to build the message */
6323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6324     {
6325       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6326         sw_if_index_set = 1;
6327       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6328         sw_if_index_set = 1;
6329       else if (unformat (i, "vrf %d", &vrf_id))
6330         ;
6331       else if (unformat (i, "ipv6"))
6332         is_ipv6 = 1;
6333       else
6334         break;
6335     }
6336
6337   if (sw_if_index_set == 0)
6338     {
6339       errmsg ("missing interface name or sw_if_index");
6340       return -99;
6341     }
6342
6343   /* Construct the API message */
6344   M (SW_INTERFACE_SET_TABLE, mp);
6345
6346   mp->sw_if_index = ntohl (sw_if_index);
6347   mp->is_ipv6 = is_ipv6;
6348   mp->vrf_id = ntohl (vrf_id);
6349
6350   /* send it... */
6351   S (mp);
6352
6353   /* Wait for a reply... */
6354   W (ret);
6355   return ret;
6356 }
6357
6358 static void vl_api_sw_interface_get_table_reply_t_handler
6359   (vl_api_sw_interface_get_table_reply_t * mp)
6360 {
6361   vat_main_t *vam = &vat_main;
6362
6363   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6364
6365   vam->retval = ntohl (mp->retval);
6366   vam->result_ready = 1;
6367
6368 }
6369
6370 static void vl_api_sw_interface_get_table_reply_t_handler_json
6371   (vl_api_sw_interface_get_table_reply_t * mp)
6372 {
6373   vat_main_t *vam = &vat_main;
6374   vat_json_node_t node;
6375
6376   vat_json_init_object (&node);
6377   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6378   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6379
6380   vat_json_print (vam->ofp, &node);
6381   vat_json_free (&node);
6382
6383   vam->retval = ntohl (mp->retval);
6384   vam->result_ready = 1;
6385 }
6386
6387 static int
6388 api_sw_interface_get_table (vat_main_t * vam)
6389 {
6390   unformat_input_t *i = vam->input;
6391   vl_api_sw_interface_get_table_t *mp;
6392   u32 sw_if_index;
6393   u8 sw_if_index_set = 0;
6394   u8 is_ipv6 = 0;
6395   int ret;
6396
6397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6398     {
6399       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6400         sw_if_index_set = 1;
6401       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6402         sw_if_index_set = 1;
6403       else if (unformat (i, "ipv6"))
6404         is_ipv6 = 1;
6405       else
6406         break;
6407     }
6408
6409   if (sw_if_index_set == 0)
6410     {
6411       errmsg ("missing interface name or sw_if_index");
6412       return -99;
6413     }
6414
6415   M (SW_INTERFACE_GET_TABLE, mp);
6416   mp->sw_if_index = htonl (sw_if_index);
6417   mp->is_ipv6 = is_ipv6;
6418
6419   S (mp);
6420   W (ret);
6421   return ret;
6422 }
6423
6424 static int
6425 api_sw_interface_set_vpath (vat_main_t * vam)
6426 {
6427   unformat_input_t *i = vam->input;
6428   vl_api_sw_interface_set_vpath_t *mp;
6429   u32 sw_if_index = 0;
6430   u8 sw_if_index_set = 0;
6431   u8 is_enable = 0;
6432   int ret;
6433
6434   /* Parse args required to build the message */
6435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6436     {
6437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6438         sw_if_index_set = 1;
6439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6440         sw_if_index_set = 1;
6441       else if (unformat (i, "enable"))
6442         is_enable = 1;
6443       else if (unformat (i, "disable"))
6444         is_enable = 0;
6445       else
6446         break;
6447     }
6448
6449   if (sw_if_index_set == 0)
6450     {
6451       errmsg ("missing interface name or sw_if_index");
6452       return -99;
6453     }
6454
6455   /* Construct the API message */
6456   M (SW_INTERFACE_SET_VPATH, mp);
6457
6458   mp->sw_if_index = ntohl (sw_if_index);
6459   mp->enable = is_enable;
6460
6461   /* send it... */
6462   S (mp);
6463
6464   /* Wait for a reply... */
6465   W (ret);
6466   return ret;
6467 }
6468
6469 static int
6470 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6471 {
6472   unformat_input_t *i = vam->input;
6473   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6474   u32 sw_if_index = 0;
6475   u8 sw_if_index_set = 0;
6476   u8 is_enable = 1;
6477   u8 is_ipv6 = 0;
6478   int ret;
6479
6480   /* Parse args required to build the message */
6481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6482     {
6483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6484         sw_if_index_set = 1;
6485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6486         sw_if_index_set = 1;
6487       else if (unformat (i, "enable"))
6488         is_enable = 1;
6489       else if (unformat (i, "disable"))
6490         is_enable = 0;
6491       else if (unformat (i, "ip4"))
6492         is_ipv6 = 0;
6493       else if (unformat (i, "ip6"))
6494         is_ipv6 = 1;
6495       else
6496         break;
6497     }
6498
6499   if (sw_if_index_set == 0)
6500     {
6501       errmsg ("missing interface name or sw_if_index");
6502       return -99;
6503     }
6504
6505   /* Construct the API message */
6506   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6507
6508   mp->sw_if_index = ntohl (sw_if_index);
6509   mp->enable = is_enable;
6510   mp->is_ipv6 = is_ipv6;
6511
6512   /* send it... */
6513   S (mp);
6514
6515   /* Wait for a reply... */
6516   W (ret);
6517   return ret;
6518 }
6519
6520 static int
6521 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6522 {
6523   unformat_input_t *i = vam->input;
6524   vl_api_sw_interface_set_geneve_bypass_t *mp;
6525   u32 sw_if_index = 0;
6526   u8 sw_if_index_set = 0;
6527   u8 is_enable = 1;
6528   u8 is_ipv6 = 0;
6529   int ret;
6530
6531   /* Parse args required to build the message */
6532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6533     {
6534       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6535         sw_if_index_set = 1;
6536       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6537         sw_if_index_set = 1;
6538       else if (unformat (i, "enable"))
6539         is_enable = 1;
6540       else if (unformat (i, "disable"))
6541         is_enable = 0;
6542       else if (unformat (i, "ip4"))
6543         is_ipv6 = 0;
6544       else if (unformat (i, "ip6"))
6545         is_ipv6 = 1;
6546       else
6547         break;
6548     }
6549
6550   if (sw_if_index_set == 0)
6551     {
6552       errmsg ("missing interface name or sw_if_index");
6553       return -99;
6554     }
6555
6556   /* Construct the API message */
6557   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6558
6559   mp->sw_if_index = ntohl (sw_if_index);
6560   mp->enable = is_enable;
6561   mp->is_ipv6 = is_ipv6;
6562
6563   /* send it... */
6564   S (mp);
6565
6566   /* Wait for a reply... */
6567   W (ret);
6568   return ret;
6569 }
6570
6571 static int
6572 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6573 {
6574   unformat_input_t *i = vam->input;
6575   vl_api_sw_interface_set_l2_xconnect_t *mp;
6576   u32 rx_sw_if_index;
6577   u8 rx_sw_if_index_set = 0;
6578   u32 tx_sw_if_index;
6579   u8 tx_sw_if_index_set = 0;
6580   u8 enable = 1;
6581   int ret;
6582
6583   /* Parse args required to build the message */
6584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6585     {
6586       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6587         rx_sw_if_index_set = 1;
6588       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6589         tx_sw_if_index_set = 1;
6590       else if (unformat (i, "rx"))
6591         {
6592           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6593             {
6594               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6595                             &rx_sw_if_index))
6596                 rx_sw_if_index_set = 1;
6597             }
6598           else
6599             break;
6600         }
6601       else if (unformat (i, "tx"))
6602         {
6603           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6604             {
6605               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6606                             &tx_sw_if_index))
6607                 tx_sw_if_index_set = 1;
6608             }
6609           else
6610             break;
6611         }
6612       else if (unformat (i, "enable"))
6613         enable = 1;
6614       else if (unformat (i, "disable"))
6615         enable = 0;
6616       else
6617         break;
6618     }
6619
6620   if (rx_sw_if_index_set == 0)
6621     {
6622       errmsg ("missing rx interface name or rx_sw_if_index");
6623       return -99;
6624     }
6625
6626   if (enable && (tx_sw_if_index_set == 0))
6627     {
6628       errmsg ("missing tx interface name or tx_sw_if_index");
6629       return -99;
6630     }
6631
6632   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6633
6634   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6635   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6636   mp->enable = enable;
6637
6638   S (mp);
6639   W (ret);
6640   return ret;
6641 }
6642
6643 static int
6644 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6645 {
6646   unformat_input_t *i = vam->input;
6647   vl_api_sw_interface_set_l2_bridge_t *mp;
6648   vl_api_l2_port_type_t port_type;
6649   u32 rx_sw_if_index;
6650   u8 rx_sw_if_index_set = 0;
6651   u32 bd_id;
6652   u8 bd_id_set = 0;
6653   u32 shg = 0;
6654   u8 enable = 1;
6655   int ret;
6656
6657   port_type = L2_API_PORT_TYPE_NORMAL;
6658
6659   /* Parse args required to build the message */
6660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6661     {
6662       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6663         rx_sw_if_index_set = 1;
6664       else if (unformat (i, "bd_id %d", &bd_id))
6665         bd_id_set = 1;
6666       else
6667         if (unformat
6668             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6669         rx_sw_if_index_set = 1;
6670       else if (unformat (i, "shg %d", &shg))
6671         ;
6672       else if (unformat (i, "bvi"))
6673         port_type = L2_API_PORT_TYPE_BVI;
6674       else if (unformat (i, "uu-fwd"))
6675         port_type = L2_API_PORT_TYPE_UU_FWD;
6676       else if (unformat (i, "enable"))
6677         enable = 1;
6678       else if (unformat (i, "disable"))
6679         enable = 0;
6680       else
6681         break;
6682     }
6683
6684   if (rx_sw_if_index_set == 0)
6685     {
6686       errmsg ("missing rx interface name or sw_if_index");
6687       return -99;
6688     }
6689
6690   if (enable && (bd_id_set == 0))
6691     {
6692       errmsg ("missing bridge domain");
6693       return -99;
6694     }
6695
6696   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6697
6698   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6699   mp->bd_id = ntohl (bd_id);
6700   mp->shg = (u8) shg;
6701   mp->port_type = ntohl (port_type);
6702   mp->enable = enable;
6703
6704   S (mp);
6705   W (ret);
6706   return ret;
6707 }
6708
6709 static int
6710 api_bridge_domain_dump (vat_main_t * vam)
6711 {
6712   unformat_input_t *i = vam->input;
6713   vl_api_bridge_domain_dump_t *mp;
6714   vl_api_control_ping_t *mp_ping;
6715   u32 bd_id = ~0;
6716   int ret;
6717
6718   /* Parse args required to build the message */
6719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6720     {
6721       if (unformat (i, "bd_id %d", &bd_id))
6722         ;
6723       else
6724         break;
6725     }
6726
6727   M (BRIDGE_DOMAIN_DUMP, mp);
6728   mp->bd_id = ntohl (bd_id);
6729   S (mp);
6730
6731   /* Use a control ping for synchronization */
6732   MPING (CONTROL_PING, mp_ping);
6733   S (mp_ping);
6734
6735   W (ret);
6736   return ret;
6737 }
6738
6739 static int
6740 api_bridge_domain_add_del (vat_main_t * vam)
6741 {
6742   unformat_input_t *i = vam->input;
6743   vl_api_bridge_domain_add_del_t *mp;
6744   u32 bd_id = ~0;
6745   u8 is_add = 1;
6746   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6747   u8 *bd_tag = NULL;
6748   u32 mac_age = 0;
6749   int ret;
6750
6751   /* Parse args required to build the message */
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "bd_id %d", &bd_id))
6755         ;
6756       else if (unformat (i, "flood %d", &flood))
6757         ;
6758       else if (unformat (i, "uu-flood %d", &uu_flood))
6759         ;
6760       else if (unformat (i, "forward %d", &forward))
6761         ;
6762       else if (unformat (i, "learn %d", &learn))
6763         ;
6764       else if (unformat (i, "arp-term %d", &arp_term))
6765         ;
6766       else if (unformat (i, "mac-age %d", &mac_age))
6767         ;
6768       else if (unformat (i, "bd-tag %s", &bd_tag))
6769         ;
6770       else if (unformat (i, "del"))
6771         {
6772           is_add = 0;
6773           flood = uu_flood = forward = learn = 0;
6774         }
6775       else
6776         break;
6777     }
6778
6779   if (bd_id == ~0)
6780     {
6781       errmsg ("missing bridge domain");
6782       ret = -99;
6783       goto done;
6784     }
6785
6786   if (mac_age > 255)
6787     {
6788       errmsg ("mac age must be less than 256 ");
6789       ret = -99;
6790       goto done;
6791     }
6792
6793   if ((bd_tag) && (vec_len (bd_tag) > 63))
6794     {
6795       errmsg ("bd-tag cannot be longer than 63");
6796       ret = -99;
6797       goto done;
6798     }
6799
6800   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6801
6802   mp->bd_id = ntohl (bd_id);
6803   mp->flood = flood;
6804   mp->uu_flood = uu_flood;
6805   mp->forward = forward;
6806   mp->learn = learn;
6807   mp->arp_term = arp_term;
6808   mp->is_add = is_add;
6809   mp->mac_age = (u8) mac_age;
6810   if (bd_tag)
6811     {
6812       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6813       mp->bd_tag[vec_len (bd_tag)] = 0;
6814     }
6815   S (mp);
6816   W (ret);
6817
6818 done:
6819   vec_free (bd_tag);
6820   return ret;
6821 }
6822
6823 static int
6824 api_l2fib_flush_bd (vat_main_t * vam)
6825 {
6826   unformat_input_t *i = vam->input;
6827   vl_api_l2fib_flush_bd_t *mp;
6828   u32 bd_id = ~0;
6829   int ret;
6830
6831   /* Parse args required to build the message */
6832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6833     {
6834       if (unformat (i, "bd_id %d", &bd_id));
6835       else
6836         break;
6837     }
6838
6839   if (bd_id == ~0)
6840     {
6841       errmsg ("missing bridge domain");
6842       return -99;
6843     }
6844
6845   M (L2FIB_FLUSH_BD, mp);
6846
6847   mp->bd_id = htonl (bd_id);
6848
6849   S (mp);
6850   W (ret);
6851   return ret;
6852 }
6853
6854 static int
6855 api_l2fib_flush_int (vat_main_t * vam)
6856 {
6857   unformat_input_t *i = vam->input;
6858   vl_api_l2fib_flush_int_t *mp;
6859   u32 sw_if_index = ~0;
6860   int ret;
6861
6862   /* Parse args required to build the message */
6863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6864     {
6865       if (unformat (i, "sw_if_index %d", &sw_if_index));
6866       else
6867         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6868       else
6869         break;
6870     }
6871
6872   if (sw_if_index == ~0)
6873     {
6874       errmsg ("missing interface name or sw_if_index");
6875       return -99;
6876     }
6877
6878   M (L2FIB_FLUSH_INT, mp);
6879
6880   mp->sw_if_index = ntohl (sw_if_index);
6881
6882   S (mp);
6883   W (ret);
6884   return ret;
6885 }
6886
6887 static int
6888 api_l2fib_add_del (vat_main_t * vam)
6889 {
6890   unformat_input_t *i = vam->input;
6891   vl_api_l2fib_add_del_t *mp;
6892   f64 timeout;
6893   u8 mac[6] = { 0 };
6894   u8 mac_set = 0;
6895   u32 bd_id;
6896   u8 bd_id_set = 0;
6897   u32 sw_if_index = 0;
6898   u8 sw_if_index_set = 0;
6899   u8 is_add = 1;
6900   u8 static_mac = 0;
6901   u8 filter_mac = 0;
6902   u8 bvi_mac = 0;
6903   int count = 1;
6904   f64 before = 0;
6905   int j;
6906
6907   /* Parse args required to build the message */
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6911         mac_set = 1;
6912       else if (unformat (i, "bd_id %d", &bd_id))
6913         bd_id_set = 1;
6914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6915         sw_if_index_set = 1;
6916       else if (unformat (i, "sw_if"))
6917         {
6918           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6919             {
6920               if (unformat
6921                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6922                 sw_if_index_set = 1;
6923             }
6924           else
6925             break;
6926         }
6927       else if (unformat (i, "static"))
6928         static_mac = 1;
6929       else if (unformat (i, "filter"))
6930         {
6931           filter_mac = 1;
6932           static_mac = 1;
6933         }
6934       else if (unformat (i, "bvi"))
6935         {
6936           bvi_mac = 1;
6937           static_mac = 1;
6938         }
6939       else if (unformat (i, "del"))
6940         is_add = 0;
6941       else if (unformat (i, "count %d", &count))
6942         ;
6943       else
6944         break;
6945     }
6946
6947   if (mac_set == 0)
6948     {
6949       errmsg ("missing mac address");
6950       return -99;
6951     }
6952
6953   if (bd_id_set == 0)
6954     {
6955       errmsg ("missing bridge domain");
6956       return -99;
6957     }
6958
6959   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6960     {
6961       errmsg ("missing interface name or sw_if_index");
6962       return -99;
6963     }
6964
6965   if (count > 1)
6966     {
6967       /* Turn on async mode */
6968       vam->async_mode = 1;
6969       vam->async_errors = 0;
6970       before = vat_time_now (vam);
6971     }
6972
6973   for (j = 0; j < count; j++)
6974     {
6975       M (L2FIB_ADD_DEL, mp);
6976
6977       clib_memcpy (mp->mac, mac, 6);
6978       mp->bd_id = ntohl (bd_id);
6979       mp->is_add = is_add;
6980       mp->sw_if_index = ntohl (sw_if_index);
6981
6982       if (is_add)
6983         {
6984           mp->static_mac = static_mac;
6985           mp->filter_mac = filter_mac;
6986           mp->bvi_mac = bvi_mac;
6987         }
6988       increment_mac_address (mac);
6989       /* send it... */
6990       S (mp);
6991     }
6992
6993   if (count > 1)
6994     {
6995       vl_api_control_ping_t *mp_ping;
6996       f64 after;
6997
6998       /* Shut off async mode */
6999       vam->async_mode = 0;
7000
7001       MPING (CONTROL_PING, mp_ping);
7002       S (mp_ping);
7003
7004       timeout = vat_time_now (vam) + 1.0;
7005       while (vat_time_now (vam) < timeout)
7006         if (vam->result_ready == 1)
7007           goto out;
7008       vam->retval = -99;
7009
7010     out:
7011       if (vam->retval == -99)
7012         errmsg ("timeout");
7013
7014       if (vam->async_errors > 0)
7015         {
7016           errmsg ("%d asynchronous errors", vam->async_errors);
7017           vam->retval = -98;
7018         }
7019       vam->async_errors = 0;
7020       after = vat_time_now (vam);
7021
7022       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7023              count, after - before, count / (after - before));
7024     }
7025   else
7026     {
7027       int ret;
7028
7029       /* Wait for a reply... */
7030       W (ret);
7031       return ret;
7032     }
7033   /* Return the good/bad news */
7034   return (vam->retval);
7035 }
7036
7037 static int
7038 api_bridge_domain_set_mac_age (vat_main_t * vam)
7039 {
7040   unformat_input_t *i = vam->input;
7041   vl_api_bridge_domain_set_mac_age_t *mp;
7042   u32 bd_id = ~0;
7043   u32 mac_age = 0;
7044   int ret;
7045
7046   /* Parse args required to build the message */
7047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7048     {
7049       if (unformat (i, "bd_id %d", &bd_id));
7050       else if (unformat (i, "mac-age %d", &mac_age));
7051       else
7052         break;
7053     }
7054
7055   if (bd_id == ~0)
7056     {
7057       errmsg ("missing bridge domain");
7058       return -99;
7059     }
7060
7061   if (mac_age > 255)
7062     {
7063       errmsg ("mac age must be less than 256 ");
7064       return -99;
7065     }
7066
7067   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7068
7069   mp->bd_id = htonl (bd_id);
7070   mp->mac_age = (u8) mac_age;
7071
7072   S (mp);
7073   W (ret);
7074   return ret;
7075 }
7076
7077 static int
7078 api_l2_flags (vat_main_t * vam)
7079 {
7080   unformat_input_t *i = vam->input;
7081   vl_api_l2_flags_t *mp;
7082   u32 sw_if_index;
7083   u32 flags = 0;
7084   u8 sw_if_index_set = 0;
7085   u8 is_set = 0;
7086   int ret;
7087
7088   /* Parse args required to build the message */
7089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7090     {
7091       if (unformat (i, "sw_if_index %d", &sw_if_index))
7092         sw_if_index_set = 1;
7093       else if (unformat (i, "sw_if"))
7094         {
7095           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7096             {
7097               if (unformat
7098                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7099                 sw_if_index_set = 1;
7100             }
7101           else
7102             break;
7103         }
7104       else if (unformat (i, "learn"))
7105         flags |= L2_LEARN;
7106       else if (unformat (i, "forward"))
7107         flags |= L2_FWD;
7108       else if (unformat (i, "flood"))
7109         flags |= L2_FLOOD;
7110       else if (unformat (i, "uu-flood"))
7111         flags |= L2_UU_FLOOD;
7112       else if (unformat (i, "arp-term"))
7113         flags |= L2_ARP_TERM;
7114       else if (unformat (i, "off"))
7115         is_set = 0;
7116       else if (unformat (i, "disable"))
7117         is_set = 0;
7118       else
7119         break;
7120     }
7121
7122   if (sw_if_index_set == 0)
7123     {
7124       errmsg ("missing interface name or sw_if_index");
7125       return -99;
7126     }
7127
7128   M (L2_FLAGS, mp);
7129
7130   mp->sw_if_index = ntohl (sw_if_index);
7131   mp->feature_bitmap = ntohl (flags);
7132   mp->is_set = is_set;
7133
7134   S (mp);
7135   W (ret);
7136   return ret;
7137 }
7138
7139 static int
7140 api_bridge_flags (vat_main_t * vam)
7141 {
7142   unformat_input_t *i = vam->input;
7143   vl_api_bridge_flags_t *mp;
7144   u32 bd_id;
7145   u8 bd_id_set = 0;
7146   u8 is_set = 1;
7147   bd_flags_t flags = 0;
7148   int ret;
7149
7150   /* Parse args required to build the message */
7151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7152     {
7153       if (unformat (i, "bd_id %d", &bd_id))
7154         bd_id_set = 1;
7155       else if (unformat (i, "learn"))
7156         flags |= BRIDGE_API_FLAG_LEARN;
7157       else if (unformat (i, "forward"))
7158         flags |= BRIDGE_API_FLAG_FWD;
7159       else if (unformat (i, "flood"))
7160         flags |= BRIDGE_API_FLAG_FLOOD;
7161       else if (unformat (i, "uu-flood"))
7162         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7163       else if (unformat (i, "arp-term"))
7164         flags |= BRIDGE_API_FLAG_ARP_TERM;
7165       else if (unformat (i, "off"))
7166         is_set = 0;
7167       else if (unformat (i, "disable"))
7168         is_set = 0;
7169       else
7170         break;
7171     }
7172
7173   if (bd_id_set == 0)
7174     {
7175       errmsg ("missing bridge domain");
7176       return -99;
7177     }
7178
7179   M (BRIDGE_FLAGS, mp);
7180
7181   mp->bd_id = ntohl (bd_id);
7182   mp->flags = ntohl (flags);
7183   mp->is_set = is_set;
7184
7185   S (mp);
7186   W (ret);
7187   return ret;
7188 }
7189
7190 static int
7191 api_bd_ip_mac_add_del (vat_main_t * vam)
7192 {
7193   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7194   vl_api_mac_address_t mac = { 0 };
7195   unformat_input_t *i = vam->input;
7196   vl_api_bd_ip_mac_add_del_t *mp;
7197   u32 bd_id;
7198   u8 is_add = 1;
7199   u8 bd_id_set = 0;
7200   u8 ip_set = 0;
7201   u8 mac_set = 0;
7202   int ret;
7203
7204
7205   /* Parse args required to build the message */
7206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7207     {
7208       if (unformat (i, "bd_id %d", &bd_id))
7209         {
7210           bd_id_set++;
7211         }
7212       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7213         {
7214           ip_set++;
7215         }
7216       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7217         {
7218           mac_set++;
7219         }
7220       else if (unformat (i, "del"))
7221         is_add = 0;
7222       else
7223         break;
7224     }
7225
7226   if (bd_id_set == 0)
7227     {
7228       errmsg ("missing bridge domain");
7229       return -99;
7230     }
7231   else if (ip_set == 0)
7232     {
7233       errmsg ("missing IP address");
7234       return -99;
7235     }
7236   else if (mac_set == 0)
7237     {
7238       errmsg ("missing MAC address");
7239       return -99;
7240     }
7241
7242   M (BD_IP_MAC_ADD_DEL, mp);
7243
7244   mp->entry.bd_id = ntohl (bd_id);
7245   mp->is_add = is_add;
7246
7247   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7248   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7249
7250   S (mp);
7251   W (ret);
7252   return ret;
7253 }
7254
7255 static int
7256 api_bd_ip_mac_flush (vat_main_t * vam)
7257 {
7258   unformat_input_t *i = vam->input;
7259   vl_api_bd_ip_mac_flush_t *mp;
7260   u32 bd_id;
7261   u8 bd_id_set = 0;
7262   int ret;
7263
7264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7265     {
7266       if (unformat (i, "bd_id %d", &bd_id))
7267         {
7268           bd_id_set++;
7269         }
7270       else
7271         break;
7272     }
7273
7274   if (bd_id_set == 0)
7275     {
7276       errmsg ("missing bridge domain");
7277       return -99;
7278     }
7279
7280   M (BD_IP_MAC_FLUSH, mp);
7281
7282   mp->bd_id = ntohl (bd_id);
7283
7284   S (mp);
7285   W (ret);
7286   return ret;
7287 }
7288
7289 static void vl_api_bd_ip_mac_details_t_handler
7290   (vl_api_bd_ip_mac_details_t * mp)
7291 {
7292   vat_main_t *vam = &vat_main;
7293
7294   print (vam->ofp,
7295          "\n%-5d %U %U",
7296          ntohl (mp->entry.bd_id),
7297          format_vl_api_mac_address, mp->entry.mac,
7298          format_vl_api_address, &mp->entry.ip);
7299 }
7300
7301 static void vl_api_bd_ip_mac_details_t_handler_json
7302   (vl_api_bd_ip_mac_details_t * mp)
7303 {
7304   vat_main_t *vam = &vat_main;
7305   vat_json_node_t *node = NULL;
7306
7307   if (VAT_JSON_ARRAY != vam->json_tree.type)
7308     {
7309       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7310       vat_json_init_array (&vam->json_tree);
7311     }
7312   node = vat_json_array_add (&vam->json_tree);
7313
7314   vat_json_init_object (node);
7315   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7316   vat_json_object_add_string_copy (node, "mac_address",
7317                                    format (0, "%U", format_vl_api_mac_address,
7318                                            &mp->entry.mac));
7319   u8 *ip = 0;
7320
7321   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7322   vat_json_object_add_string_copy (node, "ip_address", ip);
7323   vec_free (ip);
7324 }
7325
7326 static int
7327 api_bd_ip_mac_dump (vat_main_t * vam)
7328 {
7329   unformat_input_t *i = vam->input;
7330   vl_api_bd_ip_mac_dump_t *mp;
7331   vl_api_control_ping_t *mp_ping;
7332   int ret;
7333   u32 bd_id;
7334   u8 bd_id_set = 0;
7335
7336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7337     {
7338       if (unformat (i, "bd_id %d", &bd_id))
7339         {
7340           bd_id_set++;
7341         }
7342       else
7343         break;
7344     }
7345
7346   print (vam->ofp,
7347          "\n%-5s %-7s %-20s %-30s",
7348          "bd_id", "is_ipv6", "mac_address", "ip_address");
7349
7350   /* Dump Bridge Domain Ip to Mac entries */
7351   M (BD_IP_MAC_DUMP, mp);
7352
7353   if (bd_id_set)
7354     mp->bd_id = htonl (bd_id);
7355   else
7356     mp->bd_id = ~0;
7357
7358   S (mp);
7359
7360   /* Use a control ping for synchronization */
7361   MPING (CONTROL_PING, mp_ping);
7362   S (mp_ping);
7363
7364   W (ret);
7365   return ret;
7366 }
7367
7368 static int
7369 api_tap_create_v2 (vat_main_t * vam)
7370 {
7371   unformat_input_t *i = vam->input;
7372   vl_api_tap_create_v2_t *mp;
7373 #define TAP_FLAG_GSO (1 << 0)
7374   u8 mac_address[6];
7375   u8 random_mac = 1;
7376   u32 id = ~0;
7377   u8 *host_if_name = 0;
7378   u8 *host_ns = 0;
7379   u8 host_mac_addr[6];
7380   u8 host_mac_addr_set = 0;
7381   u8 *host_bridge = 0;
7382   ip4_address_t host_ip4_addr;
7383   ip4_address_t host_ip4_gw;
7384   u8 host_ip4_gw_set = 0;
7385   u32 host_ip4_prefix_len = 0;
7386   ip6_address_t host_ip6_addr;
7387   ip6_address_t host_ip6_gw;
7388   u8 host_ip6_gw_set = 0;
7389   u32 host_ip6_prefix_len = 0;
7390   u8 host_mtu_set = 0;
7391   u32 host_mtu_size = 0;
7392   u32 tap_flags = 0;
7393   int ret;
7394   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7395
7396   clib_memset (mac_address, 0, sizeof (mac_address));
7397
7398   /* Parse args required to build the message */
7399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7400     {
7401       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7402         {
7403           random_mac = 0;
7404         }
7405       else if (unformat (i, "id %u", &id))
7406         ;
7407       else if (unformat (i, "host-if-name %s", &host_if_name))
7408         ;
7409       else if (unformat (i, "host-ns %s", &host_ns))
7410         ;
7411       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7412                          host_mac_addr))
7413         host_mac_addr_set = 1;
7414       else if (unformat (i, "host-bridge %s", &host_bridge))
7415         ;
7416       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7417                          &host_ip4_addr, &host_ip4_prefix_len))
7418         ;
7419       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7420                          &host_ip6_addr, &host_ip6_prefix_len))
7421         ;
7422       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7423                          &host_ip4_gw))
7424         host_ip4_gw_set = 1;
7425       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7426                          &host_ip6_gw))
7427         host_ip6_gw_set = 1;
7428       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7429         ;
7430       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7431         ;
7432       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7433         host_mtu_set = 1;
7434       else if (unformat (i, "no-gso"))
7435         tap_flags &= ~TAP_FLAG_GSO;
7436       else if (unformat (i, "gso"))
7437         tap_flags |= TAP_FLAG_GSO;
7438       else
7439         break;
7440     }
7441
7442   if (vec_len (host_if_name) > 63)
7443     {
7444       errmsg ("tap name too long. ");
7445       return -99;
7446     }
7447   if (vec_len (host_ns) > 63)
7448     {
7449       errmsg ("host name space too long. ");
7450       return -99;
7451     }
7452   if (vec_len (host_bridge) > 63)
7453     {
7454       errmsg ("host bridge name too long. ");
7455       return -99;
7456     }
7457   if (host_ip4_prefix_len > 32)
7458     {
7459       errmsg ("host ip4 prefix length not valid. ");
7460       return -99;
7461     }
7462   if (host_ip6_prefix_len > 128)
7463     {
7464       errmsg ("host ip6 prefix length not valid. ");
7465       return -99;
7466     }
7467   if (!is_pow2 (rx_ring_sz))
7468     {
7469       errmsg ("rx ring size must be power of 2. ");
7470       return -99;
7471     }
7472   if (rx_ring_sz > 32768)
7473     {
7474       errmsg ("rx ring size must be 32768 or lower. ");
7475       return -99;
7476     }
7477   if (!is_pow2 (tx_ring_sz))
7478     {
7479       errmsg ("tx ring size must be power of 2. ");
7480       return -99;
7481     }
7482   if (tx_ring_sz > 32768)
7483     {
7484       errmsg ("tx ring size must be 32768 or lower. ");
7485       return -99;
7486     }
7487   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7488     {
7489       errmsg ("host MTU size must be in between 64 and 65355. ");
7490       return -99;
7491     }
7492
7493   /* Construct the API message */
7494   M (TAP_CREATE_V2, mp);
7495
7496   mp->use_random_mac = random_mac;
7497
7498   mp->id = ntohl (id);
7499   mp->host_namespace_set = host_ns != 0;
7500   mp->host_bridge_set = host_bridge != 0;
7501   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7502   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7503   mp->rx_ring_sz = ntohs (rx_ring_sz);
7504   mp->tx_ring_sz = ntohs (tx_ring_sz);
7505   mp->host_mtu_set = host_mtu_set;
7506   mp->host_mtu_size = ntohl (host_mtu_size);
7507   mp->tap_flags = ntohl (tap_flags);
7508
7509   if (random_mac == 0)
7510     clib_memcpy (mp->mac_address, mac_address, 6);
7511   if (host_mac_addr_set)
7512     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7513   if (host_if_name)
7514     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7515   if (host_ns)
7516     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7517   if (host_bridge)
7518     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7519   if (host_ip4_prefix_len)
7520     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7521   if (host_ip6_prefix_len)
7522     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7523   if (host_ip4_gw_set)
7524     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7525   if (host_ip6_gw_set)
7526     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7527
7528   vec_free (host_ns);
7529   vec_free (host_if_name);
7530   vec_free (host_bridge);
7531
7532   /* send it... */
7533   S (mp);
7534
7535   /* Wait for a reply... */
7536   W (ret);
7537   return ret;
7538 }
7539
7540 static int
7541 api_tap_delete_v2 (vat_main_t * vam)
7542 {
7543   unformat_input_t *i = vam->input;
7544   vl_api_tap_delete_v2_t *mp;
7545   u32 sw_if_index = ~0;
7546   u8 sw_if_index_set = 0;
7547   int ret;
7548
7549   /* Parse args required to build the message */
7550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7551     {
7552       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7553         sw_if_index_set = 1;
7554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7555         sw_if_index_set = 1;
7556       else
7557         break;
7558     }
7559
7560   if (sw_if_index_set == 0)
7561     {
7562       errmsg ("missing vpp interface name. ");
7563       return -99;
7564     }
7565
7566   /* Construct the API message */
7567   M (TAP_DELETE_V2, mp);
7568
7569   mp->sw_if_index = ntohl (sw_if_index);
7570
7571   /* send it... */
7572   S (mp);
7573
7574   /* Wait for a reply... */
7575   W (ret);
7576   return ret;
7577 }
7578
7579 uword
7580 unformat_pci_addr (unformat_input_t * input, va_list * args)
7581 {
7582   struct pci_addr_t
7583   {
7584     u16 domain;
7585     u8 bus;
7586     u8 slot:5;
7587     u8 function:3;
7588   } *addr;
7589   addr = va_arg (*args, struct pci_addr_t *);
7590   u32 x[4];
7591
7592   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7593     return 0;
7594
7595   addr->domain = x[0];
7596   addr->bus = x[1];
7597   addr->slot = x[2];
7598   addr->function = x[3];
7599
7600   return 1;
7601 }
7602
7603 static int
7604 api_virtio_pci_create (vat_main_t * vam)
7605 {
7606   unformat_input_t *i = vam->input;
7607   vl_api_virtio_pci_create_t *mp;
7608   u8 mac_address[6];
7609   u8 random_mac = 1;
7610   u8 gso_enabled = 0;
7611   u32 pci_addr = 0;
7612   u64 features = (u64) ~ (0ULL);
7613   int ret;
7614
7615   clib_memset (mac_address, 0, sizeof (mac_address));
7616
7617   /* Parse args required to build the message */
7618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7619     {
7620       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7621         {
7622           random_mac = 0;
7623         }
7624       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7625         ;
7626       else if (unformat (i, "features 0x%llx", &features))
7627         ;
7628       else if (unformat (i, "gso-enabled"))
7629         gso_enabled = 1;
7630       else
7631         break;
7632     }
7633
7634   if (pci_addr == 0)
7635     {
7636       errmsg ("pci address must be non zero. ");
7637       return -99;
7638     }
7639
7640   /* Construct the API message */
7641   M (VIRTIO_PCI_CREATE, mp);
7642
7643   mp->use_random_mac = random_mac;
7644
7645   mp->pci_addr = htonl (pci_addr);
7646   mp->features = clib_host_to_net_u64 (features);
7647   mp->gso_enabled = gso_enabled;
7648
7649   if (random_mac == 0)
7650     clib_memcpy (mp->mac_address, mac_address, 6);
7651
7652   /* send it... */
7653   S (mp);
7654
7655   /* Wait for a reply... */
7656   W (ret);
7657   return ret;
7658 }
7659
7660 static int
7661 api_virtio_pci_delete (vat_main_t * vam)
7662 {
7663   unformat_input_t *i = vam->input;
7664   vl_api_virtio_pci_delete_t *mp;
7665   u32 sw_if_index = ~0;
7666   u8 sw_if_index_set = 0;
7667   int ret;
7668
7669   /* Parse args required to build the message */
7670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7671     {
7672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7673         sw_if_index_set = 1;
7674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7675         sw_if_index_set = 1;
7676       else
7677         break;
7678     }
7679
7680   if (sw_if_index_set == 0)
7681     {
7682       errmsg ("missing vpp interface name. ");
7683       return -99;
7684     }
7685
7686   /* Construct the API message */
7687   M (VIRTIO_PCI_DELETE, mp);
7688
7689   mp->sw_if_index = htonl (sw_if_index);
7690
7691   /* send it... */
7692   S (mp);
7693
7694   /* Wait for a reply... */
7695   W (ret);
7696   return ret;
7697 }
7698
7699 static int
7700 api_bond_create (vat_main_t * vam)
7701 {
7702   unformat_input_t *i = vam->input;
7703   vl_api_bond_create_t *mp;
7704   u8 mac_address[6];
7705   u8 custom_mac = 0;
7706   int ret;
7707   u8 mode;
7708   u8 lb;
7709   u8 mode_is_set = 0;
7710   u32 id = ~0;
7711   u8 numa_only = 0;
7712
7713   clib_memset (mac_address, 0, sizeof (mac_address));
7714   lb = BOND_LB_L2;
7715
7716   /* Parse args required to build the message */
7717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7718     {
7719       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7720         mode_is_set = 1;
7721       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7722                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7723         ;
7724       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7725                          mac_address))
7726         custom_mac = 1;
7727       else if (unformat (i, "numa-only"))
7728         numa_only = 1;
7729       else if (unformat (i, "id %u", &id))
7730         ;
7731       else
7732         break;
7733     }
7734
7735   if (mode_is_set == 0)
7736     {
7737       errmsg ("Missing bond mode. ");
7738       return -99;
7739     }
7740
7741   /* Construct the API message */
7742   M (BOND_CREATE, mp);
7743
7744   mp->use_custom_mac = custom_mac;
7745
7746   mp->mode = mode;
7747   mp->lb = lb;
7748   mp->id = htonl (id);
7749   mp->numa_only = numa_only;
7750
7751   if (custom_mac)
7752     clib_memcpy (mp->mac_address, mac_address, 6);
7753
7754   /* send it... */
7755   S (mp);
7756
7757   /* Wait for a reply... */
7758   W (ret);
7759   return ret;
7760 }
7761
7762 static int
7763 api_bond_delete (vat_main_t * vam)
7764 {
7765   unformat_input_t *i = vam->input;
7766   vl_api_bond_delete_t *mp;
7767   u32 sw_if_index = ~0;
7768   u8 sw_if_index_set = 0;
7769   int ret;
7770
7771   /* Parse args required to build the message */
7772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7773     {
7774       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7775         sw_if_index_set = 1;
7776       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7777         sw_if_index_set = 1;
7778       else
7779         break;
7780     }
7781
7782   if (sw_if_index_set == 0)
7783     {
7784       errmsg ("missing vpp interface name. ");
7785       return -99;
7786     }
7787
7788   /* Construct the API message */
7789   M (BOND_DELETE, mp);
7790
7791   mp->sw_if_index = ntohl (sw_if_index);
7792
7793   /* send it... */
7794   S (mp);
7795
7796   /* Wait for a reply... */
7797   W (ret);
7798   return ret;
7799 }
7800
7801 static int
7802 api_bond_enslave (vat_main_t * vam)
7803 {
7804   unformat_input_t *i = vam->input;
7805   vl_api_bond_enslave_t *mp;
7806   u32 bond_sw_if_index;
7807   int ret;
7808   u8 is_passive;
7809   u8 is_long_timeout;
7810   u32 bond_sw_if_index_is_set = 0;
7811   u32 sw_if_index;
7812   u8 sw_if_index_is_set = 0;
7813
7814   /* Parse args required to build the message */
7815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7816     {
7817       if (unformat (i, "sw_if_index %d", &sw_if_index))
7818         sw_if_index_is_set = 1;
7819       else if (unformat (i, "bond %u", &bond_sw_if_index))
7820         bond_sw_if_index_is_set = 1;
7821       else if (unformat (i, "passive %d", &is_passive))
7822         ;
7823       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7824         ;
7825       else
7826         break;
7827     }
7828
7829   if (bond_sw_if_index_is_set == 0)
7830     {
7831       errmsg ("Missing bond sw_if_index. ");
7832       return -99;
7833     }
7834   if (sw_if_index_is_set == 0)
7835     {
7836       errmsg ("Missing slave sw_if_index. ");
7837       return -99;
7838     }
7839
7840   /* Construct the API message */
7841   M (BOND_ENSLAVE, mp);
7842
7843   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7844   mp->sw_if_index = ntohl (sw_if_index);
7845   mp->is_long_timeout = is_long_timeout;
7846   mp->is_passive = is_passive;
7847
7848   /* send it... */
7849   S (mp);
7850
7851   /* Wait for a reply... */
7852   W (ret);
7853   return ret;
7854 }
7855
7856 static int
7857 api_bond_detach_slave (vat_main_t * vam)
7858 {
7859   unformat_input_t *i = vam->input;
7860   vl_api_bond_detach_slave_t *mp;
7861   u32 sw_if_index = ~0;
7862   u8 sw_if_index_set = 0;
7863   int ret;
7864
7865   /* Parse args required to build the message */
7866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7867     {
7868       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7869         sw_if_index_set = 1;
7870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7871         sw_if_index_set = 1;
7872       else
7873         break;
7874     }
7875
7876   if (sw_if_index_set == 0)
7877     {
7878       errmsg ("missing vpp interface name. ");
7879       return -99;
7880     }
7881
7882   /* Construct the API message */
7883   M (BOND_DETACH_SLAVE, mp);
7884
7885   mp->sw_if_index = ntohl (sw_if_index);
7886
7887   /* send it... */
7888   S (mp);
7889
7890   /* Wait for a reply... */
7891   W (ret);
7892   return ret;
7893 }
7894
7895 static int
7896 api_ip_table_add_del (vat_main_t * vam)
7897 {
7898   unformat_input_t *i = vam->input;
7899   vl_api_ip_table_add_del_t *mp;
7900   u32 table_id = ~0;
7901   u8 is_ipv6 = 0;
7902   u8 is_add = 1;
7903   int ret = 0;
7904
7905   /* Parse args required to build the message */
7906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7907     {
7908       if (unformat (i, "ipv6"))
7909         is_ipv6 = 1;
7910       else if (unformat (i, "del"))
7911         is_add = 0;
7912       else if (unformat (i, "add"))
7913         is_add = 1;
7914       else if (unformat (i, "table %d", &table_id))
7915         ;
7916       else
7917         {
7918           clib_warning ("parse error '%U'", format_unformat_error, i);
7919           return -99;
7920         }
7921     }
7922
7923   if (~0 == table_id)
7924     {
7925       errmsg ("missing table-ID");
7926       return -99;
7927     }
7928
7929   /* Construct the API message */
7930   M (IP_TABLE_ADD_DEL, mp);
7931
7932   mp->table.table_id = ntohl (table_id);
7933   mp->table.is_ip6 = is_ipv6;
7934   mp->is_add = is_add;
7935
7936   /* send it... */
7937   S (mp);
7938
7939   /* Wait for a reply... */
7940   W (ret);
7941
7942   return ret;
7943 }
7944
7945 uword
7946 unformat_fib_path (unformat_input_t * input, va_list * args)
7947 {
7948   vat_main_t *vam = va_arg (*args, vat_main_t *);
7949   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7950   u32 weight, preference;
7951   mpls_label_t out_label;
7952
7953   clib_memset (path, 0, sizeof (*path));
7954   path->weight = 1;
7955   path->sw_if_index = ~0;
7956   path->rpf_id = ~0;
7957   path->n_labels = 0;
7958
7959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7960     {
7961       if (unformat (input, "%U %U",
7962                     unformat_vl_api_ip4_address,
7963                     &path->nh.address.ip4,
7964                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7965         {
7966           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7967         }
7968       else if (unformat (input, "%U %U",
7969                          unformat_vl_api_ip6_address,
7970                          &path->nh.address.ip6,
7971                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7972         {
7973           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7974         }
7975       else if (unformat (input, "weight %u", &weight))
7976         {
7977           path->weight = weight;
7978         }
7979       else if (unformat (input, "preference %u", &preference))
7980         {
7981           path->preference = preference;
7982         }
7983       else if (unformat (input, "%U next-hop-table %d",
7984                          unformat_vl_api_ip4_address,
7985                          &path->nh.address.ip4, &path->table_id))
7986         {
7987           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7988         }
7989       else if (unformat (input, "%U next-hop-table %d",
7990                          unformat_vl_api_ip6_address,
7991                          &path->nh.address.ip6, &path->table_id))
7992         {
7993           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7994         }
7995       else if (unformat (input, "%U",
7996                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7997         {
7998           /*
7999            * the recursive next-hops are by default in the default table
8000            */
8001           path->table_id = 0;
8002           path->sw_if_index = ~0;
8003           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8004         }
8005       else if (unformat (input, "%U",
8006                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8007         {
8008           /*
8009            * the recursive next-hops are by default in the default table
8010            */
8011           path->table_id = 0;
8012           path->sw_if_index = ~0;
8013           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8014         }
8015       else if (unformat (input, "resolve-via-host"))
8016         {
8017           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8018         }
8019       else if (unformat (input, "resolve-via-attached"))
8020         {
8021           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8022         }
8023       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8024         {
8025           path->type = FIB_API_PATH_TYPE_LOCAL;
8026           path->sw_if_index = ~0;
8027           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8028         }
8029       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8030         {
8031           path->type = FIB_API_PATH_TYPE_LOCAL;
8032           path->sw_if_index = ~0;
8033           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8034         }
8035       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8036         ;
8037       else if (unformat (input, "via-label %d", &path->nh.via_label))
8038         {
8039           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8040           path->sw_if_index = ~0;
8041         }
8042       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8043         {
8044           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8045           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8046         }
8047       else if (unformat (input, "local"))
8048         {
8049           path->type = FIB_API_PATH_TYPE_LOCAL;
8050         }
8051       else if (unformat (input, "out-labels"))
8052         {
8053           while (unformat (input, "%d", &out_label))
8054             {
8055               path->label_stack[path->n_labels].label = out_label;
8056               path->label_stack[path->n_labels].is_uniform = 0;
8057               path->label_stack[path->n_labels].ttl = 64;
8058               path->n_labels++;
8059             }
8060         }
8061       else if (unformat (input, "via"))
8062         {
8063           /* new path, back up and return */
8064           unformat_put_input (input);
8065           unformat_put_input (input);
8066           unformat_put_input (input);
8067           unformat_put_input (input);
8068           break;
8069         }
8070       else
8071         {
8072           return (0);
8073         }
8074     }
8075
8076   path->proto = ntohl (path->proto);
8077   path->type = ntohl (path->type);
8078   path->flags = ntohl (path->flags);
8079   path->table_id = ntohl (path->table_id);
8080   path->sw_if_index = ntohl (path->sw_if_index);
8081
8082   return (1);
8083 }
8084
8085 static int
8086 api_ip_route_add_del (vat_main_t * vam)
8087 {
8088   unformat_input_t *i = vam->input;
8089   vl_api_ip_route_add_del_t *mp;
8090   u32 vrf_id = 0;
8091   u8 is_add = 1;
8092   u8 is_multipath = 0;
8093   u8 prefix_set = 0;
8094   u8 path_count = 0;
8095   vl_api_prefix_t pfx = { };
8096   vl_api_fib_path_t paths[8];
8097   int count = 1;
8098   int j;
8099   f64 before = 0;
8100   u32 random_add_del = 0;
8101   u32 *random_vector = 0;
8102   u32 random_seed = 0xdeaddabe;
8103
8104   /* Parse args required to build the message */
8105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8106     {
8107       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8108         prefix_set = 1;
8109       else if (unformat (i, "del"))
8110         is_add = 0;
8111       else if (unformat (i, "add"))
8112         is_add = 1;
8113       else if (unformat (i, "vrf %d", &vrf_id))
8114         ;
8115       else if (unformat (i, "count %d", &count))
8116         ;
8117       else if (unformat (i, "random"))
8118         random_add_del = 1;
8119       else if (unformat (i, "multipath"))
8120         is_multipath = 1;
8121       else if (unformat (i, "seed %d", &random_seed))
8122         ;
8123       else
8124         if (unformat
8125             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8126         {
8127           path_count++;
8128           if (8 == path_count)
8129             {
8130               errmsg ("max 8 paths");
8131               return -99;
8132             }
8133         }
8134       else
8135         {
8136           clib_warning ("parse error '%U'", format_unformat_error, i);
8137           return -99;
8138         }
8139     }
8140
8141   if (!path_count)
8142     {
8143       errmsg ("specify a path; via ...");
8144       return -99;
8145     }
8146   if (prefix_set == 0)
8147     {
8148       errmsg ("missing prefix");
8149       return -99;
8150     }
8151
8152   /* Generate a pile of unique, random routes */
8153   if (random_add_del)
8154     {
8155       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8156       u32 this_random_address;
8157       uword *random_hash;
8158
8159       random_hash = hash_create (count, sizeof (uword));
8160
8161       hash_set (random_hash, i->as_u32, 1);
8162       for (j = 0; j <= count; j++)
8163         {
8164           do
8165             {
8166               this_random_address = random_u32 (&random_seed);
8167               this_random_address =
8168                 clib_host_to_net_u32 (this_random_address);
8169             }
8170           while (hash_get (random_hash, this_random_address));
8171           vec_add1 (random_vector, this_random_address);
8172           hash_set (random_hash, this_random_address, 1);
8173         }
8174       hash_free (random_hash);
8175       set_ip4_address (&pfx.address, random_vector[0]);
8176     }
8177
8178   if (count > 1)
8179     {
8180       /* Turn on async mode */
8181       vam->async_mode = 1;
8182       vam->async_errors = 0;
8183       before = vat_time_now (vam);
8184     }
8185
8186   for (j = 0; j < count; j++)
8187     {
8188       /* Construct the API message */
8189       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8190
8191       mp->is_add = is_add;
8192       mp->is_multipath = is_multipath;
8193
8194       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8195       mp->route.table_id = ntohl (vrf_id);
8196       mp->route.n_paths = path_count;
8197
8198       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8199
8200       if (random_add_del)
8201         set_ip4_address (&pfx.address, random_vector[j + 1]);
8202       else
8203         increment_address (&pfx.address);
8204       /* send it... */
8205       S (mp);
8206       /* If we receive SIGTERM, stop now... */
8207       if (vam->do_exit)
8208         break;
8209     }
8210
8211   /* When testing multiple add/del ops, use a control-ping to sync */
8212   if (count > 1)
8213     {
8214       vl_api_control_ping_t *mp_ping;
8215       f64 after;
8216       f64 timeout;
8217
8218       /* Shut off async mode */
8219       vam->async_mode = 0;
8220
8221       MPING (CONTROL_PING, mp_ping);
8222       S (mp_ping);
8223
8224       timeout = vat_time_now (vam) + 1.0;
8225       while (vat_time_now (vam) < timeout)
8226         if (vam->result_ready == 1)
8227           goto out;
8228       vam->retval = -99;
8229
8230     out:
8231       if (vam->retval == -99)
8232         errmsg ("timeout");
8233
8234       if (vam->async_errors > 0)
8235         {
8236           errmsg ("%d asynchronous errors", vam->async_errors);
8237           vam->retval = -98;
8238         }
8239       vam->async_errors = 0;
8240       after = vat_time_now (vam);
8241
8242       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8243       if (j > 0)
8244         count = j;
8245
8246       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8247              count, after - before, count / (after - before));
8248     }
8249   else
8250     {
8251       int ret;
8252
8253       /* Wait for a reply... */
8254       W (ret);
8255       return ret;
8256     }
8257
8258   /* Return the good/bad news */
8259   return (vam->retval);
8260 }
8261
8262 static int
8263 api_ip_mroute_add_del (vat_main_t * vam)
8264 {
8265   unformat_input_t *i = vam->input;
8266   u8 path_set = 0, prefix_set = 0, is_add = 1;
8267   vl_api_ip_mroute_add_del_t *mp;
8268   mfib_entry_flags_t eflags = 0;
8269   vl_api_mfib_path_t path;
8270   vl_api_mprefix_t pfx = { };
8271   u32 vrf_id = 0;
8272   int ret;
8273
8274   /* Parse args required to build the message */
8275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8276     {
8277       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8278         {
8279           prefix_set = 1;
8280           pfx.grp_address_length = htons (pfx.grp_address_length);
8281         }
8282       else if (unformat (i, "del"))
8283         is_add = 0;
8284       else if (unformat (i, "add"))
8285         is_add = 1;
8286       else if (unformat (i, "vrf %d", &vrf_id))
8287         ;
8288       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8289         path.itf_flags = htonl (path.itf_flags);
8290       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8291         ;
8292       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8293         path_set = 1;
8294       else
8295         {
8296           clib_warning ("parse error '%U'", format_unformat_error, i);
8297           return -99;
8298         }
8299     }
8300
8301   if (prefix_set == 0)
8302     {
8303       errmsg ("missing addresses\n");
8304       return -99;
8305     }
8306   if (path_set == 0)
8307     {
8308       errmsg ("missing path\n");
8309       return -99;
8310     }
8311
8312   /* Construct the API message */
8313   M (IP_MROUTE_ADD_DEL, mp);
8314
8315   mp->is_add = is_add;
8316   mp->is_multipath = 1;
8317
8318   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8319   mp->route.table_id = htonl (vrf_id);
8320   mp->route.n_paths = 1;
8321   mp->route.entry_flags = htonl (eflags);
8322
8323   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8324
8325   /* send it... */
8326   S (mp);
8327   /* Wait for a reply... */
8328   W (ret);
8329   return ret;
8330 }
8331
8332 static int
8333 api_mpls_table_add_del (vat_main_t * vam)
8334 {
8335   unformat_input_t *i = vam->input;
8336   vl_api_mpls_table_add_del_t *mp;
8337   u32 table_id = ~0;
8338   u8 is_add = 1;
8339   int ret = 0;
8340
8341   /* Parse args required to build the message */
8342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8343     {
8344       if (unformat (i, "table %d", &table_id))
8345         ;
8346       else if (unformat (i, "del"))
8347         is_add = 0;
8348       else if (unformat (i, "add"))
8349         is_add = 1;
8350       else
8351         {
8352           clib_warning ("parse error '%U'", format_unformat_error, i);
8353           return -99;
8354         }
8355     }
8356
8357   if (~0 == table_id)
8358     {
8359       errmsg ("missing table-ID");
8360       return -99;
8361     }
8362
8363   /* Construct the API message */
8364   M (MPLS_TABLE_ADD_DEL, mp);
8365
8366   mp->mt_table.mt_table_id = ntohl (table_id);
8367   mp->mt_is_add = is_add;
8368
8369   /* send it... */
8370   S (mp);
8371
8372   /* Wait for a reply... */
8373   W (ret);
8374
8375   return ret;
8376 }
8377
8378 static int
8379 api_mpls_route_add_del (vat_main_t * vam)
8380 {
8381   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8382   mpls_label_t local_label = MPLS_LABEL_INVALID;
8383   unformat_input_t *i = vam->input;
8384   vl_api_mpls_route_add_del_t *mp;
8385   vl_api_fib_path_t paths[8];
8386   int count = 1, j;
8387   f64 before = 0;
8388
8389   /* Parse args required to build the message */
8390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8391     {
8392       if (unformat (i, "%d", &local_label))
8393         ;
8394       else if (unformat (i, "eos"))
8395         is_eos = 1;
8396       else if (unformat (i, "non-eos"))
8397         is_eos = 0;
8398       else if (unformat (i, "del"))
8399         is_add = 0;
8400       else if (unformat (i, "add"))
8401         is_add = 1;
8402       else if (unformat (i, "multipath"))
8403         is_multipath = 1;
8404       else if (unformat (i, "count %d", &count))
8405         ;
8406       else
8407         if (unformat
8408             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8409         {
8410           path_count++;
8411           if (8 == path_count)
8412             {
8413               errmsg ("max 8 paths");
8414               return -99;
8415             }
8416         }
8417       else
8418         {
8419           clib_warning ("parse error '%U'", format_unformat_error, i);
8420           return -99;
8421         }
8422     }
8423
8424   if (!path_count)
8425     {
8426       errmsg ("specify a path; via ...");
8427       return -99;
8428     }
8429
8430   if (MPLS_LABEL_INVALID == local_label)
8431     {
8432       errmsg ("missing label");
8433       return -99;
8434     }
8435
8436   if (count > 1)
8437     {
8438       /* Turn on async mode */
8439       vam->async_mode = 1;
8440       vam->async_errors = 0;
8441       before = vat_time_now (vam);
8442     }
8443
8444   for (j = 0; j < count; j++)
8445     {
8446       /* Construct the API message */
8447       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8448
8449       mp->mr_is_add = is_add;
8450       mp->mr_is_multipath = is_multipath;
8451
8452       mp->mr_route.mr_label = local_label;
8453       mp->mr_route.mr_eos = is_eos;
8454       mp->mr_route.mr_table_id = 0;
8455       mp->mr_route.mr_n_paths = path_count;
8456
8457       clib_memcpy (&mp->mr_route.mr_paths, paths,
8458                    sizeof (paths[0]) * path_count);
8459
8460       local_label++;
8461
8462       /* send it... */
8463       S (mp);
8464       /* If we receive SIGTERM, stop now... */
8465       if (vam->do_exit)
8466         break;
8467     }
8468
8469   /* When testing multiple add/del ops, use a control-ping to sync */
8470   if (count > 1)
8471     {
8472       vl_api_control_ping_t *mp_ping;
8473       f64 after;
8474       f64 timeout;
8475
8476       /* Shut off async mode */
8477       vam->async_mode = 0;
8478
8479       MPING (CONTROL_PING, mp_ping);
8480       S (mp_ping);
8481
8482       timeout = vat_time_now (vam) + 1.0;
8483       while (vat_time_now (vam) < timeout)
8484         if (vam->result_ready == 1)
8485           goto out;
8486       vam->retval = -99;
8487
8488     out:
8489       if (vam->retval == -99)
8490         errmsg ("timeout");
8491
8492       if (vam->async_errors > 0)
8493         {
8494           errmsg ("%d asynchronous errors", vam->async_errors);
8495           vam->retval = -98;
8496         }
8497       vam->async_errors = 0;
8498       after = vat_time_now (vam);
8499
8500       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8501       if (j > 0)
8502         count = j;
8503
8504       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8505              count, after - before, count / (after - before));
8506     }
8507   else
8508     {
8509       int ret;
8510
8511       /* Wait for a reply... */
8512       W (ret);
8513       return ret;
8514     }
8515
8516   /* Return the good/bad news */
8517   return (vam->retval);
8518   return (0);
8519 }
8520
8521 static int
8522 api_mpls_ip_bind_unbind (vat_main_t * vam)
8523 {
8524   unformat_input_t *i = vam->input;
8525   vl_api_mpls_ip_bind_unbind_t *mp;
8526   u32 ip_table_id = 0;
8527   u8 is_bind = 1;
8528   vl_api_prefix_t pfx;
8529   u8 prefix_set = 0;
8530   mpls_label_t local_label = MPLS_LABEL_INVALID;
8531   int ret;
8532
8533   /* Parse args required to build the message */
8534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8535     {
8536       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8537         prefix_set = 1;
8538       else if (unformat (i, "%d", &local_label))
8539         ;
8540       else if (unformat (i, "table-id %d", &ip_table_id))
8541         ;
8542       else if (unformat (i, "unbind"))
8543         is_bind = 0;
8544       else if (unformat (i, "bind"))
8545         is_bind = 1;
8546       else
8547         {
8548           clib_warning ("parse error '%U'", format_unformat_error, i);
8549           return -99;
8550         }
8551     }
8552
8553   if (!prefix_set)
8554     {
8555       errmsg ("IP prefix not set");
8556       return -99;
8557     }
8558
8559   if (MPLS_LABEL_INVALID == local_label)
8560     {
8561       errmsg ("missing label");
8562       return -99;
8563     }
8564
8565   /* Construct the API message */
8566   M (MPLS_IP_BIND_UNBIND, mp);
8567
8568   mp->mb_is_bind = is_bind;
8569   mp->mb_ip_table_id = ntohl (ip_table_id);
8570   mp->mb_mpls_table_id = 0;
8571   mp->mb_label = ntohl (local_label);
8572   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8573
8574   /* send it... */
8575   S (mp);
8576
8577   /* Wait for a reply... */
8578   W (ret);
8579   return ret;
8580   return (0);
8581 }
8582
8583 static int
8584 api_sr_mpls_policy_add (vat_main_t * vam)
8585 {
8586   unformat_input_t *i = vam->input;
8587   vl_api_sr_mpls_policy_add_t *mp;
8588   u32 bsid = 0;
8589   u32 weight = 1;
8590   u8 type = 0;
8591   u8 n_segments = 0;
8592   u32 sid;
8593   u32 *segments = NULL;
8594   int ret;
8595
8596   /* Parse args required to build the message */
8597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8598     {
8599       if (unformat (i, "bsid %d", &bsid))
8600         ;
8601       else if (unformat (i, "weight %d", &weight))
8602         ;
8603       else if (unformat (i, "spray"))
8604         type = 1;
8605       else if (unformat (i, "next %d", &sid))
8606         {
8607           n_segments += 1;
8608           vec_add1 (segments, htonl (sid));
8609         }
8610       else
8611         {
8612           clib_warning ("parse error '%U'", format_unformat_error, i);
8613           return -99;
8614         }
8615     }
8616
8617   if (bsid == 0)
8618     {
8619       errmsg ("bsid not set");
8620       return -99;
8621     }
8622
8623   if (n_segments == 0)
8624     {
8625       errmsg ("no sid in segment stack");
8626       return -99;
8627     }
8628
8629   /* Construct the API message */
8630   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8631
8632   mp->bsid = htonl (bsid);
8633   mp->weight = htonl (weight);
8634   mp->type = type;
8635   mp->n_segments = n_segments;
8636   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8637   vec_free (segments);
8638
8639   /* send it... */
8640   S (mp);
8641
8642   /* Wait for a reply... */
8643   W (ret);
8644   return ret;
8645 }
8646
8647 static int
8648 api_sr_mpls_policy_del (vat_main_t * vam)
8649 {
8650   unformat_input_t *i = vam->input;
8651   vl_api_sr_mpls_policy_del_t *mp;
8652   u32 bsid = 0;
8653   int ret;
8654
8655   /* Parse args required to build the message */
8656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8657     {
8658       if (unformat (i, "bsid %d", &bsid))
8659         ;
8660       else
8661         {
8662           clib_warning ("parse error '%U'", format_unformat_error, i);
8663           return -99;
8664         }
8665     }
8666
8667   if (bsid == 0)
8668     {
8669       errmsg ("bsid not set");
8670       return -99;
8671     }
8672
8673   /* Construct the API message */
8674   M (SR_MPLS_POLICY_DEL, mp);
8675
8676   mp->bsid = htonl (bsid);
8677
8678   /* send it... */
8679   S (mp);
8680
8681   /* Wait for a reply... */
8682   W (ret);
8683   return ret;
8684 }
8685
8686 static int
8687 api_bier_table_add_del (vat_main_t * vam)
8688 {
8689   unformat_input_t *i = vam->input;
8690   vl_api_bier_table_add_del_t *mp;
8691   u8 is_add = 1;
8692   u32 set = 0, sub_domain = 0, hdr_len = 3;
8693   mpls_label_t local_label = MPLS_LABEL_INVALID;
8694   int ret;
8695
8696   /* Parse args required to build the message */
8697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8698     {
8699       if (unformat (i, "sub-domain %d", &sub_domain))
8700         ;
8701       else if (unformat (i, "set %d", &set))
8702         ;
8703       else if (unformat (i, "label %d", &local_label))
8704         ;
8705       else if (unformat (i, "hdr-len %d", &hdr_len))
8706         ;
8707       else if (unformat (i, "add"))
8708         is_add = 1;
8709       else if (unformat (i, "del"))
8710         is_add = 0;
8711       else
8712         {
8713           clib_warning ("parse error '%U'", format_unformat_error, i);
8714           return -99;
8715         }
8716     }
8717
8718   if (MPLS_LABEL_INVALID == local_label)
8719     {
8720       errmsg ("missing label\n");
8721       return -99;
8722     }
8723
8724   /* Construct the API message */
8725   M (BIER_TABLE_ADD_DEL, mp);
8726
8727   mp->bt_is_add = is_add;
8728   mp->bt_label = ntohl (local_label);
8729   mp->bt_tbl_id.bt_set = set;
8730   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8731   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8732
8733   /* send it... */
8734   S (mp);
8735
8736   /* Wait for a reply... */
8737   W (ret);
8738
8739   return (ret);
8740 }
8741
8742 static int
8743 api_bier_route_add_del (vat_main_t * vam)
8744 {
8745   unformat_input_t *i = vam->input;
8746   vl_api_bier_route_add_del_t *mp;
8747   u8 is_add = 1;
8748   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8749   ip4_address_t v4_next_hop_address;
8750   ip6_address_t v6_next_hop_address;
8751   u8 next_hop_set = 0;
8752   u8 next_hop_proto_is_ip4 = 1;
8753   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8754   int ret;
8755
8756   /* Parse args required to build the message */
8757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8758     {
8759       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8760         {
8761           next_hop_proto_is_ip4 = 1;
8762           next_hop_set = 1;
8763         }
8764       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8765         {
8766           next_hop_proto_is_ip4 = 0;
8767           next_hop_set = 1;
8768         }
8769       if (unformat (i, "sub-domain %d", &sub_domain))
8770         ;
8771       else if (unformat (i, "set %d", &set))
8772         ;
8773       else if (unformat (i, "hdr-len %d", &hdr_len))
8774         ;
8775       else if (unformat (i, "bp %d", &bp))
8776         ;
8777       else if (unformat (i, "add"))
8778         is_add = 1;
8779       else if (unformat (i, "del"))
8780         is_add = 0;
8781       else if (unformat (i, "out-label %d", &next_hop_out_label))
8782         ;
8783       else
8784         {
8785           clib_warning ("parse error '%U'", format_unformat_error, i);
8786           return -99;
8787         }
8788     }
8789
8790   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8791     {
8792       errmsg ("next hop / label set\n");
8793       return -99;
8794     }
8795   if (0 == bp)
8796     {
8797       errmsg ("bit=position not set\n");
8798       return -99;
8799     }
8800
8801   /* Construct the API message */
8802   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8803
8804   mp->br_is_add = is_add;
8805   mp->br_route.br_tbl_id.bt_set = set;
8806   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8807   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8808   mp->br_route.br_bp = ntohs (bp);
8809   mp->br_route.br_n_paths = 1;
8810   mp->br_route.br_paths[0].n_labels = 1;
8811   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8812   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8813                                     FIB_API_PATH_NH_PROTO_IP4 :
8814                                     FIB_API_PATH_NH_PROTO_IP6);
8815
8816   if (next_hop_proto_is_ip4)
8817     {
8818       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8819                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8820     }
8821   else
8822     {
8823       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8824                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8825     }
8826
8827   /* send it... */
8828   S (mp);
8829
8830   /* Wait for a reply... */
8831   W (ret);
8832
8833   return (ret);
8834 }
8835
8836 static int
8837 api_proxy_arp_add_del (vat_main_t * vam)
8838 {
8839   unformat_input_t *i = vam->input;
8840   vl_api_proxy_arp_add_del_t *mp;
8841   u32 vrf_id = 0;
8842   u8 is_add = 1;
8843   vl_api_ip4_address_t lo, hi;
8844   u8 range_set = 0;
8845   int ret;
8846
8847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8848     {
8849       if (unformat (i, "vrf %d", &vrf_id))
8850         ;
8851       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8852                          unformat_vl_api_ip4_address, &hi))
8853         range_set = 1;
8854       else if (unformat (i, "del"))
8855         is_add = 0;
8856       else
8857         {
8858           clib_warning ("parse error '%U'", format_unformat_error, i);
8859           return -99;
8860         }
8861     }
8862
8863   if (range_set == 0)
8864     {
8865       errmsg ("address range not set");
8866       return -99;
8867     }
8868
8869   M (PROXY_ARP_ADD_DEL, mp);
8870
8871   mp->proxy.table_id = ntohl (vrf_id);
8872   mp->is_add = is_add;
8873   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8874   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8875
8876   S (mp);
8877   W (ret);
8878   return ret;
8879 }
8880
8881 static int
8882 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8883 {
8884   unformat_input_t *i = vam->input;
8885   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8886   u32 sw_if_index;
8887   u8 enable = 1;
8888   u8 sw_if_index_set = 0;
8889   int ret;
8890
8891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8892     {
8893       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8894         sw_if_index_set = 1;
8895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8896         sw_if_index_set = 1;
8897       else if (unformat (i, "enable"))
8898         enable = 1;
8899       else if (unformat (i, "disable"))
8900         enable = 0;
8901       else
8902         {
8903           clib_warning ("parse error '%U'", format_unformat_error, i);
8904           return -99;
8905         }
8906     }
8907
8908   if (sw_if_index_set == 0)
8909     {
8910       errmsg ("missing interface name or sw_if_index");
8911       return -99;
8912     }
8913
8914   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8915
8916   mp->sw_if_index = ntohl (sw_if_index);
8917   mp->enable_disable = enable;
8918
8919   S (mp);
8920   W (ret);
8921   return ret;
8922 }
8923
8924 static int
8925 api_mpls_tunnel_add_del (vat_main_t * vam)
8926 {
8927   unformat_input_t *i = vam->input;
8928   vl_api_mpls_tunnel_add_del_t *mp;
8929
8930   vl_api_fib_path_t paths[8];
8931   u32 sw_if_index = ~0;
8932   u8 path_count = 0;
8933   u8 l2_only = 0;
8934   u8 is_add = 1;
8935   int ret;
8936
8937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8938     {
8939       if (unformat (i, "add"))
8940         is_add = 1;
8941       else
8942         if (unformat
8943             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8944         is_add = 0;
8945       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8946         is_add = 0;
8947       else if (unformat (i, "l2-only"))
8948         l2_only = 1;
8949       else
8950         if (unformat
8951             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8952         {
8953           path_count++;
8954           if (8 == path_count)
8955             {
8956               errmsg ("max 8 paths");
8957               return -99;
8958             }
8959         }
8960       else
8961         {
8962           clib_warning ("parse error '%U'", format_unformat_error, i);
8963           return -99;
8964         }
8965     }
8966
8967   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8968
8969   mp->mt_is_add = is_add;
8970   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8971   mp->mt_tunnel.mt_l2_only = l2_only;
8972   mp->mt_tunnel.mt_is_multicast = 0;
8973   mp->mt_tunnel.mt_n_paths = path_count;
8974
8975   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8976                sizeof (paths[0]) * path_count);
8977
8978   S (mp);
8979   W (ret);
8980   return ret;
8981 }
8982
8983 static int
8984 api_sw_interface_set_unnumbered (vat_main_t * vam)
8985 {
8986   unformat_input_t *i = vam->input;
8987   vl_api_sw_interface_set_unnumbered_t *mp;
8988   u32 sw_if_index;
8989   u32 unnum_sw_index = ~0;
8990   u8 is_add = 1;
8991   u8 sw_if_index_set = 0;
8992   int ret;
8993
8994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8995     {
8996       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8997         sw_if_index_set = 1;
8998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8999         sw_if_index_set = 1;
9000       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9001         ;
9002       else if (unformat (i, "del"))
9003         is_add = 0;
9004       else
9005         {
9006           clib_warning ("parse error '%U'", format_unformat_error, i);
9007           return -99;
9008         }
9009     }
9010
9011   if (sw_if_index_set == 0)
9012     {
9013       errmsg ("missing interface name or sw_if_index");
9014       return -99;
9015     }
9016
9017   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9018
9019   mp->sw_if_index = ntohl (sw_if_index);
9020   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9021   mp->is_add = is_add;
9022
9023   S (mp);
9024   W (ret);
9025   return ret;
9026 }
9027
9028 static int
9029 api_ip_neighbor_add_del (vat_main_t * vam)
9030 {
9031   vl_api_mac_address_t mac_address;
9032   unformat_input_t *i = vam->input;
9033   vl_api_ip_neighbor_add_del_t *mp;
9034   vl_api_address_t ip_address;
9035   u32 sw_if_index;
9036   u8 sw_if_index_set = 0;
9037   u8 is_add = 1;
9038   u8 mac_set = 0;
9039   u8 address_set = 0;
9040   int ret;
9041   ip_neighbor_flags_t flags;
9042
9043   flags = IP_NEIGHBOR_FLAG_NONE;
9044   clib_memset (&ip_address, 0, sizeof (ip_address));
9045   clib_memset (&mac_address, 0, sizeof (mac_address));
9046
9047   /* Parse args required to build the message */
9048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9049     {
9050       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9051         {
9052           mac_set = 1;
9053         }
9054       else if (unformat (i, "del"))
9055         is_add = 0;
9056       else
9057         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9058         sw_if_index_set = 1;
9059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9060         sw_if_index_set = 1;
9061       else if (unformat (i, "static"))
9062         flags |= IP_NEIGHBOR_FLAG_STATIC;
9063       else if (unformat (i, "no-fib-entry"))
9064         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9065       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9066         address_set = 1;
9067       else
9068         {
9069           clib_warning ("parse error '%U'", format_unformat_error, i);
9070           return -99;
9071         }
9072     }
9073
9074   if (sw_if_index_set == 0)
9075     {
9076       errmsg ("missing interface name or sw_if_index");
9077       return -99;
9078     }
9079   if (!address_set)
9080     {
9081       errmsg ("no address set");
9082       return -99;
9083     }
9084
9085   /* Construct the API message */
9086   M (IP_NEIGHBOR_ADD_DEL, mp);
9087
9088   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9089   mp->is_add = is_add;
9090   mp->neighbor.flags = htonl (flags);
9091   if (mac_set)
9092     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9093                  sizeof (mac_address));
9094   if (address_set)
9095     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9096
9097   /* send it... */
9098   S (mp);
9099
9100   /* Wait for a reply, return good/bad news  */
9101   W (ret);
9102   return ret;
9103 }
9104
9105 static int
9106 api_create_vlan_subif (vat_main_t * vam)
9107 {
9108   unformat_input_t *i = vam->input;
9109   vl_api_create_vlan_subif_t *mp;
9110   u32 sw_if_index;
9111   u8 sw_if_index_set = 0;
9112   u32 vlan_id;
9113   u8 vlan_id_set = 0;
9114   int ret;
9115
9116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9117     {
9118       if (unformat (i, "sw_if_index %d", &sw_if_index))
9119         sw_if_index_set = 1;
9120       else
9121         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9122         sw_if_index_set = 1;
9123       else if (unformat (i, "vlan %d", &vlan_id))
9124         vlan_id_set = 1;
9125       else
9126         {
9127           clib_warning ("parse error '%U'", format_unformat_error, i);
9128           return -99;
9129         }
9130     }
9131
9132   if (sw_if_index_set == 0)
9133     {
9134       errmsg ("missing interface name or sw_if_index");
9135       return -99;
9136     }
9137
9138   if (vlan_id_set == 0)
9139     {
9140       errmsg ("missing vlan_id");
9141       return -99;
9142     }
9143   M (CREATE_VLAN_SUBIF, mp);
9144
9145   mp->sw_if_index = ntohl (sw_if_index);
9146   mp->vlan_id = ntohl (vlan_id);
9147
9148   S (mp);
9149   W (ret);
9150   return ret;
9151 }
9152
9153 #define foreach_create_subif_bit                \
9154 _(no_tags)                                      \
9155 _(one_tag)                                      \
9156 _(two_tags)                                     \
9157 _(dot1ad)                                       \
9158 _(exact_match)                                  \
9159 _(default_sub)                                  \
9160 _(outer_vlan_id_any)                            \
9161 _(inner_vlan_id_any)
9162
9163 #define foreach_create_subif_flag               \
9164 _(0, "no_tags")                                 \
9165 _(1, "one_tag")                                 \
9166 _(2, "two_tags")                                \
9167 _(3, "dot1ad")                                  \
9168 _(4, "exact_match")                             \
9169 _(5, "default_sub")                             \
9170 _(6, "outer_vlan_id_any")                       \
9171 _(7, "inner_vlan_id_any")
9172
9173 static int
9174 api_create_subif (vat_main_t * vam)
9175 {
9176   unformat_input_t *i = vam->input;
9177   vl_api_create_subif_t *mp;
9178   u32 sw_if_index;
9179   u8 sw_if_index_set = 0;
9180   u32 sub_id;
9181   u8 sub_id_set = 0;
9182   u32 __attribute__ ((unused)) no_tags = 0;
9183   u32 __attribute__ ((unused)) one_tag = 0;
9184   u32 __attribute__ ((unused)) two_tags = 0;
9185   u32 __attribute__ ((unused)) dot1ad = 0;
9186   u32 __attribute__ ((unused)) exact_match = 0;
9187   u32 __attribute__ ((unused)) default_sub = 0;
9188   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9189   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9190   u32 tmp;
9191   u16 outer_vlan_id = 0;
9192   u16 inner_vlan_id = 0;
9193   int ret;
9194
9195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9196     {
9197       if (unformat (i, "sw_if_index %d", &sw_if_index))
9198         sw_if_index_set = 1;
9199       else
9200         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9201         sw_if_index_set = 1;
9202       else if (unformat (i, "sub_id %d", &sub_id))
9203         sub_id_set = 1;
9204       else if (unformat (i, "outer_vlan_id %d", &tmp))
9205         outer_vlan_id = tmp;
9206       else if (unformat (i, "inner_vlan_id %d", &tmp))
9207         inner_vlan_id = tmp;
9208
9209 #define _(a) else if (unformat (i, #a)) a = 1 ;
9210       foreach_create_subif_bit
9211 #undef _
9212         else
9213         {
9214           clib_warning ("parse error '%U'", format_unformat_error, i);
9215           return -99;
9216         }
9217     }
9218
9219   if (sw_if_index_set == 0)
9220     {
9221       errmsg ("missing interface name or sw_if_index");
9222       return -99;
9223     }
9224
9225   if (sub_id_set == 0)
9226     {
9227       errmsg ("missing sub_id");
9228       return -99;
9229     }
9230   M (CREATE_SUBIF, mp);
9231
9232   mp->sw_if_index = ntohl (sw_if_index);
9233   mp->sub_id = ntohl (sub_id);
9234
9235 #define _(a,b) mp->sub_if_flags |= (1 << a);
9236   foreach_create_subif_flag;
9237 #undef _
9238
9239   mp->outer_vlan_id = ntohs (outer_vlan_id);
9240   mp->inner_vlan_id = ntohs (inner_vlan_id);
9241
9242   S (mp);
9243   W (ret);
9244   return ret;
9245 }
9246
9247 static int
9248 api_reset_fib (vat_main_t * vam)
9249 {
9250   unformat_input_t *i = vam->input;
9251   vl_api_reset_fib_t *mp;
9252   u32 vrf_id = 0;
9253   u8 is_ipv6 = 0;
9254   u8 vrf_id_set = 0;
9255
9256   int ret;
9257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9258     {
9259       if (unformat (i, "vrf %d", &vrf_id))
9260         vrf_id_set = 1;
9261       else if (unformat (i, "ipv6"))
9262         is_ipv6 = 1;
9263       else
9264         {
9265           clib_warning ("parse error '%U'", format_unformat_error, i);
9266           return -99;
9267         }
9268     }
9269
9270   if (vrf_id_set == 0)
9271     {
9272       errmsg ("missing vrf id");
9273       return -99;
9274     }
9275
9276   M (RESET_FIB, mp);
9277
9278   mp->vrf_id = ntohl (vrf_id);
9279   mp->is_ipv6 = is_ipv6;
9280
9281   S (mp);
9282   W (ret);
9283   return ret;
9284 }
9285
9286 static int
9287 api_dhcp_proxy_config (vat_main_t * vam)
9288 {
9289   unformat_input_t *i = vam->input;
9290   vl_api_dhcp_proxy_config_t *mp;
9291   u32 rx_vrf_id = 0;
9292   u32 server_vrf_id = 0;
9293   u8 is_add = 1;
9294   u8 v4_address_set = 0;
9295   u8 v6_address_set = 0;
9296   ip4_address_t v4address;
9297   ip6_address_t v6address;
9298   u8 v4_src_address_set = 0;
9299   u8 v6_src_address_set = 0;
9300   ip4_address_t v4srcaddress;
9301   ip6_address_t v6srcaddress;
9302   int ret;
9303
9304   /* Parse args required to build the message */
9305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9306     {
9307       if (unformat (i, "del"))
9308         is_add = 0;
9309       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9310         ;
9311       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9312         ;
9313       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9314         v4_address_set = 1;
9315       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9316         v6_address_set = 1;
9317       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9318         v4_src_address_set = 1;
9319       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9320         v6_src_address_set = 1;
9321       else
9322         break;
9323     }
9324
9325   if (v4_address_set && v6_address_set)
9326     {
9327       errmsg ("both v4 and v6 server addresses set");
9328       return -99;
9329     }
9330   if (!v4_address_set && !v6_address_set)
9331     {
9332       errmsg ("no server addresses set");
9333       return -99;
9334     }
9335
9336   if (v4_src_address_set && v6_src_address_set)
9337     {
9338       errmsg ("both v4 and v6  src addresses set");
9339       return -99;
9340     }
9341   if (!v4_src_address_set && !v6_src_address_set)
9342     {
9343       errmsg ("no src addresses set");
9344       return -99;
9345     }
9346
9347   if (!(v4_src_address_set && v4_address_set) &&
9348       !(v6_src_address_set && v6_address_set))
9349     {
9350       errmsg ("no matching server and src addresses set");
9351       return -99;
9352     }
9353
9354   /* Construct the API message */
9355   M (DHCP_PROXY_CONFIG, mp);
9356
9357   mp->is_add = is_add;
9358   mp->rx_vrf_id = ntohl (rx_vrf_id);
9359   mp->server_vrf_id = ntohl (server_vrf_id);
9360   if (v6_address_set)
9361     {
9362       mp->is_ipv6 = 1;
9363       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9364       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9365     }
9366   else
9367     {
9368       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9369       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9370     }
9371
9372   /* send it... */
9373   S (mp);
9374
9375   /* Wait for a reply, return good/bad news  */
9376   W (ret);
9377   return ret;
9378 }
9379
9380 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9381 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9382
9383 static void
9384 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9385 {
9386   vat_main_t *vam = &vat_main;
9387   u32 i, count = mp->count;
9388   vl_api_dhcp_server_t *s;
9389
9390   if (mp->is_ipv6)
9391     print (vam->ofp,
9392            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9393            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9394            ntohl (mp->rx_vrf_id),
9395            format_ip6_address, mp->dhcp_src_address,
9396            mp->vss_type, mp->vss_vpn_ascii_id,
9397            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9398   else
9399     print (vam->ofp,
9400            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9401            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9402            ntohl (mp->rx_vrf_id),
9403            format_ip4_address, mp->dhcp_src_address,
9404            mp->vss_type, mp->vss_vpn_ascii_id,
9405            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9406
9407   for (i = 0; i < count; i++)
9408     {
9409       s = &mp->servers[i];
9410
9411       if (mp->is_ipv6)
9412         print (vam->ofp,
9413                " Server Table-ID %d, Server Address %U",
9414                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9415       else
9416         print (vam->ofp,
9417                " Server Table-ID %d, Server Address %U",
9418                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9419     }
9420 }
9421
9422 static void vl_api_dhcp_proxy_details_t_handler_json
9423   (vl_api_dhcp_proxy_details_t * mp)
9424 {
9425   vat_main_t *vam = &vat_main;
9426   vat_json_node_t *node = NULL;
9427   u32 i, count = mp->count;
9428   struct in_addr ip4;
9429   struct in6_addr ip6;
9430   vl_api_dhcp_server_t *s;
9431
9432   if (VAT_JSON_ARRAY != vam->json_tree.type)
9433     {
9434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9435       vat_json_init_array (&vam->json_tree);
9436     }
9437   node = vat_json_array_add (&vam->json_tree);
9438
9439   vat_json_init_object (node);
9440   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9441   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9442                              sizeof (mp->vss_type));
9443   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9444                                    mp->vss_vpn_ascii_id);
9445   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9446   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9447
9448   if (mp->is_ipv6)
9449     {
9450       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9451       vat_json_object_add_ip6 (node, "src_address", ip6);
9452     }
9453   else
9454     {
9455       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9456       vat_json_object_add_ip4 (node, "src_address", ip4);
9457     }
9458
9459   for (i = 0; i < count; i++)
9460     {
9461       s = &mp->servers[i];
9462
9463       vat_json_object_add_uint (node, "server-table-id",
9464                                 ntohl (s->server_vrf_id));
9465
9466       if (mp->is_ipv6)
9467         {
9468           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9469           vat_json_object_add_ip4 (node, "src_address", ip4);
9470         }
9471       else
9472         {
9473           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9474           vat_json_object_add_ip6 (node, "server_address", ip6);
9475         }
9476     }
9477 }
9478
9479 static int
9480 api_dhcp_proxy_dump (vat_main_t * vam)
9481 {
9482   unformat_input_t *i = vam->input;
9483   vl_api_control_ping_t *mp_ping;
9484   vl_api_dhcp_proxy_dump_t *mp;
9485   u8 is_ipv6 = 0;
9486   int ret;
9487
9488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9489     {
9490       if (unformat (i, "ipv6"))
9491         is_ipv6 = 1;
9492       else
9493         {
9494           clib_warning ("parse error '%U'", format_unformat_error, i);
9495           return -99;
9496         }
9497     }
9498
9499   M (DHCP_PROXY_DUMP, mp);
9500
9501   mp->is_ip6 = is_ipv6;
9502   S (mp);
9503
9504   /* Use a control ping for synchronization */
9505   MPING (CONTROL_PING, mp_ping);
9506   S (mp_ping);
9507
9508   W (ret);
9509   return ret;
9510 }
9511
9512 static int
9513 api_dhcp_proxy_set_vss (vat_main_t * vam)
9514 {
9515   unformat_input_t *i = vam->input;
9516   vl_api_dhcp_proxy_set_vss_t *mp;
9517   u8 is_ipv6 = 0;
9518   u8 is_add = 1;
9519   u32 tbl_id = ~0;
9520   u8 vss_type = VSS_TYPE_DEFAULT;
9521   u8 *vpn_ascii_id = 0;
9522   u32 oui = 0;
9523   u32 fib_id = 0;
9524   int ret;
9525
9526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9527     {
9528       if (unformat (i, "tbl_id %d", &tbl_id))
9529         ;
9530       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9531         vss_type = VSS_TYPE_ASCII;
9532       else if (unformat (i, "fib_id %d", &fib_id))
9533         vss_type = VSS_TYPE_VPN_ID;
9534       else if (unformat (i, "oui %d", &oui))
9535         vss_type = VSS_TYPE_VPN_ID;
9536       else if (unformat (i, "ipv6"))
9537         is_ipv6 = 1;
9538       else if (unformat (i, "del"))
9539         is_add = 0;
9540       else
9541         break;
9542     }
9543
9544   if (tbl_id == ~0)
9545     {
9546       errmsg ("missing tbl_id ");
9547       vec_free (vpn_ascii_id);
9548       return -99;
9549     }
9550
9551   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9552     {
9553       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9554       vec_free (vpn_ascii_id);
9555       return -99;
9556     }
9557
9558   M (DHCP_PROXY_SET_VSS, mp);
9559   mp->tbl_id = ntohl (tbl_id);
9560   mp->vss_type = vss_type;
9561   if (vpn_ascii_id)
9562     {
9563       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9564       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9565     }
9566   mp->vpn_index = ntohl (fib_id);
9567   mp->oui = ntohl (oui);
9568   mp->is_ipv6 = is_ipv6;
9569   mp->is_add = is_add;
9570
9571   S (mp);
9572   W (ret);
9573
9574   vec_free (vpn_ascii_id);
9575   return ret;
9576 }
9577
9578 static int
9579 api_dhcp_client_config (vat_main_t * vam)
9580 {
9581   unformat_input_t *i = vam->input;
9582   vl_api_dhcp_client_config_t *mp;
9583   u32 sw_if_index;
9584   u8 sw_if_index_set = 0;
9585   u8 is_add = 1;
9586   u8 *hostname = 0;
9587   u8 disable_event = 0;
9588   int ret;
9589
9590   /* Parse args required to build the message */
9591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9592     {
9593       if (unformat (i, "del"))
9594         is_add = 0;
9595       else
9596         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9597         sw_if_index_set = 1;
9598       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9599         sw_if_index_set = 1;
9600       else if (unformat (i, "hostname %s", &hostname))
9601         ;
9602       else if (unformat (i, "disable_event"))
9603         disable_event = 1;
9604       else
9605         break;
9606     }
9607
9608   if (sw_if_index_set == 0)
9609     {
9610       errmsg ("missing interface name or sw_if_index");
9611       return -99;
9612     }
9613
9614   if (vec_len (hostname) > 63)
9615     {
9616       errmsg ("hostname too long");
9617     }
9618   vec_add1 (hostname, 0);
9619
9620   /* Construct the API message */
9621   M (DHCP_CLIENT_CONFIG, mp);
9622
9623   mp->is_add = is_add;
9624   mp->client.sw_if_index = htonl (sw_if_index);
9625   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9626   vec_free (hostname);
9627   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9628   mp->client.pid = htonl (getpid ());
9629
9630   /* send it... */
9631   S (mp);
9632
9633   /* Wait for a reply, return good/bad news  */
9634   W (ret);
9635   return ret;
9636 }
9637
9638 static int
9639 api_set_ip_flow_hash (vat_main_t * vam)
9640 {
9641   unformat_input_t *i = vam->input;
9642   vl_api_set_ip_flow_hash_t *mp;
9643   u32 vrf_id = 0;
9644   u8 is_ipv6 = 0;
9645   u8 vrf_id_set = 0;
9646   u8 src = 0;
9647   u8 dst = 0;
9648   u8 sport = 0;
9649   u8 dport = 0;
9650   u8 proto = 0;
9651   u8 reverse = 0;
9652   int ret;
9653
9654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9655     {
9656       if (unformat (i, "vrf %d", &vrf_id))
9657         vrf_id_set = 1;
9658       else if (unformat (i, "ipv6"))
9659         is_ipv6 = 1;
9660       else if (unformat (i, "src"))
9661         src = 1;
9662       else if (unformat (i, "dst"))
9663         dst = 1;
9664       else if (unformat (i, "sport"))
9665         sport = 1;
9666       else if (unformat (i, "dport"))
9667         dport = 1;
9668       else if (unformat (i, "proto"))
9669         proto = 1;
9670       else if (unformat (i, "reverse"))
9671         reverse = 1;
9672
9673       else
9674         {
9675           clib_warning ("parse error '%U'", format_unformat_error, i);
9676           return -99;
9677         }
9678     }
9679
9680   if (vrf_id_set == 0)
9681     {
9682       errmsg ("missing vrf id");
9683       return -99;
9684     }
9685
9686   M (SET_IP_FLOW_HASH, mp);
9687   mp->src = src;
9688   mp->dst = dst;
9689   mp->sport = sport;
9690   mp->dport = dport;
9691   mp->proto = proto;
9692   mp->reverse = reverse;
9693   mp->vrf_id = ntohl (vrf_id);
9694   mp->is_ipv6 = is_ipv6;
9695
9696   S (mp);
9697   W (ret);
9698   return ret;
9699 }
9700
9701 static int
9702 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9703 {
9704   unformat_input_t *i = vam->input;
9705   vl_api_sw_interface_ip6_enable_disable_t *mp;
9706   u32 sw_if_index;
9707   u8 sw_if_index_set = 0;
9708   u8 enable = 0;
9709   int ret;
9710
9711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9712     {
9713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9714         sw_if_index_set = 1;
9715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9716         sw_if_index_set = 1;
9717       else if (unformat (i, "enable"))
9718         enable = 1;
9719       else if (unformat (i, "disable"))
9720         enable = 0;
9721       else
9722         {
9723           clib_warning ("parse error '%U'", format_unformat_error, i);
9724           return -99;
9725         }
9726     }
9727
9728   if (sw_if_index_set == 0)
9729     {
9730       errmsg ("missing interface name or sw_if_index");
9731       return -99;
9732     }
9733
9734   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9735
9736   mp->sw_if_index = ntohl (sw_if_index);
9737   mp->enable = enable;
9738
9739   S (mp);
9740   W (ret);
9741   return ret;
9742 }
9743
9744 static int
9745 api_ip6nd_proxy_add_del (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   vl_api_ip6nd_proxy_add_del_t *mp;
9749   u32 sw_if_index = ~0;
9750   u8 v6_address_set = 0;
9751   vl_api_ip6_address_t v6address;
9752   u8 is_del = 0;
9753   int ret;
9754
9755   /* Parse args required to build the message */
9756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9757     {
9758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9759         ;
9760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9761         ;
9762       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9763         v6_address_set = 1;
9764       if (unformat (i, "del"))
9765         is_del = 1;
9766       else
9767         {
9768           clib_warning ("parse error '%U'", format_unformat_error, i);
9769           return -99;
9770         }
9771     }
9772
9773   if (sw_if_index == ~0)
9774     {
9775       errmsg ("missing interface name or sw_if_index");
9776       return -99;
9777     }
9778   if (!v6_address_set)
9779     {
9780       errmsg ("no address set");
9781       return -99;
9782     }
9783
9784   /* Construct the API message */
9785   M (IP6ND_PROXY_ADD_DEL, mp);
9786
9787   mp->is_del = is_del;
9788   mp->sw_if_index = ntohl (sw_if_index);
9789   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9790
9791   /* send it... */
9792   S (mp);
9793
9794   /* Wait for a reply, return good/bad news  */
9795   W (ret);
9796   return ret;
9797 }
9798
9799 static int
9800 api_ip6nd_proxy_dump (vat_main_t * vam)
9801 {
9802   vl_api_ip6nd_proxy_dump_t *mp;
9803   vl_api_control_ping_t *mp_ping;
9804   int ret;
9805
9806   M (IP6ND_PROXY_DUMP, mp);
9807
9808   S (mp);
9809
9810   /* Use a control ping for synchronization */
9811   MPING (CONTROL_PING, mp_ping);
9812   S (mp_ping);
9813
9814   W (ret);
9815   return ret;
9816 }
9817
9818 static void vl_api_ip6nd_proxy_details_t_handler
9819   (vl_api_ip6nd_proxy_details_t * mp)
9820 {
9821   vat_main_t *vam = &vat_main;
9822
9823   print (vam->ofp, "host %U sw_if_index %d",
9824          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9825 }
9826
9827 static void vl_api_ip6nd_proxy_details_t_handler_json
9828   (vl_api_ip6nd_proxy_details_t * mp)
9829 {
9830   vat_main_t *vam = &vat_main;
9831   struct in6_addr ip6;
9832   vat_json_node_t *node = NULL;
9833
9834   if (VAT_JSON_ARRAY != vam->json_tree.type)
9835     {
9836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9837       vat_json_init_array (&vam->json_tree);
9838     }
9839   node = vat_json_array_add (&vam->json_tree);
9840
9841   vat_json_init_object (node);
9842   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9843
9844   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9845   vat_json_object_add_ip6 (node, "host", ip6);
9846 }
9847
9848 static int
9849 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9850 {
9851   unformat_input_t *i = vam->input;
9852   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9853   u32 sw_if_index;
9854   u8 sw_if_index_set = 0;
9855   u8 v6_address_set = 0;
9856   vl_api_prefix_t pfx;
9857   u8 use_default = 0;
9858   u8 no_advertise = 0;
9859   u8 off_link = 0;
9860   u8 no_autoconfig = 0;
9861   u8 no_onlink = 0;
9862   u8 is_no = 0;
9863   u32 val_lifetime = 0;
9864   u32 pref_lifetime = 0;
9865   int ret;
9866
9867   /* Parse args required to build the message */
9868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9869     {
9870       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9871         sw_if_index_set = 1;
9872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9873         sw_if_index_set = 1;
9874       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9875         v6_address_set = 1;
9876       else if (unformat (i, "val_life %d", &val_lifetime))
9877         ;
9878       else if (unformat (i, "pref_life %d", &pref_lifetime))
9879         ;
9880       else if (unformat (i, "def"))
9881         use_default = 1;
9882       else if (unformat (i, "noadv"))
9883         no_advertise = 1;
9884       else if (unformat (i, "offl"))
9885         off_link = 1;
9886       else if (unformat (i, "noauto"))
9887         no_autoconfig = 1;
9888       else if (unformat (i, "nolink"))
9889         no_onlink = 1;
9890       else if (unformat (i, "isno"))
9891         is_no = 1;
9892       else
9893         {
9894           clib_warning ("parse error '%U'", format_unformat_error, i);
9895           return -99;
9896         }
9897     }
9898
9899   if (sw_if_index_set == 0)
9900     {
9901       errmsg ("missing interface name or sw_if_index");
9902       return -99;
9903     }
9904   if (!v6_address_set)
9905     {
9906       errmsg ("no address set");
9907       return -99;
9908     }
9909
9910   /* Construct the API message */
9911   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9912
9913   mp->sw_if_index = ntohl (sw_if_index);
9914   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9915   mp->use_default = use_default;
9916   mp->no_advertise = no_advertise;
9917   mp->off_link = off_link;
9918   mp->no_autoconfig = no_autoconfig;
9919   mp->no_onlink = no_onlink;
9920   mp->is_no = is_no;
9921   mp->val_lifetime = ntohl (val_lifetime);
9922   mp->pref_lifetime = ntohl (pref_lifetime);
9923
9924   /* send it... */
9925   S (mp);
9926
9927   /* Wait for a reply, return good/bad news  */
9928   W (ret);
9929   return ret;
9930 }
9931
9932 static int
9933 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9934 {
9935   unformat_input_t *i = vam->input;
9936   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9937   u32 sw_if_index;
9938   u8 sw_if_index_set = 0;
9939   u8 suppress = 0;
9940   u8 managed = 0;
9941   u8 other = 0;
9942   u8 ll_option = 0;
9943   u8 send_unicast = 0;
9944   u8 cease = 0;
9945   u8 is_no = 0;
9946   u8 default_router = 0;
9947   u32 max_interval = 0;
9948   u32 min_interval = 0;
9949   u32 lifetime = 0;
9950   u32 initial_count = 0;
9951   u32 initial_interval = 0;
9952   int ret;
9953
9954
9955   /* Parse args required to build the message */
9956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9957     {
9958       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9959         sw_if_index_set = 1;
9960       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9961         sw_if_index_set = 1;
9962       else if (unformat (i, "maxint %d", &max_interval))
9963         ;
9964       else if (unformat (i, "minint %d", &min_interval))
9965         ;
9966       else if (unformat (i, "life %d", &lifetime))
9967         ;
9968       else if (unformat (i, "count %d", &initial_count))
9969         ;
9970       else if (unformat (i, "interval %d", &initial_interval))
9971         ;
9972       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9973         suppress = 1;
9974       else if (unformat (i, "managed"))
9975         managed = 1;
9976       else if (unformat (i, "other"))
9977         other = 1;
9978       else if (unformat (i, "ll"))
9979         ll_option = 1;
9980       else if (unformat (i, "send"))
9981         send_unicast = 1;
9982       else if (unformat (i, "cease"))
9983         cease = 1;
9984       else if (unformat (i, "isno"))
9985         is_no = 1;
9986       else if (unformat (i, "def"))
9987         default_router = 1;
9988       else
9989         {
9990           clib_warning ("parse error '%U'", format_unformat_error, i);
9991           return -99;
9992         }
9993     }
9994
9995   if (sw_if_index_set == 0)
9996     {
9997       errmsg ("missing interface name or sw_if_index");
9998       return -99;
9999     }
10000
10001   /* Construct the API message */
10002   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10003
10004   mp->sw_if_index = ntohl (sw_if_index);
10005   mp->max_interval = ntohl (max_interval);
10006   mp->min_interval = ntohl (min_interval);
10007   mp->lifetime = ntohl (lifetime);
10008   mp->initial_count = ntohl (initial_count);
10009   mp->initial_interval = ntohl (initial_interval);
10010   mp->suppress = suppress;
10011   mp->managed = managed;
10012   mp->other = other;
10013   mp->ll_option = ll_option;
10014   mp->send_unicast = send_unicast;
10015   mp->cease = cease;
10016   mp->is_no = is_no;
10017   mp->default_router = default_router;
10018
10019   /* send it... */
10020   S (mp);
10021
10022   /* Wait for a reply, return good/bad news  */
10023   W (ret);
10024   return ret;
10025 }
10026
10027 static int
10028 api_set_arp_neighbor_limit (vat_main_t * vam)
10029 {
10030   unformat_input_t *i = vam->input;
10031   vl_api_set_arp_neighbor_limit_t *mp;
10032   u32 arp_nbr_limit;
10033   u8 limit_set = 0;
10034   u8 is_ipv6 = 0;
10035   int ret;
10036
10037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10038     {
10039       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10040         limit_set = 1;
10041       else if (unformat (i, "ipv6"))
10042         is_ipv6 = 1;
10043       else
10044         {
10045           clib_warning ("parse error '%U'", format_unformat_error, i);
10046           return -99;
10047         }
10048     }
10049
10050   if (limit_set == 0)
10051     {
10052       errmsg ("missing limit value");
10053       return -99;
10054     }
10055
10056   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10057
10058   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10059   mp->is_ipv6 = is_ipv6;
10060
10061   S (mp);
10062   W (ret);
10063   return ret;
10064 }
10065
10066 static int
10067 api_l2_patch_add_del (vat_main_t * vam)
10068 {
10069   unformat_input_t *i = vam->input;
10070   vl_api_l2_patch_add_del_t *mp;
10071   u32 rx_sw_if_index;
10072   u8 rx_sw_if_index_set = 0;
10073   u32 tx_sw_if_index;
10074   u8 tx_sw_if_index_set = 0;
10075   u8 is_add = 1;
10076   int ret;
10077
10078   /* Parse args required to build the message */
10079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10080     {
10081       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10082         rx_sw_if_index_set = 1;
10083       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10084         tx_sw_if_index_set = 1;
10085       else if (unformat (i, "rx"))
10086         {
10087           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10088             {
10089               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10090                             &rx_sw_if_index))
10091                 rx_sw_if_index_set = 1;
10092             }
10093           else
10094             break;
10095         }
10096       else if (unformat (i, "tx"))
10097         {
10098           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10099             {
10100               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10101                             &tx_sw_if_index))
10102                 tx_sw_if_index_set = 1;
10103             }
10104           else
10105             break;
10106         }
10107       else if (unformat (i, "del"))
10108         is_add = 0;
10109       else
10110         break;
10111     }
10112
10113   if (rx_sw_if_index_set == 0)
10114     {
10115       errmsg ("missing rx interface name or rx_sw_if_index");
10116       return -99;
10117     }
10118
10119   if (tx_sw_if_index_set == 0)
10120     {
10121       errmsg ("missing tx interface name or tx_sw_if_index");
10122       return -99;
10123     }
10124
10125   M (L2_PATCH_ADD_DEL, mp);
10126
10127   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10128   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10129   mp->is_add = is_add;
10130
10131   S (mp);
10132   W (ret);
10133   return ret;
10134 }
10135
10136 u8 is_del;
10137 u8 localsid_addr[16];
10138 u8 end_psp;
10139 u8 behavior;
10140 u32 sw_if_index;
10141 u32 vlan_index;
10142 u32 fib_table;
10143 u8 nh_addr[16];
10144
10145 static int
10146 api_sr_localsid_add_del (vat_main_t * vam)
10147 {
10148   unformat_input_t *i = vam->input;
10149   vl_api_sr_localsid_add_del_t *mp;
10150
10151   u8 is_del;
10152   ip6_address_t localsid;
10153   u8 end_psp = 0;
10154   u8 behavior = ~0;
10155   u32 sw_if_index;
10156   u32 fib_table = ~(u32) 0;
10157   ip6_address_t nh_addr6;
10158   ip4_address_t nh_addr4;
10159   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10160   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10161
10162   bool nexthop_set = 0;
10163
10164   int ret;
10165
10166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10167     {
10168       if (unformat (i, "del"))
10169         is_del = 1;
10170       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10171       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10172         nexthop_set = 1;
10173       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10174         nexthop_set = 1;
10175       else if (unformat (i, "behavior %u", &behavior));
10176       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10177       else if (unformat (i, "fib-table %u", &fib_table));
10178       else if (unformat (i, "end.psp %u", &behavior));
10179       else
10180         break;
10181     }
10182
10183   M (SR_LOCALSID_ADD_DEL, mp);
10184
10185   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10186   if (nexthop_set)
10187     {
10188       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10189       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10190     }
10191   mp->behavior = behavior;
10192   mp->sw_if_index = ntohl (sw_if_index);
10193   mp->fib_table = ntohl (fib_table);
10194   mp->end_psp = end_psp;
10195   mp->is_del = is_del;
10196
10197   S (mp);
10198   W (ret);
10199   return ret;
10200 }
10201
10202 static int
10203 api_ioam_enable (vat_main_t * vam)
10204 {
10205   unformat_input_t *input = vam->input;
10206   vl_api_ioam_enable_t *mp;
10207   u32 id = 0;
10208   int has_trace_option = 0;
10209   int has_pot_option = 0;
10210   int has_seqno_option = 0;
10211   int has_analyse_option = 0;
10212   int ret;
10213
10214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10215     {
10216       if (unformat (input, "trace"))
10217         has_trace_option = 1;
10218       else if (unformat (input, "pot"))
10219         has_pot_option = 1;
10220       else if (unformat (input, "seqno"))
10221         has_seqno_option = 1;
10222       else if (unformat (input, "analyse"))
10223         has_analyse_option = 1;
10224       else
10225         break;
10226     }
10227   M (IOAM_ENABLE, mp);
10228   mp->id = htons (id);
10229   mp->seqno = has_seqno_option;
10230   mp->analyse = has_analyse_option;
10231   mp->pot_enable = has_pot_option;
10232   mp->trace_enable = has_trace_option;
10233
10234   S (mp);
10235   W (ret);
10236   return ret;
10237 }
10238
10239
10240 static int
10241 api_ioam_disable (vat_main_t * vam)
10242 {
10243   vl_api_ioam_disable_t *mp;
10244   int ret;
10245
10246   M (IOAM_DISABLE, mp);
10247   S (mp);
10248   W (ret);
10249   return ret;
10250 }
10251
10252 #define foreach_tcp_proto_field                 \
10253 _(src_port)                                     \
10254 _(dst_port)
10255
10256 #define foreach_udp_proto_field                 \
10257 _(src_port)                                     \
10258 _(dst_port)
10259
10260 #define foreach_ip4_proto_field                 \
10261 _(src_address)                                  \
10262 _(dst_address)                                  \
10263 _(tos)                                          \
10264 _(length)                                       \
10265 _(fragment_id)                                  \
10266 _(ttl)                                          \
10267 _(protocol)                                     \
10268 _(checksum)
10269
10270 typedef struct
10271 {
10272   u16 src_port, dst_port;
10273 } tcpudp_header_t;
10274
10275 #if VPP_API_TEST_BUILTIN == 0
10276 uword
10277 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10278 {
10279   u8 **maskp = va_arg (*args, u8 **);
10280   u8 *mask = 0;
10281   u8 found_something = 0;
10282   tcp_header_t *tcp;
10283
10284 #define _(a) u8 a=0;
10285   foreach_tcp_proto_field;
10286 #undef _
10287
10288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10289     {
10290       if (0);
10291 #define _(a) else if (unformat (input, #a)) a=1;
10292       foreach_tcp_proto_field
10293 #undef _
10294         else
10295         break;
10296     }
10297
10298 #define _(a) found_something += a;
10299   foreach_tcp_proto_field;
10300 #undef _
10301
10302   if (found_something == 0)
10303     return 0;
10304
10305   vec_validate (mask, sizeof (*tcp) - 1);
10306
10307   tcp = (tcp_header_t *) mask;
10308
10309 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10310   foreach_tcp_proto_field;
10311 #undef _
10312
10313   *maskp = mask;
10314   return 1;
10315 }
10316
10317 uword
10318 unformat_udp_mask (unformat_input_t * input, va_list * args)
10319 {
10320   u8 **maskp = va_arg (*args, u8 **);
10321   u8 *mask = 0;
10322   u8 found_something = 0;
10323   udp_header_t *udp;
10324
10325 #define _(a) u8 a=0;
10326   foreach_udp_proto_field;
10327 #undef _
10328
10329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10330     {
10331       if (0);
10332 #define _(a) else if (unformat (input, #a)) a=1;
10333       foreach_udp_proto_field
10334 #undef _
10335         else
10336         break;
10337     }
10338
10339 #define _(a) found_something += a;
10340   foreach_udp_proto_field;
10341 #undef _
10342
10343   if (found_something == 0)
10344     return 0;
10345
10346   vec_validate (mask, sizeof (*udp) - 1);
10347
10348   udp = (udp_header_t *) mask;
10349
10350 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10351   foreach_udp_proto_field;
10352 #undef _
10353
10354   *maskp = mask;
10355   return 1;
10356 }
10357
10358 uword
10359 unformat_l4_mask (unformat_input_t * input, va_list * args)
10360 {
10361   u8 **maskp = va_arg (*args, u8 **);
10362   u16 src_port = 0, dst_port = 0;
10363   tcpudp_header_t *tcpudp;
10364
10365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10366     {
10367       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10368         return 1;
10369       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10370         return 1;
10371       else if (unformat (input, "src_port"))
10372         src_port = 0xFFFF;
10373       else if (unformat (input, "dst_port"))
10374         dst_port = 0xFFFF;
10375       else
10376         return 0;
10377     }
10378
10379   if (!src_port && !dst_port)
10380     return 0;
10381
10382   u8 *mask = 0;
10383   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10384
10385   tcpudp = (tcpudp_header_t *) mask;
10386   tcpudp->src_port = src_port;
10387   tcpudp->dst_port = dst_port;
10388
10389   *maskp = mask;
10390
10391   return 1;
10392 }
10393
10394 uword
10395 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10396 {
10397   u8 **maskp = va_arg (*args, u8 **);
10398   u8 *mask = 0;
10399   u8 found_something = 0;
10400   ip4_header_t *ip;
10401
10402 #define _(a) u8 a=0;
10403   foreach_ip4_proto_field;
10404 #undef _
10405   u8 version = 0;
10406   u8 hdr_length = 0;
10407
10408
10409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10410     {
10411       if (unformat (input, "version"))
10412         version = 1;
10413       else if (unformat (input, "hdr_length"))
10414         hdr_length = 1;
10415       else if (unformat (input, "src"))
10416         src_address = 1;
10417       else if (unformat (input, "dst"))
10418         dst_address = 1;
10419       else if (unformat (input, "proto"))
10420         protocol = 1;
10421
10422 #define _(a) else if (unformat (input, #a)) a=1;
10423       foreach_ip4_proto_field
10424 #undef _
10425         else
10426         break;
10427     }
10428
10429 #define _(a) found_something += a;
10430   foreach_ip4_proto_field;
10431 #undef _
10432
10433   if (found_something == 0)
10434     return 0;
10435
10436   vec_validate (mask, sizeof (*ip) - 1);
10437
10438   ip = (ip4_header_t *) mask;
10439
10440 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10441   foreach_ip4_proto_field;
10442 #undef _
10443
10444   ip->ip_version_and_header_length = 0;
10445
10446   if (version)
10447     ip->ip_version_and_header_length |= 0xF0;
10448
10449   if (hdr_length)
10450     ip->ip_version_and_header_length |= 0x0F;
10451
10452   *maskp = mask;
10453   return 1;
10454 }
10455
10456 #define foreach_ip6_proto_field                 \
10457 _(src_address)                                  \
10458 _(dst_address)                                  \
10459 _(payload_length)                               \
10460 _(hop_limit)                                    \
10461 _(protocol)
10462
10463 uword
10464 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10465 {
10466   u8 **maskp = va_arg (*args, u8 **);
10467   u8 *mask = 0;
10468   u8 found_something = 0;
10469   ip6_header_t *ip;
10470   u32 ip_version_traffic_class_and_flow_label;
10471
10472 #define _(a) u8 a=0;
10473   foreach_ip6_proto_field;
10474 #undef _
10475   u8 version = 0;
10476   u8 traffic_class = 0;
10477   u8 flow_label = 0;
10478
10479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10480     {
10481       if (unformat (input, "version"))
10482         version = 1;
10483       else if (unformat (input, "traffic-class"))
10484         traffic_class = 1;
10485       else if (unformat (input, "flow-label"))
10486         flow_label = 1;
10487       else if (unformat (input, "src"))
10488         src_address = 1;
10489       else if (unformat (input, "dst"))
10490         dst_address = 1;
10491       else if (unformat (input, "proto"))
10492         protocol = 1;
10493
10494 #define _(a) else if (unformat (input, #a)) a=1;
10495       foreach_ip6_proto_field
10496 #undef _
10497         else
10498         break;
10499     }
10500
10501 #define _(a) found_something += a;
10502   foreach_ip6_proto_field;
10503 #undef _
10504
10505   if (found_something == 0)
10506     return 0;
10507
10508   vec_validate (mask, sizeof (*ip) - 1);
10509
10510   ip = (ip6_header_t *) mask;
10511
10512 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10513   foreach_ip6_proto_field;
10514 #undef _
10515
10516   ip_version_traffic_class_and_flow_label = 0;
10517
10518   if (version)
10519     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10520
10521   if (traffic_class)
10522     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10523
10524   if (flow_label)
10525     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10526
10527   ip->ip_version_traffic_class_and_flow_label =
10528     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10529
10530   *maskp = mask;
10531   return 1;
10532 }
10533
10534 uword
10535 unformat_l3_mask (unformat_input_t * input, va_list * args)
10536 {
10537   u8 **maskp = va_arg (*args, u8 **);
10538
10539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10540     {
10541       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10542         return 1;
10543       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10544         return 1;
10545       else
10546         break;
10547     }
10548   return 0;
10549 }
10550
10551 uword
10552 unformat_l2_mask (unformat_input_t * input, va_list * args)
10553 {
10554   u8 **maskp = va_arg (*args, u8 **);
10555   u8 *mask = 0;
10556   u8 src = 0;
10557   u8 dst = 0;
10558   u8 proto = 0;
10559   u8 tag1 = 0;
10560   u8 tag2 = 0;
10561   u8 ignore_tag1 = 0;
10562   u8 ignore_tag2 = 0;
10563   u8 cos1 = 0;
10564   u8 cos2 = 0;
10565   u8 dot1q = 0;
10566   u8 dot1ad = 0;
10567   int len = 14;
10568
10569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10570     {
10571       if (unformat (input, "src"))
10572         src = 1;
10573       else if (unformat (input, "dst"))
10574         dst = 1;
10575       else if (unformat (input, "proto"))
10576         proto = 1;
10577       else if (unformat (input, "tag1"))
10578         tag1 = 1;
10579       else if (unformat (input, "tag2"))
10580         tag2 = 1;
10581       else if (unformat (input, "ignore-tag1"))
10582         ignore_tag1 = 1;
10583       else if (unformat (input, "ignore-tag2"))
10584         ignore_tag2 = 1;
10585       else if (unformat (input, "cos1"))
10586         cos1 = 1;
10587       else if (unformat (input, "cos2"))
10588         cos2 = 1;
10589       else if (unformat (input, "dot1q"))
10590         dot1q = 1;
10591       else if (unformat (input, "dot1ad"))
10592         dot1ad = 1;
10593       else
10594         break;
10595     }
10596   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10597        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10598     return 0;
10599
10600   if (tag1 || ignore_tag1 || cos1 || dot1q)
10601     len = 18;
10602   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10603     len = 22;
10604
10605   vec_validate (mask, len - 1);
10606
10607   if (dst)
10608     clib_memset (mask, 0xff, 6);
10609
10610   if (src)
10611     clib_memset (mask + 6, 0xff, 6);
10612
10613   if (tag2 || dot1ad)
10614     {
10615       /* inner vlan tag */
10616       if (tag2)
10617         {
10618           mask[19] = 0xff;
10619           mask[18] = 0x0f;
10620         }
10621       if (cos2)
10622         mask[18] |= 0xe0;
10623       if (proto)
10624         mask[21] = mask[20] = 0xff;
10625       if (tag1)
10626         {
10627           mask[15] = 0xff;
10628           mask[14] = 0x0f;
10629         }
10630       if (cos1)
10631         mask[14] |= 0xe0;
10632       *maskp = mask;
10633       return 1;
10634     }
10635   if (tag1 | dot1q)
10636     {
10637       if (tag1)
10638         {
10639           mask[15] = 0xff;
10640           mask[14] = 0x0f;
10641         }
10642       if (cos1)
10643         mask[14] |= 0xe0;
10644       if (proto)
10645         mask[16] = mask[17] = 0xff;
10646
10647       *maskp = mask;
10648       return 1;
10649     }
10650   if (cos2)
10651     mask[18] |= 0xe0;
10652   if (cos1)
10653     mask[14] |= 0xe0;
10654   if (proto)
10655     mask[12] = mask[13] = 0xff;
10656
10657   *maskp = mask;
10658   return 1;
10659 }
10660
10661 uword
10662 unformat_classify_mask (unformat_input_t * input, va_list * args)
10663 {
10664   u8 **maskp = va_arg (*args, u8 **);
10665   u32 *skipp = va_arg (*args, u32 *);
10666   u32 *matchp = va_arg (*args, u32 *);
10667   u32 match;
10668   u8 *mask = 0;
10669   u8 *l2 = 0;
10670   u8 *l3 = 0;
10671   u8 *l4 = 0;
10672   int i;
10673
10674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10675     {
10676       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10677         ;
10678       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10679         ;
10680       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10681         ;
10682       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10683         ;
10684       else
10685         break;
10686     }
10687
10688   if (l4 && !l3)
10689     {
10690       vec_free (mask);
10691       vec_free (l2);
10692       vec_free (l4);
10693       return 0;
10694     }
10695
10696   if (mask || l2 || l3 || l4)
10697     {
10698       if (l2 || l3 || l4)
10699         {
10700           /* "With a free Ethernet header in every package" */
10701           if (l2 == 0)
10702             vec_validate (l2, 13);
10703           mask = l2;
10704           if (vec_len (l3))
10705             {
10706               vec_append (mask, l3);
10707               vec_free (l3);
10708             }
10709           if (vec_len (l4))
10710             {
10711               vec_append (mask, l4);
10712               vec_free (l4);
10713             }
10714         }
10715
10716       /* Scan forward looking for the first significant mask octet */
10717       for (i = 0; i < vec_len (mask); i++)
10718         if (mask[i])
10719           break;
10720
10721       /* compute (skip, match) params */
10722       *skipp = i / sizeof (u32x4);
10723       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10724
10725       /* Pad mask to an even multiple of the vector size */
10726       while (vec_len (mask) % sizeof (u32x4))
10727         vec_add1 (mask, 0);
10728
10729       match = vec_len (mask) / sizeof (u32x4);
10730
10731       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10732         {
10733           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10734           if (*tmp || *(tmp + 1))
10735             break;
10736           match--;
10737         }
10738       if (match == 0)
10739         clib_warning ("BUG: match 0");
10740
10741       _vec_len (mask) = match * sizeof (u32x4);
10742
10743       *matchp = match;
10744       *maskp = mask;
10745
10746       return 1;
10747     }
10748
10749   return 0;
10750 }
10751 #endif /* VPP_API_TEST_BUILTIN */
10752
10753 #define foreach_l2_next                         \
10754 _(drop, DROP)                                   \
10755 _(ethernet, ETHERNET_INPUT)                     \
10756 _(ip4, IP4_INPUT)                               \
10757 _(ip6, IP6_INPUT)
10758
10759 uword
10760 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10761 {
10762   u32 *miss_next_indexp = va_arg (*args, u32 *);
10763   u32 next_index = 0;
10764   u32 tmp;
10765
10766 #define _(n,N) \
10767   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10768   foreach_l2_next;
10769 #undef _
10770
10771   if (unformat (input, "%d", &tmp))
10772     {
10773       next_index = tmp;
10774       goto out;
10775     }
10776
10777   return 0;
10778
10779 out:
10780   *miss_next_indexp = next_index;
10781   return 1;
10782 }
10783
10784 #define foreach_ip_next                         \
10785 _(drop, DROP)                                   \
10786 _(local, LOCAL)                                 \
10787 _(rewrite, REWRITE)
10788
10789 uword
10790 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10791 {
10792   u32 *miss_next_indexp = va_arg (*args, u32 *);
10793   u32 next_index = 0;
10794   u32 tmp;
10795
10796 #define _(n,N) \
10797   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10798   foreach_ip_next;
10799 #undef _
10800
10801   if (unformat (input, "%d", &tmp))
10802     {
10803       next_index = tmp;
10804       goto out;
10805     }
10806
10807   return 0;
10808
10809 out:
10810   *miss_next_indexp = next_index;
10811   return 1;
10812 }
10813
10814 #define foreach_acl_next                        \
10815 _(deny, DENY)
10816
10817 uword
10818 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10819 {
10820   u32 *miss_next_indexp = va_arg (*args, u32 *);
10821   u32 next_index = 0;
10822   u32 tmp;
10823
10824 #define _(n,N) \
10825   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10826   foreach_acl_next;
10827 #undef _
10828
10829   if (unformat (input, "permit"))
10830     {
10831       next_index = ~0;
10832       goto out;
10833     }
10834   else if (unformat (input, "%d", &tmp))
10835     {
10836       next_index = tmp;
10837       goto out;
10838     }
10839
10840   return 0;
10841
10842 out:
10843   *miss_next_indexp = next_index;
10844   return 1;
10845 }
10846
10847 uword
10848 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10849 {
10850   u32 *r = va_arg (*args, u32 *);
10851
10852   if (unformat (input, "conform-color"))
10853     *r = POLICE_CONFORM;
10854   else if (unformat (input, "exceed-color"))
10855     *r = POLICE_EXCEED;
10856   else
10857     return 0;
10858
10859   return 1;
10860 }
10861
10862 static int
10863 api_classify_add_del_table (vat_main_t * vam)
10864 {
10865   unformat_input_t *i = vam->input;
10866   vl_api_classify_add_del_table_t *mp;
10867
10868   u32 nbuckets = 2;
10869   u32 skip = ~0;
10870   u32 match = ~0;
10871   int is_add = 1;
10872   int del_chain = 0;
10873   u32 table_index = ~0;
10874   u32 next_table_index = ~0;
10875   u32 miss_next_index = ~0;
10876   u32 memory_size = 32 << 20;
10877   u8 *mask = 0;
10878   u32 current_data_flag = 0;
10879   int current_data_offset = 0;
10880   int ret;
10881
10882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10883     {
10884       if (unformat (i, "del"))
10885         is_add = 0;
10886       else if (unformat (i, "del-chain"))
10887         {
10888           is_add = 0;
10889           del_chain = 1;
10890         }
10891       else if (unformat (i, "buckets %d", &nbuckets))
10892         ;
10893       else if (unformat (i, "memory_size %d", &memory_size))
10894         ;
10895       else if (unformat (i, "skip %d", &skip))
10896         ;
10897       else if (unformat (i, "match %d", &match))
10898         ;
10899       else if (unformat (i, "table %d", &table_index))
10900         ;
10901       else if (unformat (i, "mask %U", unformat_classify_mask,
10902                          &mask, &skip, &match))
10903         ;
10904       else if (unformat (i, "next-table %d", &next_table_index))
10905         ;
10906       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10907                          &miss_next_index))
10908         ;
10909       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10910                          &miss_next_index))
10911         ;
10912       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10913                          &miss_next_index))
10914         ;
10915       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10916         ;
10917       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10918         ;
10919       else
10920         break;
10921     }
10922
10923   if (is_add && mask == 0)
10924     {
10925       errmsg ("Mask required");
10926       return -99;
10927     }
10928
10929   if (is_add && skip == ~0)
10930     {
10931       errmsg ("skip count required");
10932       return -99;
10933     }
10934
10935   if (is_add && match == ~0)
10936     {
10937       errmsg ("match count required");
10938       return -99;
10939     }
10940
10941   if (!is_add && table_index == ~0)
10942     {
10943       errmsg ("table index required for delete");
10944       return -99;
10945     }
10946
10947   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10948
10949   mp->is_add = is_add;
10950   mp->del_chain = del_chain;
10951   mp->table_index = ntohl (table_index);
10952   mp->nbuckets = ntohl (nbuckets);
10953   mp->memory_size = ntohl (memory_size);
10954   mp->skip_n_vectors = ntohl (skip);
10955   mp->match_n_vectors = ntohl (match);
10956   mp->next_table_index = ntohl (next_table_index);
10957   mp->miss_next_index = ntohl (miss_next_index);
10958   mp->current_data_flag = ntohl (current_data_flag);
10959   mp->current_data_offset = ntohl (current_data_offset);
10960   mp->mask_len = ntohl (vec_len (mask));
10961   clib_memcpy (mp->mask, mask, vec_len (mask));
10962
10963   vec_free (mask);
10964
10965   S (mp);
10966   W (ret);
10967   return ret;
10968 }
10969
10970 #if VPP_API_TEST_BUILTIN == 0
10971 uword
10972 unformat_l4_match (unformat_input_t * input, va_list * args)
10973 {
10974   u8 **matchp = va_arg (*args, u8 **);
10975
10976   u8 *proto_header = 0;
10977   int src_port = 0;
10978   int dst_port = 0;
10979
10980   tcpudp_header_t h;
10981
10982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (input, "src_port %d", &src_port))
10985         ;
10986       else if (unformat (input, "dst_port %d", &dst_port))
10987         ;
10988       else
10989         return 0;
10990     }
10991
10992   h.src_port = clib_host_to_net_u16 (src_port);
10993   h.dst_port = clib_host_to_net_u16 (dst_port);
10994   vec_validate (proto_header, sizeof (h) - 1);
10995   memcpy (proto_header, &h, sizeof (h));
10996
10997   *matchp = proto_header;
10998
10999   return 1;
11000 }
11001
11002 uword
11003 unformat_ip4_match (unformat_input_t * input, va_list * args)
11004 {
11005   u8 **matchp = va_arg (*args, u8 **);
11006   u8 *match = 0;
11007   ip4_header_t *ip;
11008   int version = 0;
11009   u32 version_val;
11010   int hdr_length = 0;
11011   u32 hdr_length_val;
11012   int src = 0, dst = 0;
11013   ip4_address_t src_val, dst_val;
11014   int proto = 0;
11015   u32 proto_val;
11016   int tos = 0;
11017   u32 tos_val;
11018   int length = 0;
11019   u32 length_val;
11020   int fragment_id = 0;
11021   u32 fragment_id_val;
11022   int ttl = 0;
11023   int ttl_val;
11024   int checksum = 0;
11025   u32 checksum_val;
11026
11027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11028     {
11029       if (unformat (input, "version %d", &version_val))
11030         version = 1;
11031       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11032         hdr_length = 1;
11033       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11034         src = 1;
11035       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11036         dst = 1;
11037       else if (unformat (input, "proto %d", &proto_val))
11038         proto = 1;
11039       else if (unformat (input, "tos %d", &tos_val))
11040         tos = 1;
11041       else if (unformat (input, "length %d", &length_val))
11042         length = 1;
11043       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11044         fragment_id = 1;
11045       else if (unformat (input, "ttl %d", &ttl_val))
11046         ttl = 1;
11047       else if (unformat (input, "checksum %d", &checksum_val))
11048         checksum = 1;
11049       else
11050         break;
11051     }
11052
11053   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11054       + ttl + checksum == 0)
11055     return 0;
11056
11057   /*
11058    * Aligned because we use the real comparison functions
11059    */
11060   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11061
11062   ip = (ip4_header_t *) match;
11063
11064   /* These are realistically matched in practice */
11065   if (src)
11066     ip->src_address.as_u32 = src_val.as_u32;
11067
11068   if (dst)
11069     ip->dst_address.as_u32 = dst_val.as_u32;
11070
11071   if (proto)
11072     ip->protocol = proto_val;
11073
11074
11075   /* These are not, but they're included for completeness */
11076   if (version)
11077     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11078
11079   if (hdr_length)
11080     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11081
11082   if (tos)
11083     ip->tos = tos_val;
11084
11085   if (length)
11086     ip->length = clib_host_to_net_u16 (length_val);
11087
11088   if (ttl)
11089     ip->ttl = ttl_val;
11090
11091   if (checksum)
11092     ip->checksum = clib_host_to_net_u16 (checksum_val);
11093
11094   *matchp = match;
11095   return 1;
11096 }
11097
11098 uword
11099 unformat_ip6_match (unformat_input_t * input, va_list * args)
11100 {
11101   u8 **matchp = va_arg (*args, u8 **);
11102   u8 *match = 0;
11103   ip6_header_t *ip;
11104   int version = 0;
11105   u32 version_val;
11106   u8 traffic_class = 0;
11107   u32 traffic_class_val = 0;
11108   u8 flow_label = 0;
11109   u8 flow_label_val;
11110   int src = 0, dst = 0;
11111   ip6_address_t src_val, dst_val;
11112   int proto = 0;
11113   u32 proto_val;
11114   int payload_length = 0;
11115   u32 payload_length_val;
11116   int hop_limit = 0;
11117   int hop_limit_val;
11118   u32 ip_version_traffic_class_and_flow_label;
11119
11120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11121     {
11122       if (unformat (input, "version %d", &version_val))
11123         version = 1;
11124       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11125         traffic_class = 1;
11126       else if (unformat (input, "flow_label %d", &flow_label_val))
11127         flow_label = 1;
11128       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11129         src = 1;
11130       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11131         dst = 1;
11132       else if (unformat (input, "proto %d", &proto_val))
11133         proto = 1;
11134       else if (unformat (input, "payload_length %d", &payload_length_val))
11135         payload_length = 1;
11136       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11137         hop_limit = 1;
11138       else
11139         break;
11140     }
11141
11142   if (version + traffic_class + flow_label + src + dst + proto +
11143       payload_length + hop_limit == 0)
11144     return 0;
11145
11146   /*
11147    * Aligned because we use the real comparison functions
11148    */
11149   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11150
11151   ip = (ip6_header_t *) match;
11152
11153   if (src)
11154     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11155
11156   if (dst)
11157     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11158
11159   if (proto)
11160     ip->protocol = proto_val;
11161
11162   ip_version_traffic_class_and_flow_label = 0;
11163
11164   if (version)
11165     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11166
11167   if (traffic_class)
11168     ip_version_traffic_class_and_flow_label |=
11169       (traffic_class_val & 0xFF) << 20;
11170
11171   if (flow_label)
11172     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11173
11174   ip->ip_version_traffic_class_and_flow_label =
11175     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11176
11177   if (payload_length)
11178     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11179
11180   if (hop_limit)
11181     ip->hop_limit = hop_limit_val;
11182
11183   *matchp = match;
11184   return 1;
11185 }
11186
11187 uword
11188 unformat_l3_match (unformat_input_t * input, va_list * args)
11189 {
11190   u8 **matchp = va_arg (*args, u8 **);
11191
11192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11193     {
11194       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11195         return 1;
11196       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11197         return 1;
11198       else
11199         break;
11200     }
11201   return 0;
11202 }
11203
11204 uword
11205 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11206 {
11207   u8 *tagp = va_arg (*args, u8 *);
11208   u32 tag;
11209
11210   if (unformat (input, "%d", &tag))
11211     {
11212       tagp[0] = (tag >> 8) & 0x0F;
11213       tagp[1] = tag & 0xFF;
11214       return 1;
11215     }
11216
11217   return 0;
11218 }
11219
11220 uword
11221 unformat_l2_match (unformat_input_t * input, va_list * args)
11222 {
11223   u8 **matchp = va_arg (*args, u8 **);
11224   u8 *match = 0;
11225   u8 src = 0;
11226   u8 src_val[6];
11227   u8 dst = 0;
11228   u8 dst_val[6];
11229   u8 proto = 0;
11230   u16 proto_val;
11231   u8 tag1 = 0;
11232   u8 tag1_val[2];
11233   u8 tag2 = 0;
11234   u8 tag2_val[2];
11235   int len = 14;
11236   u8 ignore_tag1 = 0;
11237   u8 ignore_tag2 = 0;
11238   u8 cos1 = 0;
11239   u8 cos2 = 0;
11240   u32 cos1_val = 0;
11241   u32 cos2_val = 0;
11242
11243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11244     {
11245       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11246         src = 1;
11247       else
11248         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11249         dst = 1;
11250       else if (unformat (input, "proto %U",
11251                          unformat_ethernet_type_host_byte_order, &proto_val))
11252         proto = 1;
11253       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11254         tag1 = 1;
11255       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11256         tag2 = 1;
11257       else if (unformat (input, "ignore-tag1"))
11258         ignore_tag1 = 1;
11259       else if (unformat (input, "ignore-tag2"))
11260         ignore_tag2 = 1;
11261       else if (unformat (input, "cos1 %d", &cos1_val))
11262         cos1 = 1;
11263       else if (unformat (input, "cos2 %d", &cos2_val))
11264         cos2 = 1;
11265       else
11266         break;
11267     }
11268   if ((src + dst + proto + tag1 + tag2 +
11269        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11270     return 0;
11271
11272   if (tag1 || ignore_tag1 || cos1)
11273     len = 18;
11274   if (tag2 || ignore_tag2 || cos2)
11275     len = 22;
11276
11277   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11278
11279   if (dst)
11280     clib_memcpy (match, dst_val, 6);
11281
11282   if (src)
11283     clib_memcpy (match + 6, src_val, 6);
11284
11285   if (tag2)
11286     {
11287       /* inner vlan tag */
11288       match[19] = tag2_val[1];
11289       match[18] = tag2_val[0];
11290       if (cos2)
11291         match[18] |= (cos2_val & 0x7) << 5;
11292       if (proto)
11293         {
11294           match[21] = proto_val & 0xff;
11295           match[20] = proto_val >> 8;
11296         }
11297       if (tag1)
11298         {
11299           match[15] = tag1_val[1];
11300           match[14] = tag1_val[0];
11301         }
11302       if (cos1)
11303         match[14] |= (cos1_val & 0x7) << 5;
11304       *matchp = match;
11305       return 1;
11306     }
11307   if (tag1)
11308     {
11309       match[15] = tag1_val[1];
11310       match[14] = tag1_val[0];
11311       if (proto)
11312         {
11313           match[17] = proto_val & 0xff;
11314           match[16] = proto_val >> 8;
11315         }
11316       if (cos1)
11317         match[14] |= (cos1_val & 0x7) << 5;
11318
11319       *matchp = match;
11320       return 1;
11321     }
11322   if (cos2)
11323     match[18] |= (cos2_val & 0x7) << 5;
11324   if (cos1)
11325     match[14] |= (cos1_val & 0x7) << 5;
11326   if (proto)
11327     {
11328       match[13] = proto_val & 0xff;
11329       match[12] = proto_val >> 8;
11330     }
11331
11332   *matchp = match;
11333   return 1;
11334 }
11335
11336 uword
11337 unformat_qos_source (unformat_input_t * input, va_list * args)
11338 {
11339   int *qs = va_arg (*args, int *);
11340
11341   if (unformat (input, "ip"))
11342     *qs = QOS_SOURCE_IP;
11343   else if (unformat (input, "mpls"))
11344     *qs = QOS_SOURCE_MPLS;
11345   else if (unformat (input, "ext"))
11346     *qs = QOS_SOURCE_EXT;
11347   else if (unformat (input, "vlan"))
11348     *qs = QOS_SOURCE_VLAN;
11349   else
11350     return 0;
11351
11352   return 1;
11353 }
11354 #endif
11355
11356 uword
11357 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11358 {
11359   u8 **matchp = va_arg (*args, u8 **);
11360   u32 skip_n_vectors = va_arg (*args, u32);
11361   u32 match_n_vectors = va_arg (*args, u32);
11362
11363   u8 *match = 0;
11364   u8 *l2 = 0;
11365   u8 *l3 = 0;
11366   u8 *l4 = 0;
11367
11368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11369     {
11370       if (unformat (input, "hex %U", unformat_hex_string, &match))
11371         ;
11372       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11373         ;
11374       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11375         ;
11376       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11377         ;
11378       else
11379         break;
11380     }
11381
11382   if (l4 && !l3)
11383     {
11384       vec_free (match);
11385       vec_free (l2);
11386       vec_free (l4);
11387       return 0;
11388     }
11389
11390   if (match || l2 || l3 || l4)
11391     {
11392       if (l2 || l3 || l4)
11393         {
11394           /* "Win a free Ethernet header in every packet" */
11395           if (l2 == 0)
11396             vec_validate_aligned (l2, 13, sizeof (u32x4));
11397           match = l2;
11398           if (vec_len (l3))
11399             {
11400               vec_append_aligned (match, l3, sizeof (u32x4));
11401               vec_free (l3);
11402             }
11403           if (vec_len (l4))
11404             {
11405               vec_append_aligned (match, l4, sizeof (u32x4));
11406               vec_free (l4);
11407             }
11408         }
11409
11410       /* Make sure the vector is big enough even if key is all 0's */
11411       vec_validate_aligned
11412         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11413          sizeof (u32x4));
11414
11415       /* Set size, include skipped vectors */
11416       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11417
11418       *matchp = match;
11419
11420       return 1;
11421     }
11422
11423   return 0;
11424 }
11425
11426 static int
11427 api_classify_add_del_session (vat_main_t * vam)
11428 {
11429   unformat_input_t *i = vam->input;
11430   vl_api_classify_add_del_session_t *mp;
11431   int is_add = 1;
11432   u32 table_index = ~0;
11433   u32 hit_next_index = ~0;
11434   u32 opaque_index = ~0;
11435   u8 *match = 0;
11436   i32 advance = 0;
11437   u32 skip_n_vectors = 0;
11438   u32 match_n_vectors = 0;
11439   u32 action = 0;
11440   u32 metadata = 0;
11441   int ret;
11442
11443   /*
11444    * Warning: you have to supply skip_n and match_n
11445    * because the API client cant simply look at the classify
11446    * table object.
11447    */
11448
11449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11450     {
11451       if (unformat (i, "del"))
11452         is_add = 0;
11453       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11454                          &hit_next_index))
11455         ;
11456       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11457                          &hit_next_index))
11458         ;
11459       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11460                          &hit_next_index))
11461         ;
11462       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11463         ;
11464       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11465         ;
11466       else if (unformat (i, "opaque-index %d", &opaque_index))
11467         ;
11468       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11469         ;
11470       else if (unformat (i, "match_n %d", &match_n_vectors))
11471         ;
11472       else if (unformat (i, "match %U", api_unformat_classify_match,
11473                          &match, skip_n_vectors, match_n_vectors))
11474         ;
11475       else if (unformat (i, "advance %d", &advance))
11476         ;
11477       else if (unformat (i, "table-index %d", &table_index))
11478         ;
11479       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11480         action = 1;
11481       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11482         action = 2;
11483       else if (unformat (i, "action %d", &action))
11484         ;
11485       else if (unformat (i, "metadata %d", &metadata))
11486         ;
11487       else
11488         break;
11489     }
11490
11491   if (table_index == ~0)
11492     {
11493       errmsg ("Table index required");
11494       return -99;
11495     }
11496
11497   if (is_add && match == 0)
11498     {
11499       errmsg ("Match value required");
11500       return -99;
11501     }
11502
11503   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11504
11505   mp->is_add = is_add;
11506   mp->table_index = ntohl (table_index);
11507   mp->hit_next_index = ntohl (hit_next_index);
11508   mp->opaque_index = ntohl (opaque_index);
11509   mp->advance = ntohl (advance);
11510   mp->action = action;
11511   mp->metadata = ntohl (metadata);
11512   mp->match_len = ntohl (vec_len (match));
11513   clib_memcpy (mp->match, match, vec_len (match));
11514   vec_free (match);
11515
11516   S (mp);
11517   W (ret);
11518   return ret;
11519 }
11520
11521 static int
11522 api_classify_set_interface_ip_table (vat_main_t * vam)
11523 {
11524   unformat_input_t *i = vam->input;
11525   vl_api_classify_set_interface_ip_table_t *mp;
11526   u32 sw_if_index;
11527   int sw_if_index_set;
11528   u32 table_index = ~0;
11529   u8 is_ipv6 = 0;
11530   int ret;
11531
11532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11533     {
11534       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11535         sw_if_index_set = 1;
11536       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11537         sw_if_index_set = 1;
11538       else if (unformat (i, "table %d", &table_index))
11539         ;
11540       else
11541         {
11542           clib_warning ("parse error '%U'", format_unformat_error, i);
11543           return -99;
11544         }
11545     }
11546
11547   if (sw_if_index_set == 0)
11548     {
11549       errmsg ("missing interface name or sw_if_index");
11550       return -99;
11551     }
11552
11553
11554   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11555
11556   mp->sw_if_index = ntohl (sw_if_index);
11557   mp->table_index = ntohl (table_index);
11558   mp->is_ipv6 = is_ipv6;
11559
11560   S (mp);
11561   W (ret);
11562   return ret;
11563 }
11564
11565 static int
11566 api_classify_set_interface_l2_tables (vat_main_t * vam)
11567 {
11568   unformat_input_t *i = vam->input;
11569   vl_api_classify_set_interface_l2_tables_t *mp;
11570   u32 sw_if_index;
11571   int sw_if_index_set;
11572   u32 ip4_table_index = ~0;
11573   u32 ip6_table_index = ~0;
11574   u32 other_table_index = ~0;
11575   u32 is_input = 1;
11576   int ret;
11577
11578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11579     {
11580       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11581         sw_if_index_set = 1;
11582       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11583         sw_if_index_set = 1;
11584       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11585         ;
11586       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11587         ;
11588       else if (unformat (i, "other-table %d", &other_table_index))
11589         ;
11590       else if (unformat (i, "is-input %d", &is_input))
11591         ;
11592       else
11593         {
11594           clib_warning ("parse error '%U'", format_unformat_error, i);
11595           return -99;
11596         }
11597     }
11598
11599   if (sw_if_index_set == 0)
11600     {
11601       errmsg ("missing interface name or sw_if_index");
11602       return -99;
11603     }
11604
11605
11606   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11607
11608   mp->sw_if_index = ntohl (sw_if_index);
11609   mp->ip4_table_index = ntohl (ip4_table_index);
11610   mp->ip6_table_index = ntohl (ip6_table_index);
11611   mp->other_table_index = ntohl (other_table_index);
11612   mp->is_input = (u8) is_input;
11613
11614   S (mp);
11615   W (ret);
11616   return ret;
11617 }
11618
11619 static int
11620 api_set_ipfix_exporter (vat_main_t * vam)
11621 {
11622   unformat_input_t *i = vam->input;
11623   vl_api_set_ipfix_exporter_t *mp;
11624   ip4_address_t collector_address;
11625   u8 collector_address_set = 0;
11626   u32 collector_port = ~0;
11627   ip4_address_t src_address;
11628   u8 src_address_set = 0;
11629   u32 vrf_id = ~0;
11630   u32 path_mtu = ~0;
11631   u32 template_interval = ~0;
11632   u8 udp_checksum = 0;
11633   int ret;
11634
11635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11636     {
11637       if (unformat (i, "collector_address %U", unformat_ip4_address,
11638                     &collector_address))
11639         collector_address_set = 1;
11640       else if (unformat (i, "collector_port %d", &collector_port))
11641         ;
11642       else if (unformat (i, "src_address %U", unformat_ip4_address,
11643                          &src_address))
11644         src_address_set = 1;
11645       else if (unformat (i, "vrf_id %d", &vrf_id))
11646         ;
11647       else if (unformat (i, "path_mtu %d", &path_mtu))
11648         ;
11649       else if (unformat (i, "template_interval %d", &template_interval))
11650         ;
11651       else if (unformat (i, "udp_checksum"))
11652         udp_checksum = 1;
11653       else
11654         break;
11655     }
11656
11657   if (collector_address_set == 0)
11658     {
11659       errmsg ("collector_address required");
11660       return -99;
11661     }
11662
11663   if (src_address_set == 0)
11664     {
11665       errmsg ("src_address required");
11666       return -99;
11667     }
11668
11669   M (SET_IPFIX_EXPORTER, mp);
11670
11671   memcpy (mp->collector_address, collector_address.data,
11672           sizeof (collector_address.data));
11673   mp->collector_port = htons ((u16) collector_port);
11674   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11675   mp->vrf_id = htonl (vrf_id);
11676   mp->path_mtu = htonl (path_mtu);
11677   mp->template_interval = htonl (template_interval);
11678   mp->udp_checksum = udp_checksum;
11679
11680   S (mp);
11681   W (ret);
11682   return ret;
11683 }
11684
11685 static int
11686 api_set_ipfix_classify_stream (vat_main_t * vam)
11687 {
11688   unformat_input_t *i = vam->input;
11689   vl_api_set_ipfix_classify_stream_t *mp;
11690   u32 domain_id = 0;
11691   u32 src_port = UDP_DST_PORT_ipfix;
11692   int ret;
11693
11694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11695     {
11696       if (unformat (i, "domain %d", &domain_id))
11697         ;
11698       else if (unformat (i, "src_port %d", &src_port))
11699         ;
11700       else
11701         {
11702           errmsg ("unknown input `%U'", format_unformat_error, i);
11703           return -99;
11704         }
11705     }
11706
11707   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11708
11709   mp->domain_id = htonl (domain_id);
11710   mp->src_port = htons ((u16) src_port);
11711
11712   S (mp);
11713   W (ret);
11714   return ret;
11715 }
11716
11717 static int
11718 api_ipfix_classify_table_add_del (vat_main_t * vam)
11719 {
11720   unformat_input_t *i = vam->input;
11721   vl_api_ipfix_classify_table_add_del_t *mp;
11722   int is_add = -1;
11723   u32 classify_table_index = ~0;
11724   u8 ip_version = 0;
11725   u8 transport_protocol = 255;
11726   int ret;
11727
11728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11729     {
11730       if (unformat (i, "add"))
11731         is_add = 1;
11732       else if (unformat (i, "del"))
11733         is_add = 0;
11734       else if (unformat (i, "table %d", &classify_table_index))
11735         ;
11736       else if (unformat (i, "ip4"))
11737         ip_version = 4;
11738       else if (unformat (i, "ip6"))
11739         ip_version = 6;
11740       else if (unformat (i, "tcp"))
11741         transport_protocol = 6;
11742       else if (unformat (i, "udp"))
11743         transport_protocol = 17;
11744       else
11745         {
11746           errmsg ("unknown input `%U'", format_unformat_error, i);
11747           return -99;
11748         }
11749     }
11750
11751   if (is_add == -1)
11752     {
11753       errmsg ("expecting: add|del");
11754       return -99;
11755     }
11756   if (classify_table_index == ~0)
11757     {
11758       errmsg ("classifier table not specified");
11759       return -99;
11760     }
11761   if (ip_version == 0)
11762     {
11763       errmsg ("IP version not specified");
11764       return -99;
11765     }
11766
11767   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11768
11769   mp->is_add = is_add;
11770   mp->table_id = htonl (classify_table_index);
11771   mp->ip_version = ip_version;
11772   mp->transport_protocol = transport_protocol;
11773
11774   S (mp);
11775   W (ret);
11776   return ret;
11777 }
11778
11779 static int
11780 api_get_node_index (vat_main_t * vam)
11781 {
11782   unformat_input_t *i = vam->input;
11783   vl_api_get_node_index_t *mp;
11784   u8 *name = 0;
11785   int ret;
11786
11787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (i, "node %s", &name))
11790         ;
11791       else
11792         break;
11793     }
11794   if (name == 0)
11795     {
11796       errmsg ("node name required");
11797       return -99;
11798     }
11799   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11800     {
11801       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11802       return -99;
11803     }
11804
11805   M (GET_NODE_INDEX, mp);
11806   clib_memcpy (mp->node_name, name, vec_len (name));
11807   vec_free (name);
11808
11809   S (mp);
11810   W (ret);
11811   return ret;
11812 }
11813
11814 static int
11815 api_get_next_index (vat_main_t * vam)
11816 {
11817   unformat_input_t *i = vam->input;
11818   vl_api_get_next_index_t *mp;
11819   u8 *node_name = 0, *next_node_name = 0;
11820   int ret;
11821
11822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11823     {
11824       if (unformat (i, "node-name %s", &node_name))
11825         ;
11826       else if (unformat (i, "next-node-name %s", &next_node_name))
11827         break;
11828     }
11829
11830   if (node_name == 0)
11831     {
11832       errmsg ("node name required");
11833       return -99;
11834     }
11835   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11836     {
11837       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11838       return -99;
11839     }
11840
11841   if (next_node_name == 0)
11842     {
11843       errmsg ("next node name required");
11844       return -99;
11845     }
11846   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11847     {
11848       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11849       return -99;
11850     }
11851
11852   M (GET_NEXT_INDEX, mp);
11853   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11854   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11855   vec_free (node_name);
11856   vec_free (next_node_name);
11857
11858   S (mp);
11859   W (ret);
11860   return ret;
11861 }
11862
11863 static int
11864 api_add_node_next (vat_main_t * vam)
11865 {
11866   unformat_input_t *i = vam->input;
11867   vl_api_add_node_next_t *mp;
11868   u8 *name = 0;
11869   u8 *next = 0;
11870   int ret;
11871
11872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11873     {
11874       if (unformat (i, "node %s", &name))
11875         ;
11876       else if (unformat (i, "next %s", &next))
11877         ;
11878       else
11879         break;
11880     }
11881   if (name == 0)
11882     {
11883       errmsg ("node name required");
11884       return -99;
11885     }
11886   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11887     {
11888       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11889       return -99;
11890     }
11891   if (next == 0)
11892     {
11893       errmsg ("next node required");
11894       return -99;
11895     }
11896   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11897     {
11898       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11899       return -99;
11900     }
11901
11902   M (ADD_NODE_NEXT, mp);
11903   clib_memcpy (mp->node_name, name, vec_len (name));
11904   clib_memcpy (mp->next_name, next, vec_len (next));
11905   vec_free (name);
11906   vec_free (next);
11907
11908   S (mp);
11909   W (ret);
11910   return ret;
11911 }
11912
11913 static int
11914 api_l2tpv3_create_tunnel (vat_main_t * vam)
11915 {
11916   unformat_input_t *i = vam->input;
11917   ip6_address_t client_address, our_address;
11918   int client_address_set = 0;
11919   int our_address_set = 0;
11920   u32 local_session_id = 0;
11921   u32 remote_session_id = 0;
11922   u64 local_cookie = 0;
11923   u64 remote_cookie = 0;
11924   u8 l2_sublayer_present = 0;
11925   vl_api_l2tpv3_create_tunnel_t *mp;
11926   int ret;
11927
11928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11929     {
11930       if (unformat (i, "client_address %U", unformat_ip6_address,
11931                     &client_address))
11932         client_address_set = 1;
11933       else if (unformat (i, "our_address %U", unformat_ip6_address,
11934                          &our_address))
11935         our_address_set = 1;
11936       else if (unformat (i, "local_session_id %d", &local_session_id))
11937         ;
11938       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11939         ;
11940       else if (unformat (i, "local_cookie %lld", &local_cookie))
11941         ;
11942       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11943         ;
11944       else if (unformat (i, "l2-sublayer-present"))
11945         l2_sublayer_present = 1;
11946       else
11947         break;
11948     }
11949
11950   if (client_address_set == 0)
11951     {
11952       errmsg ("client_address required");
11953       return -99;
11954     }
11955
11956   if (our_address_set == 0)
11957     {
11958       errmsg ("our_address required");
11959       return -99;
11960     }
11961
11962   M (L2TPV3_CREATE_TUNNEL, mp);
11963
11964   clib_memcpy (mp->client_address, client_address.as_u8,
11965                sizeof (mp->client_address));
11966
11967   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11968
11969   mp->local_session_id = ntohl (local_session_id);
11970   mp->remote_session_id = ntohl (remote_session_id);
11971   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11972   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11973   mp->l2_sublayer_present = l2_sublayer_present;
11974   mp->is_ipv6 = 1;
11975
11976   S (mp);
11977   W (ret);
11978   return ret;
11979 }
11980
11981 static int
11982 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11983 {
11984   unformat_input_t *i = vam->input;
11985   u32 sw_if_index;
11986   u8 sw_if_index_set = 0;
11987   u64 new_local_cookie = 0;
11988   u64 new_remote_cookie = 0;
11989   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11990   int ret;
11991
11992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11993     {
11994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11995         sw_if_index_set = 1;
11996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11997         sw_if_index_set = 1;
11998       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11999         ;
12000       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12001         ;
12002       else
12003         break;
12004     }
12005
12006   if (sw_if_index_set == 0)
12007     {
12008       errmsg ("missing interface name or sw_if_index");
12009       return -99;
12010     }
12011
12012   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12013
12014   mp->sw_if_index = ntohl (sw_if_index);
12015   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12016   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12017
12018   S (mp);
12019   W (ret);
12020   return ret;
12021 }
12022
12023 static int
12024 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12025 {
12026   unformat_input_t *i = vam->input;
12027   vl_api_l2tpv3_interface_enable_disable_t *mp;
12028   u32 sw_if_index;
12029   u8 sw_if_index_set = 0;
12030   u8 enable_disable = 1;
12031   int ret;
12032
12033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12034     {
12035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12036         sw_if_index_set = 1;
12037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12038         sw_if_index_set = 1;
12039       else if (unformat (i, "enable"))
12040         enable_disable = 1;
12041       else if (unformat (i, "disable"))
12042         enable_disable = 0;
12043       else
12044         break;
12045     }
12046
12047   if (sw_if_index_set == 0)
12048     {
12049       errmsg ("missing interface name or sw_if_index");
12050       return -99;
12051     }
12052
12053   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12054
12055   mp->sw_if_index = ntohl (sw_if_index);
12056   mp->enable_disable = enable_disable;
12057
12058   S (mp);
12059   W (ret);
12060   return ret;
12061 }
12062
12063 static int
12064 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12065 {
12066   unformat_input_t *i = vam->input;
12067   vl_api_l2tpv3_set_lookup_key_t *mp;
12068   u8 key = ~0;
12069   int ret;
12070
12071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12072     {
12073       if (unformat (i, "lookup_v6_src"))
12074         key = L2T_LOOKUP_SRC_ADDRESS;
12075       else if (unformat (i, "lookup_v6_dst"))
12076         key = L2T_LOOKUP_DST_ADDRESS;
12077       else if (unformat (i, "lookup_session_id"))
12078         key = L2T_LOOKUP_SESSION_ID;
12079       else
12080         break;
12081     }
12082
12083   if (key == (u8) ~ 0)
12084     {
12085       errmsg ("l2tp session lookup key unset");
12086       return -99;
12087     }
12088
12089   M (L2TPV3_SET_LOOKUP_KEY, mp);
12090
12091   mp->key = key;
12092
12093   S (mp);
12094   W (ret);
12095   return ret;
12096 }
12097
12098 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12099   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12100 {
12101   vat_main_t *vam = &vat_main;
12102
12103   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12104          format_ip6_address, mp->our_address,
12105          format_ip6_address, mp->client_address,
12106          clib_net_to_host_u32 (mp->sw_if_index));
12107
12108   print (vam->ofp,
12109          "   local cookies %016llx %016llx remote cookie %016llx",
12110          clib_net_to_host_u64 (mp->local_cookie[0]),
12111          clib_net_to_host_u64 (mp->local_cookie[1]),
12112          clib_net_to_host_u64 (mp->remote_cookie));
12113
12114   print (vam->ofp, "   local session-id %d remote session-id %d",
12115          clib_net_to_host_u32 (mp->local_session_id),
12116          clib_net_to_host_u32 (mp->remote_session_id));
12117
12118   print (vam->ofp, "   l2 specific sublayer %s\n",
12119          mp->l2_sublayer_present ? "preset" : "absent");
12120
12121 }
12122
12123 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12124   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12125 {
12126   vat_main_t *vam = &vat_main;
12127   vat_json_node_t *node = NULL;
12128   struct in6_addr addr;
12129
12130   if (VAT_JSON_ARRAY != vam->json_tree.type)
12131     {
12132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12133       vat_json_init_array (&vam->json_tree);
12134     }
12135   node = vat_json_array_add (&vam->json_tree);
12136
12137   vat_json_init_object (node);
12138
12139   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12140   vat_json_object_add_ip6 (node, "our_address", addr);
12141   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12142   vat_json_object_add_ip6 (node, "client_address", addr);
12143
12144   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12145   vat_json_init_array (lc);
12146   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12147   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12148   vat_json_object_add_uint (node, "remote_cookie",
12149                             clib_net_to_host_u64 (mp->remote_cookie));
12150
12151   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12152   vat_json_object_add_uint (node, "local_session_id",
12153                             clib_net_to_host_u32 (mp->local_session_id));
12154   vat_json_object_add_uint (node, "remote_session_id",
12155                             clib_net_to_host_u32 (mp->remote_session_id));
12156   vat_json_object_add_string_copy (node, "l2_sublayer",
12157                                    mp->l2_sublayer_present ? (u8 *) "present"
12158                                    : (u8 *) "absent");
12159 }
12160
12161 static int
12162 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12163 {
12164   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12165   vl_api_control_ping_t *mp_ping;
12166   int ret;
12167
12168   /* Get list of l2tpv3-tunnel interfaces */
12169   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12170   S (mp);
12171
12172   /* Use a control ping for synchronization */
12173   MPING (CONTROL_PING, mp_ping);
12174   S (mp_ping);
12175
12176   W (ret);
12177   return ret;
12178 }
12179
12180
12181 static void vl_api_sw_interface_tap_v2_details_t_handler
12182   (vl_api_sw_interface_tap_v2_details_t * mp)
12183 {
12184   vat_main_t *vam = &vat_main;
12185
12186   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12187                     mp->host_ip4_prefix_len);
12188   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12189                     mp->host_ip6_prefix_len);
12190
12191   print (vam->ofp,
12192          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12193          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12194          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12195          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12196          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12197
12198   vec_free (ip4);
12199   vec_free (ip6);
12200 }
12201
12202 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12203   (vl_api_sw_interface_tap_v2_details_t * mp)
12204 {
12205   vat_main_t *vam = &vat_main;
12206   vat_json_node_t *node = NULL;
12207
12208   if (VAT_JSON_ARRAY != vam->json_tree.type)
12209     {
12210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12211       vat_json_init_array (&vam->json_tree);
12212     }
12213   node = vat_json_array_add (&vam->json_tree);
12214
12215   vat_json_init_object (node);
12216   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12217   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12218   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12219   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12220   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12221   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12222   vat_json_object_add_string_copy (node, "host_mac_addr",
12223                                    format (0, "%U", format_ethernet_address,
12224                                            &mp->host_mac_addr));
12225   vat_json_object_add_string_copy (node, "host_namespace",
12226                                    mp->host_namespace);
12227   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12228   vat_json_object_add_string_copy (node, "host_ip4_addr",
12229                                    format (0, "%U/%d", format_ip4_address,
12230                                            mp->host_ip4_addr,
12231                                            mp->host_ip4_prefix_len));
12232   vat_json_object_add_string_copy (node, "host_ip6_addr",
12233                                    format (0, "%U/%d", format_ip6_address,
12234                                            mp->host_ip6_addr,
12235                                            mp->host_ip6_prefix_len));
12236
12237 }
12238
12239 static int
12240 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12241 {
12242   vl_api_sw_interface_tap_v2_dump_t *mp;
12243   vl_api_control_ping_t *mp_ping;
12244   int ret;
12245
12246   print (vam->ofp,
12247          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12248          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12249          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12250          "host_ip6_addr");
12251
12252   /* Get list of tap interfaces */
12253   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12254   S (mp);
12255
12256   /* Use a control ping for synchronization */
12257   MPING (CONTROL_PING, mp_ping);
12258   S (mp_ping);
12259
12260   W (ret);
12261   return ret;
12262 }
12263
12264 static void vl_api_sw_interface_virtio_pci_details_t_handler
12265   (vl_api_sw_interface_virtio_pci_details_t * mp)
12266 {
12267   vat_main_t *vam = &vat_main;
12268
12269   typedef union
12270   {
12271     struct
12272     {
12273       u16 domain;
12274       u8 bus;
12275       u8 slot:5;
12276       u8 function:3;
12277     };
12278     u32 as_u32;
12279   } pci_addr_t;
12280   pci_addr_t addr;
12281   addr.as_u32 = ntohl (mp->pci_addr);
12282   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12283                          addr.slot, addr.function);
12284
12285   print (vam->ofp,
12286          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12287          pci_addr, ntohl (mp->sw_if_index),
12288          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12289          format_ethernet_address, mp->mac_addr,
12290          clib_net_to_host_u64 (mp->features));
12291   vec_free (pci_addr);
12292 }
12293
12294 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12295   (vl_api_sw_interface_virtio_pci_details_t * mp)
12296 {
12297   vat_main_t *vam = &vat_main;
12298   vat_json_node_t *node = NULL;
12299
12300   if (VAT_JSON_ARRAY != vam->json_tree.type)
12301     {
12302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12303       vat_json_init_array (&vam->json_tree);
12304     }
12305   node = vat_json_array_add (&vam->json_tree);
12306
12307   vat_json_init_object (node);
12308   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12309   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12310   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12311   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12312   vat_json_object_add_uint (node, "features",
12313                             clib_net_to_host_u64 (mp->features));
12314   vat_json_object_add_string_copy (node, "mac_addr",
12315                                    format (0, "%U", format_ethernet_address,
12316                                            &mp->mac_addr));
12317 }
12318
12319 static int
12320 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12321 {
12322   vl_api_sw_interface_virtio_pci_dump_t *mp;
12323   vl_api_control_ping_t *mp_ping;
12324   int ret;
12325
12326   print (vam->ofp,
12327          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12328          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12329          "mac_addr", "features");
12330
12331   /* Get list of tap interfaces */
12332   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12333   S (mp);
12334
12335   /* Use a control ping for synchronization */
12336   MPING (CONTROL_PING, mp_ping);
12337   S (mp_ping);
12338
12339   W (ret);
12340   return ret;
12341 }
12342
12343 static int
12344 api_vxlan_offload_rx (vat_main_t * vam)
12345 {
12346   unformat_input_t *line_input = vam->input;
12347   vl_api_vxlan_offload_rx_t *mp;
12348   u32 hw_if_index = ~0, rx_if_index = ~0;
12349   u8 is_add = 1;
12350   int ret;
12351
12352   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12353     {
12354       if (unformat (line_input, "del"))
12355         is_add = 0;
12356       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12357                          &hw_if_index))
12358         ;
12359       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12360         ;
12361       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12362                          &rx_if_index))
12363         ;
12364       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12365         ;
12366       else
12367         {
12368           errmsg ("parse error '%U'", format_unformat_error, line_input);
12369           return -99;
12370         }
12371     }
12372
12373   if (hw_if_index == ~0)
12374     {
12375       errmsg ("no hw interface");
12376       return -99;
12377     }
12378
12379   if (rx_if_index == ~0)
12380     {
12381       errmsg ("no rx tunnel");
12382       return -99;
12383     }
12384
12385   M (VXLAN_OFFLOAD_RX, mp);
12386
12387   mp->hw_if_index = ntohl (hw_if_index);
12388   mp->sw_if_index = ntohl (rx_if_index);
12389   mp->enable = is_add;
12390
12391   S (mp);
12392   W (ret);
12393   return ret;
12394 }
12395
12396 static uword unformat_vxlan_decap_next
12397   (unformat_input_t * input, va_list * args)
12398 {
12399   u32 *result = va_arg (*args, u32 *);
12400   u32 tmp;
12401
12402   if (unformat (input, "l2"))
12403     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12404   else if (unformat (input, "%d", &tmp))
12405     *result = tmp;
12406   else
12407     return 0;
12408   return 1;
12409 }
12410
12411 static int
12412 api_vxlan_add_del_tunnel (vat_main_t * vam)
12413 {
12414   unformat_input_t *line_input = vam->input;
12415   vl_api_vxlan_add_del_tunnel_t *mp;
12416   ip46_address_t src, dst;
12417   u8 is_add = 1;
12418   u8 ipv4_set = 0, ipv6_set = 0;
12419   u8 src_set = 0;
12420   u8 dst_set = 0;
12421   u8 grp_set = 0;
12422   u32 instance = ~0;
12423   u32 mcast_sw_if_index = ~0;
12424   u32 encap_vrf_id = 0;
12425   u32 decap_next_index = ~0;
12426   u32 vni = 0;
12427   int ret;
12428
12429   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12430   clib_memset (&src, 0, sizeof src);
12431   clib_memset (&dst, 0, sizeof dst);
12432
12433   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12434     {
12435       if (unformat (line_input, "del"))
12436         is_add = 0;
12437       else if (unformat (line_input, "instance %d", &instance))
12438         ;
12439       else
12440         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12441         {
12442           ipv4_set = 1;
12443           src_set = 1;
12444         }
12445       else
12446         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12447         {
12448           ipv4_set = 1;
12449           dst_set = 1;
12450         }
12451       else
12452         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12453         {
12454           ipv6_set = 1;
12455           src_set = 1;
12456         }
12457       else
12458         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12459         {
12460           ipv6_set = 1;
12461           dst_set = 1;
12462         }
12463       else if (unformat (line_input, "group %U %U",
12464                          unformat_ip4_address, &dst.ip4,
12465                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12466         {
12467           grp_set = dst_set = 1;
12468           ipv4_set = 1;
12469         }
12470       else if (unformat (line_input, "group %U",
12471                          unformat_ip4_address, &dst.ip4))
12472         {
12473           grp_set = dst_set = 1;
12474           ipv4_set = 1;
12475         }
12476       else if (unformat (line_input, "group %U %U",
12477                          unformat_ip6_address, &dst.ip6,
12478                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12479         {
12480           grp_set = dst_set = 1;
12481           ipv6_set = 1;
12482         }
12483       else if (unformat (line_input, "group %U",
12484                          unformat_ip6_address, &dst.ip6))
12485         {
12486           grp_set = dst_set = 1;
12487           ipv6_set = 1;
12488         }
12489       else
12490         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12491         ;
12492       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12493         ;
12494       else if (unformat (line_input, "decap-next %U",
12495                          unformat_vxlan_decap_next, &decap_next_index))
12496         ;
12497       else if (unformat (line_input, "vni %d", &vni))
12498         ;
12499       else
12500         {
12501           errmsg ("parse error '%U'", format_unformat_error, line_input);
12502           return -99;
12503         }
12504     }
12505
12506   if (src_set == 0)
12507     {
12508       errmsg ("tunnel src address not specified");
12509       return -99;
12510     }
12511   if (dst_set == 0)
12512     {
12513       errmsg ("tunnel dst address not specified");
12514       return -99;
12515     }
12516
12517   if (grp_set && !ip46_address_is_multicast (&dst))
12518     {
12519       errmsg ("tunnel group address not multicast");
12520       return -99;
12521     }
12522   if (grp_set && mcast_sw_if_index == ~0)
12523     {
12524       errmsg ("tunnel nonexistent multicast device");
12525       return -99;
12526     }
12527   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12528     {
12529       errmsg ("tunnel dst address must be unicast");
12530       return -99;
12531     }
12532
12533
12534   if (ipv4_set && ipv6_set)
12535     {
12536       errmsg ("both IPv4 and IPv6 addresses specified");
12537       return -99;
12538     }
12539
12540   if ((vni == 0) || (vni >> 24))
12541     {
12542       errmsg ("vni not specified or out of range");
12543       return -99;
12544     }
12545
12546   M (VXLAN_ADD_DEL_TUNNEL, mp);
12547
12548   if (ipv6_set)
12549     {
12550       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12551       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12552     }
12553   else
12554     {
12555       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12556       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12557     }
12558
12559   mp->instance = htonl (instance);
12560   mp->encap_vrf_id = ntohl (encap_vrf_id);
12561   mp->decap_next_index = ntohl (decap_next_index);
12562   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12563   mp->vni = ntohl (vni);
12564   mp->is_add = is_add;
12565   mp->is_ipv6 = ipv6_set;
12566
12567   S (mp);
12568   W (ret);
12569   return ret;
12570 }
12571
12572 static void vl_api_vxlan_tunnel_details_t_handler
12573   (vl_api_vxlan_tunnel_details_t * mp)
12574 {
12575   vat_main_t *vam = &vat_main;
12576   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12577   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12578
12579   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12580          ntohl (mp->sw_if_index),
12581          ntohl (mp->instance),
12582          format_ip46_address, &src, IP46_TYPE_ANY,
12583          format_ip46_address, &dst, IP46_TYPE_ANY,
12584          ntohl (mp->encap_vrf_id),
12585          ntohl (mp->decap_next_index), ntohl (mp->vni),
12586          ntohl (mp->mcast_sw_if_index));
12587 }
12588
12589 static void vl_api_vxlan_tunnel_details_t_handler_json
12590   (vl_api_vxlan_tunnel_details_t * mp)
12591 {
12592   vat_main_t *vam = &vat_main;
12593   vat_json_node_t *node = NULL;
12594
12595   if (VAT_JSON_ARRAY != vam->json_tree.type)
12596     {
12597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12598       vat_json_init_array (&vam->json_tree);
12599     }
12600   node = vat_json_array_add (&vam->json_tree);
12601
12602   vat_json_init_object (node);
12603   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12604
12605   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12606
12607   if (mp->is_ipv6)
12608     {
12609       struct in6_addr ip6;
12610
12611       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12612       vat_json_object_add_ip6 (node, "src_address", ip6);
12613       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12614       vat_json_object_add_ip6 (node, "dst_address", ip6);
12615     }
12616   else
12617     {
12618       struct in_addr ip4;
12619
12620       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12621       vat_json_object_add_ip4 (node, "src_address", ip4);
12622       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12623       vat_json_object_add_ip4 (node, "dst_address", ip4);
12624     }
12625   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12626   vat_json_object_add_uint (node, "decap_next_index",
12627                             ntohl (mp->decap_next_index));
12628   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12629   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12630   vat_json_object_add_uint (node, "mcast_sw_if_index",
12631                             ntohl (mp->mcast_sw_if_index));
12632 }
12633
12634 static int
12635 api_vxlan_tunnel_dump (vat_main_t * vam)
12636 {
12637   unformat_input_t *i = vam->input;
12638   vl_api_vxlan_tunnel_dump_t *mp;
12639   vl_api_control_ping_t *mp_ping;
12640   u32 sw_if_index;
12641   u8 sw_if_index_set = 0;
12642   int ret;
12643
12644   /* Parse args required to build the message */
12645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12646     {
12647       if (unformat (i, "sw_if_index %d", &sw_if_index))
12648         sw_if_index_set = 1;
12649       else
12650         break;
12651     }
12652
12653   if (sw_if_index_set == 0)
12654     {
12655       sw_if_index = ~0;
12656     }
12657
12658   if (!vam->json_output)
12659     {
12660       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12661              "sw_if_index", "instance", "src_address", "dst_address",
12662              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12663     }
12664
12665   /* Get list of vxlan-tunnel interfaces */
12666   M (VXLAN_TUNNEL_DUMP, mp);
12667
12668   mp->sw_if_index = htonl (sw_if_index);
12669
12670   S (mp);
12671
12672   /* Use a control ping for synchronization */
12673   MPING (CONTROL_PING, mp_ping);
12674   S (mp_ping);
12675
12676   W (ret);
12677   return ret;
12678 }
12679
12680 static uword unformat_geneve_decap_next
12681   (unformat_input_t * input, va_list * args)
12682 {
12683   u32 *result = va_arg (*args, u32 *);
12684   u32 tmp;
12685
12686   if (unformat (input, "l2"))
12687     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12688   else if (unformat (input, "%d", &tmp))
12689     *result = tmp;
12690   else
12691     return 0;
12692   return 1;
12693 }
12694
12695 static int
12696 api_geneve_add_del_tunnel (vat_main_t * vam)
12697 {
12698   unformat_input_t *line_input = vam->input;
12699   vl_api_geneve_add_del_tunnel_t *mp;
12700   ip46_address_t src, dst;
12701   u8 is_add = 1;
12702   u8 ipv4_set = 0, ipv6_set = 0;
12703   u8 src_set = 0;
12704   u8 dst_set = 0;
12705   u8 grp_set = 0;
12706   u32 mcast_sw_if_index = ~0;
12707   u32 encap_vrf_id = 0;
12708   u32 decap_next_index = ~0;
12709   u32 vni = 0;
12710   int ret;
12711
12712   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12713   clib_memset (&src, 0, sizeof src);
12714   clib_memset (&dst, 0, sizeof dst);
12715
12716   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12717     {
12718       if (unformat (line_input, "del"))
12719         is_add = 0;
12720       else
12721         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12722         {
12723           ipv4_set = 1;
12724           src_set = 1;
12725         }
12726       else
12727         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12728         {
12729           ipv4_set = 1;
12730           dst_set = 1;
12731         }
12732       else
12733         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12734         {
12735           ipv6_set = 1;
12736           src_set = 1;
12737         }
12738       else
12739         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12740         {
12741           ipv6_set = 1;
12742           dst_set = 1;
12743         }
12744       else if (unformat (line_input, "group %U %U",
12745                          unformat_ip4_address, &dst.ip4,
12746                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12747         {
12748           grp_set = dst_set = 1;
12749           ipv4_set = 1;
12750         }
12751       else if (unformat (line_input, "group %U",
12752                          unformat_ip4_address, &dst.ip4))
12753         {
12754           grp_set = dst_set = 1;
12755           ipv4_set = 1;
12756         }
12757       else if (unformat (line_input, "group %U %U",
12758                          unformat_ip6_address, &dst.ip6,
12759                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12760         {
12761           grp_set = dst_set = 1;
12762           ipv6_set = 1;
12763         }
12764       else if (unformat (line_input, "group %U",
12765                          unformat_ip6_address, &dst.ip6))
12766         {
12767           grp_set = dst_set = 1;
12768           ipv6_set = 1;
12769         }
12770       else
12771         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12772         ;
12773       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12774         ;
12775       else if (unformat (line_input, "decap-next %U",
12776                          unformat_geneve_decap_next, &decap_next_index))
12777         ;
12778       else if (unformat (line_input, "vni %d", &vni))
12779         ;
12780       else
12781         {
12782           errmsg ("parse error '%U'", format_unformat_error, line_input);
12783           return -99;
12784         }
12785     }
12786
12787   if (src_set == 0)
12788     {
12789       errmsg ("tunnel src address not specified");
12790       return -99;
12791     }
12792   if (dst_set == 0)
12793     {
12794       errmsg ("tunnel dst address not specified");
12795       return -99;
12796     }
12797
12798   if (grp_set && !ip46_address_is_multicast (&dst))
12799     {
12800       errmsg ("tunnel group address not multicast");
12801       return -99;
12802     }
12803   if (grp_set && mcast_sw_if_index == ~0)
12804     {
12805       errmsg ("tunnel nonexistent multicast device");
12806       return -99;
12807     }
12808   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12809     {
12810       errmsg ("tunnel dst address must be unicast");
12811       return -99;
12812     }
12813
12814
12815   if (ipv4_set && ipv6_set)
12816     {
12817       errmsg ("both IPv4 and IPv6 addresses specified");
12818       return -99;
12819     }
12820
12821   if ((vni == 0) || (vni >> 24))
12822     {
12823       errmsg ("vni not specified or out of range");
12824       return -99;
12825     }
12826
12827   M (GENEVE_ADD_DEL_TUNNEL, mp);
12828
12829   if (ipv6_set)
12830     {
12831       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12832       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12833     }
12834   else
12835     {
12836       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12837       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12838     }
12839   mp->encap_vrf_id = ntohl (encap_vrf_id);
12840   mp->decap_next_index = ntohl (decap_next_index);
12841   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12842   mp->vni = ntohl (vni);
12843   mp->is_add = is_add;
12844   mp->is_ipv6 = ipv6_set;
12845
12846   S (mp);
12847   W (ret);
12848   return ret;
12849 }
12850
12851 static void vl_api_geneve_tunnel_details_t_handler
12852   (vl_api_geneve_tunnel_details_t * mp)
12853 {
12854   vat_main_t *vam = &vat_main;
12855   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12856   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12857
12858   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12859          ntohl (mp->sw_if_index),
12860          format_ip46_address, &src, IP46_TYPE_ANY,
12861          format_ip46_address, &dst, IP46_TYPE_ANY,
12862          ntohl (mp->encap_vrf_id),
12863          ntohl (mp->decap_next_index), ntohl (mp->vni),
12864          ntohl (mp->mcast_sw_if_index));
12865 }
12866
12867 static void vl_api_geneve_tunnel_details_t_handler_json
12868   (vl_api_geneve_tunnel_details_t * mp)
12869 {
12870   vat_main_t *vam = &vat_main;
12871   vat_json_node_t *node = NULL;
12872
12873   if (VAT_JSON_ARRAY != vam->json_tree.type)
12874     {
12875       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12876       vat_json_init_array (&vam->json_tree);
12877     }
12878   node = vat_json_array_add (&vam->json_tree);
12879
12880   vat_json_init_object (node);
12881   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12882   if (mp->is_ipv6)
12883     {
12884       struct in6_addr ip6;
12885
12886       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12887       vat_json_object_add_ip6 (node, "src_address", ip6);
12888       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12889       vat_json_object_add_ip6 (node, "dst_address", ip6);
12890     }
12891   else
12892     {
12893       struct in_addr ip4;
12894
12895       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12896       vat_json_object_add_ip4 (node, "src_address", ip4);
12897       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12898       vat_json_object_add_ip4 (node, "dst_address", ip4);
12899     }
12900   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12901   vat_json_object_add_uint (node, "decap_next_index",
12902                             ntohl (mp->decap_next_index));
12903   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12904   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12905   vat_json_object_add_uint (node, "mcast_sw_if_index",
12906                             ntohl (mp->mcast_sw_if_index));
12907 }
12908
12909 static int
12910 api_geneve_tunnel_dump (vat_main_t * vam)
12911 {
12912   unformat_input_t *i = vam->input;
12913   vl_api_geneve_tunnel_dump_t *mp;
12914   vl_api_control_ping_t *mp_ping;
12915   u32 sw_if_index;
12916   u8 sw_if_index_set = 0;
12917   int ret;
12918
12919   /* Parse args required to build the message */
12920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12921     {
12922       if (unformat (i, "sw_if_index %d", &sw_if_index))
12923         sw_if_index_set = 1;
12924       else
12925         break;
12926     }
12927
12928   if (sw_if_index_set == 0)
12929     {
12930       sw_if_index = ~0;
12931     }
12932
12933   if (!vam->json_output)
12934     {
12935       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12936              "sw_if_index", "local_address", "remote_address",
12937              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12938     }
12939
12940   /* Get list of geneve-tunnel interfaces */
12941   M (GENEVE_TUNNEL_DUMP, mp);
12942
12943   mp->sw_if_index = htonl (sw_if_index);
12944
12945   S (mp);
12946
12947   /* Use a control ping for synchronization */
12948   M (CONTROL_PING, mp_ping);
12949   S (mp_ping);
12950
12951   W (ret);
12952   return ret;
12953 }
12954
12955 static int
12956 api_gre_tunnel_add_del (vat_main_t * vam)
12957 {
12958   unformat_input_t *line_input = vam->input;
12959   vl_api_address_t src = { }, dst =
12960   {
12961   };
12962   vl_api_gre_tunnel_add_del_t *mp;
12963   vl_api_gre_tunnel_type_t t_type;
12964   u8 is_add = 1;
12965   u8 src_set = 0;
12966   u8 dst_set = 0;
12967   u32 outer_fib_id = 0;
12968   u32 session_id = 0;
12969   u32 instance = ~0;
12970   int ret;
12971
12972   t_type = GRE_API_TUNNEL_TYPE_L3;
12973
12974   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12975     {
12976       if (unformat (line_input, "del"))
12977         is_add = 0;
12978       else if (unformat (line_input, "instance %d", &instance))
12979         ;
12980       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12981         {
12982           src_set = 1;
12983         }
12984       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12985         {
12986           dst_set = 1;
12987         }
12988       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12989         ;
12990       else if (unformat (line_input, "teb"))
12991         t_type = GRE_API_TUNNEL_TYPE_TEB;
12992       else if (unformat (line_input, "erspan %d", &session_id))
12993         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12994       else
12995         {
12996           errmsg ("parse error '%U'", format_unformat_error, line_input);
12997           return -99;
12998         }
12999     }
13000
13001   if (src_set == 0)
13002     {
13003       errmsg ("tunnel src address not specified");
13004       return -99;
13005     }
13006   if (dst_set == 0)
13007     {
13008       errmsg ("tunnel dst address not specified");
13009       return -99;
13010     }
13011
13012   M (GRE_TUNNEL_ADD_DEL, mp);
13013
13014   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13015   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13016
13017   mp->tunnel.instance = htonl (instance);
13018   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13019   mp->is_add = is_add;
13020   mp->tunnel.session_id = htons ((u16) session_id);
13021   mp->tunnel.type = htonl (t_type);
13022
13023   S (mp);
13024   W (ret);
13025   return ret;
13026 }
13027
13028 static void vl_api_gre_tunnel_details_t_handler
13029   (vl_api_gre_tunnel_details_t * mp)
13030 {
13031   vat_main_t *vam = &vat_main;
13032
13033   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13034          ntohl (mp->tunnel.sw_if_index),
13035          ntohl (mp->tunnel.instance),
13036          format_vl_api_address, &mp->tunnel.src,
13037          format_vl_api_address, &mp->tunnel.dst,
13038          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13039          ntohl (mp->tunnel.session_id));
13040 }
13041
13042 static void vl_api_gre_tunnel_details_t_handler_json
13043   (vl_api_gre_tunnel_details_t * mp)
13044 {
13045   vat_main_t *vam = &vat_main;
13046   vat_json_node_t *node = NULL;
13047
13048   if (VAT_JSON_ARRAY != vam->json_tree.type)
13049     {
13050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13051       vat_json_init_array (&vam->json_tree);
13052     }
13053   node = vat_json_array_add (&vam->json_tree);
13054
13055   vat_json_init_object (node);
13056   vat_json_object_add_uint (node, "sw_if_index",
13057                             ntohl (mp->tunnel.sw_if_index));
13058   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13059
13060   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13061   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13062   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13063   vat_json_object_add_uint (node, "outer_fib_id",
13064                             ntohl (mp->tunnel.outer_fib_id));
13065   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13066 }
13067
13068 static int
13069 api_gre_tunnel_dump (vat_main_t * vam)
13070 {
13071   unformat_input_t *i = vam->input;
13072   vl_api_gre_tunnel_dump_t *mp;
13073   vl_api_control_ping_t *mp_ping;
13074   u32 sw_if_index;
13075   u8 sw_if_index_set = 0;
13076   int ret;
13077
13078   /* Parse args required to build the message */
13079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13080     {
13081       if (unformat (i, "sw_if_index %d", &sw_if_index))
13082         sw_if_index_set = 1;
13083       else
13084         break;
13085     }
13086
13087   if (sw_if_index_set == 0)
13088     {
13089       sw_if_index = ~0;
13090     }
13091
13092   if (!vam->json_output)
13093     {
13094       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13095              "sw_if_index", "instance", "src_address", "dst_address",
13096              "tunnel_type", "outer_fib_id", "session_id");
13097     }
13098
13099   /* Get list of gre-tunnel interfaces */
13100   M (GRE_TUNNEL_DUMP, mp);
13101
13102   mp->sw_if_index = htonl (sw_if_index);
13103
13104   S (mp);
13105
13106   /* Use a control ping for synchronization */
13107   MPING (CONTROL_PING, mp_ping);
13108   S (mp_ping);
13109
13110   W (ret);
13111   return ret;
13112 }
13113
13114 static int
13115 api_l2_fib_clear_table (vat_main_t * vam)
13116 {
13117 //  unformat_input_t * i = vam->input;
13118   vl_api_l2_fib_clear_table_t *mp;
13119   int ret;
13120
13121   M (L2_FIB_CLEAR_TABLE, mp);
13122
13123   S (mp);
13124   W (ret);
13125   return ret;
13126 }
13127
13128 static int
13129 api_l2_interface_efp_filter (vat_main_t * vam)
13130 {
13131   unformat_input_t *i = vam->input;
13132   vl_api_l2_interface_efp_filter_t *mp;
13133   u32 sw_if_index;
13134   u8 enable = 1;
13135   u8 sw_if_index_set = 0;
13136   int ret;
13137
13138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13139     {
13140       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13141         sw_if_index_set = 1;
13142       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13143         sw_if_index_set = 1;
13144       else if (unformat (i, "enable"))
13145         enable = 1;
13146       else if (unformat (i, "disable"))
13147         enable = 0;
13148       else
13149         {
13150           clib_warning ("parse error '%U'", format_unformat_error, i);
13151           return -99;
13152         }
13153     }
13154
13155   if (sw_if_index_set == 0)
13156     {
13157       errmsg ("missing sw_if_index");
13158       return -99;
13159     }
13160
13161   M (L2_INTERFACE_EFP_FILTER, mp);
13162
13163   mp->sw_if_index = ntohl (sw_if_index);
13164   mp->enable_disable = enable;
13165
13166   S (mp);
13167   W (ret);
13168   return ret;
13169 }
13170
13171 #define foreach_vtr_op                          \
13172 _("disable",  L2_VTR_DISABLED)                  \
13173 _("push-1",  L2_VTR_PUSH_1)                     \
13174 _("push-2",  L2_VTR_PUSH_2)                     \
13175 _("pop-1",  L2_VTR_POP_1)                       \
13176 _("pop-2",  L2_VTR_POP_2)                       \
13177 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13178 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13179 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13180 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13181
13182 static int
13183 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13184 {
13185   unformat_input_t *i = vam->input;
13186   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13187   u32 sw_if_index;
13188   u8 sw_if_index_set = 0;
13189   u8 vtr_op_set = 0;
13190   u32 vtr_op = 0;
13191   u32 push_dot1q = 1;
13192   u32 tag1 = ~0;
13193   u32 tag2 = ~0;
13194   int ret;
13195
13196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13197     {
13198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13199         sw_if_index_set = 1;
13200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13201         sw_if_index_set = 1;
13202       else if (unformat (i, "vtr_op %d", &vtr_op))
13203         vtr_op_set = 1;
13204 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13205       foreach_vtr_op
13206 #undef _
13207         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13208         ;
13209       else if (unformat (i, "tag1 %d", &tag1))
13210         ;
13211       else if (unformat (i, "tag2 %d", &tag2))
13212         ;
13213       else
13214         {
13215           clib_warning ("parse error '%U'", format_unformat_error, i);
13216           return -99;
13217         }
13218     }
13219
13220   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13221     {
13222       errmsg ("missing vtr operation or sw_if_index");
13223       return -99;
13224     }
13225
13226   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13227   mp->sw_if_index = ntohl (sw_if_index);
13228   mp->vtr_op = ntohl (vtr_op);
13229   mp->push_dot1q = ntohl (push_dot1q);
13230   mp->tag1 = ntohl (tag1);
13231   mp->tag2 = ntohl (tag2);
13232
13233   S (mp);
13234   W (ret);
13235   return ret;
13236 }
13237
13238 static int
13239 api_create_vhost_user_if (vat_main_t * vam)
13240 {
13241   unformat_input_t *i = vam->input;
13242   vl_api_create_vhost_user_if_t *mp;
13243   u8 *file_name;
13244   u8 is_server = 0;
13245   u8 file_name_set = 0;
13246   u32 custom_dev_instance = ~0;
13247   u8 hwaddr[6];
13248   u8 use_custom_mac = 0;
13249   u8 disable_mrg_rxbuf = 0;
13250   u8 disable_indirect_desc = 0;
13251   u8 *tag = 0;
13252   u8 enable_gso = 0;
13253   int ret;
13254
13255   /* Shut up coverity */
13256   clib_memset (hwaddr, 0, sizeof (hwaddr));
13257
13258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13259     {
13260       if (unformat (i, "socket %s", &file_name))
13261         {
13262           file_name_set = 1;
13263         }
13264       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13265         ;
13266       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13267         use_custom_mac = 1;
13268       else if (unformat (i, "server"))
13269         is_server = 1;
13270       else if (unformat (i, "disable_mrg_rxbuf"))
13271         disable_mrg_rxbuf = 1;
13272       else if (unformat (i, "disable_indirect_desc"))
13273         disable_indirect_desc = 1;
13274       else if (unformat (i, "gso"))
13275         enable_gso = 1;
13276       else if (unformat (i, "tag %s", &tag))
13277         ;
13278       else
13279         break;
13280     }
13281
13282   if (file_name_set == 0)
13283     {
13284       errmsg ("missing socket file name");
13285       return -99;
13286     }
13287
13288   if (vec_len (file_name) > 255)
13289     {
13290       errmsg ("socket file name too long");
13291       return -99;
13292     }
13293   vec_add1 (file_name, 0);
13294
13295   M (CREATE_VHOST_USER_IF, mp);
13296
13297   mp->is_server = is_server;
13298   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13299   mp->disable_indirect_desc = disable_indirect_desc;
13300   mp->enable_gso = enable_gso;
13301   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13302   vec_free (file_name);
13303   if (custom_dev_instance != ~0)
13304     {
13305       mp->renumber = 1;
13306       mp->custom_dev_instance = ntohl (custom_dev_instance);
13307     }
13308
13309   mp->use_custom_mac = use_custom_mac;
13310   clib_memcpy (mp->mac_address, hwaddr, 6);
13311   if (tag)
13312     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13313   vec_free (tag);
13314
13315   S (mp);
13316   W (ret);
13317   return ret;
13318 }
13319
13320 static int
13321 api_modify_vhost_user_if (vat_main_t * vam)
13322 {
13323   unformat_input_t *i = vam->input;
13324   vl_api_modify_vhost_user_if_t *mp;
13325   u8 *file_name;
13326   u8 is_server = 0;
13327   u8 file_name_set = 0;
13328   u32 custom_dev_instance = ~0;
13329   u8 sw_if_index_set = 0;
13330   u32 sw_if_index = (u32) ~ 0;
13331   u8 enable_gso = 0;
13332   int ret;
13333
13334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13335     {
13336       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13337         sw_if_index_set = 1;
13338       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13339         sw_if_index_set = 1;
13340       else if (unformat (i, "socket %s", &file_name))
13341         {
13342           file_name_set = 1;
13343         }
13344       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13345         ;
13346       else if (unformat (i, "server"))
13347         is_server = 1;
13348       else if (unformat (i, "gso"))
13349         enable_gso = 1;
13350       else
13351         break;
13352     }
13353
13354   if (sw_if_index_set == 0)
13355     {
13356       errmsg ("missing sw_if_index or interface name");
13357       return -99;
13358     }
13359
13360   if (file_name_set == 0)
13361     {
13362       errmsg ("missing socket file name");
13363       return -99;
13364     }
13365
13366   if (vec_len (file_name) > 255)
13367     {
13368       errmsg ("socket file name too long");
13369       return -99;
13370     }
13371   vec_add1 (file_name, 0);
13372
13373   M (MODIFY_VHOST_USER_IF, mp);
13374
13375   mp->sw_if_index = ntohl (sw_if_index);
13376   mp->is_server = is_server;
13377   mp->enable_gso = enable_gso;
13378   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13379   vec_free (file_name);
13380   if (custom_dev_instance != ~0)
13381     {
13382       mp->renumber = 1;
13383       mp->custom_dev_instance = ntohl (custom_dev_instance);
13384     }
13385
13386   S (mp);
13387   W (ret);
13388   return ret;
13389 }
13390
13391 static int
13392 api_delete_vhost_user_if (vat_main_t * vam)
13393 {
13394   unformat_input_t *i = vam->input;
13395   vl_api_delete_vhost_user_if_t *mp;
13396   u32 sw_if_index = ~0;
13397   u8 sw_if_index_set = 0;
13398   int ret;
13399
13400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13401     {
13402       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13403         sw_if_index_set = 1;
13404       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13405         sw_if_index_set = 1;
13406       else
13407         break;
13408     }
13409
13410   if (sw_if_index_set == 0)
13411     {
13412       errmsg ("missing sw_if_index or interface name");
13413       return -99;
13414     }
13415
13416
13417   M (DELETE_VHOST_USER_IF, mp);
13418
13419   mp->sw_if_index = ntohl (sw_if_index);
13420
13421   S (mp);
13422   W (ret);
13423   return ret;
13424 }
13425
13426 static void vl_api_sw_interface_vhost_user_details_t_handler
13427   (vl_api_sw_interface_vhost_user_details_t * mp)
13428 {
13429   vat_main_t *vam = &vat_main;
13430
13431   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13432          (char *) mp->interface_name,
13433          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13434          clib_net_to_host_u64 (mp->features), mp->is_server,
13435          ntohl (mp->num_regions), (char *) mp->sock_filename);
13436   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13437 }
13438
13439 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13440   (vl_api_sw_interface_vhost_user_details_t * mp)
13441 {
13442   vat_main_t *vam = &vat_main;
13443   vat_json_node_t *node = NULL;
13444
13445   if (VAT_JSON_ARRAY != vam->json_tree.type)
13446     {
13447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13448       vat_json_init_array (&vam->json_tree);
13449     }
13450   node = vat_json_array_add (&vam->json_tree);
13451
13452   vat_json_init_object (node);
13453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13454   vat_json_object_add_string_copy (node, "interface_name",
13455                                    mp->interface_name);
13456   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13457                             ntohl (mp->virtio_net_hdr_sz));
13458   vat_json_object_add_uint (node, "features",
13459                             clib_net_to_host_u64 (mp->features));
13460   vat_json_object_add_uint (node, "is_server", mp->is_server);
13461   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13462   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13463   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13464 }
13465
13466 static int
13467 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13468 {
13469   vl_api_sw_interface_vhost_user_dump_t *mp;
13470   vl_api_control_ping_t *mp_ping;
13471   int ret;
13472   print (vam->ofp,
13473          "Interface name            idx hdr_sz features server regions filename");
13474
13475   /* Get list of vhost-user interfaces */
13476   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13477   S (mp);
13478
13479   /* Use a control ping for synchronization */
13480   MPING (CONTROL_PING, mp_ping);
13481   S (mp_ping);
13482
13483   W (ret);
13484   return ret;
13485 }
13486
13487 static int
13488 api_show_version (vat_main_t * vam)
13489 {
13490   vl_api_show_version_t *mp;
13491   int ret;
13492
13493   M (SHOW_VERSION, mp);
13494
13495   S (mp);
13496   W (ret);
13497   return ret;
13498 }
13499
13500
13501 static int
13502 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13503 {
13504   unformat_input_t *line_input = vam->input;
13505   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13506   ip4_address_t local4, remote4;
13507   ip6_address_t local6, remote6;
13508   u8 is_add = 1;
13509   u8 ipv4_set = 0, ipv6_set = 0;
13510   u8 local_set = 0;
13511   u8 remote_set = 0;
13512   u8 grp_set = 0;
13513   u32 mcast_sw_if_index = ~0;
13514   u32 encap_vrf_id = 0;
13515   u32 decap_vrf_id = 0;
13516   u8 protocol = ~0;
13517   u32 vni;
13518   u8 vni_set = 0;
13519   int ret;
13520
13521   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13522   clib_memset (&local4, 0, sizeof local4);
13523   clib_memset (&remote4, 0, sizeof remote4);
13524   clib_memset (&local6, 0, sizeof local6);
13525   clib_memset (&remote6, 0, sizeof remote6);
13526
13527   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13528     {
13529       if (unformat (line_input, "del"))
13530         is_add = 0;
13531       else if (unformat (line_input, "local %U",
13532                          unformat_ip4_address, &local4))
13533         {
13534           local_set = 1;
13535           ipv4_set = 1;
13536         }
13537       else if (unformat (line_input, "remote %U",
13538                          unformat_ip4_address, &remote4))
13539         {
13540           remote_set = 1;
13541           ipv4_set = 1;
13542         }
13543       else if (unformat (line_input, "local %U",
13544                          unformat_ip6_address, &local6))
13545         {
13546           local_set = 1;
13547           ipv6_set = 1;
13548         }
13549       else if (unformat (line_input, "remote %U",
13550                          unformat_ip6_address, &remote6))
13551         {
13552           remote_set = 1;
13553           ipv6_set = 1;
13554         }
13555       else if (unformat (line_input, "group %U %U",
13556                          unformat_ip4_address, &remote4,
13557                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13558         {
13559           grp_set = remote_set = 1;
13560           ipv4_set = 1;
13561         }
13562       else if (unformat (line_input, "group %U",
13563                          unformat_ip4_address, &remote4))
13564         {
13565           grp_set = remote_set = 1;
13566           ipv4_set = 1;
13567         }
13568       else if (unformat (line_input, "group %U %U",
13569                          unformat_ip6_address, &remote6,
13570                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13571         {
13572           grp_set = remote_set = 1;
13573           ipv6_set = 1;
13574         }
13575       else if (unformat (line_input, "group %U",
13576                          unformat_ip6_address, &remote6))
13577         {
13578           grp_set = remote_set = 1;
13579           ipv6_set = 1;
13580         }
13581       else
13582         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13583         ;
13584       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13585         ;
13586       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13587         ;
13588       else if (unformat (line_input, "vni %d", &vni))
13589         vni_set = 1;
13590       else if (unformat (line_input, "next-ip4"))
13591         protocol = 1;
13592       else if (unformat (line_input, "next-ip6"))
13593         protocol = 2;
13594       else if (unformat (line_input, "next-ethernet"))
13595         protocol = 3;
13596       else if (unformat (line_input, "next-nsh"))
13597         protocol = 4;
13598       else
13599         {
13600           errmsg ("parse error '%U'", format_unformat_error, line_input);
13601           return -99;
13602         }
13603     }
13604
13605   if (local_set == 0)
13606     {
13607       errmsg ("tunnel local address not specified");
13608       return -99;
13609     }
13610   if (remote_set == 0)
13611     {
13612       errmsg ("tunnel remote address not specified");
13613       return -99;
13614     }
13615   if (grp_set && mcast_sw_if_index == ~0)
13616     {
13617       errmsg ("tunnel nonexistent multicast device");
13618       return -99;
13619     }
13620   if (ipv4_set && ipv6_set)
13621     {
13622       errmsg ("both IPv4 and IPv6 addresses specified");
13623       return -99;
13624     }
13625
13626   if (vni_set == 0)
13627     {
13628       errmsg ("vni not specified");
13629       return -99;
13630     }
13631
13632   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13633
13634
13635   if (ipv6_set)
13636     {
13637       clib_memcpy (&mp->local, &local6, sizeof (local6));
13638       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13639     }
13640   else
13641     {
13642       clib_memcpy (&mp->local, &local4, sizeof (local4));
13643       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13644     }
13645
13646   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13647   mp->encap_vrf_id = ntohl (encap_vrf_id);
13648   mp->decap_vrf_id = ntohl (decap_vrf_id);
13649   mp->protocol = protocol;
13650   mp->vni = ntohl (vni);
13651   mp->is_add = is_add;
13652   mp->is_ipv6 = ipv6_set;
13653
13654   S (mp);
13655   W (ret);
13656   return ret;
13657 }
13658
13659 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13660   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13661 {
13662   vat_main_t *vam = &vat_main;
13663   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13664   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13665
13666   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13667          ntohl (mp->sw_if_index),
13668          format_ip46_address, &local, IP46_TYPE_ANY,
13669          format_ip46_address, &remote, IP46_TYPE_ANY,
13670          ntohl (mp->vni), mp->protocol,
13671          ntohl (mp->mcast_sw_if_index),
13672          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13673 }
13674
13675
13676 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13677   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13678 {
13679   vat_main_t *vam = &vat_main;
13680   vat_json_node_t *node = NULL;
13681   struct in_addr ip4;
13682   struct in6_addr ip6;
13683
13684   if (VAT_JSON_ARRAY != vam->json_tree.type)
13685     {
13686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13687       vat_json_init_array (&vam->json_tree);
13688     }
13689   node = vat_json_array_add (&vam->json_tree);
13690
13691   vat_json_init_object (node);
13692   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13693   if (mp->is_ipv6)
13694     {
13695       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13696       vat_json_object_add_ip6 (node, "local", ip6);
13697       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13698       vat_json_object_add_ip6 (node, "remote", ip6);
13699     }
13700   else
13701     {
13702       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13703       vat_json_object_add_ip4 (node, "local", ip4);
13704       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13705       vat_json_object_add_ip4 (node, "remote", ip4);
13706     }
13707   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13708   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13709   vat_json_object_add_uint (node, "mcast_sw_if_index",
13710                             ntohl (mp->mcast_sw_if_index));
13711   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13712   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13713   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13714 }
13715
13716 static int
13717 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13718 {
13719   unformat_input_t *i = vam->input;
13720   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13721   vl_api_control_ping_t *mp_ping;
13722   u32 sw_if_index;
13723   u8 sw_if_index_set = 0;
13724   int ret;
13725
13726   /* Parse args required to build the message */
13727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13728     {
13729       if (unformat (i, "sw_if_index %d", &sw_if_index))
13730         sw_if_index_set = 1;
13731       else
13732         break;
13733     }
13734
13735   if (sw_if_index_set == 0)
13736     {
13737       sw_if_index = ~0;
13738     }
13739
13740   if (!vam->json_output)
13741     {
13742       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13743              "sw_if_index", "local", "remote", "vni",
13744              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13745     }
13746
13747   /* Get list of vxlan-tunnel interfaces */
13748   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13749
13750   mp->sw_if_index = htonl (sw_if_index);
13751
13752   S (mp);
13753
13754   /* Use a control ping for synchronization */
13755   MPING (CONTROL_PING, mp_ping);
13756   S (mp_ping);
13757
13758   W (ret);
13759   return ret;
13760 }
13761
13762 static void vl_api_l2_fib_table_details_t_handler
13763   (vl_api_l2_fib_table_details_t * mp)
13764 {
13765   vat_main_t *vam = &vat_main;
13766
13767   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13768          "       %d       %d     %d",
13769          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13770          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13771          mp->bvi_mac);
13772 }
13773
13774 static void vl_api_l2_fib_table_details_t_handler_json
13775   (vl_api_l2_fib_table_details_t * mp)
13776 {
13777   vat_main_t *vam = &vat_main;
13778   vat_json_node_t *node = NULL;
13779
13780   if (VAT_JSON_ARRAY != vam->json_tree.type)
13781     {
13782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13783       vat_json_init_array (&vam->json_tree);
13784     }
13785   node = vat_json_array_add (&vam->json_tree);
13786
13787   vat_json_init_object (node);
13788   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13789   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13790   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13791   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13792   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13793   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13794 }
13795
13796 static int
13797 api_l2_fib_table_dump (vat_main_t * vam)
13798 {
13799   unformat_input_t *i = vam->input;
13800   vl_api_l2_fib_table_dump_t *mp;
13801   vl_api_control_ping_t *mp_ping;
13802   u32 bd_id;
13803   u8 bd_id_set = 0;
13804   int ret;
13805
13806   /* Parse args required to build the message */
13807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13808     {
13809       if (unformat (i, "bd_id %d", &bd_id))
13810         bd_id_set = 1;
13811       else
13812         break;
13813     }
13814
13815   if (bd_id_set == 0)
13816     {
13817       errmsg ("missing bridge domain");
13818       return -99;
13819     }
13820
13821   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13822
13823   /* Get list of l2 fib entries */
13824   M (L2_FIB_TABLE_DUMP, mp);
13825
13826   mp->bd_id = ntohl (bd_id);
13827   S (mp);
13828
13829   /* Use a control ping for synchronization */
13830   MPING (CONTROL_PING, mp_ping);
13831   S (mp_ping);
13832
13833   W (ret);
13834   return ret;
13835 }
13836
13837
13838 static int
13839 api_interface_name_renumber (vat_main_t * vam)
13840 {
13841   unformat_input_t *line_input = vam->input;
13842   vl_api_interface_name_renumber_t *mp;
13843   u32 sw_if_index = ~0;
13844   u32 new_show_dev_instance = ~0;
13845   int ret;
13846
13847   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13848     {
13849       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13850                     &sw_if_index))
13851         ;
13852       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13853         ;
13854       else if (unformat (line_input, "new_show_dev_instance %d",
13855                          &new_show_dev_instance))
13856         ;
13857       else
13858         break;
13859     }
13860
13861   if (sw_if_index == ~0)
13862     {
13863       errmsg ("missing interface name or sw_if_index");
13864       return -99;
13865     }
13866
13867   if (new_show_dev_instance == ~0)
13868     {
13869       errmsg ("missing new_show_dev_instance");
13870       return -99;
13871     }
13872
13873   M (INTERFACE_NAME_RENUMBER, mp);
13874
13875   mp->sw_if_index = ntohl (sw_if_index);
13876   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13877
13878   S (mp);
13879   W (ret);
13880   return ret;
13881 }
13882
13883 static int
13884 api_ip_probe_neighbor (vat_main_t * vam)
13885 {
13886   unformat_input_t *i = vam->input;
13887   vl_api_ip_probe_neighbor_t *mp;
13888   vl_api_address_t dst_adr = { };
13889   u8 int_set = 0;
13890   u8 adr_set = 0;
13891   u32 sw_if_index;
13892   int ret;
13893
13894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13895     {
13896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13897         int_set = 1;
13898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13899         int_set = 1;
13900       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13901         adr_set = 1;
13902       else
13903         break;
13904     }
13905
13906   if (int_set == 0)
13907     {
13908       errmsg ("missing interface");
13909       return -99;
13910     }
13911
13912   if (adr_set == 0)
13913     {
13914       errmsg ("missing addresses");
13915       return -99;
13916     }
13917
13918   M (IP_PROBE_NEIGHBOR, mp);
13919
13920   mp->sw_if_index = ntohl (sw_if_index);
13921   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13922
13923   S (mp);
13924   W (ret);
13925   return ret;
13926 }
13927
13928 static int
13929 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13930 {
13931   unformat_input_t *i = vam->input;
13932   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13933   u8 mode = IP_SCAN_V46_NEIGHBORS;
13934   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13935   int ret;
13936
13937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13938     {
13939       if (unformat (i, "ip4"))
13940         mode = IP_SCAN_V4_NEIGHBORS;
13941       else if (unformat (i, "ip6"))
13942         mode = IP_SCAN_V6_NEIGHBORS;
13943       if (unformat (i, "both"))
13944         mode = IP_SCAN_V46_NEIGHBORS;
13945       else if (unformat (i, "disable"))
13946         mode = IP_SCAN_DISABLED;
13947       else if (unformat (i, "interval %d", &interval))
13948         ;
13949       else if (unformat (i, "max-time %d", &time))
13950         ;
13951       else if (unformat (i, "max-update %d", &update))
13952         ;
13953       else if (unformat (i, "delay %d", &delay))
13954         ;
13955       else if (unformat (i, "stale %d", &stale))
13956         ;
13957       else
13958         break;
13959     }
13960
13961   if (interval > 255)
13962     {
13963       errmsg ("interval cannot exceed 255 minutes.");
13964       return -99;
13965     }
13966   if (time > 255)
13967     {
13968       errmsg ("max-time cannot exceed 255 usec.");
13969       return -99;
13970     }
13971   if (update > 255)
13972     {
13973       errmsg ("max-update cannot exceed 255.");
13974       return -99;
13975     }
13976   if (delay > 255)
13977     {
13978       errmsg ("delay cannot exceed 255 msec.");
13979       return -99;
13980     }
13981   if (stale > 255)
13982     {
13983       errmsg ("stale cannot exceed 255 minutes.");
13984       return -99;
13985     }
13986
13987   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13988   mp->mode = mode;
13989   mp->scan_interval = interval;
13990   mp->max_proc_time = time;
13991   mp->max_update = update;
13992   mp->scan_int_delay = delay;
13993   mp->stale_threshold = stale;
13994
13995   S (mp);
13996   W (ret);
13997   return ret;
13998 }
13999
14000 static int
14001 api_want_ip4_arp_events (vat_main_t * vam)
14002 {
14003   unformat_input_t *line_input = vam->input;
14004   vl_api_want_ip4_arp_events_t *mp;
14005   ip4_address_t address;
14006   int address_set = 0;
14007   u32 enable_disable = 1;
14008   int ret;
14009
14010   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14011     {
14012       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14013         address_set = 1;
14014       else if (unformat (line_input, "del"))
14015         enable_disable = 0;
14016       else
14017         break;
14018     }
14019
14020   if (address_set == 0)
14021     {
14022       errmsg ("missing addresses");
14023       return -99;
14024     }
14025
14026   M (WANT_IP4_ARP_EVENTS, mp);
14027   mp->enable_disable = enable_disable;
14028   mp->pid = htonl (getpid ());
14029   clib_memcpy (mp->ip, &address, sizeof (address));
14030
14031   S (mp);
14032   W (ret);
14033   return ret;
14034 }
14035
14036 static int
14037 api_want_ip6_nd_events (vat_main_t * vam)
14038 {
14039   unformat_input_t *line_input = vam->input;
14040   vl_api_want_ip6_nd_events_t *mp;
14041   vl_api_ip6_address_t address;
14042   int address_set = 0;
14043   u32 enable_disable = 1;
14044   int ret;
14045
14046   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14047     {
14048       if (unformat
14049           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14050         address_set = 1;
14051       else if (unformat (line_input, "del"))
14052         enable_disable = 0;
14053       else
14054         break;
14055     }
14056
14057   if (address_set == 0)
14058     {
14059       errmsg ("missing addresses");
14060       return -99;
14061     }
14062
14063   M (WANT_IP6_ND_EVENTS, mp);
14064   mp->enable_disable = enable_disable;
14065   mp->pid = htonl (getpid ());
14066   clib_memcpy (&mp->ip, &address, sizeof (address));
14067
14068   S (mp);
14069   W (ret);
14070   return ret;
14071 }
14072
14073 static int
14074 api_want_l2_macs_events (vat_main_t * vam)
14075 {
14076   unformat_input_t *line_input = vam->input;
14077   vl_api_want_l2_macs_events_t *mp;
14078   u8 enable_disable = 1;
14079   u32 scan_delay = 0;
14080   u32 max_macs_in_event = 0;
14081   u32 learn_limit = 0;
14082   int ret;
14083
14084   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14085     {
14086       if (unformat (line_input, "learn-limit %d", &learn_limit))
14087         ;
14088       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14089         ;
14090       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14091         ;
14092       else if (unformat (line_input, "disable"))
14093         enable_disable = 0;
14094       else
14095         break;
14096     }
14097
14098   M (WANT_L2_MACS_EVENTS, mp);
14099   mp->enable_disable = enable_disable;
14100   mp->pid = htonl (getpid ());
14101   mp->learn_limit = htonl (learn_limit);
14102   mp->scan_delay = (u8) scan_delay;
14103   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14104   S (mp);
14105   W (ret);
14106   return ret;
14107 }
14108
14109 static int
14110 api_input_acl_set_interface (vat_main_t * vam)
14111 {
14112   unformat_input_t *i = vam->input;
14113   vl_api_input_acl_set_interface_t *mp;
14114   u32 sw_if_index;
14115   int sw_if_index_set;
14116   u32 ip4_table_index = ~0;
14117   u32 ip6_table_index = ~0;
14118   u32 l2_table_index = ~0;
14119   u8 is_add = 1;
14120   int ret;
14121
14122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14123     {
14124       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14125         sw_if_index_set = 1;
14126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14127         sw_if_index_set = 1;
14128       else if (unformat (i, "del"))
14129         is_add = 0;
14130       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14131         ;
14132       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14133         ;
14134       else if (unformat (i, "l2-table %d", &l2_table_index))
14135         ;
14136       else
14137         {
14138           clib_warning ("parse error '%U'", format_unformat_error, i);
14139           return -99;
14140         }
14141     }
14142
14143   if (sw_if_index_set == 0)
14144     {
14145       errmsg ("missing interface name or sw_if_index");
14146       return -99;
14147     }
14148
14149   M (INPUT_ACL_SET_INTERFACE, mp);
14150
14151   mp->sw_if_index = ntohl (sw_if_index);
14152   mp->ip4_table_index = ntohl (ip4_table_index);
14153   mp->ip6_table_index = ntohl (ip6_table_index);
14154   mp->l2_table_index = ntohl (l2_table_index);
14155   mp->is_add = is_add;
14156
14157   S (mp);
14158   W (ret);
14159   return ret;
14160 }
14161
14162 static int
14163 api_output_acl_set_interface (vat_main_t * vam)
14164 {
14165   unformat_input_t *i = vam->input;
14166   vl_api_output_acl_set_interface_t *mp;
14167   u32 sw_if_index;
14168   int sw_if_index_set;
14169   u32 ip4_table_index = ~0;
14170   u32 ip6_table_index = ~0;
14171   u32 l2_table_index = ~0;
14172   u8 is_add = 1;
14173   int ret;
14174
14175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14176     {
14177       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14178         sw_if_index_set = 1;
14179       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14180         sw_if_index_set = 1;
14181       else if (unformat (i, "del"))
14182         is_add = 0;
14183       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14184         ;
14185       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14186         ;
14187       else if (unformat (i, "l2-table %d", &l2_table_index))
14188         ;
14189       else
14190         {
14191           clib_warning ("parse error '%U'", format_unformat_error, i);
14192           return -99;
14193         }
14194     }
14195
14196   if (sw_if_index_set == 0)
14197     {
14198       errmsg ("missing interface name or sw_if_index");
14199       return -99;
14200     }
14201
14202   M (OUTPUT_ACL_SET_INTERFACE, mp);
14203
14204   mp->sw_if_index = ntohl (sw_if_index);
14205   mp->ip4_table_index = ntohl (ip4_table_index);
14206   mp->ip6_table_index = ntohl (ip6_table_index);
14207   mp->l2_table_index = ntohl (l2_table_index);
14208   mp->is_add = is_add;
14209
14210   S (mp);
14211   W (ret);
14212   return ret;
14213 }
14214
14215 static int
14216 api_ip_address_dump (vat_main_t * vam)
14217 {
14218   unformat_input_t *i = vam->input;
14219   vl_api_ip_address_dump_t *mp;
14220   vl_api_control_ping_t *mp_ping;
14221   u32 sw_if_index = ~0;
14222   u8 sw_if_index_set = 0;
14223   u8 ipv4_set = 0;
14224   u8 ipv6_set = 0;
14225   int ret;
14226
14227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14228     {
14229       if (unformat (i, "sw_if_index %d", &sw_if_index))
14230         sw_if_index_set = 1;
14231       else
14232         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14233         sw_if_index_set = 1;
14234       else if (unformat (i, "ipv4"))
14235         ipv4_set = 1;
14236       else if (unformat (i, "ipv6"))
14237         ipv6_set = 1;
14238       else
14239         break;
14240     }
14241
14242   if (ipv4_set && ipv6_set)
14243     {
14244       errmsg ("ipv4 and ipv6 flags cannot be both set");
14245       return -99;
14246     }
14247
14248   if ((!ipv4_set) && (!ipv6_set))
14249     {
14250       errmsg ("no ipv4 nor ipv6 flag set");
14251       return -99;
14252     }
14253
14254   if (sw_if_index_set == 0)
14255     {
14256       errmsg ("missing interface name or sw_if_index");
14257       return -99;
14258     }
14259
14260   vam->current_sw_if_index = sw_if_index;
14261   vam->is_ipv6 = ipv6_set;
14262
14263   M (IP_ADDRESS_DUMP, mp);
14264   mp->sw_if_index = ntohl (sw_if_index);
14265   mp->is_ipv6 = ipv6_set;
14266   S (mp);
14267
14268   /* Use a control ping for synchronization */
14269   MPING (CONTROL_PING, mp_ping);
14270   S (mp_ping);
14271
14272   W (ret);
14273   return ret;
14274 }
14275
14276 static int
14277 api_ip_dump (vat_main_t * vam)
14278 {
14279   vl_api_ip_dump_t *mp;
14280   vl_api_control_ping_t *mp_ping;
14281   unformat_input_t *in = vam->input;
14282   int ipv4_set = 0;
14283   int ipv6_set = 0;
14284   int is_ipv6;
14285   int i;
14286   int ret;
14287
14288   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14289     {
14290       if (unformat (in, "ipv4"))
14291         ipv4_set = 1;
14292       else if (unformat (in, "ipv6"))
14293         ipv6_set = 1;
14294       else
14295         break;
14296     }
14297
14298   if (ipv4_set && ipv6_set)
14299     {
14300       errmsg ("ipv4 and ipv6 flags cannot be both set");
14301       return -99;
14302     }
14303
14304   if ((!ipv4_set) && (!ipv6_set))
14305     {
14306       errmsg ("no ipv4 nor ipv6 flag set");
14307       return -99;
14308     }
14309
14310   is_ipv6 = ipv6_set;
14311   vam->is_ipv6 = is_ipv6;
14312
14313   /* free old data */
14314   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14315     {
14316       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14317     }
14318   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14319
14320   M (IP_DUMP, mp);
14321   mp->is_ipv6 = ipv6_set;
14322   S (mp);
14323
14324   /* Use a control ping for synchronization */
14325   MPING (CONTROL_PING, mp_ping);
14326   S (mp_ping);
14327
14328   W (ret);
14329   return ret;
14330 }
14331
14332 static int
14333 api_ipsec_spd_add_del (vat_main_t * vam)
14334 {
14335   unformat_input_t *i = vam->input;
14336   vl_api_ipsec_spd_add_del_t *mp;
14337   u32 spd_id = ~0;
14338   u8 is_add = 1;
14339   int ret;
14340
14341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14342     {
14343       if (unformat (i, "spd_id %d", &spd_id))
14344         ;
14345       else if (unformat (i, "del"))
14346         is_add = 0;
14347       else
14348         {
14349           clib_warning ("parse error '%U'", format_unformat_error, i);
14350           return -99;
14351         }
14352     }
14353   if (spd_id == ~0)
14354     {
14355       errmsg ("spd_id must be set");
14356       return -99;
14357     }
14358
14359   M (IPSEC_SPD_ADD_DEL, mp);
14360
14361   mp->spd_id = ntohl (spd_id);
14362   mp->is_add = is_add;
14363
14364   S (mp);
14365   W (ret);
14366   return ret;
14367 }
14368
14369 static int
14370 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14371 {
14372   unformat_input_t *i = vam->input;
14373   vl_api_ipsec_interface_add_del_spd_t *mp;
14374   u32 sw_if_index;
14375   u8 sw_if_index_set = 0;
14376   u32 spd_id = (u32) ~ 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, "del"))
14383         is_add = 0;
14384       else if (unformat (i, "spd_id %d", &spd_id))
14385         ;
14386       else
14387         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14388         sw_if_index_set = 1;
14389       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14390         sw_if_index_set = 1;
14391       else
14392         {
14393           clib_warning ("parse error '%U'", format_unformat_error, i);
14394           return -99;
14395         }
14396
14397     }
14398
14399   if (spd_id == (u32) ~ 0)
14400     {
14401       errmsg ("spd_id must be set");
14402       return -99;
14403     }
14404
14405   if (sw_if_index_set == 0)
14406     {
14407       errmsg ("missing interface name or sw_if_index");
14408       return -99;
14409     }
14410
14411   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14412
14413   mp->spd_id = ntohl (spd_id);
14414   mp->sw_if_index = ntohl (sw_if_index);
14415   mp->is_add = is_add;
14416
14417   S (mp);
14418   W (ret);
14419   return ret;
14420 }
14421
14422 static int
14423 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14424 {
14425   unformat_input_t *i = vam->input;
14426   vl_api_ipsec_spd_entry_add_del_t *mp;
14427   u8 is_add = 1, is_outbound = 0;
14428   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14429   i32 priority = 0;
14430   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14431   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14432   vl_api_address_t laddr_start = { }, laddr_stop =
14433   {
14434   }, raddr_start =
14435   {
14436   }, raddr_stop =
14437   {
14438   };
14439   int ret;
14440
14441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14442     {
14443       if (unformat (i, "del"))
14444         is_add = 0;
14445       if (unformat (i, "outbound"))
14446         is_outbound = 1;
14447       if (unformat (i, "inbound"))
14448         is_outbound = 0;
14449       else if (unformat (i, "spd_id %d", &spd_id))
14450         ;
14451       else if (unformat (i, "sa_id %d", &sa_id))
14452         ;
14453       else if (unformat (i, "priority %d", &priority))
14454         ;
14455       else if (unformat (i, "protocol %d", &protocol))
14456         ;
14457       else if (unformat (i, "lport_start %d", &lport_start))
14458         ;
14459       else if (unformat (i, "lport_stop %d", &lport_stop))
14460         ;
14461       else if (unformat (i, "rport_start %d", &rport_start))
14462         ;
14463       else if (unformat (i, "rport_stop %d", &rport_stop))
14464         ;
14465       else if (unformat (i, "laddr_start %U",
14466                          unformat_vl_api_address, &laddr_start))
14467         ;
14468       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14469                          &laddr_stop))
14470         ;
14471       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14472                          &raddr_start))
14473         ;
14474       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14475                          &raddr_stop))
14476         ;
14477       else
14478         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14479         {
14480           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14481             {
14482               clib_warning ("unsupported action: 'resolve'");
14483               return -99;
14484             }
14485         }
14486       else
14487         {
14488           clib_warning ("parse error '%U'", format_unformat_error, i);
14489           return -99;
14490         }
14491
14492     }
14493
14494   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14495
14496   mp->is_add = is_add;
14497
14498   mp->entry.spd_id = ntohl (spd_id);
14499   mp->entry.priority = ntohl (priority);
14500   mp->entry.is_outbound = is_outbound;
14501
14502   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14503                sizeof (vl_api_address_t));
14504   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14505                sizeof (vl_api_address_t));
14506   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14507                sizeof (vl_api_address_t));
14508   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14509                sizeof (vl_api_address_t));
14510
14511   mp->entry.protocol = (u8) protocol;
14512   mp->entry.local_port_start = ntohs ((u16) lport_start);
14513   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14514   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14515   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14516   mp->entry.policy = (u8) policy;
14517   mp->entry.sa_id = ntohl (sa_id);
14518
14519   S (mp);
14520   W (ret);
14521   return ret;
14522 }
14523
14524 static int
14525 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14526 {
14527   unformat_input_t *i = vam->input;
14528   vl_api_ipsec_sad_entry_add_del_t *mp;
14529   u32 sad_id = 0, spi = 0;
14530   u8 *ck = 0, *ik = 0;
14531   u8 is_add = 1;
14532
14533   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14534   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14535   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14536   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14537   vl_api_address_t tun_src, tun_dst;
14538   int ret;
14539
14540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14541     {
14542       if (unformat (i, "del"))
14543         is_add = 0;
14544       else if (unformat (i, "sad_id %d", &sad_id))
14545         ;
14546       else if (unformat (i, "spi %d", &spi))
14547         ;
14548       else if (unformat (i, "esp"))
14549         protocol = IPSEC_API_PROTO_ESP;
14550       else
14551         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14552         {
14553           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14554           if (ADDRESS_IP6 == tun_src.af)
14555             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14556         }
14557       else
14558         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14559         {
14560           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14561           if (ADDRESS_IP6 == tun_src.af)
14562             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14563         }
14564       else
14565         if (unformat (i, "crypto_alg %U",
14566                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14567         ;
14568       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14569         ;
14570       else if (unformat (i, "integ_alg %U",
14571                          unformat_ipsec_api_integ_alg, &integ_alg))
14572         ;
14573       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14574         ;
14575       else
14576         {
14577           clib_warning ("parse error '%U'", format_unformat_error, i);
14578           return -99;
14579         }
14580
14581     }
14582
14583   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14584
14585   mp->is_add = is_add;
14586   mp->entry.sad_id = ntohl (sad_id);
14587   mp->entry.protocol = protocol;
14588   mp->entry.spi = ntohl (spi);
14589   mp->entry.flags = flags;
14590
14591   mp->entry.crypto_algorithm = crypto_alg;
14592   mp->entry.integrity_algorithm = integ_alg;
14593   mp->entry.crypto_key.length = vec_len (ck);
14594   mp->entry.integrity_key.length = vec_len (ik);
14595
14596   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14597     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14598
14599   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14600     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14601
14602   if (ck)
14603     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14604   if (ik)
14605     clib_memcpy (mp->entry.integrity_key.data, ik,
14606                  mp->entry.integrity_key.length);
14607
14608   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14609     {
14610       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14611                    sizeof (mp->entry.tunnel_src));
14612       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14613                    sizeof (mp->entry.tunnel_dst));
14614     }
14615
14616   S (mp);
14617   W (ret);
14618   return ret;
14619 }
14620
14621 static int
14622 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14623 {
14624   unformat_input_t *i = vam->input;
14625   vl_api_ipsec_tunnel_if_add_del_t *mp;
14626   u32 local_spi = 0, remote_spi = 0;
14627   u32 crypto_alg = 0, integ_alg = 0;
14628   u8 *lck = NULL, *rck = NULL;
14629   u8 *lik = NULL, *rik = NULL;
14630   vl_api_address_t local_ip = { 0 };
14631   vl_api_address_t remote_ip = { 0 };
14632   f64 before = 0;
14633   u8 is_add = 1;
14634   u8 esn = 0;
14635   u8 anti_replay = 0;
14636   u8 renumber = 0;
14637   u32 instance = ~0;
14638   u32 count = 1, jj;
14639   int ret = -1;
14640
14641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14642     {
14643       if (unformat (i, "del"))
14644         is_add = 0;
14645       else if (unformat (i, "esn"))
14646         esn = 1;
14647       else if (unformat (i, "anti-replay"))
14648         anti_replay = 1;
14649       else if (unformat (i, "count %d", &count))
14650         ;
14651       else if (unformat (i, "local_spi %d", &local_spi))
14652         ;
14653       else if (unformat (i, "remote_spi %d", &remote_spi))
14654         ;
14655       else
14656         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14657         ;
14658       else
14659         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14660         ;
14661       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14662         ;
14663       else
14664         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14665         ;
14666       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14667         ;
14668       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14669         ;
14670       else
14671         if (unformat
14672             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14673         {
14674           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14675             {
14676               errmsg ("unsupported crypto-alg: '%U'\n",
14677                       format_ipsec_crypto_alg, crypto_alg);
14678               return -99;
14679             }
14680         }
14681       else
14682         if (unformat
14683             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14684         {
14685           if (integ_alg >= IPSEC_INTEG_N_ALG)
14686             {
14687               errmsg ("unsupported integ-alg: '%U'\n",
14688                       format_ipsec_integ_alg, integ_alg);
14689               return -99;
14690             }
14691         }
14692       else if (unformat (i, "instance %u", &instance))
14693         renumber = 1;
14694       else
14695         {
14696           errmsg ("parse error '%U'\n", format_unformat_error, i);
14697           return -99;
14698         }
14699     }
14700
14701   if (count > 1)
14702     {
14703       /* Turn on async mode */
14704       vam->async_mode = 1;
14705       vam->async_errors = 0;
14706       before = vat_time_now (vam);
14707     }
14708
14709   for (jj = 0; jj < count; jj++)
14710     {
14711       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14712
14713       mp->is_add = is_add;
14714       mp->esn = esn;
14715       mp->anti_replay = anti_replay;
14716
14717       if (jj > 0)
14718         increment_address (&remote_ip);
14719
14720       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14721       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14722
14723       mp->local_spi = htonl (local_spi + jj);
14724       mp->remote_spi = htonl (remote_spi + jj);
14725       mp->crypto_alg = (u8) crypto_alg;
14726
14727       mp->local_crypto_key_len = 0;
14728       if (lck)
14729         {
14730           mp->local_crypto_key_len = vec_len (lck);
14731           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14732             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14733           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14734         }
14735
14736       mp->remote_crypto_key_len = 0;
14737       if (rck)
14738         {
14739           mp->remote_crypto_key_len = vec_len (rck);
14740           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14741             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14742           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14743         }
14744
14745       mp->integ_alg = (u8) integ_alg;
14746
14747       mp->local_integ_key_len = 0;
14748       if (lik)
14749         {
14750           mp->local_integ_key_len = vec_len (lik);
14751           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14752             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14753           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14754         }
14755
14756       mp->remote_integ_key_len = 0;
14757       if (rik)
14758         {
14759           mp->remote_integ_key_len = vec_len (rik);
14760           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14761             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14762           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14763         }
14764
14765       if (renumber)
14766         {
14767           mp->renumber = renumber;
14768           mp->show_instance = ntohl (instance);
14769         }
14770       S (mp);
14771     }
14772
14773   /* When testing multiple add/del ops, use a control-ping to sync */
14774   if (count > 1)
14775     {
14776       vl_api_control_ping_t *mp_ping;
14777       f64 after;
14778       f64 timeout;
14779
14780       /* Shut off async mode */
14781       vam->async_mode = 0;
14782
14783       MPING (CONTROL_PING, mp_ping);
14784       S (mp_ping);
14785
14786       timeout = vat_time_now (vam) + 1.0;
14787       while (vat_time_now (vam) < timeout)
14788         if (vam->result_ready == 1)
14789           goto out;
14790       vam->retval = -99;
14791
14792     out:
14793       if (vam->retval == -99)
14794         errmsg ("timeout");
14795
14796       if (vam->async_errors > 0)
14797         {
14798           errmsg ("%d asynchronous errors", vam->async_errors);
14799           vam->retval = -98;
14800         }
14801       vam->async_errors = 0;
14802       after = vat_time_now (vam);
14803
14804       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14805       if (jj > 0)
14806         count = jj;
14807
14808       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14809              count, after - before, count / (after - before));
14810     }
14811   else
14812     {
14813       /* Wait for a reply... */
14814       W (ret);
14815       return ret;
14816     }
14817
14818   return ret;
14819 }
14820
14821 static void
14822 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14823 {
14824   vat_main_t *vam = &vat_main;
14825
14826   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14827          "crypto_key %U integ_alg %u integ_key %U flags %x "
14828          "tunnel_src_addr %U tunnel_dst_addr %U "
14829          "salt %u seq_outbound %lu last_seq_inbound %lu "
14830          "replay_window %lu\n",
14831          ntohl (mp->entry.sad_id),
14832          ntohl (mp->sw_if_index),
14833          ntohl (mp->entry.spi),
14834          ntohl (mp->entry.protocol),
14835          ntohl (mp->entry.crypto_algorithm),
14836          format_hex_bytes, mp->entry.crypto_key.data,
14837          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14838          format_hex_bytes, mp->entry.integrity_key.data,
14839          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14840          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14841          &mp->entry.tunnel_dst, ntohl (mp->salt),
14842          clib_net_to_host_u64 (mp->seq_outbound),
14843          clib_net_to_host_u64 (mp->last_seq_inbound),
14844          clib_net_to_host_u64 (mp->replay_window));
14845 }
14846
14847 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14848 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14849
14850 static void vl_api_ipsec_sa_details_t_handler_json
14851   (vl_api_ipsec_sa_details_t * mp)
14852 {
14853   vat_main_t *vam = &vat_main;
14854   vat_json_node_t *node = NULL;
14855   vl_api_ipsec_sad_flags_t flags;
14856
14857   if (VAT_JSON_ARRAY != vam->json_tree.type)
14858     {
14859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14860       vat_json_init_array (&vam->json_tree);
14861     }
14862   node = vat_json_array_add (&vam->json_tree);
14863
14864   vat_json_init_object (node);
14865   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14866   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14867   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14868   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14869   vat_json_object_add_uint (node, "crypto_alg",
14870                             ntohl (mp->entry.crypto_algorithm));
14871   vat_json_object_add_uint (node, "integ_alg",
14872                             ntohl (mp->entry.integrity_algorithm));
14873   flags = ntohl (mp->entry.flags);
14874   vat_json_object_add_uint (node, "use_esn",
14875                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14876   vat_json_object_add_uint (node, "use_anti_replay",
14877                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14878   vat_json_object_add_uint (node, "is_tunnel",
14879                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14880   vat_json_object_add_uint (node, "is_tunnel_ip6",
14881                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14882   vat_json_object_add_uint (node, "udp_encap",
14883                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14884   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14885                              mp->entry.crypto_key.length);
14886   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14887                              mp->entry.integrity_key.length);
14888   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14889   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14890   vat_json_object_add_uint (node, "replay_window",
14891                             clib_net_to_host_u64 (mp->replay_window));
14892 }
14893
14894 static int
14895 api_ipsec_sa_dump (vat_main_t * vam)
14896 {
14897   unformat_input_t *i = vam->input;
14898   vl_api_ipsec_sa_dump_t *mp;
14899   vl_api_control_ping_t *mp_ping;
14900   u32 sa_id = ~0;
14901   int ret;
14902
14903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14904     {
14905       if (unformat (i, "sa_id %d", &sa_id))
14906         ;
14907       else
14908         {
14909           clib_warning ("parse error '%U'", format_unformat_error, i);
14910           return -99;
14911         }
14912     }
14913
14914   M (IPSEC_SA_DUMP, mp);
14915
14916   mp->sa_id = ntohl (sa_id);
14917
14918   S (mp);
14919
14920   /* Use a control ping for synchronization */
14921   M (CONTROL_PING, mp_ping);
14922   S (mp_ping);
14923
14924   W (ret);
14925   return ret;
14926 }
14927
14928 static int
14929 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14930 {
14931   unformat_input_t *i = vam->input;
14932   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14933   u32 sw_if_index = ~0;
14934   u32 sa_id = ~0;
14935   u8 is_outbound = (u8) ~ 0;
14936   int ret;
14937
14938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14939     {
14940       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14941         ;
14942       else if (unformat (i, "sa_id %d", &sa_id))
14943         ;
14944       else if (unformat (i, "outbound"))
14945         is_outbound = 1;
14946       else if (unformat (i, "inbound"))
14947         is_outbound = 0;
14948       else
14949         {
14950           clib_warning ("parse error '%U'", format_unformat_error, i);
14951           return -99;
14952         }
14953     }
14954
14955   if (sw_if_index == ~0)
14956     {
14957       errmsg ("interface must be specified");
14958       return -99;
14959     }
14960
14961   if (sa_id == ~0)
14962     {
14963       errmsg ("SA ID must be specified");
14964       return -99;
14965     }
14966
14967   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14968
14969   mp->sw_if_index = htonl (sw_if_index);
14970   mp->sa_id = htonl (sa_id);
14971   mp->is_outbound = is_outbound;
14972
14973   S (mp);
14974   W (ret);
14975
14976   return ret;
14977 }
14978
14979 static int
14980 api_get_first_msg_id (vat_main_t * vam)
14981 {
14982   vl_api_get_first_msg_id_t *mp;
14983   unformat_input_t *i = vam->input;
14984   u8 *name;
14985   u8 name_set = 0;
14986   int ret;
14987
14988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14989     {
14990       if (unformat (i, "client %s", &name))
14991         name_set = 1;
14992       else
14993         break;
14994     }
14995
14996   if (name_set == 0)
14997     {
14998       errmsg ("missing client name");
14999       return -99;
15000     }
15001   vec_add1 (name, 0);
15002
15003   if (vec_len (name) > 63)
15004     {
15005       errmsg ("client name too long");
15006       return -99;
15007     }
15008
15009   M (GET_FIRST_MSG_ID, mp);
15010   clib_memcpy (mp->name, name, vec_len (name));
15011   S (mp);
15012   W (ret);
15013   return ret;
15014 }
15015
15016 static int
15017 api_cop_interface_enable_disable (vat_main_t * vam)
15018 {
15019   unformat_input_t *line_input = vam->input;
15020   vl_api_cop_interface_enable_disable_t *mp;
15021   u32 sw_if_index = ~0;
15022   u8 enable_disable = 1;
15023   int ret;
15024
15025   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15026     {
15027       if (unformat (line_input, "disable"))
15028         enable_disable = 0;
15029       if (unformat (line_input, "enable"))
15030         enable_disable = 1;
15031       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15032                          vam, &sw_if_index))
15033         ;
15034       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15035         ;
15036       else
15037         break;
15038     }
15039
15040   if (sw_if_index == ~0)
15041     {
15042       errmsg ("missing interface name or sw_if_index");
15043       return -99;
15044     }
15045
15046   /* Construct the API message */
15047   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15048   mp->sw_if_index = ntohl (sw_if_index);
15049   mp->enable_disable = enable_disable;
15050
15051   /* send it... */
15052   S (mp);
15053   /* Wait for the reply */
15054   W (ret);
15055   return ret;
15056 }
15057
15058 static int
15059 api_cop_whitelist_enable_disable (vat_main_t * vam)
15060 {
15061   unformat_input_t *line_input = vam->input;
15062   vl_api_cop_whitelist_enable_disable_t *mp;
15063   u32 sw_if_index = ~0;
15064   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15065   u32 fib_id = 0;
15066   int ret;
15067
15068   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15069     {
15070       if (unformat (line_input, "ip4"))
15071         ip4 = 1;
15072       else if (unformat (line_input, "ip6"))
15073         ip6 = 1;
15074       else if (unformat (line_input, "default"))
15075         default_cop = 1;
15076       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15077                          vam, &sw_if_index))
15078         ;
15079       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15080         ;
15081       else if (unformat (line_input, "fib-id %d", &fib_id))
15082         ;
15083       else
15084         break;
15085     }
15086
15087   if (sw_if_index == ~0)
15088     {
15089       errmsg ("missing interface name or sw_if_index");
15090       return -99;
15091     }
15092
15093   /* Construct the API message */
15094   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15095   mp->sw_if_index = ntohl (sw_if_index);
15096   mp->fib_id = ntohl (fib_id);
15097   mp->ip4 = ip4;
15098   mp->ip6 = ip6;
15099   mp->default_cop = default_cop;
15100
15101   /* send it... */
15102   S (mp);
15103   /* Wait for the reply */
15104   W (ret);
15105   return ret;
15106 }
15107
15108 static int
15109 api_get_node_graph (vat_main_t * vam)
15110 {
15111   vl_api_get_node_graph_t *mp;
15112   int ret;
15113
15114   M (GET_NODE_GRAPH, mp);
15115
15116   /* send it... */
15117   S (mp);
15118   /* Wait for the reply */
15119   W (ret);
15120   return ret;
15121 }
15122
15123 /* *INDENT-OFF* */
15124 /** Used for parsing LISP eids */
15125 typedef CLIB_PACKED(struct{
15126   u8 addr[16];   /**< eid address */
15127   u32 len;       /**< prefix length if IP */
15128   u8 type;      /**< type of eid */
15129 }) lisp_eid_vat_t;
15130 /* *INDENT-ON* */
15131
15132 static uword
15133 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15134 {
15135   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15136
15137   clib_memset (a, 0, sizeof (a[0]));
15138
15139   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15140     {
15141       a->type = 0;              /* ipv4 type */
15142     }
15143   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15144     {
15145       a->type = 1;              /* ipv6 type */
15146     }
15147   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15148     {
15149       a->type = 2;              /* mac type */
15150     }
15151   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15152     {
15153       a->type = 3;              /* NSH type */
15154       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15155       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15156     }
15157   else
15158     {
15159       return 0;
15160     }
15161
15162   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15163     {
15164       return 0;
15165     }
15166
15167   return 1;
15168 }
15169
15170 static int
15171 lisp_eid_size_vat (u8 type)
15172 {
15173   switch (type)
15174     {
15175     case 0:
15176       return 4;
15177     case 1:
15178       return 16;
15179     case 2:
15180       return 6;
15181     case 3:
15182       return 5;
15183     }
15184   return 0;
15185 }
15186
15187 static void
15188 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15189 {
15190   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15191 }
15192
15193 static int
15194 api_one_add_del_locator_set (vat_main_t * vam)
15195 {
15196   unformat_input_t *input = vam->input;
15197   vl_api_one_add_del_locator_set_t *mp;
15198   u8 is_add = 1;
15199   u8 *locator_set_name = NULL;
15200   u8 locator_set_name_set = 0;
15201   vl_api_local_locator_t locator, *locators = 0;
15202   u32 sw_if_index, priority, weight;
15203   u32 data_len = 0;
15204
15205   int ret;
15206   /* Parse args required to build the message */
15207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15208     {
15209       if (unformat (input, "del"))
15210         {
15211           is_add = 0;
15212         }
15213       else if (unformat (input, "locator-set %s", &locator_set_name))
15214         {
15215           locator_set_name_set = 1;
15216         }
15217       else if (unformat (input, "sw_if_index %u p %u w %u",
15218                          &sw_if_index, &priority, &weight))
15219         {
15220           locator.sw_if_index = htonl (sw_if_index);
15221           locator.priority = priority;
15222           locator.weight = weight;
15223           vec_add1 (locators, locator);
15224         }
15225       else
15226         if (unformat
15227             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15228              &sw_if_index, &priority, &weight))
15229         {
15230           locator.sw_if_index = htonl (sw_if_index);
15231           locator.priority = priority;
15232           locator.weight = weight;
15233           vec_add1 (locators, locator);
15234         }
15235       else
15236         break;
15237     }
15238
15239   if (locator_set_name_set == 0)
15240     {
15241       errmsg ("missing locator-set name");
15242       vec_free (locators);
15243       return -99;
15244     }
15245
15246   if (vec_len (locator_set_name) > 64)
15247     {
15248       errmsg ("locator-set name too long");
15249       vec_free (locator_set_name);
15250       vec_free (locators);
15251       return -99;
15252     }
15253   vec_add1 (locator_set_name, 0);
15254
15255   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15256
15257   /* Construct the API message */
15258   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15259
15260   mp->is_add = is_add;
15261   clib_memcpy (mp->locator_set_name, locator_set_name,
15262                vec_len (locator_set_name));
15263   vec_free (locator_set_name);
15264
15265   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15266   if (locators)
15267     clib_memcpy (mp->locators, locators, data_len);
15268   vec_free (locators);
15269
15270   /* send it... */
15271   S (mp);
15272
15273   /* Wait for a reply... */
15274   W (ret);
15275   return ret;
15276 }
15277
15278 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15279
15280 static int
15281 api_one_add_del_locator (vat_main_t * vam)
15282 {
15283   unformat_input_t *input = vam->input;
15284   vl_api_one_add_del_locator_t *mp;
15285   u32 tmp_if_index = ~0;
15286   u32 sw_if_index = ~0;
15287   u8 sw_if_index_set = 0;
15288   u8 sw_if_index_if_name_set = 0;
15289   u32 priority = ~0;
15290   u8 priority_set = 0;
15291   u32 weight = ~0;
15292   u8 weight_set = 0;
15293   u8 is_add = 1;
15294   u8 *locator_set_name = NULL;
15295   u8 locator_set_name_set = 0;
15296   int ret;
15297
15298   /* Parse args required to build the message */
15299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15300     {
15301       if (unformat (input, "del"))
15302         {
15303           is_add = 0;
15304         }
15305       else if (unformat (input, "locator-set %s", &locator_set_name))
15306         {
15307           locator_set_name_set = 1;
15308         }
15309       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15310                          &tmp_if_index))
15311         {
15312           sw_if_index_if_name_set = 1;
15313           sw_if_index = tmp_if_index;
15314         }
15315       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15316         {
15317           sw_if_index_set = 1;
15318           sw_if_index = tmp_if_index;
15319         }
15320       else if (unformat (input, "p %d", &priority))
15321         {
15322           priority_set = 1;
15323         }
15324       else if (unformat (input, "w %d", &weight))
15325         {
15326           weight_set = 1;
15327         }
15328       else
15329         break;
15330     }
15331
15332   if (locator_set_name_set == 0)
15333     {
15334       errmsg ("missing locator-set name");
15335       return -99;
15336     }
15337
15338   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15339     {
15340       errmsg ("missing sw_if_index");
15341       vec_free (locator_set_name);
15342       return -99;
15343     }
15344
15345   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15346     {
15347       errmsg ("cannot use both params interface name and sw_if_index");
15348       vec_free (locator_set_name);
15349       return -99;
15350     }
15351
15352   if (priority_set == 0)
15353     {
15354       errmsg ("missing locator-set priority");
15355       vec_free (locator_set_name);
15356       return -99;
15357     }
15358
15359   if (weight_set == 0)
15360     {
15361       errmsg ("missing locator-set weight");
15362       vec_free (locator_set_name);
15363       return -99;
15364     }
15365
15366   if (vec_len (locator_set_name) > 64)
15367     {
15368       errmsg ("locator-set name too long");
15369       vec_free (locator_set_name);
15370       return -99;
15371     }
15372   vec_add1 (locator_set_name, 0);
15373
15374   /* Construct the API message */
15375   M (ONE_ADD_DEL_LOCATOR, mp);
15376
15377   mp->is_add = is_add;
15378   mp->sw_if_index = ntohl (sw_if_index);
15379   mp->priority = priority;
15380   mp->weight = weight;
15381   clib_memcpy (mp->locator_set_name, locator_set_name,
15382                vec_len (locator_set_name));
15383   vec_free (locator_set_name);
15384
15385   /* send it... */
15386   S (mp);
15387
15388   /* Wait for a reply... */
15389   W (ret);
15390   return ret;
15391 }
15392
15393 #define api_lisp_add_del_locator api_one_add_del_locator
15394
15395 uword
15396 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15397 {
15398   u32 *key_id = va_arg (*args, u32 *);
15399   u8 *s = 0;
15400
15401   if (unformat (input, "%s", &s))
15402     {
15403       if (!strcmp ((char *) s, "sha1"))
15404         key_id[0] = HMAC_SHA_1_96;
15405       else if (!strcmp ((char *) s, "sha256"))
15406         key_id[0] = HMAC_SHA_256_128;
15407       else
15408         {
15409           clib_warning ("invalid key_id: '%s'", s);
15410           key_id[0] = HMAC_NO_KEY;
15411         }
15412     }
15413   else
15414     return 0;
15415
15416   vec_free (s);
15417   return 1;
15418 }
15419
15420 static int
15421 api_one_add_del_local_eid (vat_main_t * vam)
15422 {
15423   unformat_input_t *input = vam->input;
15424   vl_api_one_add_del_local_eid_t *mp;
15425   u8 is_add = 1;
15426   u8 eid_set = 0;
15427   lisp_eid_vat_t _eid, *eid = &_eid;
15428   u8 *locator_set_name = 0;
15429   u8 locator_set_name_set = 0;
15430   u32 vni = 0;
15431   u16 key_id = 0;
15432   u8 *key = 0;
15433   int ret;
15434
15435   /* Parse args required to build the message */
15436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15437     {
15438       if (unformat (input, "del"))
15439         {
15440           is_add = 0;
15441         }
15442       else if (unformat (input, "vni %d", &vni))
15443         {
15444           ;
15445         }
15446       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15447         {
15448           eid_set = 1;
15449         }
15450       else if (unformat (input, "locator-set %s", &locator_set_name))
15451         {
15452           locator_set_name_set = 1;
15453         }
15454       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15455         ;
15456       else if (unformat (input, "secret-key %_%v%_", &key))
15457         ;
15458       else
15459         break;
15460     }
15461
15462   if (locator_set_name_set == 0)
15463     {
15464       errmsg ("missing locator-set name");
15465       return -99;
15466     }
15467
15468   if (0 == eid_set)
15469     {
15470       errmsg ("EID address not set!");
15471       vec_free (locator_set_name);
15472       return -99;
15473     }
15474
15475   if (key && (0 == key_id))
15476     {
15477       errmsg ("invalid key_id!");
15478       return -99;
15479     }
15480
15481   if (vec_len (key) > 64)
15482     {
15483       errmsg ("key too long");
15484       vec_free (key);
15485       return -99;
15486     }
15487
15488   if (vec_len (locator_set_name) > 64)
15489     {
15490       errmsg ("locator-set name too long");
15491       vec_free (locator_set_name);
15492       return -99;
15493     }
15494   vec_add1 (locator_set_name, 0);
15495
15496   /* Construct the API message */
15497   M (ONE_ADD_DEL_LOCAL_EID, mp);
15498
15499   mp->is_add = is_add;
15500   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15501   mp->eid_type = eid->type;
15502   mp->prefix_len = eid->len;
15503   mp->vni = clib_host_to_net_u32 (vni);
15504   mp->key_id = clib_host_to_net_u16 (key_id);
15505   clib_memcpy (mp->locator_set_name, locator_set_name,
15506                vec_len (locator_set_name));
15507   clib_memcpy (mp->key, key, vec_len (key));
15508
15509   vec_free (locator_set_name);
15510   vec_free (key);
15511
15512   /* send it... */
15513   S (mp);
15514
15515   /* Wait for a reply... */
15516   W (ret);
15517   return ret;
15518 }
15519
15520 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15521
15522 static int
15523 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15524 {
15525   u32 dp_table = 0, vni = 0;;
15526   unformat_input_t *input = vam->input;
15527   vl_api_gpe_add_del_fwd_entry_t *mp;
15528   u8 is_add = 1;
15529   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15530   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15531   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15532   u32 action = ~0, w;
15533   ip4_address_t rmt_rloc4, lcl_rloc4;
15534   ip6_address_t rmt_rloc6, lcl_rloc6;
15535   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15536   int ret;
15537
15538   clib_memset (&rloc, 0, sizeof (rloc));
15539
15540   /* Parse args required to build the message */
15541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15542     {
15543       if (unformat (input, "del"))
15544         is_add = 0;
15545       else if (unformat (input, "add"))
15546         is_add = 1;
15547       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15548         {
15549           rmt_eid_set = 1;
15550         }
15551       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15552         {
15553           lcl_eid_set = 1;
15554         }
15555       else if (unformat (input, "vrf %d", &dp_table))
15556         ;
15557       else if (unformat (input, "bd %d", &dp_table))
15558         ;
15559       else if (unformat (input, "vni %d", &vni))
15560         ;
15561       else if (unformat (input, "w %d", &w))
15562         {
15563           if (!curr_rloc)
15564             {
15565               errmsg ("No RLOC configured for setting priority/weight!");
15566               return -99;
15567             }
15568           curr_rloc->weight = w;
15569         }
15570       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15571                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15572         {
15573           rloc.is_ip4 = 1;
15574
15575           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15576           rloc.weight = 0;
15577           vec_add1 (lcl_locs, rloc);
15578
15579           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15580           vec_add1 (rmt_locs, rloc);
15581           /* weight saved in rmt loc */
15582           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15583         }
15584       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15585                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15586         {
15587           rloc.is_ip4 = 0;
15588           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15589           rloc.weight = 0;
15590           vec_add1 (lcl_locs, rloc);
15591
15592           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15593           vec_add1 (rmt_locs, rloc);
15594           /* weight saved in rmt loc */
15595           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15596         }
15597       else if (unformat (input, "action %d", &action))
15598         {
15599           ;
15600         }
15601       else
15602         {
15603           clib_warning ("parse error '%U'", format_unformat_error, input);
15604           return -99;
15605         }
15606     }
15607
15608   if (!rmt_eid_set)
15609     {
15610       errmsg ("remote eid addresses not set");
15611       return -99;
15612     }
15613
15614   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15615     {
15616       errmsg ("eid types don't match");
15617       return -99;
15618     }
15619
15620   if (0 == rmt_locs && (u32) ~ 0 == action)
15621     {
15622       errmsg ("action not set for negative mapping");
15623       return -99;
15624     }
15625
15626   /* Construct the API message */
15627   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15628       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15629
15630   mp->is_add = is_add;
15631   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15632   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15633   mp->eid_type = rmt_eid->type;
15634   mp->dp_table = clib_host_to_net_u32 (dp_table);
15635   mp->vni = clib_host_to_net_u32 (vni);
15636   mp->rmt_len = rmt_eid->len;
15637   mp->lcl_len = lcl_eid->len;
15638   mp->action = action;
15639
15640   if (0 != rmt_locs && 0 != lcl_locs)
15641     {
15642       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15643       clib_memcpy (mp->locs, lcl_locs,
15644                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15645
15646       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15647       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15648                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15649     }
15650   vec_free (lcl_locs);
15651   vec_free (rmt_locs);
15652
15653   /* send it... */
15654   S (mp);
15655
15656   /* Wait for a reply... */
15657   W (ret);
15658   return ret;
15659 }
15660
15661 static int
15662 api_one_add_del_map_server (vat_main_t * vam)
15663 {
15664   unformat_input_t *input = vam->input;
15665   vl_api_one_add_del_map_server_t *mp;
15666   u8 is_add = 1;
15667   u8 ipv4_set = 0;
15668   u8 ipv6_set = 0;
15669   ip4_address_t ipv4;
15670   ip6_address_t ipv6;
15671   int ret;
15672
15673   /* Parse args required to build the message */
15674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15675     {
15676       if (unformat (input, "del"))
15677         {
15678           is_add = 0;
15679         }
15680       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15681         {
15682           ipv4_set = 1;
15683         }
15684       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15685         {
15686           ipv6_set = 1;
15687         }
15688       else
15689         break;
15690     }
15691
15692   if (ipv4_set && ipv6_set)
15693     {
15694       errmsg ("both eid v4 and v6 addresses set");
15695       return -99;
15696     }
15697
15698   if (!ipv4_set && !ipv6_set)
15699     {
15700       errmsg ("eid addresses not set");
15701       return -99;
15702     }
15703
15704   /* Construct the API message */
15705   M (ONE_ADD_DEL_MAP_SERVER, mp);
15706
15707   mp->is_add = is_add;
15708   if (ipv6_set)
15709     {
15710       mp->is_ipv6 = 1;
15711       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15712     }
15713   else
15714     {
15715       mp->is_ipv6 = 0;
15716       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15717     }
15718
15719   /* send it... */
15720   S (mp);
15721
15722   /* Wait for a reply... */
15723   W (ret);
15724   return ret;
15725 }
15726
15727 #define api_lisp_add_del_map_server api_one_add_del_map_server
15728
15729 static int
15730 api_one_add_del_map_resolver (vat_main_t * vam)
15731 {
15732   unformat_input_t *input = vam->input;
15733   vl_api_one_add_del_map_resolver_t *mp;
15734   u8 is_add = 1;
15735   u8 ipv4_set = 0;
15736   u8 ipv6_set = 0;
15737   ip4_address_t ipv4;
15738   ip6_address_t ipv6;
15739   int ret;
15740
15741   /* Parse args required to build the message */
15742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15743     {
15744       if (unformat (input, "del"))
15745         {
15746           is_add = 0;
15747         }
15748       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15749         {
15750           ipv4_set = 1;
15751         }
15752       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15753         {
15754           ipv6_set = 1;
15755         }
15756       else
15757         break;
15758     }
15759
15760   if (ipv4_set && ipv6_set)
15761     {
15762       errmsg ("both eid v4 and v6 addresses set");
15763       return -99;
15764     }
15765
15766   if (!ipv4_set && !ipv6_set)
15767     {
15768       errmsg ("eid addresses not set");
15769       return -99;
15770     }
15771
15772   /* Construct the API message */
15773   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15774
15775   mp->is_add = is_add;
15776   if (ipv6_set)
15777     {
15778       mp->is_ipv6 = 1;
15779       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15780     }
15781   else
15782     {
15783       mp->is_ipv6 = 0;
15784       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15785     }
15786
15787   /* send it... */
15788   S (mp);
15789
15790   /* Wait for a reply... */
15791   W (ret);
15792   return ret;
15793 }
15794
15795 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15796
15797 static int
15798 api_lisp_gpe_enable_disable (vat_main_t * vam)
15799 {
15800   unformat_input_t *input = vam->input;
15801   vl_api_gpe_enable_disable_t *mp;
15802   u8 is_set = 0;
15803   u8 is_en = 1;
15804   int ret;
15805
15806   /* Parse args required to build the message */
15807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15808     {
15809       if (unformat (input, "enable"))
15810         {
15811           is_set = 1;
15812           is_en = 1;
15813         }
15814       else if (unformat (input, "disable"))
15815         {
15816           is_set = 1;
15817           is_en = 0;
15818         }
15819       else
15820         break;
15821     }
15822
15823   if (is_set == 0)
15824     {
15825       errmsg ("Value not set");
15826       return -99;
15827     }
15828
15829   /* Construct the API message */
15830   M (GPE_ENABLE_DISABLE, mp);
15831
15832   mp->is_en = is_en;
15833
15834   /* send it... */
15835   S (mp);
15836
15837   /* Wait for a reply... */
15838   W (ret);
15839   return ret;
15840 }
15841
15842 static int
15843 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15844 {
15845   unformat_input_t *input = vam->input;
15846   vl_api_one_rloc_probe_enable_disable_t *mp;
15847   u8 is_set = 0;
15848   u8 is_en = 0;
15849   int ret;
15850
15851   /* Parse args required to build the message */
15852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15853     {
15854       if (unformat (input, "enable"))
15855         {
15856           is_set = 1;
15857           is_en = 1;
15858         }
15859       else if (unformat (input, "disable"))
15860         is_set = 1;
15861       else
15862         break;
15863     }
15864
15865   if (!is_set)
15866     {
15867       errmsg ("Value not set");
15868       return -99;
15869     }
15870
15871   /* Construct the API message */
15872   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15873
15874   mp->is_enabled = is_en;
15875
15876   /* send it... */
15877   S (mp);
15878
15879   /* Wait for a reply... */
15880   W (ret);
15881   return ret;
15882 }
15883
15884 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15885
15886 static int
15887 api_one_map_register_enable_disable (vat_main_t * vam)
15888 {
15889   unformat_input_t *input = vam->input;
15890   vl_api_one_map_register_enable_disable_t *mp;
15891   u8 is_set = 0;
15892   u8 is_en = 0;
15893   int ret;
15894
15895   /* Parse args required to build the message */
15896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15897     {
15898       if (unformat (input, "enable"))
15899         {
15900           is_set = 1;
15901           is_en = 1;
15902         }
15903       else if (unformat (input, "disable"))
15904         is_set = 1;
15905       else
15906         break;
15907     }
15908
15909   if (!is_set)
15910     {
15911       errmsg ("Value not set");
15912       return -99;
15913     }
15914
15915   /* Construct the API message */
15916   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15917
15918   mp->is_enabled = is_en;
15919
15920   /* send it... */
15921   S (mp);
15922
15923   /* Wait for a reply... */
15924   W (ret);
15925   return ret;
15926 }
15927
15928 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15929
15930 static int
15931 api_one_enable_disable (vat_main_t * vam)
15932 {
15933   unformat_input_t *input = vam->input;
15934   vl_api_one_enable_disable_t *mp;
15935   u8 is_set = 0;
15936   u8 is_en = 0;
15937   int ret;
15938
15939   /* Parse args required to build the message */
15940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15941     {
15942       if (unformat (input, "enable"))
15943         {
15944           is_set = 1;
15945           is_en = 1;
15946         }
15947       else if (unformat (input, "disable"))
15948         {
15949           is_set = 1;
15950         }
15951       else
15952         break;
15953     }
15954
15955   if (!is_set)
15956     {
15957       errmsg ("Value not set");
15958       return -99;
15959     }
15960
15961   /* Construct the API message */
15962   M (ONE_ENABLE_DISABLE, mp);
15963
15964   mp->is_en = is_en;
15965
15966   /* send it... */
15967   S (mp);
15968
15969   /* Wait for a reply... */
15970   W (ret);
15971   return ret;
15972 }
15973
15974 #define api_lisp_enable_disable api_one_enable_disable
15975
15976 static int
15977 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15978 {
15979   unformat_input_t *input = vam->input;
15980   vl_api_one_enable_disable_xtr_mode_t *mp;
15981   u8 is_set = 0;
15982   u8 is_en = 0;
15983   int ret;
15984
15985   /* Parse args required to build the message */
15986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15987     {
15988       if (unformat (input, "enable"))
15989         {
15990           is_set = 1;
15991           is_en = 1;
15992         }
15993       else if (unformat (input, "disable"))
15994         {
15995           is_set = 1;
15996         }
15997       else
15998         break;
15999     }
16000
16001   if (!is_set)
16002     {
16003       errmsg ("Value not set");
16004       return -99;
16005     }
16006
16007   /* Construct the API message */
16008   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16009
16010   mp->is_en = is_en;
16011
16012   /* send it... */
16013   S (mp);
16014
16015   /* Wait for a reply... */
16016   W (ret);
16017   return ret;
16018 }
16019
16020 static int
16021 api_one_show_xtr_mode (vat_main_t * vam)
16022 {
16023   vl_api_one_show_xtr_mode_t *mp;
16024   int ret;
16025
16026   /* Construct the API message */
16027   M (ONE_SHOW_XTR_MODE, mp);
16028
16029   /* send it... */
16030   S (mp);
16031
16032   /* Wait for a reply... */
16033   W (ret);
16034   return ret;
16035 }
16036
16037 static int
16038 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16039 {
16040   unformat_input_t *input = vam->input;
16041   vl_api_one_enable_disable_pitr_mode_t *mp;
16042   u8 is_set = 0;
16043   u8 is_en = 0;
16044   int ret;
16045
16046   /* Parse args required to build the message */
16047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16048     {
16049       if (unformat (input, "enable"))
16050         {
16051           is_set = 1;
16052           is_en = 1;
16053         }
16054       else if (unformat (input, "disable"))
16055         {
16056           is_set = 1;
16057         }
16058       else
16059         break;
16060     }
16061
16062   if (!is_set)
16063     {
16064       errmsg ("Value not set");
16065       return -99;
16066     }
16067
16068   /* Construct the API message */
16069   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16070
16071   mp->is_en = is_en;
16072
16073   /* send it... */
16074   S (mp);
16075
16076   /* Wait for a reply... */
16077   W (ret);
16078   return ret;
16079 }
16080
16081 static int
16082 api_one_show_pitr_mode (vat_main_t * vam)
16083 {
16084   vl_api_one_show_pitr_mode_t *mp;
16085   int ret;
16086
16087   /* Construct the API message */
16088   M (ONE_SHOW_PITR_MODE, mp);
16089
16090   /* send it... */
16091   S (mp);
16092
16093   /* Wait for a reply... */
16094   W (ret);
16095   return ret;
16096 }
16097
16098 static int
16099 api_one_enable_disable_petr_mode (vat_main_t * vam)
16100 {
16101   unformat_input_t *input = vam->input;
16102   vl_api_one_enable_disable_petr_mode_t *mp;
16103   u8 is_set = 0;
16104   u8 is_en = 0;
16105   int ret;
16106
16107   /* Parse args required to build the message */
16108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16109     {
16110       if (unformat (input, "enable"))
16111         {
16112           is_set = 1;
16113           is_en = 1;
16114         }
16115       else if (unformat (input, "disable"))
16116         {
16117           is_set = 1;
16118         }
16119       else
16120         break;
16121     }
16122
16123   if (!is_set)
16124     {
16125       errmsg ("Value not set");
16126       return -99;
16127     }
16128
16129   /* Construct the API message */
16130   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16131
16132   mp->is_en = is_en;
16133
16134   /* send it... */
16135   S (mp);
16136
16137   /* Wait for a reply... */
16138   W (ret);
16139   return ret;
16140 }
16141
16142 static int
16143 api_one_show_petr_mode (vat_main_t * vam)
16144 {
16145   vl_api_one_show_petr_mode_t *mp;
16146   int ret;
16147
16148   /* Construct the API message */
16149   M (ONE_SHOW_PETR_MODE, mp);
16150
16151   /* send it... */
16152   S (mp);
16153
16154   /* Wait for a reply... */
16155   W (ret);
16156   return ret;
16157 }
16158
16159 static int
16160 api_show_one_map_register_state (vat_main_t * vam)
16161 {
16162   vl_api_show_one_map_register_state_t *mp;
16163   int ret;
16164
16165   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16166
16167   /* send */
16168   S (mp);
16169
16170   /* wait for reply */
16171   W (ret);
16172   return ret;
16173 }
16174
16175 #define api_show_lisp_map_register_state api_show_one_map_register_state
16176
16177 static int
16178 api_show_one_rloc_probe_state (vat_main_t * vam)
16179 {
16180   vl_api_show_one_rloc_probe_state_t *mp;
16181   int ret;
16182
16183   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16184
16185   /* send */
16186   S (mp);
16187
16188   /* wait for reply */
16189   W (ret);
16190   return ret;
16191 }
16192
16193 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16194
16195 static int
16196 api_one_add_del_ndp_entry (vat_main_t * vam)
16197 {
16198   vl_api_one_add_del_ndp_entry_t *mp;
16199   unformat_input_t *input = vam->input;
16200   u8 is_add = 1;
16201   u8 mac_set = 0;
16202   u8 bd_set = 0;
16203   u8 ip_set = 0;
16204   u8 mac[6] = { 0, };
16205   u8 ip6[16] = { 0, };
16206   u32 bd = ~0;
16207   int ret;
16208
16209   /* Parse args required to build the message */
16210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16211     {
16212       if (unformat (input, "del"))
16213         is_add = 0;
16214       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16215         mac_set = 1;
16216       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16217         ip_set = 1;
16218       else if (unformat (input, "bd %d", &bd))
16219         bd_set = 1;
16220       else
16221         {
16222           errmsg ("parse error '%U'", format_unformat_error, input);
16223           return -99;
16224         }
16225     }
16226
16227   if (!bd_set || !ip_set || (!mac_set && is_add))
16228     {
16229       errmsg ("Missing BD, IP or MAC!");
16230       return -99;
16231     }
16232
16233   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16234   mp->is_add = is_add;
16235   clib_memcpy (mp->mac, mac, 6);
16236   mp->bd = clib_host_to_net_u32 (bd);
16237   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16238
16239   /* send */
16240   S (mp);
16241
16242   /* wait for reply */
16243   W (ret);
16244   return ret;
16245 }
16246
16247 static int
16248 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16249 {
16250   vl_api_one_add_del_l2_arp_entry_t *mp;
16251   unformat_input_t *input = vam->input;
16252   u8 is_add = 1;
16253   u8 mac_set = 0;
16254   u8 bd_set = 0;
16255   u8 ip_set = 0;
16256   u8 mac[6] = { 0, };
16257   u32 ip4 = 0, bd = ~0;
16258   int ret;
16259
16260   /* Parse args required to build the message */
16261   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16262     {
16263       if (unformat (input, "del"))
16264         is_add = 0;
16265       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16266         mac_set = 1;
16267       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16268         ip_set = 1;
16269       else if (unformat (input, "bd %d", &bd))
16270         bd_set = 1;
16271       else
16272         {
16273           errmsg ("parse error '%U'", format_unformat_error, input);
16274           return -99;
16275         }
16276     }
16277
16278   if (!bd_set || !ip_set || (!mac_set && is_add))
16279     {
16280       errmsg ("Missing BD, IP or MAC!");
16281       return -99;
16282     }
16283
16284   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16285   mp->is_add = is_add;
16286   clib_memcpy (mp->mac, mac, 6);
16287   mp->bd = clib_host_to_net_u32 (bd);
16288   mp->ip4 = ip4;
16289
16290   /* send */
16291   S (mp);
16292
16293   /* wait for reply */
16294   W (ret);
16295   return ret;
16296 }
16297
16298 static int
16299 api_one_ndp_bd_get (vat_main_t * vam)
16300 {
16301   vl_api_one_ndp_bd_get_t *mp;
16302   int ret;
16303
16304   M (ONE_NDP_BD_GET, mp);
16305
16306   /* send */
16307   S (mp);
16308
16309   /* wait for reply */
16310   W (ret);
16311   return ret;
16312 }
16313
16314 static int
16315 api_one_ndp_entries_get (vat_main_t * vam)
16316 {
16317   vl_api_one_ndp_entries_get_t *mp;
16318   unformat_input_t *input = vam->input;
16319   u8 bd_set = 0;
16320   u32 bd = ~0;
16321   int ret;
16322
16323   /* Parse args required to build the message */
16324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16325     {
16326       if (unformat (input, "bd %d", &bd))
16327         bd_set = 1;
16328       else
16329         {
16330           errmsg ("parse error '%U'", format_unformat_error, input);
16331           return -99;
16332         }
16333     }
16334
16335   if (!bd_set)
16336     {
16337       errmsg ("Expected bridge domain!");
16338       return -99;
16339     }
16340
16341   M (ONE_NDP_ENTRIES_GET, mp);
16342   mp->bd = clib_host_to_net_u32 (bd);
16343
16344   /* send */
16345   S (mp);
16346
16347   /* wait for reply */
16348   W (ret);
16349   return ret;
16350 }
16351
16352 static int
16353 api_one_l2_arp_bd_get (vat_main_t * vam)
16354 {
16355   vl_api_one_l2_arp_bd_get_t *mp;
16356   int ret;
16357
16358   M (ONE_L2_ARP_BD_GET, mp);
16359
16360   /* send */
16361   S (mp);
16362
16363   /* wait for reply */
16364   W (ret);
16365   return ret;
16366 }
16367
16368 static int
16369 api_one_l2_arp_entries_get (vat_main_t * vam)
16370 {
16371   vl_api_one_l2_arp_entries_get_t *mp;
16372   unformat_input_t *input = vam->input;
16373   u8 bd_set = 0;
16374   u32 bd = ~0;
16375   int ret;
16376
16377   /* Parse args required to build the message */
16378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16379     {
16380       if (unformat (input, "bd %d", &bd))
16381         bd_set = 1;
16382       else
16383         {
16384           errmsg ("parse error '%U'", format_unformat_error, input);
16385           return -99;
16386         }
16387     }
16388
16389   if (!bd_set)
16390     {
16391       errmsg ("Expected bridge domain!");
16392       return -99;
16393     }
16394
16395   M (ONE_L2_ARP_ENTRIES_GET, mp);
16396   mp->bd = clib_host_to_net_u32 (bd);
16397
16398   /* send */
16399   S (mp);
16400
16401   /* wait for reply */
16402   W (ret);
16403   return ret;
16404 }
16405
16406 static int
16407 api_one_stats_enable_disable (vat_main_t * vam)
16408 {
16409   vl_api_one_stats_enable_disable_t *mp;
16410   unformat_input_t *input = vam->input;
16411   u8 is_set = 0;
16412   u8 is_en = 0;
16413   int ret;
16414
16415   /* Parse args required to build the message */
16416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16417     {
16418       if (unformat (input, "enable"))
16419         {
16420           is_set = 1;
16421           is_en = 1;
16422         }
16423       else if (unformat (input, "disable"))
16424         {
16425           is_set = 1;
16426         }
16427       else
16428         break;
16429     }
16430
16431   if (!is_set)
16432     {
16433       errmsg ("Value not set");
16434       return -99;
16435     }
16436
16437   M (ONE_STATS_ENABLE_DISABLE, mp);
16438   mp->is_en = is_en;
16439
16440   /* send */
16441   S (mp);
16442
16443   /* wait for reply */
16444   W (ret);
16445   return ret;
16446 }
16447
16448 static int
16449 api_show_one_stats_enable_disable (vat_main_t * vam)
16450 {
16451   vl_api_show_one_stats_enable_disable_t *mp;
16452   int ret;
16453
16454   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16455
16456   /* send */
16457   S (mp);
16458
16459   /* wait for reply */
16460   W (ret);
16461   return ret;
16462 }
16463
16464 static int
16465 api_show_one_map_request_mode (vat_main_t * vam)
16466 {
16467   vl_api_show_one_map_request_mode_t *mp;
16468   int ret;
16469
16470   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16471
16472   /* send */
16473   S (mp);
16474
16475   /* wait for reply */
16476   W (ret);
16477   return ret;
16478 }
16479
16480 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16481
16482 static int
16483 api_one_map_request_mode (vat_main_t * vam)
16484 {
16485   unformat_input_t *input = vam->input;
16486   vl_api_one_map_request_mode_t *mp;
16487   u8 mode = 0;
16488   int ret;
16489
16490   /* Parse args required to build the message */
16491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16492     {
16493       if (unformat (input, "dst-only"))
16494         mode = 0;
16495       else if (unformat (input, "src-dst"))
16496         mode = 1;
16497       else
16498         {
16499           errmsg ("parse error '%U'", format_unformat_error, input);
16500           return -99;
16501         }
16502     }
16503
16504   M (ONE_MAP_REQUEST_MODE, mp);
16505
16506   mp->mode = mode;
16507
16508   /* send */
16509   S (mp);
16510
16511   /* wait for reply */
16512   W (ret);
16513   return ret;
16514 }
16515
16516 #define api_lisp_map_request_mode api_one_map_request_mode
16517
16518 /**
16519  * Enable/disable ONE proxy ITR.
16520  *
16521  * @param vam vpp API test context
16522  * @return return code
16523  */
16524 static int
16525 api_one_pitr_set_locator_set (vat_main_t * vam)
16526 {
16527   u8 ls_name_set = 0;
16528   unformat_input_t *input = vam->input;
16529   vl_api_one_pitr_set_locator_set_t *mp;
16530   u8 is_add = 1;
16531   u8 *ls_name = 0;
16532   int ret;
16533
16534   /* Parse args required to build the message */
16535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16536     {
16537       if (unformat (input, "del"))
16538         is_add = 0;
16539       else if (unformat (input, "locator-set %s", &ls_name))
16540         ls_name_set = 1;
16541       else
16542         {
16543           errmsg ("parse error '%U'", format_unformat_error, input);
16544           return -99;
16545         }
16546     }
16547
16548   if (!ls_name_set)
16549     {
16550       errmsg ("locator-set name not set!");
16551       return -99;
16552     }
16553
16554   M (ONE_PITR_SET_LOCATOR_SET, mp);
16555
16556   mp->is_add = is_add;
16557   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16558   vec_free (ls_name);
16559
16560   /* send */
16561   S (mp);
16562
16563   /* wait for reply */
16564   W (ret);
16565   return ret;
16566 }
16567
16568 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16569
16570 static int
16571 api_one_nsh_set_locator_set (vat_main_t * vam)
16572 {
16573   u8 ls_name_set = 0;
16574   unformat_input_t *input = vam->input;
16575   vl_api_one_nsh_set_locator_set_t *mp;
16576   u8 is_add = 1;
16577   u8 *ls_name = 0;
16578   int ret;
16579
16580   /* Parse args required to build the message */
16581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16582     {
16583       if (unformat (input, "del"))
16584         is_add = 0;
16585       else if (unformat (input, "ls %s", &ls_name))
16586         ls_name_set = 1;
16587       else
16588         {
16589           errmsg ("parse error '%U'", format_unformat_error, input);
16590           return -99;
16591         }
16592     }
16593
16594   if (!ls_name_set && is_add)
16595     {
16596       errmsg ("locator-set name not set!");
16597       return -99;
16598     }
16599
16600   M (ONE_NSH_SET_LOCATOR_SET, mp);
16601
16602   mp->is_add = is_add;
16603   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16604   vec_free (ls_name);
16605
16606   /* send */
16607   S (mp);
16608
16609   /* wait for reply */
16610   W (ret);
16611   return ret;
16612 }
16613
16614 static int
16615 api_show_one_pitr (vat_main_t * vam)
16616 {
16617   vl_api_show_one_pitr_t *mp;
16618   int ret;
16619
16620   if (!vam->json_output)
16621     {
16622       print (vam->ofp, "%=20s", "lisp status:");
16623     }
16624
16625   M (SHOW_ONE_PITR, mp);
16626   /* send it... */
16627   S (mp);
16628
16629   /* Wait for a reply... */
16630   W (ret);
16631   return ret;
16632 }
16633
16634 #define api_show_lisp_pitr api_show_one_pitr
16635
16636 static int
16637 api_one_use_petr (vat_main_t * vam)
16638 {
16639   unformat_input_t *input = vam->input;
16640   vl_api_one_use_petr_t *mp;
16641   u8 is_add = 0;
16642   ip_address_t ip;
16643   int ret;
16644
16645   clib_memset (&ip, 0, sizeof (ip));
16646
16647   /* Parse args required to build the message */
16648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16649     {
16650       if (unformat (input, "disable"))
16651         is_add = 0;
16652       else
16653         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16654         {
16655           is_add = 1;
16656           ip_addr_version (&ip) = IP4;
16657         }
16658       else
16659         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16660         {
16661           is_add = 1;
16662           ip_addr_version (&ip) = IP6;
16663         }
16664       else
16665         {
16666           errmsg ("parse error '%U'", format_unformat_error, input);
16667           return -99;
16668         }
16669     }
16670
16671   M (ONE_USE_PETR, mp);
16672
16673   mp->is_add = is_add;
16674   if (is_add)
16675     {
16676       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16677       if (mp->is_ip4)
16678         clib_memcpy (mp->address, &ip, 4);
16679       else
16680         clib_memcpy (mp->address, &ip, 16);
16681     }
16682
16683   /* send */
16684   S (mp);
16685
16686   /* wait for reply */
16687   W (ret);
16688   return ret;
16689 }
16690
16691 #define api_lisp_use_petr api_one_use_petr
16692
16693 static int
16694 api_show_one_nsh_mapping (vat_main_t * vam)
16695 {
16696   vl_api_show_one_use_petr_t *mp;
16697   int ret;
16698
16699   if (!vam->json_output)
16700     {
16701       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16702     }
16703
16704   M (SHOW_ONE_NSH_MAPPING, mp);
16705   /* send it... */
16706   S (mp);
16707
16708   /* Wait for a reply... */
16709   W (ret);
16710   return ret;
16711 }
16712
16713 static int
16714 api_show_one_use_petr (vat_main_t * vam)
16715 {
16716   vl_api_show_one_use_petr_t *mp;
16717   int ret;
16718
16719   if (!vam->json_output)
16720     {
16721       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16722     }
16723
16724   M (SHOW_ONE_USE_PETR, mp);
16725   /* send it... */
16726   S (mp);
16727
16728   /* Wait for a reply... */
16729   W (ret);
16730   return ret;
16731 }
16732
16733 #define api_show_lisp_use_petr api_show_one_use_petr
16734
16735 /**
16736  * Add/delete mapping between vni and vrf
16737  */
16738 static int
16739 api_one_eid_table_add_del_map (vat_main_t * vam)
16740 {
16741   unformat_input_t *input = vam->input;
16742   vl_api_one_eid_table_add_del_map_t *mp;
16743   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16744   u32 vni, vrf, bd_index;
16745   int ret;
16746
16747   /* Parse args required to build the message */
16748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16749     {
16750       if (unformat (input, "del"))
16751         is_add = 0;
16752       else if (unformat (input, "vrf %d", &vrf))
16753         vrf_set = 1;
16754       else if (unformat (input, "bd_index %d", &bd_index))
16755         bd_index_set = 1;
16756       else if (unformat (input, "vni %d", &vni))
16757         vni_set = 1;
16758       else
16759         break;
16760     }
16761
16762   if (!vni_set || (!vrf_set && !bd_index_set))
16763     {
16764       errmsg ("missing arguments!");
16765       return -99;
16766     }
16767
16768   if (vrf_set && bd_index_set)
16769     {
16770       errmsg ("error: both vrf and bd entered!");
16771       return -99;
16772     }
16773
16774   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16775
16776   mp->is_add = is_add;
16777   mp->vni = htonl (vni);
16778   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16779   mp->is_l2 = bd_index_set;
16780
16781   /* send */
16782   S (mp);
16783
16784   /* wait for reply */
16785   W (ret);
16786   return ret;
16787 }
16788
16789 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16790
16791 uword
16792 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16793 {
16794   u32 *action = va_arg (*args, u32 *);
16795   u8 *s = 0;
16796
16797   if (unformat (input, "%s", &s))
16798     {
16799       if (!strcmp ((char *) s, "no-action"))
16800         action[0] = 0;
16801       else if (!strcmp ((char *) s, "natively-forward"))
16802         action[0] = 1;
16803       else if (!strcmp ((char *) s, "send-map-request"))
16804         action[0] = 2;
16805       else if (!strcmp ((char *) s, "drop"))
16806         action[0] = 3;
16807       else
16808         {
16809           clib_warning ("invalid action: '%s'", s);
16810           action[0] = 3;
16811         }
16812     }
16813   else
16814     return 0;
16815
16816   vec_free (s);
16817   return 1;
16818 }
16819
16820 /**
16821  * Add/del remote mapping to/from ONE control plane
16822  *
16823  * @param vam vpp API test context
16824  * @return return code
16825  */
16826 static int
16827 api_one_add_del_remote_mapping (vat_main_t * vam)
16828 {
16829   unformat_input_t *input = vam->input;
16830   vl_api_one_add_del_remote_mapping_t *mp;
16831   u32 vni = 0;
16832   lisp_eid_vat_t _eid, *eid = &_eid;
16833   lisp_eid_vat_t _seid, *seid = &_seid;
16834   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16835   u32 action = ~0, p, w, data_len;
16836   ip4_address_t rloc4;
16837   ip6_address_t rloc6;
16838   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16839   int ret;
16840
16841   clib_memset (&rloc, 0, sizeof (rloc));
16842
16843   /* Parse args required to build the message */
16844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16845     {
16846       if (unformat (input, "del-all"))
16847         {
16848           del_all = 1;
16849         }
16850       else if (unformat (input, "del"))
16851         {
16852           is_add = 0;
16853         }
16854       else if (unformat (input, "add"))
16855         {
16856           is_add = 1;
16857         }
16858       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16859         {
16860           eid_set = 1;
16861         }
16862       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16863         {
16864           seid_set = 1;
16865         }
16866       else if (unformat (input, "vni %d", &vni))
16867         {
16868           ;
16869         }
16870       else if (unformat (input, "p %d w %d", &p, &w))
16871         {
16872           if (!curr_rloc)
16873             {
16874               errmsg ("No RLOC configured for setting priority/weight!");
16875               return -99;
16876             }
16877           curr_rloc->priority = p;
16878           curr_rloc->weight = w;
16879         }
16880       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16881         {
16882           rloc.is_ip4 = 1;
16883           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16884           vec_add1 (rlocs, rloc);
16885           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16886         }
16887       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16888         {
16889           rloc.is_ip4 = 0;
16890           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16891           vec_add1 (rlocs, rloc);
16892           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16893         }
16894       else if (unformat (input, "action %U",
16895                          unformat_negative_mapping_action, &action))
16896         {
16897           ;
16898         }
16899       else
16900         {
16901           clib_warning ("parse error '%U'", format_unformat_error, input);
16902           return -99;
16903         }
16904     }
16905
16906   if (0 == eid_set)
16907     {
16908       errmsg ("missing params!");
16909       return -99;
16910     }
16911
16912   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16913     {
16914       errmsg ("no action set for negative map-reply!");
16915       return -99;
16916     }
16917
16918   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16919
16920   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16921   mp->is_add = is_add;
16922   mp->vni = htonl (vni);
16923   mp->action = (u8) action;
16924   mp->is_src_dst = seid_set;
16925   mp->eid_len = eid->len;
16926   mp->seid_len = seid->len;
16927   mp->del_all = del_all;
16928   mp->eid_type = eid->type;
16929   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16930   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16931
16932   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16933   clib_memcpy (mp->rlocs, rlocs, data_len);
16934   vec_free (rlocs);
16935
16936   /* send it... */
16937   S (mp);
16938
16939   /* Wait for a reply... */
16940   W (ret);
16941   return ret;
16942 }
16943
16944 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16945
16946 /**
16947  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16948  * forwarding entries in data-plane accordingly.
16949  *
16950  * @param vam vpp API test context
16951  * @return return code
16952  */
16953 static int
16954 api_one_add_del_adjacency (vat_main_t * vam)
16955 {
16956   unformat_input_t *input = vam->input;
16957   vl_api_one_add_del_adjacency_t *mp;
16958   u32 vni = 0;
16959   ip4_address_t leid4, reid4;
16960   ip6_address_t leid6, reid6;
16961   u8 reid_mac[6] = { 0 };
16962   u8 leid_mac[6] = { 0 };
16963   u8 reid_type, leid_type;
16964   u32 leid_len = 0, reid_len = 0, len;
16965   u8 is_add = 1;
16966   int ret;
16967
16968   leid_type = reid_type = (u8) ~ 0;
16969
16970   /* Parse args required to build the message */
16971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16972     {
16973       if (unformat (input, "del"))
16974         {
16975           is_add = 0;
16976         }
16977       else if (unformat (input, "add"))
16978         {
16979           is_add = 1;
16980         }
16981       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16982                          &reid4, &len))
16983         {
16984           reid_type = 0;        /* ipv4 */
16985           reid_len = len;
16986         }
16987       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16988                          &reid6, &len))
16989         {
16990           reid_type = 1;        /* ipv6 */
16991           reid_len = len;
16992         }
16993       else if (unformat (input, "reid %U", unformat_ethernet_address,
16994                          reid_mac))
16995         {
16996           reid_type = 2;        /* mac */
16997         }
16998       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16999                          &leid4, &len))
17000         {
17001           leid_type = 0;        /* ipv4 */
17002           leid_len = len;
17003         }
17004       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17005                          &leid6, &len))
17006         {
17007           leid_type = 1;        /* ipv6 */
17008           leid_len = len;
17009         }
17010       else if (unformat (input, "leid %U", unformat_ethernet_address,
17011                          leid_mac))
17012         {
17013           leid_type = 2;        /* mac */
17014         }
17015       else if (unformat (input, "vni %d", &vni))
17016         {
17017           ;
17018         }
17019       else
17020         {
17021           errmsg ("parse error '%U'", format_unformat_error, input);
17022           return -99;
17023         }
17024     }
17025
17026   if ((u8) ~ 0 == reid_type)
17027     {
17028       errmsg ("missing params!");
17029       return -99;
17030     }
17031
17032   if (leid_type != reid_type)
17033     {
17034       errmsg ("remote and local EIDs are of different types!");
17035       return -99;
17036     }
17037
17038   M (ONE_ADD_DEL_ADJACENCY, mp);
17039   mp->is_add = is_add;
17040   mp->vni = htonl (vni);
17041   mp->leid_len = leid_len;
17042   mp->reid_len = reid_len;
17043   mp->eid_type = reid_type;
17044
17045   switch (mp->eid_type)
17046     {
17047     case 0:
17048       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17049       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17050       break;
17051     case 1:
17052       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17053       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17054       break;
17055     case 2:
17056       clib_memcpy (mp->leid, leid_mac, 6);
17057       clib_memcpy (mp->reid, reid_mac, 6);
17058       break;
17059     default:
17060       errmsg ("unknown EID type %d!", mp->eid_type);
17061       return 0;
17062     }
17063
17064   /* send it... */
17065   S (mp);
17066
17067   /* Wait for a reply... */
17068   W (ret);
17069   return ret;
17070 }
17071
17072 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17073
17074 uword
17075 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17076 {
17077   u32 *mode = va_arg (*args, u32 *);
17078
17079   if (unformat (input, "lisp"))
17080     *mode = 0;
17081   else if (unformat (input, "vxlan"))
17082     *mode = 1;
17083   else
17084     return 0;
17085
17086   return 1;
17087 }
17088
17089 static int
17090 api_gpe_get_encap_mode (vat_main_t * vam)
17091 {
17092   vl_api_gpe_get_encap_mode_t *mp;
17093   int ret;
17094
17095   /* Construct the API message */
17096   M (GPE_GET_ENCAP_MODE, mp);
17097
17098   /* send it... */
17099   S (mp);
17100
17101   /* Wait for a reply... */
17102   W (ret);
17103   return ret;
17104 }
17105
17106 static int
17107 api_gpe_set_encap_mode (vat_main_t * vam)
17108 {
17109   unformat_input_t *input = vam->input;
17110   vl_api_gpe_set_encap_mode_t *mp;
17111   int ret;
17112   u32 mode = 0;
17113
17114   /* Parse args required to build the message */
17115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17116     {
17117       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17118         ;
17119       else
17120         break;
17121     }
17122
17123   /* Construct the API message */
17124   M (GPE_SET_ENCAP_MODE, mp);
17125
17126   mp->mode = mode;
17127
17128   /* send it... */
17129   S (mp);
17130
17131   /* Wait for a reply... */
17132   W (ret);
17133   return ret;
17134 }
17135
17136 static int
17137 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17138 {
17139   unformat_input_t *input = vam->input;
17140   vl_api_gpe_add_del_iface_t *mp;
17141   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17142   u32 dp_table = 0, vni = 0;
17143   int ret;
17144
17145   /* Parse args required to build the message */
17146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17147     {
17148       if (unformat (input, "up"))
17149         {
17150           action_set = 1;
17151           is_add = 1;
17152         }
17153       else if (unformat (input, "down"))
17154         {
17155           action_set = 1;
17156           is_add = 0;
17157         }
17158       else if (unformat (input, "table_id %d", &dp_table))
17159         {
17160           dp_table_set = 1;
17161         }
17162       else if (unformat (input, "bd_id %d", &dp_table))
17163         {
17164           dp_table_set = 1;
17165           is_l2 = 1;
17166         }
17167       else if (unformat (input, "vni %d", &vni))
17168         {
17169           vni_set = 1;
17170         }
17171       else
17172         break;
17173     }
17174
17175   if (action_set == 0)
17176     {
17177       errmsg ("Action not set");
17178       return -99;
17179     }
17180   if (dp_table_set == 0 || vni_set == 0)
17181     {
17182       errmsg ("vni and dp_table must be set");
17183       return -99;
17184     }
17185
17186   /* Construct the API message */
17187   M (GPE_ADD_DEL_IFACE, mp);
17188
17189   mp->is_add = is_add;
17190   mp->dp_table = clib_host_to_net_u32 (dp_table);
17191   mp->is_l2 = is_l2;
17192   mp->vni = clib_host_to_net_u32 (vni);
17193
17194   /* send it... */
17195   S (mp);
17196
17197   /* Wait for a reply... */
17198   W (ret);
17199   return ret;
17200 }
17201
17202 static int
17203 api_one_map_register_fallback_threshold (vat_main_t * vam)
17204 {
17205   unformat_input_t *input = vam->input;
17206   vl_api_one_map_register_fallback_threshold_t *mp;
17207   u32 value = 0;
17208   u8 is_set = 0;
17209   int ret;
17210
17211   /* Parse args required to build the message */
17212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17213     {
17214       if (unformat (input, "%u", &value))
17215         is_set = 1;
17216       else
17217         {
17218           clib_warning ("parse error '%U'", format_unformat_error, input);
17219           return -99;
17220         }
17221     }
17222
17223   if (!is_set)
17224     {
17225       errmsg ("fallback threshold value is missing!");
17226       return -99;
17227     }
17228
17229   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17230   mp->value = clib_host_to_net_u32 (value);
17231
17232   /* send it... */
17233   S (mp);
17234
17235   /* Wait for a reply... */
17236   W (ret);
17237   return ret;
17238 }
17239
17240 static int
17241 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17242 {
17243   vl_api_show_one_map_register_fallback_threshold_t *mp;
17244   int ret;
17245
17246   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17247
17248   /* send it... */
17249   S (mp);
17250
17251   /* Wait for a reply... */
17252   W (ret);
17253   return ret;
17254 }
17255
17256 uword
17257 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17258 {
17259   u32 *proto = va_arg (*args, u32 *);
17260
17261   if (unformat (input, "udp"))
17262     *proto = 1;
17263   else if (unformat (input, "api"))
17264     *proto = 2;
17265   else
17266     return 0;
17267
17268   return 1;
17269 }
17270
17271 static int
17272 api_one_set_transport_protocol (vat_main_t * vam)
17273 {
17274   unformat_input_t *input = vam->input;
17275   vl_api_one_set_transport_protocol_t *mp;
17276   u8 is_set = 0;
17277   u32 protocol = 0;
17278   int ret;
17279
17280   /* Parse args required to build the message */
17281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17282     {
17283       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17284         is_set = 1;
17285       else
17286         {
17287           clib_warning ("parse error '%U'", format_unformat_error, input);
17288           return -99;
17289         }
17290     }
17291
17292   if (!is_set)
17293     {
17294       errmsg ("Transport protocol missing!");
17295       return -99;
17296     }
17297
17298   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17299   mp->protocol = (u8) protocol;
17300
17301   /* send it... */
17302   S (mp);
17303
17304   /* Wait for a reply... */
17305   W (ret);
17306   return ret;
17307 }
17308
17309 static int
17310 api_one_get_transport_protocol (vat_main_t * vam)
17311 {
17312   vl_api_one_get_transport_protocol_t *mp;
17313   int ret;
17314
17315   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17316
17317   /* send it... */
17318   S (mp);
17319
17320   /* Wait for a reply... */
17321   W (ret);
17322   return ret;
17323 }
17324
17325 static int
17326 api_one_map_register_set_ttl (vat_main_t * vam)
17327 {
17328   unformat_input_t *input = vam->input;
17329   vl_api_one_map_register_set_ttl_t *mp;
17330   u32 ttl = 0;
17331   u8 is_set = 0;
17332   int ret;
17333
17334   /* Parse args required to build the message */
17335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17336     {
17337       if (unformat (input, "%u", &ttl))
17338         is_set = 1;
17339       else
17340         {
17341           clib_warning ("parse error '%U'", format_unformat_error, input);
17342           return -99;
17343         }
17344     }
17345
17346   if (!is_set)
17347     {
17348       errmsg ("TTL value missing!");
17349       return -99;
17350     }
17351
17352   M (ONE_MAP_REGISTER_SET_TTL, mp);
17353   mp->ttl = clib_host_to_net_u32 (ttl);
17354
17355   /* send it... */
17356   S (mp);
17357
17358   /* Wait for a reply... */
17359   W (ret);
17360   return ret;
17361 }
17362
17363 static int
17364 api_show_one_map_register_ttl (vat_main_t * vam)
17365 {
17366   vl_api_show_one_map_register_ttl_t *mp;
17367   int ret;
17368
17369   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17370
17371   /* send it... */
17372   S (mp);
17373
17374   /* Wait for a reply... */
17375   W (ret);
17376   return ret;
17377 }
17378
17379 /**
17380  * Add/del map request itr rlocs from ONE control plane and updates
17381  *
17382  * @param vam vpp API test context
17383  * @return return code
17384  */
17385 static int
17386 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17387 {
17388   unformat_input_t *input = vam->input;
17389   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17390   u8 *locator_set_name = 0;
17391   u8 locator_set_name_set = 0;
17392   u8 is_add = 1;
17393   int ret;
17394
17395   /* Parse args required to build the message */
17396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17397     {
17398       if (unformat (input, "del"))
17399         {
17400           is_add = 0;
17401         }
17402       else if (unformat (input, "%_%v%_", &locator_set_name))
17403         {
17404           locator_set_name_set = 1;
17405         }
17406       else
17407         {
17408           clib_warning ("parse error '%U'", format_unformat_error, input);
17409           return -99;
17410         }
17411     }
17412
17413   if (is_add && !locator_set_name_set)
17414     {
17415       errmsg ("itr-rloc is not set!");
17416       return -99;
17417     }
17418
17419   if (is_add && vec_len (locator_set_name) > 64)
17420     {
17421       errmsg ("itr-rloc locator-set name too long");
17422       vec_free (locator_set_name);
17423       return -99;
17424     }
17425
17426   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17427   mp->is_add = is_add;
17428   if (is_add)
17429     {
17430       clib_memcpy (mp->locator_set_name, locator_set_name,
17431                    vec_len (locator_set_name));
17432     }
17433   else
17434     {
17435       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17436     }
17437   vec_free (locator_set_name);
17438
17439   /* send it... */
17440   S (mp);
17441
17442   /* Wait for a reply... */
17443   W (ret);
17444   return ret;
17445 }
17446
17447 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17448
17449 static int
17450 api_one_locator_dump (vat_main_t * vam)
17451 {
17452   unformat_input_t *input = vam->input;
17453   vl_api_one_locator_dump_t *mp;
17454   vl_api_control_ping_t *mp_ping;
17455   u8 is_index_set = 0, is_name_set = 0;
17456   u8 *ls_name = 0;
17457   u32 ls_index = ~0;
17458   int ret;
17459
17460   /* Parse args required to build the message */
17461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17462     {
17463       if (unformat (input, "ls_name %_%v%_", &ls_name))
17464         {
17465           is_name_set = 1;
17466         }
17467       else if (unformat (input, "ls_index %d", &ls_index))
17468         {
17469           is_index_set = 1;
17470         }
17471       else
17472         {
17473           errmsg ("parse error '%U'", format_unformat_error, input);
17474           return -99;
17475         }
17476     }
17477
17478   if (!is_index_set && !is_name_set)
17479     {
17480       errmsg ("error: expected one of index or name!");
17481       return -99;
17482     }
17483
17484   if (is_index_set && is_name_set)
17485     {
17486       errmsg ("error: only one param expected!");
17487       return -99;
17488     }
17489
17490   if (vec_len (ls_name) > 62)
17491     {
17492       errmsg ("error: locator set name too long!");
17493       return -99;
17494     }
17495
17496   if (!vam->json_output)
17497     {
17498       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17499     }
17500
17501   M (ONE_LOCATOR_DUMP, mp);
17502   mp->is_index_set = is_index_set;
17503
17504   if (is_index_set)
17505     mp->ls_index = clib_host_to_net_u32 (ls_index);
17506   else
17507     {
17508       vec_add1 (ls_name, 0);
17509       strncpy ((char *) mp->ls_name, (char *) ls_name,
17510                sizeof (mp->ls_name) - 1);
17511     }
17512
17513   /* send it... */
17514   S (mp);
17515
17516   /* Use a control ping for synchronization */
17517   MPING (CONTROL_PING, mp_ping);
17518   S (mp_ping);
17519
17520   /* Wait for a reply... */
17521   W (ret);
17522   return ret;
17523 }
17524
17525 #define api_lisp_locator_dump api_one_locator_dump
17526
17527 static int
17528 api_one_locator_set_dump (vat_main_t * vam)
17529 {
17530   vl_api_one_locator_set_dump_t *mp;
17531   vl_api_control_ping_t *mp_ping;
17532   unformat_input_t *input = vam->input;
17533   u8 filter = 0;
17534   int ret;
17535
17536   /* Parse args required to build the message */
17537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17538     {
17539       if (unformat (input, "local"))
17540         {
17541           filter = 1;
17542         }
17543       else if (unformat (input, "remote"))
17544         {
17545           filter = 2;
17546         }
17547       else
17548         {
17549           errmsg ("parse error '%U'", format_unformat_error, input);
17550           return -99;
17551         }
17552     }
17553
17554   if (!vam->json_output)
17555     {
17556       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17557     }
17558
17559   M (ONE_LOCATOR_SET_DUMP, mp);
17560
17561   mp->filter = filter;
17562
17563   /* send it... */
17564   S (mp);
17565
17566   /* Use a control ping for synchronization */
17567   MPING (CONTROL_PING, mp_ping);
17568   S (mp_ping);
17569
17570   /* Wait for a reply... */
17571   W (ret);
17572   return ret;
17573 }
17574
17575 #define api_lisp_locator_set_dump api_one_locator_set_dump
17576
17577 static int
17578 api_one_eid_table_map_dump (vat_main_t * vam)
17579 {
17580   u8 is_l2 = 0;
17581   u8 mode_set = 0;
17582   unformat_input_t *input = vam->input;
17583   vl_api_one_eid_table_map_dump_t *mp;
17584   vl_api_control_ping_t *mp_ping;
17585   int ret;
17586
17587   /* Parse args required to build the message */
17588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17589     {
17590       if (unformat (input, "l2"))
17591         {
17592           is_l2 = 1;
17593           mode_set = 1;
17594         }
17595       else if (unformat (input, "l3"))
17596         {
17597           is_l2 = 0;
17598           mode_set = 1;
17599         }
17600       else
17601         {
17602           errmsg ("parse error '%U'", format_unformat_error, input);
17603           return -99;
17604         }
17605     }
17606
17607   if (!mode_set)
17608     {
17609       errmsg ("expected one of 'l2' or 'l3' parameter!");
17610       return -99;
17611     }
17612
17613   if (!vam->json_output)
17614     {
17615       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17616     }
17617
17618   M (ONE_EID_TABLE_MAP_DUMP, mp);
17619   mp->is_l2 = is_l2;
17620
17621   /* send it... */
17622   S (mp);
17623
17624   /* Use a control ping for synchronization */
17625   MPING (CONTROL_PING, mp_ping);
17626   S (mp_ping);
17627
17628   /* Wait for a reply... */
17629   W (ret);
17630   return ret;
17631 }
17632
17633 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17634
17635 static int
17636 api_one_eid_table_vni_dump (vat_main_t * vam)
17637 {
17638   vl_api_one_eid_table_vni_dump_t *mp;
17639   vl_api_control_ping_t *mp_ping;
17640   int ret;
17641
17642   if (!vam->json_output)
17643     {
17644       print (vam->ofp, "VNI");
17645     }
17646
17647   M (ONE_EID_TABLE_VNI_DUMP, mp);
17648
17649   /* send it... */
17650   S (mp);
17651
17652   /* Use a control ping for synchronization */
17653   MPING (CONTROL_PING, mp_ping);
17654   S (mp_ping);
17655
17656   /* Wait for a reply... */
17657   W (ret);
17658   return ret;
17659 }
17660
17661 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17662
17663 static int
17664 api_one_eid_table_dump (vat_main_t * vam)
17665 {
17666   unformat_input_t *i = vam->input;
17667   vl_api_one_eid_table_dump_t *mp;
17668   vl_api_control_ping_t *mp_ping;
17669   struct in_addr ip4;
17670   struct in6_addr ip6;
17671   u8 mac[6];
17672   u8 eid_type = ~0, eid_set = 0;
17673   u32 prefix_length = ~0, t, vni = 0;
17674   u8 filter = 0;
17675   int ret;
17676   lisp_nsh_api_t nsh;
17677
17678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17679     {
17680       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17681         {
17682           eid_set = 1;
17683           eid_type = 0;
17684           prefix_length = t;
17685         }
17686       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17687         {
17688           eid_set = 1;
17689           eid_type = 1;
17690           prefix_length = t;
17691         }
17692       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17693         {
17694           eid_set = 1;
17695           eid_type = 2;
17696         }
17697       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17698         {
17699           eid_set = 1;
17700           eid_type = 3;
17701         }
17702       else if (unformat (i, "vni %d", &t))
17703         {
17704           vni = t;
17705         }
17706       else if (unformat (i, "local"))
17707         {
17708           filter = 1;
17709         }
17710       else if (unformat (i, "remote"))
17711         {
17712           filter = 2;
17713         }
17714       else
17715         {
17716           errmsg ("parse error '%U'", format_unformat_error, i);
17717           return -99;
17718         }
17719     }
17720
17721   if (!vam->json_output)
17722     {
17723       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17724              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17725     }
17726
17727   M (ONE_EID_TABLE_DUMP, mp);
17728
17729   mp->filter = filter;
17730   if (eid_set)
17731     {
17732       mp->eid_set = 1;
17733       mp->vni = htonl (vni);
17734       mp->eid_type = eid_type;
17735       switch (eid_type)
17736         {
17737         case 0:
17738           mp->prefix_length = prefix_length;
17739           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17740           break;
17741         case 1:
17742           mp->prefix_length = prefix_length;
17743           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17744           break;
17745         case 2:
17746           clib_memcpy (mp->eid, mac, sizeof (mac));
17747           break;
17748         case 3:
17749           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17750           break;
17751         default:
17752           errmsg ("unknown EID type %d!", eid_type);
17753           return -99;
17754         }
17755     }
17756
17757   /* send it... */
17758   S (mp);
17759
17760   /* Use a control ping for synchronization */
17761   MPING (CONTROL_PING, mp_ping);
17762   S (mp_ping);
17763
17764   /* Wait for a reply... */
17765   W (ret);
17766   return ret;
17767 }
17768
17769 #define api_lisp_eid_table_dump api_one_eid_table_dump
17770
17771 static int
17772 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17773 {
17774   unformat_input_t *i = vam->input;
17775   vl_api_gpe_fwd_entries_get_t *mp;
17776   u8 vni_set = 0;
17777   u32 vni = ~0;
17778   int ret;
17779
17780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17781     {
17782       if (unformat (i, "vni %d", &vni))
17783         {
17784           vni_set = 1;
17785         }
17786       else
17787         {
17788           errmsg ("parse error '%U'", format_unformat_error, i);
17789           return -99;
17790         }
17791     }
17792
17793   if (!vni_set)
17794     {
17795       errmsg ("vni not set!");
17796       return -99;
17797     }
17798
17799   if (!vam->json_output)
17800     {
17801       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17802              "leid", "reid");
17803     }
17804
17805   M (GPE_FWD_ENTRIES_GET, mp);
17806   mp->vni = clib_host_to_net_u32 (vni);
17807
17808   /* send it... */
17809   S (mp);
17810
17811   /* Wait for a reply... */
17812   W (ret);
17813   return ret;
17814 }
17815
17816 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17817 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17818 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17819 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17820 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17821 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17822 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17823 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17824
17825 static int
17826 api_one_adjacencies_get (vat_main_t * vam)
17827 {
17828   unformat_input_t *i = vam->input;
17829   vl_api_one_adjacencies_get_t *mp;
17830   u8 vni_set = 0;
17831   u32 vni = ~0;
17832   int ret;
17833
17834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17835     {
17836       if (unformat (i, "vni %d", &vni))
17837         {
17838           vni_set = 1;
17839         }
17840       else
17841         {
17842           errmsg ("parse error '%U'", format_unformat_error, i);
17843           return -99;
17844         }
17845     }
17846
17847   if (!vni_set)
17848     {
17849       errmsg ("vni not set!");
17850       return -99;
17851     }
17852
17853   if (!vam->json_output)
17854     {
17855       print (vam->ofp, "%s %40s", "leid", "reid");
17856     }
17857
17858   M (ONE_ADJACENCIES_GET, mp);
17859   mp->vni = clib_host_to_net_u32 (vni);
17860
17861   /* send it... */
17862   S (mp);
17863
17864   /* Wait for a reply... */
17865   W (ret);
17866   return ret;
17867 }
17868
17869 #define api_lisp_adjacencies_get api_one_adjacencies_get
17870
17871 static int
17872 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17873 {
17874   unformat_input_t *i = vam->input;
17875   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17876   int ret;
17877   u8 ip_family_set = 0, is_ip4 = 1;
17878
17879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17880     {
17881       if (unformat (i, "ip4"))
17882         {
17883           ip_family_set = 1;
17884           is_ip4 = 1;
17885         }
17886       else if (unformat (i, "ip6"))
17887         {
17888           ip_family_set = 1;
17889           is_ip4 = 0;
17890         }
17891       else
17892         {
17893           errmsg ("parse error '%U'", format_unformat_error, i);
17894           return -99;
17895         }
17896     }
17897
17898   if (!ip_family_set)
17899     {
17900       errmsg ("ip family not set!");
17901       return -99;
17902     }
17903
17904   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17905   mp->is_ip4 = is_ip4;
17906
17907   /* send it... */
17908   S (mp);
17909
17910   /* Wait for a reply... */
17911   W (ret);
17912   return ret;
17913 }
17914
17915 static int
17916 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17917 {
17918   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17919   int ret;
17920
17921   if (!vam->json_output)
17922     {
17923       print (vam->ofp, "VNIs");
17924     }
17925
17926   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17927
17928   /* send it... */
17929   S (mp);
17930
17931   /* Wait for a reply... */
17932   W (ret);
17933   return ret;
17934 }
17935
17936 static int
17937 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17938 {
17939   unformat_input_t *i = vam->input;
17940   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17941   int ret = 0;
17942   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17943   struct in_addr ip4;
17944   struct in6_addr ip6;
17945   u32 table_id = 0, nh_sw_if_index = ~0;
17946
17947   clib_memset (&ip4, 0, sizeof (ip4));
17948   clib_memset (&ip6, 0, sizeof (ip6));
17949
17950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17951     {
17952       if (unformat (i, "del"))
17953         is_add = 0;
17954       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17955                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17956         {
17957           ip_set = 1;
17958           is_ip4 = 1;
17959         }
17960       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17961                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17962         {
17963           ip_set = 1;
17964           is_ip4 = 0;
17965         }
17966       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17967         {
17968           ip_set = 1;
17969           is_ip4 = 1;
17970           nh_sw_if_index = ~0;
17971         }
17972       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17973         {
17974           ip_set = 1;
17975           is_ip4 = 0;
17976           nh_sw_if_index = ~0;
17977         }
17978       else if (unformat (i, "table %d", &table_id))
17979         ;
17980       else
17981         {
17982           errmsg ("parse error '%U'", format_unformat_error, i);
17983           return -99;
17984         }
17985     }
17986
17987   if (!ip_set)
17988     {
17989       errmsg ("nh addr not set!");
17990       return -99;
17991     }
17992
17993   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17994   mp->is_add = is_add;
17995   mp->table_id = clib_host_to_net_u32 (table_id);
17996   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17997   mp->is_ip4 = is_ip4;
17998   if (is_ip4)
17999     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18000   else
18001     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18002
18003   /* send it... */
18004   S (mp);
18005
18006   /* Wait for a reply... */
18007   W (ret);
18008   return ret;
18009 }
18010
18011 static int
18012 api_one_map_server_dump (vat_main_t * vam)
18013 {
18014   vl_api_one_map_server_dump_t *mp;
18015   vl_api_control_ping_t *mp_ping;
18016   int ret;
18017
18018   if (!vam->json_output)
18019     {
18020       print (vam->ofp, "%=20s", "Map server");
18021     }
18022
18023   M (ONE_MAP_SERVER_DUMP, mp);
18024   /* send it... */
18025   S (mp);
18026
18027   /* Use a control ping for synchronization */
18028   MPING (CONTROL_PING, mp_ping);
18029   S (mp_ping);
18030
18031   /* Wait for a reply... */
18032   W (ret);
18033   return ret;
18034 }
18035
18036 #define api_lisp_map_server_dump api_one_map_server_dump
18037
18038 static int
18039 api_one_map_resolver_dump (vat_main_t * vam)
18040 {
18041   vl_api_one_map_resolver_dump_t *mp;
18042   vl_api_control_ping_t *mp_ping;
18043   int ret;
18044
18045   if (!vam->json_output)
18046     {
18047       print (vam->ofp, "%=20s", "Map resolver");
18048     }
18049
18050   M (ONE_MAP_RESOLVER_DUMP, mp);
18051   /* send it... */
18052   S (mp);
18053
18054   /* Use a control ping for synchronization */
18055   MPING (CONTROL_PING, mp_ping);
18056   S (mp_ping);
18057
18058   /* Wait for a reply... */
18059   W (ret);
18060   return ret;
18061 }
18062
18063 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18064
18065 static int
18066 api_one_stats_flush (vat_main_t * vam)
18067 {
18068   vl_api_one_stats_flush_t *mp;
18069   int ret = 0;
18070
18071   M (ONE_STATS_FLUSH, mp);
18072   S (mp);
18073   W (ret);
18074   return ret;
18075 }
18076
18077 static int
18078 api_one_stats_dump (vat_main_t * vam)
18079 {
18080   vl_api_one_stats_dump_t *mp;
18081   vl_api_control_ping_t *mp_ping;
18082   int ret;
18083
18084   M (ONE_STATS_DUMP, mp);
18085   /* send it... */
18086   S (mp);
18087
18088   /* Use a control ping for synchronization */
18089   MPING (CONTROL_PING, mp_ping);
18090   S (mp_ping);
18091
18092   /* Wait for a reply... */
18093   W (ret);
18094   return ret;
18095 }
18096
18097 static int
18098 api_show_one_status (vat_main_t * vam)
18099 {
18100   vl_api_show_one_status_t *mp;
18101   int ret;
18102
18103   if (!vam->json_output)
18104     {
18105       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18106     }
18107
18108   M (SHOW_ONE_STATUS, mp);
18109   /* send it... */
18110   S (mp);
18111   /* Wait for a reply... */
18112   W (ret);
18113   return ret;
18114 }
18115
18116 #define api_show_lisp_status api_show_one_status
18117
18118 static int
18119 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18120 {
18121   vl_api_gpe_fwd_entry_path_dump_t *mp;
18122   vl_api_control_ping_t *mp_ping;
18123   unformat_input_t *i = vam->input;
18124   u32 fwd_entry_index = ~0;
18125   int ret;
18126
18127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18128     {
18129       if (unformat (i, "index %d", &fwd_entry_index))
18130         ;
18131       else
18132         break;
18133     }
18134
18135   if (~0 == fwd_entry_index)
18136     {
18137       errmsg ("no index specified!");
18138       return -99;
18139     }
18140
18141   if (!vam->json_output)
18142     {
18143       print (vam->ofp, "first line");
18144     }
18145
18146   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18147
18148   /* send it... */
18149   S (mp);
18150   /* Use a control ping for synchronization */
18151   MPING (CONTROL_PING, mp_ping);
18152   S (mp_ping);
18153
18154   /* Wait for a reply... */
18155   W (ret);
18156   return ret;
18157 }
18158
18159 static int
18160 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18161 {
18162   vl_api_one_get_map_request_itr_rlocs_t *mp;
18163   int ret;
18164
18165   if (!vam->json_output)
18166     {
18167       print (vam->ofp, "%=20s", "itr-rlocs:");
18168     }
18169
18170   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18171   /* send it... */
18172   S (mp);
18173   /* Wait for a reply... */
18174   W (ret);
18175   return ret;
18176 }
18177
18178 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18179
18180 static int
18181 api_af_packet_create (vat_main_t * vam)
18182 {
18183   unformat_input_t *i = vam->input;
18184   vl_api_af_packet_create_t *mp;
18185   u8 *host_if_name = 0;
18186   u8 hw_addr[6];
18187   u8 random_hw_addr = 1;
18188   int ret;
18189
18190   clib_memset (hw_addr, 0, sizeof (hw_addr));
18191
18192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18193     {
18194       if (unformat (i, "name %s", &host_if_name))
18195         vec_add1 (host_if_name, 0);
18196       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18197         random_hw_addr = 0;
18198       else
18199         break;
18200     }
18201
18202   if (!vec_len (host_if_name))
18203     {
18204       errmsg ("host-interface name must be specified");
18205       return -99;
18206     }
18207
18208   if (vec_len (host_if_name) > 64)
18209     {
18210       errmsg ("host-interface name too long");
18211       return -99;
18212     }
18213
18214   M (AF_PACKET_CREATE, mp);
18215
18216   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18217   clib_memcpy (mp->hw_addr, hw_addr, 6);
18218   mp->use_random_hw_addr = random_hw_addr;
18219   vec_free (host_if_name);
18220
18221   S (mp);
18222
18223   /* *INDENT-OFF* */
18224   W2 (ret,
18225       ({
18226         if (ret == 0)
18227           fprintf (vam->ofp ? vam->ofp : stderr,
18228                    " new sw_if_index = %d\n", vam->sw_if_index);
18229       }));
18230   /* *INDENT-ON* */
18231   return ret;
18232 }
18233
18234 static int
18235 api_af_packet_delete (vat_main_t * vam)
18236 {
18237   unformat_input_t *i = vam->input;
18238   vl_api_af_packet_delete_t *mp;
18239   u8 *host_if_name = 0;
18240   int ret;
18241
18242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18243     {
18244       if (unformat (i, "name %s", &host_if_name))
18245         vec_add1 (host_if_name, 0);
18246       else
18247         break;
18248     }
18249
18250   if (!vec_len (host_if_name))
18251     {
18252       errmsg ("host-interface name must be specified");
18253       return -99;
18254     }
18255
18256   if (vec_len (host_if_name) > 64)
18257     {
18258       errmsg ("host-interface name too long");
18259       return -99;
18260     }
18261
18262   M (AF_PACKET_DELETE, mp);
18263
18264   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18265   vec_free (host_if_name);
18266
18267   S (mp);
18268   W (ret);
18269   return ret;
18270 }
18271
18272 static void vl_api_af_packet_details_t_handler
18273   (vl_api_af_packet_details_t * mp)
18274 {
18275   vat_main_t *vam = &vat_main;
18276
18277   print (vam->ofp, "%-16s %d",
18278          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18279 }
18280
18281 static void vl_api_af_packet_details_t_handler_json
18282   (vl_api_af_packet_details_t * mp)
18283 {
18284   vat_main_t *vam = &vat_main;
18285   vat_json_node_t *node = NULL;
18286
18287   if (VAT_JSON_ARRAY != vam->json_tree.type)
18288     {
18289       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18290       vat_json_init_array (&vam->json_tree);
18291     }
18292   node = vat_json_array_add (&vam->json_tree);
18293
18294   vat_json_init_object (node);
18295   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18296   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18297 }
18298
18299 static int
18300 api_af_packet_dump (vat_main_t * vam)
18301 {
18302   vl_api_af_packet_dump_t *mp;
18303   vl_api_control_ping_t *mp_ping;
18304   int ret;
18305
18306   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18307   /* Get list of tap interfaces */
18308   M (AF_PACKET_DUMP, mp);
18309   S (mp);
18310
18311   /* Use a control ping for synchronization */
18312   MPING (CONTROL_PING, mp_ping);
18313   S (mp_ping);
18314
18315   W (ret);
18316   return ret;
18317 }
18318
18319 static int
18320 api_policer_add_del (vat_main_t * vam)
18321 {
18322   unformat_input_t *i = vam->input;
18323   vl_api_policer_add_del_t *mp;
18324   u8 is_add = 1;
18325   u8 *name = 0;
18326   u32 cir = 0;
18327   u32 eir = 0;
18328   u64 cb = 0;
18329   u64 eb = 0;
18330   u8 rate_type = 0;
18331   u8 round_type = 0;
18332   u8 type = 0;
18333   u8 color_aware = 0;
18334   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18335   int ret;
18336
18337   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18338   conform_action.dscp = 0;
18339   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18340   exceed_action.dscp = 0;
18341   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18342   violate_action.dscp = 0;
18343
18344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18345     {
18346       if (unformat (i, "del"))
18347         is_add = 0;
18348       else if (unformat (i, "name %s", &name))
18349         vec_add1 (name, 0);
18350       else if (unformat (i, "cir %u", &cir))
18351         ;
18352       else if (unformat (i, "eir %u", &eir))
18353         ;
18354       else if (unformat (i, "cb %u", &cb))
18355         ;
18356       else if (unformat (i, "eb %u", &eb))
18357         ;
18358       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18359                          &rate_type))
18360         ;
18361       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18362                          &round_type))
18363         ;
18364       else if (unformat (i, "type %U", unformat_policer_type, &type))
18365         ;
18366       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18367                          &conform_action))
18368         ;
18369       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18370                          &exceed_action))
18371         ;
18372       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18373                          &violate_action))
18374         ;
18375       else if (unformat (i, "color-aware"))
18376         color_aware = 1;
18377       else
18378         break;
18379     }
18380
18381   if (!vec_len (name))
18382     {
18383       errmsg ("policer name must be specified");
18384       return -99;
18385     }
18386
18387   if (vec_len (name) > 64)
18388     {
18389       errmsg ("policer name too long");
18390       return -99;
18391     }
18392
18393   M (POLICER_ADD_DEL, mp);
18394
18395   clib_memcpy (mp->name, name, vec_len (name));
18396   vec_free (name);
18397   mp->is_add = is_add;
18398   mp->cir = ntohl (cir);
18399   mp->eir = ntohl (eir);
18400   mp->cb = clib_net_to_host_u64 (cb);
18401   mp->eb = clib_net_to_host_u64 (eb);
18402   mp->rate_type = rate_type;
18403   mp->round_type = round_type;
18404   mp->type = type;
18405   mp->conform_action_type = conform_action.action_type;
18406   mp->conform_dscp = conform_action.dscp;
18407   mp->exceed_action_type = exceed_action.action_type;
18408   mp->exceed_dscp = exceed_action.dscp;
18409   mp->violate_action_type = violate_action.action_type;
18410   mp->violate_dscp = violate_action.dscp;
18411   mp->color_aware = color_aware;
18412
18413   S (mp);
18414   W (ret);
18415   return ret;
18416 }
18417
18418 static int
18419 api_policer_dump (vat_main_t * vam)
18420 {
18421   unformat_input_t *i = vam->input;
18422   vl_api_policer_dump_t *mp;
18423   vl_api_control_ping_t *mp_ping;
18424   u8 *match_name = 0;
18425   u8 match_name_valid = 0;
18426   int ret;
18427
18428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18429     {
18430       if (unformat (i, "name %s", &match_name))
18431         {
18432           vec_add1 (match_name, 0);
18433           match_name_valid = 1;
18434         }
18435       else
18436         break;
18437     }
18438
18439   M (POLICER_DUMP, mp);
18440   mp->match_name_valid = match_name_valid;
18441   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18442   vec_free (match_name);
18443   /* send it... */
18444   S (mp);
18445
18446   /* Use a control ping for synchronization */
18447   MPING (CONTROL_PING, mp_ping);
18448   S (mp_ping);
18449
18450   /* Wait for a reply... */
18451   W (ret);
18452   return ret;
18453 }
18454
18455 static int
18456 api_policer_classify_set_interface (vat_main_t * vam)
18457 {
18458   unformat_input_t *i = vam->input;
18459   vl_api_policer_classify_set_interface_t *mp;
18460   u32 sw_if_index;
18461   int sw_if_index_set;
18462   u32 ip4_table_index = ~0;
18463   u32 ip6_table_index = ~0;
18464   u32 l2_table_index = ~0;
18465   u8 is_add = 1;
18466   int ret;
18467
18468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18469     {
18470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18471         sw_if_index_set = 1;
18472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18473         sw_if_index_set = 1;
18474       else if (unformat (i, "del"))
18475         is_add = 0;
18476       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18477         ;
18478       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18479         ;
18480       else if (unformat (i, "l2-table %d", &l2_table_index))
18481         ;
18482       else
18483         {
18484           clib_warning ("parse error '%U'", format_unformat_error, i);
18485           return -99;
18486         }
18487     }
18488
18489   if (sw_if_index_set == 0)
18490     {
18491       errmsg ("missing interface name or sw_if_index");
18492       return -99;
18493     }
18494
18495   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18496
18497   mp->sw_if_index = ntohl (sw_if_index);
18498   mp->ip4_table_index = ntohl (ip4_table_index);
18499   mp->ip6_table_index = ntohl (ip6_table_index);
18500   mp->l2_table_index = ntohl (l2_table_index);
18501   mp->is_add = is_add;
18502
18503   S (mp);
18504   W (ret);
18505   return ret;
18506 }
18507
18508 static int
18509 api_policer_classify_dump (vat_main_t * vam)
18510 {
18511   unformat_input_t *i = vam->input;
18512   vl_api_policer_classify_dump_t *mp;
18513   vl_api_control_ping_t *mp_ping;
18514   u8 type = POLICER_CLASSIFY_N_TABLES;
18515   int ret;
18516
18517   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18518     ;
18519   else
18520     {
18521       errmsg ("classify table type must be specified");
18522       return -99;
18523     }
18524
18525   if (!vam->json_output)
18526     {
18527       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18528     }
18529
18530   M (POLICER_CLASSIFY_DUMP, mp);
18531   mp->type = type;
18532   /* send it... */
18533   S (mp);
18534
18535   /* Use a control ping for synchronization */
18536   MPING (CONTROL_PING, mp_ping);
18537   S (mp_ping);
18538
18539   /* Wait for a reply... */
18540   W (ret);
18541   return ret;
18542 }
18543
18544 static int
18545 api_netmap_create (vat_main_t * vam)
18546 {
18547   unformat_input_t *i = vam->input;
18548   vl_api_netmap_create_t *mp;
18549   u8 *if_name = 0;
18550   u8 hw_addr[6];
18551   u8 random_hw_addr = 1;
18552   u8 is_pipe = 0;
18553   u8 is_master = 0;
18554   int ret;
18555
18556   clib_memset (hw_addr, 0, sizeof (hw_addr));
18557
18558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18559     {
18560       if (unformat (i, "name %s", &if_name))
18561         vec_add1 (if_name, 0);
18562       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18563         random_hw_addr = 0;
18564       else if (unformat (i, "pipe"))
18565         is_pipe = 1;
18566       else if (unformat (i, "master"))
18567         is_master = 1;
18568       else if (unformat (i, "slave"))
18569         is_master = 0;
18570       else
18571         break;
18572     }
18573
18574   if (!vec_len (if_name))
18575     {
18576       errmsg ("interface name must be specified");
18577       return -99;
18578     }
18579
18580   if (vec_len (if_name) > 64)
18581     {
18582       errmsg ("interface name too long");
18583       return -99;
18584     }
18585
18586   M (NETMAP_CREATE, mp);
18587
18588   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18589   clib_memcpy (mp->hw_addr, hw_addr, 6);
18590   mp->use_random_hw_addr = random_hw_addr;
18591   mp->is_pipe = is_pipe;
18592   mp->is_master = is_master;
18593   vec_free (if_name);
18594
18595   S (mp);
18596   W (ret);
18597   return ret;
18598 }
18599
18600 static int
18601 api_netmap_delete (vat_main_t * vam)
18602 {
18603   unformat_input_t *i = vam->input;
18604   vl_api_netmap_delete_t *mp;
18605   u8 *if_name = 0;
18606   int ret;
18607
18608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18609     {
18610       if (unformat (i, "name %s", &if_name))
18611         vec_add1 (if_name, 0);
18612       else
18613         break;
18614     }
18615
18616   if (!vec_len (if_name))
18617     {
18618       errmsg ("interface name must be specified");
18619       return -99;
18620     }
18621
18622   if (vec_len (if_name) > 64)
18623     {
18624       errmsg ("interface name too long");
18625       return -99;
18626     }
18627
18628   M (NETMAP_DELETE, mp);
18629
18630   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18631   vec_free (if_name);
18632
18633   S (mp);
18634   W (ret);
18635   return ret;
18636 }
18637
18638 static u8 *
18639 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18640 {
18641   vl_api_fib_path_nh_proto_t proto =
18642     va_arg (*args, vl_api_fib_path_nh_proto_t);
18643
18644   switch (proto)
18645     {
18646     case FIB_API_PATH_NH_PROTO_IP4:
18647       s = format (s, "ip4");
18648       break;
18649     case FIB_API_PATH_NH_PROTO_IP6:
18650       s = format (s, "ip6");
18651       break;
18652     case FIB_API_PATH_NH_PROTO_MPLS:
18653       s = format (s, "mpls");
18654       break;
18655     case FIB_API_PATH_NH_PROTO_BIER:
18656       s = format (s, "bier");
18657       break;
18658     case FIB_API_PATH_NH_PROTO_ETHERNET:
18659       s = format (s, "ethernet");
18660       break;
18661     }
18662
18663   return (s);
18664 }
18665
18666 static u8 *
18667 format_vl_api_ip_address_union (u8 * s, va_list * args)
18668 {
18669   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18670   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18671
18672   switch (af)
18673     {
18674     case ADDRESS_IP4:
18675       s = format (s, "%U", format_ip4_address, u->ip4);
18676       break;
18677     case ADDRESS_IP6:
18678       s = format (s, "%U", format_ip6_address, u->ip6);
18679       break;
18680     }
18681   return (s);
18682 }
18683
18684 static u8 *
18685 format_vl_api_fib_path_type (u8 * s, va_list * args)
18686 {
18687   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18688
18689   switch (t)
18690     {
18691     case FIB_API_PATH_TYPE_NORMAL:
18692       s = format (s, "normal");
18693       break;
18694     case FIB_API_PATH_TYPE_LOCAL:
18695       s = format (s, "local");
18696       break;
18697     case FIB_API_PATH_TYPE_DROP:
18698       s = format (s, "drop");
18699       break;
18700     case FIB_API_PATH_TYPE_UDP_ENCAP:
18701       s = format (s, "udp-encap");
18702       break;
18703     case FIB_API_PATH_TYPE_BIER_IMP:
18704       s = format (s, "bier-imp");
18705       break;
18706     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18707       s = format (s, "unreach");
18708       break;
18709     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18710       s = format (s, "prohibit");
18711       break;
18712     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18713       s = format (s, "src-lookup");
18714       break;
18715     case FIB_API_PATH_TYPE_DVR:
18716       s = format (s, "dvr");
18717       break;
18718     case FIB_API_PATH_TYPE_INTERFACE_RX:
18719       s = format (s, "interface-rx");
18720       break;
18721     case FIB_API_PATH_TYPE_CLASSIFY:
18722       s = format (s, "classify");
18723       break;
18724     }
18725
18726   return (s);
18727 }
18728
18729 static void
18730 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18731 {
18732   print (vam->ofp,
18733          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18734          ntohl (fp->weight), ntohl (fp->sw_if_index),
18735          format_vl_api_fib_path_type, fp->type,
18736          format_fib_api_path_nh_proto, fp->proto,
18737          format_vl_api_ip_address_union, &fp->nh.address);
18738 }
18739
18740 static void
18741 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18742                                  vl_api_fib_path_t * fp)
18743 {
18744   struct in_addr ip4;
18745   struct in6_addr ip6;
18746
18747   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18748   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18749   vat_json_object_add_uint (node, "type", fp->type);
18750   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18751   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18752     {
18753       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18754       vat_json_object_add_ip4 (node, "next_hop", ip4);
18755     }
18756   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18757     {
18758       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18759       vat_json_object_add_ip6 (node, "next_hop", ip6);
18760     }
18761 }
18762
18763 static void
18764 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18765 {
18766   vat_main_t *vam = &vat_main;
18767   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18768   vl_api_fib_path_t *fp;
18769   i32 i;
18770
18771   print (vam->ofp, "sw_if_index %d via:",
18772          ntohl (mp->mt_tunnel.mt_sw_if_index));
18773   fp = mp->mt_tunnel.mt_paths;
18774   for (i = 0; i < count; i++)
18775     {
18776       vl_api_fib_path_print (vam, fp);
18777       fp++;
18778     }
18779
18780   print (vam->ofp, "");
18781 }
18782
18783 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18784 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18785
18786 static void
18787 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18788 {
18789   vat_main_t *vam = &vat_main;
18790   vat_json_node_t *node = NULL;
18791   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18792   vl_api_fib_path_t *fp;
18793   i32 i;
18794
18795   if (VAT_JSON_ARRAY != vam->json_tree.type)
18796     {
18797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18798       vat_json_init_array (&vam->json_tree);
18799     }
18800   node = vat_json_array_add (&vam->json_tree);
18801
18802   vat_json_init_object (node);
18803   vat_json_object_add_uint (node, "sw_if_index",
18804                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18805
18806   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18807
18808   fp = mp->mt_tunnel.mt_paths;
18809   for (i = 0; i < count; i++)
18810     {
18811       vl_api_mpls_fib_path_json_print (node, fp);
18812       fp++;
18813     }
18814 }
18815
18816 static int
18817 api_mpls_tunnel_dump (vat_main_t * vam)
18818 {
18819   vl_api_mpls_tunnel_dump_t *mp;
18820   vl_api_control_ping_t *mp_ping;
18821   int ret;
18822
18823   M (MPLS_TUNNEL_DUMP, mp);
18824
18825   S (mp);
18826
18827   /* Use a control ping for synchronization */
18828   MPING (CONTROL_PING, mp_ping);
18829   S (mp_ping);
18830
18831   W (ret);
18832   return ret;
18833 }
18834
18835 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18836 #define vl_api_mpls_table_details_t_print vl_noop_handler
18837
18838
18839 static void
18840 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18841 {
18842   vat_main_t *vam = &vat_main;
18843
18844   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18845 }
18846
18847 static void vl_api_mpls_table_details_t_handler_json
18848   (vl_api_mpls_table_details_t * mp)
18849 {
18850   vat_main_t *vam = &vat_main;
18851   vat_json_node_t *node = NULL;
18852
18853   if (VAT_JSON_ARRAY != vam->json_tree.type)
18854     {
18855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18856       vat_json_init_array (&vam->json_tree);
18857     }
18858   node = vat_json_array_add (&vam->json_tree);
18859
18860   vat_json_init_object (node);
18861   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18862 }
18863
18864 static int
18865 api_mpls_table_dump (vat_main_t * vam)
18866 {
18867   vl_api_mpls_table_dump_t *mp;
18868   vl_api_control_ping_t *mp_ping;
18869   int ret;
18870
18871   M (MPLS_TABLE_DUMP, mp);
18872   S (mp);
18873
18874   /* Use a control ping for synchronization */
18875   MPING (CONTROL_PING, mp_ping);
18876   S (mp_ping);
18877
18878   W (ret);
18879   return ret;
18880 }
18881
18882 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18883 #define vl_api_mpls_route_details_t_print vl_noop_handler
18884
18885 static void
18886 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18887 {
18888   vat_main_t *vam = &vat_main;
18889   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18890   vl_api_fib_path_t *fp;
18891   int i;
18892
18893   print (vam->ofp,
18894          "table-id %d, label %u, ess_bit %u",
18895          ntohl (mp->mr_route.mr_table_id),
18896          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18897   fp = mp->mr_route.mr_paths;
18898   for (i = 0; i < count; i++)
18899     {
18900       vl_api_fib_path_print (vam, fp);
18901       fp++;
18902     }
18903 }
18904
18905 static void vl_api_mpls_route_details_t_handler_json
18906   (vl_api_mpls_route_details_t * mp)
18907 {
18908   vat_main_t *vam = &vat_main;
18909   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18910   vat_json_node_t *node = NULL;
18911   vl_api_fib_path_t *fp;
18912   int i;
18913
18914   if (VAT_JSON_ARRAY != vam->json_tree.type)
18915     {
18916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18917       vat_json_init_array (&vam->json_tree);
18918     }
18919   node = vat_json_array_add (&vam->json_tree);
18920
18921   vat_json_init_object (node);
18922   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18923   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18924   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18925   vat_json_object_add_uint (node, "path_count", count);
18926   fp = mp->mr_route.mr_paths;
18927   for (i = 0; i < count; i++)
18928     {
18929       vl_api_mpls_fib_path_json_print (node, fp);
18930       fp++;
18931     }
18932 }
18933
18934 static int
18935 api_mpls_route_dump (vat_main_t * vam)
18936 {
18937   unformat_input_t *input = vam->input;
18938   vl_api_mpls_route_dump_t *mp;
18939   vl_api_control_ping_t *mp_ping;
18940   u32 table_id;
18941   int ret;
18942
18943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18944     {
18945       if (unformat (input, "table_id %d", &table_id))
18946         ;
18947       else
18948         break;
18949     }
18950   if (table_id == ~0)
18951     {
18952       errmsg ("missing table id");
18953       return -99;
18954     }
18955
18956   M (MPLS_ROUTE_DUMP, mp);
18957
18958   mp->table.mt_table_id = ntohl (table_id);
18959   S (mp);
18960
18961   /* Use a control ping for synchronization */
18962   MPING (CONTROL_PING, mp_ping);
18963   S (mp_ping);
18964
18965   W (ret);
18966   return ret;
18967 }
18968
18969 #define vl_api_ip_table_details_t_endian vl_noop_handler
18970 #define vl_api_ip_table_details_t_print vl_noop_handler
18971
18972 static void
18973 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18974 {
18975   vat_main_t *vam = &vat_main;
18976
18977   print (vam->ofp,
18978          "%s; table-id %d, prefix %U/%d",
18979          mp->table.name, ntohl (mp->table.table_id));
18980 }
18981
18982
18983 static void vl_api_ip_table_details_t_handler_json
18984   (vl_api_ip_table_details_t * mp)
18985 {
18986   vat_main_t *vam = &vat_main;
18987   vat_json_node_t *node = NULL;
18988
18989   if (VAT_JSON_ARRAY != vam->json_tree.type)
18990     {
18991       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18992       vat_json_init_array (&vam->json_tree);
18993     }
18994   node = vat_json_array_add (&vam->json_tree);
18995
18996   vat_json_init_object (node);
18997   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18998 }
18999
19000 static int
19001 api_ip_table_dump (vat_main_t * vam)
19002 {
19003   vl_api_ip_table_dump_t *mp;
19004   vl_api_control_ping_t *mp_ping;
19005   int ret;
19006
19007   M (IP_TABLE_DUMP, mp);
19008   S (mp);
19009
19010   /* Use a control ping for synchronization */
19011   MPING (CONTROL_PING, mp_ping);
19012   S (mp_ping);
19013
19014   W (ret);
19015   return ret;
19016 }
19017
19018 static int
19019 api_ip_mtable_dump (vat_main_t * vam)
19020 {
19021   vl_api_ip_mtable_dump_t *mp;
19022   vl_api_control_ping_t *mp_ping;
19023   int ret;
19024
19025   M (IP_MTABLE_DUMP, mp);
19026   S (mp);
19027
19028   /* Use a control ping for synchronization */
19029   MPING (CONTROL_PING, mp_ping);
19030   S (mp_ping);
19031
19032   W (ret);
19033   return ret;
19034 }
19035
19036 static int
19037 api_ip_mroute_dump (vat_main_t * vam)
19038 {
19039   unformat_input_t *input = vam->input;
19040   vl_api_control_ping_t *mp_ping;
19041   vl_api_ip_mroute_dump_t *mp;
19042   int ret, is_ip6;
19043   u32 table_id;
19044
19045   is_ip6 = 0;
19046   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19047     {
19048       if (unformat (input, "table_id %d", &table_id))
19049         ;
19050       else if (unformat (input, "ip6"))
19051         is_ip6 = 1;
19052       else if (unformat (input, "ip4"))
19053         is_ip6 = 0;
19054       else
19055         break;
19056     }
19057   if (table_id == ~0)
19058     {
19059       errmsg ("missing table id");
19060       return -99;
19061     }
19062
19063   M (IP_MROUTE_DUMP, mp);
19064   mp->table.table_id = table_id;
19065   mp->table.is_ip6 = is_ip6;
19066   S (mp);
19067
19068   /* Use a control ping for synchronization */
19069   MPING (CONTROL_PING, mp_ping);
19070   S (mp_ping);
19071
19072   W (ret);
19073   return ret;
19074 }
19075
19076 static void vl_api_ip_neighbor_details_t_handler
19077   (vl_api_ip_neighbor_details_t * mp)
19078 {
19079   vat_main_t *vam = &vat_main;
19080
19081   print (vam->ofp, "%c %U %U",
19082          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19083          format_vl_api_mac_address, &mp->neighbor.mac_address,
19084          format_vl_api_address, &mp->neighbor.ip_address);
19085 }
19086
19087 static void vl_api_ip_neighbor_details_t_handler_json
19088   (vl_api_ip_neighbor_details_t * mp)
19089 {
19090
19091   vat_main_t *vam = &vat_main;
19092   vat_json_node_t *node;
19093
19094   if (VAT_JSON_ARRAY != vam->json_tree.type)
19095     {
19096       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19097       vat_json_init_array (&vam->json_tree);
19098     }
19099   node = vat_json_array_add (&vam->json_tree);
19100
19101   vat_json_init_object (node);
19102   vat_json_object_add_string_copy
19103     (node, "flag",
19104      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19105       (u8 *) "static" : (u8 *) "dynamic"));
19106
19107   vat_json_object_add_string_copy (node, "link_layer",
19108                                    format (0, "%U", format_vl_api_mac_address,
19109                                            &mp->neighbor.mac_address));
19110   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19111 }
19112
19113 static int
19114 api_ip_neighbor_dump (vat_main_t * vam)
19115 {
19116   unformat_input_t *i = vam->input;
19117   vl_api_ip_neighbor_dump_t *mp;
19118   vl_api_control_ping_t *mp_ping;
19119   u8 is_ipv6 = 0;
19120   u32 sw_if_index = ~0;
19121   int ret;
19122
19123   /* Parse args required to build the message */
19124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19125     {
19126       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19127         ;
19128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19129         ;
19130       else if (unformat (i, "ip6"))
19131         is_ipv6 = 1;
19132       else
19133         break;
19134     }
19135
19136   if (sw_if_index == ~0)
19137     {
19138       errmsg ("missing interface name or sw_if_index");
19139       return -99;
19140     }
19141
19142   M (IP_NEIGHBOR_DUMP, mp);
19143   mp->is_ipv6 = (u8) is_ipv6;
19144   mp->sw_if_index = ntohl (sw_if_index);
19145   S (mp);
19146
19147   /* Use a control ping for synchronization */
19148   MPING (CONTROL_PING, mp_ping);
19149   S (mp_ping);
19150
19151   W (ret);
19152   return ret;
19153 }
19154
19155 #define vl_api_ip_route_details_t_endian vl_noop_handler
19156 #define vl_api_ip_route_details_t_print vl_noop_handler
19157
19158 static void
19159 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19160 {
19161   vat_main_t *vam = &vat_main;
19162   u8 count = mp->route.n_paths;
19163   vl_api_fib_path_t *fp;
19164   int i;
19165
19166   print (vam->ofp,
19167          "table-id %d, prefix %U/%d",
19168          ntohl (mp->route.table_id),
19169          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19170   for (i = 0; i < count; i++)
19171     {
19172       fp = &mp->route.paths[i];
19173
19174       vl_api_fib_path_print (vam, fp);
19175       fp++;
19176     }
19177 }
19178
19179 static void vl_api_ip_route_details_t_handler_json
19180   (vl_api_ip_route_details_t * mp)
19181 {
19182   vat_main_t *vam = &vat_main;
19183   u8 count = mp->route.n_paths;
19184   vat_json_node_t *node = NULL;
19185   struct in_addr ip4;
19186   struct in6_addr ip6;
19187   vl_api_fib_path_t *fp;
19188   int i;
19189
19190   if (VAT_JSON_ARRAY != vam->json_tree.type)
19191     {
19192       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19193       vat_json_init_array (&vam->json_tree);
19194     }
19195   node = vat_json_array_add (&vam->json_tree);
19196
19197   vat_json_init_object (node);
19198   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19199   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19200     {
19201       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19202       vat_json_object_add_ip6 (node, "prefix", ip6);
19203     }
19204   else
19205     {
19206       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19207       vat_json_object_add_ip4 (node, "prefix", ip4);
19208     }
19209   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19210   vat_json_object_add_uint (node, "path_count", count);
19211   for (i = 0; i < count; i++)
19212     {
19213       fp = &mp->route.paths[i];
19214       vl_api_mpls_fib_path_json_print (node, fp);
19215     }
19216 }
19217
19218 static int
19219 api_ip_route_dump (vat_main_t * vam)
19220 {
19221   unformat_input_t *input = vam->input;
19222   vl_api_ip_route_dump_t *mp;
19223   vl_api_control_ping_t *mp_ping;
19224   u32 table_id;
19225   u8 is_ip6;
19226   int ret;
19227
19228   is_ip6 = 0;
19229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19230     {
19231       if (unformat (input, "table_id %d", &table_id))
19232         ;
19233       else if (unformat (input, "ip6"))
19234         is_ip6 = 1;
19235       else if (unformat (input, "ip4"))
19236         is_ip6 = 0;
19237       else
19238         break;
19239     }
19240   if (table_id == ~0)
19241     {
19242       errmsg ("missing table id");
19243       return -99;
19244     }
19245
19246   M (IP_ROUTE_DUMP, mp);
19247
19248   mp->table.table_id = table_id;
19249   mp->table.is_ip6 = is_ip6;
19250
19251   S (mp);
19252
19253   /* Use a control ping for synchronization */
19254   MPING (CONTROL_PING, mp_ping);
19255   S (mp_ping);
19256
19257   W (ret);
19258   return ret;
19259 }
19260
19261 int
19262 api_classify_table_ids (vat_main_t * vam)
19263 {
19264   vl_api_classify_table_ids_t *mp;
19265   int ret;
19266
19267   /* Construct the API message */
19268   M (CLASSIFY_TABLE_IDS, mp);
19269   mp->context = 0;
19270
19271   S (mp);
19272   W (ret);
19273   return ret;
19274 }
19275
19276 int
19277 api_classify_table_by_interface (vat_main_t * vam)
19278 {
19279   unformat_input_t *input = vam->input;
19280   vl_api_classify_table_by_interface_t *mp;
19281
19282   u32 sw_if_index = ~0;
19283   int ret;
19284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19285     {
19286       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19287         ;
19288       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19289         ;
19290       else
19291         break;
19292     }
19293   if (sw_if_index == ~0)
19294     {
19295       errmsg ("missing interface name or sw_if_index");
19296       return -99;
19297     }
19298
19299   /* Construct the API message */
19300   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19301   mp->context = 0;
19302   mp->sw_if_index = ntohl (sw_if_index);
19303
19304   S (mp);
19305   W (ret);
19306   return ret;
19307 }
19308
19309 int
19310 api_classify_table_info (vat_main_t * vam)
19311 {
19312   unformat_input_t *input = vam->input;
19313   vl_api_classify_table_info_t *mp;
19314
19315   u32 table_id = ~0;
19316   int ret;
19317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19318     {
19319       if (unformat (input, "table_id %d", &table_id))
19320         ;
19321       else
19322         break;
19323     }
19324   if (table_id == ~0)
19325     {
19326       errmsg ("missing table id");
19327       return -99;
19328     }
19329
19330   /* Construct the API message */
19331   M (CLASSIFY_TABLE_INFO, mp);
19332   mp->context = 0;
19333   mp->table_id = ntohl (table_id);
19334
19335   S (mp);
19336   W (ret);
19337   return ret;
19338 }
19339
19340 int
19341 api_classify_session_dump (vat_main_t * vam)
19342 {
19343   unformat_input_t *input = vam->input;
19344   vl_api_classify_session_dump_t *mp;
19345   vl_api_control_ping_t *mp_ping;
19346
19347   u32 table_id = ~0;
19348   int ret;
19349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19350     {
19351       if (unformat (input, "table_id %d", &table_id))
19352         ;
19353       else
19354         break;
19355     }
19356   if (table_id == ~0)
19357     {
19358       errmsg ("missing table id");
19359       return -99;
19360     }
19361
19362   /* Construct the API message */
19363   M (CLASSIFY_SESSION_DUMP, mp);
19364   mp->context = 0;
19365   mp->table_id = ntohl (table_id);
19366   S (mp);
19367
19368   /* Use a control ping for synchronization */
19369   MPING (CONTROL_PING, mp_ping);
19370   S (mp_ping);
19371
19372   W (ret);
19373   return ret;
19374 }
19375
19376 static void
19377 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19378 {
19379   vat_main_t *vam = &vat_main;
19380
19381   print (vam->ofp, "collector_address %U, collector_port %d, "
19382          "src_address %U, vrf_id %d, path_mtu %u, "
19383          "template_interval %u, udp_checksum %d",
19384          format_ip4_address, mp->collector_address,
19385          ntohs (mp->collector_port),
19386          format_ip4_address, mp->src_address,
19387          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19388          ntohl (mp->template_interval), mp->udp_checksum);
19389
19390   vam->retval = 0;
19391   vam->result_ready = 1;
19392 }
19393
19394 static void
19395   vl_api_ipfix_exporter_details_t_handler_json
19396   (vl_api_ipfix_exporter_details_t * mp)
19397 {
19398   vat_main_t *vam = &vat_main;
19399   vat_json_node_t node;
19400   struct in_addr collector_address;
19401   struct in_addr src_address;
19402
19403   vat_json_init_object (&node);
19404   clib_memcpy (&collector_address, &mp->collector_address,
19405                sizeof (collector_address));
19406   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19407   vat_json_object_add_uint (&node, "collector_port",
19408                             ntohs (mp->collector_port));
19409   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19410   vat_json_object_add_ip4 (&node, "src_address", src_address);
19411   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19412   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19413   vat_json_object_add_uint (&node, "template_interval",
19414                             ntohl (mp->template_interval));
19415   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19416
19417   vat_json_print (vam->ofp, &node);
19418   vat_json_free (&node);
19419   vam->retval = 0;
19420   vam->result_ready = 1;
19421 }
19422
19423 int
19424 api_ipfix_exporter_dump (vat_main_t * vam)
19425 {
19426   vl_api_ipfix_exporter_dump_t *mp;
19427   int ret;
19428
19429   /* Construct the API message */
19430   M (IPFIX_EXPORTER_DUMP, mp);
19431   mp->context = 0;
19432
19433   S (mp);
19434   W (ret);
19435   return ret;
19436 }
19437
19438 static int
19439 api_ipfix_classify_stream_dump (vat_main_t * vam)
19440 {
19441   vl_api_ipfix_classify_stream_dump_t *mp;
19442   int ret;
19443
19444   /* Construct the API message */
19445   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19446   mp->context = 0;
19447
19448   S (mp);
19449   W (ret);
19450   return ret;
19451   /* NOTREACHED */
19452   return 0;
19453 }
19454
19455 static void
19456   vl_api_ipfix_classify_stream_details_t_handler
19457   (vl_api_ipfix_classify_stream_details_t * mp)
19458 {
19459   vat_main_t *vam = &vat_main;
19460   print (vam->ofp, "domain_id %d, src_port %d",
19461          ntohl (mp->domain_id), ntohs (mp->src_port));
19462   vam->retval = 0;
19463   vam->result_ready = 1;
19464 }
19465
19466 static void
19467   vl_api_ipfix_classify_stream_details_t_handler_json
19468   (vl_api_ipfix_classify_stream_details_t * mp)
19469 {
19470   vat_main_t *vam = &vat_main;
19471   vat_json_node_t node;
19472
19473   vat_json_init_object (&node);
19474   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19475   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19476
19477   vat_json_print (vam->ofp, &node);
19478   vat_json_free (&node);
19479   vam->retval = 0;
19480   vam->result_ready = 1;
19481 }
19482
19483 static int
19484 api_ipfix_classify_table_dump (vat_main_t * vam)
19485 {
19486   vl_api_ipfix_classify_table_dump_t *mp;
19487   vl_api_control_ping_t *mp_ping;
19488   int ret;
19489
19490   if (!vam->json_output)
19491     {
19492       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19493              "transport_protocol");
19494     }
19495
19496   /* Construct the API message */
19497   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19498
19499   /* send it... */
19500   S (mp);
19501
19502   /* Use a control ping for synchronization */
19503   MPING (CONTROL_PING, mp_ping);
19504   S (mp_ping);
19505
19506   W (ret);
19507   return ret;
19508 }
19509
19510 static void
19511   vl_api_ipfix_classify_table_details_t_handler
19512   (vl_api_ipfix_classify_table_details_t * mp)
19513 {
19514   vat_main_t *vam = &vat_main;
19515   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19516          mp->transport_protocol);
19517 }
19518
19519 static void
19520   vl_api_ipfix_classify_table_details_t_handler_json
19521   (vl_api_ipfix_classify_table_details_t * mp)
19522 {
19523   vat_json_node_t *node = NULL;
19524   vat_main_t *vam = &vat_main;
19525
19526   if (VAT_JSON_ARRAY != vam->json_tree.type)
19527     {
19528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19529       vat_json_init_array (&vam->json_tree);
19530     }
19531
19532   node = vat_json_array_add (&vam->json_tree);
19533   vat_json_init_object (node);
19534
19535   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19536   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19537   vat_json_object_add_uint (node, "transport_protocol",
19538                             mp->transport_protocol);
19539 }
19540
19541 static int
19542 api_sw_interface_span_enable_disable (vat_main_t * vam)
19543 {
19544   unformat_input_t *i = vam->input;
19545   vl_api_sw_interface_span_enable_disable_t *mp;
19546   u32 src_sw_if_index = ~0;
19547   u32 dst_sw_if_index = ~0;
19548   u8 state = 3;
19549   int ret;
19550   u8 is_l2 = 0;
19551
19552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19553     {
19554       if (unformat
19555           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19556         ;
19557       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19558         ;
19559       else
19560         if (unformat
19561             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19562         ;
19563       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19564         ;
19565       else if (unformat (i, "disable"))
19566         state = 0;
19567       else if (unformat (i, "rx"))
19568         state = 1;
19569       else if (unformat (i, "tx"))
19570         state = 2;
19571       else if (unformat (i, "both"))
19572         state = 3;
19573       else if (unformat (i, "l2"))
19574         is_l2 = 1;
19575       else
19576         break;
19577     }
19578
19579   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19580
19581   mp->sw_if_index_from = htonl (src_sw_if_index);
19582   mp->sw_if_index_to = htonl (dst_sw_if_index);
19583   mp->state = state;
19584   mp->is_l2 = is_l2;
19585
19586   S (mp);
19587   W (ret);
19588   return ret;
19589 }
19590
19591 static void
19592 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19593                                             * mp)
19594 {
19595   vat_main_t *vam = &vat_main;
19596   u8 *sw_if_from_name = 0;
19597   u8 *sw_if_to_name = 0;
19598   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19599   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19600   char *states[] = { "none", "rx", "tx", "both" };
19601   hash_pair_t *p;
19602
19603   /* *INDENT-OFF* */
19604   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19605   ({
19606     if ((u32) p->value[0] == sw_if_index_from)
19607       {
19608         sw_if_from_name = (u8 *)(p->key);
19609         if (sw_if_to_name)
19610           break;
19611       }
19612     if ((u32) p->value[0] == sw_if_index_to)
19613       {
19614         sw_if_to_name = (u8 *)(p->key);
19615         if (sw_if_from_name)
19616           break;
19617       }
19618   }));
19619   /* *INDENT-ON* */
19620   print (vam->ofp, "%20s => %20s (%s) %s",
19621          sw_if_from_name, sw_if_to_name, states[mp->state],
19622          mp->is_l2 ? "l2" : "device");
19623 }
19624
19625 static void
19626   vl_api_sw_interface_span_details_t_handler_json
19627   (vl_api_sw_interface_span_details_t * mp)
19628 {
19629   vat_main_t *vam = &vat_main;
19630   vat_json_node_t *node = NULL;
19631   u8 *sw_if_from_name = 0;
19632   u8 *sw_if_to_name = 0;
19633   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19634   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19635   hash_pair_t *p;
19636
19637   /* *INDENT-OFF* */
19638   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19639   ({
19640     if ((u32) p->value[0] == sw_if_index_from)
19641       {
19642         sw_if_from_name = (u8 *)(p->key);
19643         if (sw_if_to_name)
19644           break;
19645       }
19646     if ((u32) p->value[0] == sw_if_index_to)
19647       {
19648         sw_if_to_name = (u8 *)(p->key);
19649         if (sw_if_from_name)
19650           break;
19651       }
19652   }));
19653   /* *INDENT-ON* */
19654
19655   if (VAT_JSON_ARRAY != vam->json_tree.type)
19656     {
19657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19658       vat_json_init_array (&vam->json_tree);
19659     }
19660   node = vat_json_array_add (&vam->json_tree);
19661
19662   vat_json_init_object (node);
19663   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19664   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19665   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19666   if (0 != sw_if_to_name)
19667     {
19668       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19669     }
19670   vat_json_object_add_uint (node, "state", mp->state);
19671   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19672 }
19673
19674 static int
19675 api_sw_interface_span_dump (vat_main_t * vam)
19676 {
19677   unformat_input_t *input = vam->input;
19678   vl_api_sw_interface_span_dump_t *mp;
19679   vl_api_control_ping_t *mp_ping;
19680   u8 is_l2 = 0;
19681   int ret;
19682
19683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19684     {
19685       if (unformat (input, "l2"))
19686         is_l2 = 1;
19687       else
19688         break;
19689     }
19690
19691   M (SW_INTERFACE_SPAN_DUMP, mp);
19692   mp->is_l2 = is_l2;
19693   S (mp);
19694
19695   /* Use a control ping for synchronization */
19696   MPING (CONTROL_PING, mp_ping);
19697   S (mp_ping);
19698
19699   W (ret);
19700   return ret;
19701 }
19702
19703 int
19704 api_pg_create_interface (vat_main_t * vam)
19705 {
19706   unformat_input_t *input = vam->input;
19707   vl_api_pg_create_interface_t *mp;
19708
19709   u32 if_id = ~0, gso_size = 0;
19710   u8 gso_enabled = 0;
19711   int ret;
19712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19713     {
19714       if (unformat (input, "if_id %d", &if_id))
19715         ;
19716       else if (unformat (input, "gso-enabled"))
19717         {
19718           gso_enabled = 1;
19719           if (unformat (input, "gso-size %u", &gso_size))
19720             ;
19721           else
19722             {
19723               errmsg ("missing gso-size");
19724               return -99;
19725             }
19726         }
19727       else
19728         break;
19729     }
19730   if (if_id == ~0)
19731     {
19732       errmsg ("missing pg interface index");
19733       return -99;
19734     }
19735
19736   /* Construct the API message */
19737   M (PG_CREATE_INTERFACE, mp);
19738   mp->context = 0;
19739   mp->interface_id = ntohl (if_id);
19740   mp->gso_enabled = gso_enabled;
19741
19742   S (mp);
19743   W (ret);
19744   return ret;
19745 }
19746
19747 int
19748 api_pg_capture (vat_main_t * vam)
19749 {
19750   unformat_input_t *input = vam->input;
19751   vl_api_pg_capture_t *mp;
19752
19753   u32 if_id = ~0;
19754   u8 enable = 1;
19755   u32 count = 1;
19756   u8 pcap_file_set = 0;
19757   u8 *pcap_file = 0;
19758   int ret;
19759   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19760     {
19761       if (unformat (input, "if_id %d", &if_id))
19762         ;
19763       else if (unformat (input, "pcap %s", &pcap_file))
19764         pcap_file_set = 1;
19765       else if (unformat (input, "count %d", &count))
19766         ;
19767       else if (unformat (input, "disable"))
19768         enable = 0;
19769       else
19770         break;
19771     }
19772   if (if_id == ~0)
19773     {
19774       errmsg ("missing pg interface index");
19775       return -99;
19776     }
19777   if (pcap_file_set > 0)
19778     {
19779       if (vec_len (pcap_file) > 255)
19780         {
19781           errmsg ("pcap file name is too long");
19782           return -99;
19783         }
19784     }
19785
19786   u32 name_len = vec_len (pcap_file);
19787   /* Construct the API message */
19788   M (PG_CAPTURE, mp);
19789   mp->context = 0;
19790   mp->interface_id = ntohl (if_id);
19791   mp->is_enabled = enable;
19792   mp->count = ntohl (count);
19793   mp->pcap_name_length = ntohl (name_len);
19794   if (pcap_file_set != 0)
19795     {
19796       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19797     }
19798   vec_free (pcap_file);
19799
19800   S (mp);
19801   W (ret);
19802   return ret;
19803 }
19804
19805 int
19806 api_pg_enable_disable (vat_main_t * vam)
19807 {
19808   unformat_input_t *input = vam->input;
19809   vl_api_pg_enable_disable_t *mp;
19810
19811   u8 enable = 1;
19812   u8 stream_name_set = 0;
19813   u8 *stream_name = 0;
19814   int ret;
19815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19816     {
19817       if (unformat (input, "stream %s", &stream_name))
19818         stream_name_set = 1;
19819       else if (unformat (input, "disable"))
19820         enable = 0;
19821       else
19822         break;
19823     }
19824
19825   if (stream_name_set > 0)
19826     {
19827       if (vec_len (stream_name) > 255)
19828         {
19829           errmsg ("stream name too long");
19830           return -99;
19831         }
19832     }
19833
19834   u32 name_len = vec_len (stream_name);
19835   /* Construct the API message */
19836   M (PG_ENABLE_DISABLE, mp);
19837   mp->context = 0;
19838   mp->is_enabled = enable;
19839   if (stream_name_set != 0)
19840     {
19841       mp->stream_name_length = ntohl (name_len);
19842       clib_memcpy (mp->stream_name, stream_name, name_len);
19843     }
19844   vec_free (stream_name);
19845
19846   S (mp);
19847   W (ret);
19848   return ret;
19849 }
19850
19851 int
19852 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19853 {
19854   unformat_input_t *input = vam->input;
19855   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19856
19857   u16 *low_ports = 0;
19858   u16 *high_ports = 0;
19859   u16 this_low;
19860   u16 this_hi;
19861   vl_api_prefix_t prefix;
19862   u32 tmp, tmp2;
19863   u8 prefix_set = 0;
19864   u32 vrf_id = ~0;
19865   u8 is_add = 1;
19866   int ret;
19867
19868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19869     {
19870       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19871         prefix_set = 1;
19872       else if (unformat (input, "vrf %d", &vrf_id))
19873         ;
19874       else if (unformat (input, "del"))
19875         is_add = 0;
19876       else if (unformat (input, "port %d", &tmp))
19877         {
19878           if (tmp == 0 || tmp > 65535)
19879             {
19880               errmsg ("port %d out of range", tmp);
19881               return -99;
19882             }
19883           this_low = tmp;
19884           this_hi = this_low + 1;
19885           vec_add1 (low_ports, this_low);
19886           vec_add1 (high_ports, this_hi);
19887         }
19888       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19889         {
19890           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19891             {
19892               errmsg ("incorrect range parameters");
19893               return -99;
19894             }
19895           this_low = tmp;
19896           /* Note: in debug CLI +1 is added to high before
19897              passing to real fn that does "the work"
19898              (ip_source_and_port_range_check_add_del).
19899              This fn is a wrapper around the binary API fn a
19900              control plane will call, which expects this increment
19901              to have occurred. Hence letting the binary API control
19902              plane fn do the increment for consistency between VAT
19903              and other control planes.
19904            */
19905           this_hi = tmp2;
19906           vec_add1 (low_ports, this_low);
19907           vec_add1 (high_ports, this_hi);
19908         }
19909       else
19910         break;
19911     }
19912
19913   if (prefix_set == 0)
19914     {
19915       errmsg ("<address>/<mask> not specified");
19916       return -99;
19917     }
19918
19919   if (vrf_id == ~0)
19920     {
19921       errmsg ("VRF ID required, not specified");
19922       return -99;
19923     }
19924
19925   if (vrf_id == 0)
19926     {
19927       errmsg
19928         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19929       return -99;
19930     }
19931
19932   if (vec_len (low_ports) == 0)
19933     {
19934       errmsg ("At least one port or port range required");
19935       return -99;
19936     }
19937
19938   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19939
19940   mp->is_add = is_add;
19941
19942   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19943
19944   mp->number_of_ranges = vec_len (low_ports);
19945
19946   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19947   vec_free (low_ports);
19948
19949   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19950   vec_free (high_ports);
19951
19952   mp->vrf_id = ntohl (vrf_id);
19953
19954   S (mp);
19955   W (ret);
19956   return ret;
19957 }
19958
19959 int
19960 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19961 {
19962   unformat_input_t *input = vam->input;
19963   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19964   u32 sw_if_index = ~0;
19965   int vrf_set = 0;
19966   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19967   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19968   u8 is_add = 1;
19969   int ret;
19970
19971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19972     {
19973       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19974         ;
19975       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19976         ;
19977       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19978         vrf_set = 1;
19979       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19980         vrf_set = 1;
19981       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19982         vrf_set = 1;
19983       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19984         vrf_set = 1;
19985       else if (unformat (input, "del"))
19986         is_add = 0;
19987       else
19988         break;
19989     }
19990
19991   if (sw_if_index == ~0)
19992     {
19993       errmsg ("Interface required but not specified");
19994       return -99;
19995     }
19996
19997   if (vrf_set == 0)
19998     {
19999       errmsg ("VRF ID required but not specified");
20000       return -99;
20001     }
20002
20003   if (tcp_out_vrf_id == 0
20004       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20005     {
20006       errmsg
20007         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20008       return -99;
20009     }
20010
20011   /* Construct the API message */
20012   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20013
20014   mp->sw_if_index = ntohl (sw_if_index);
20015   mp->is_add = is_add;
20016   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20017   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20018   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20019   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20020
20021   /* send it... */
20022   S (mp);
20023
20024   /* Wait for a reply... */
20025   W (ret);
20026   return ret;
20027 }
20028
20029 static int
20030 api_set_punt (vat_main_t * vam)
20031 {
20032   unformat_input_t *i = vam->input;
20033   vl_api_address_family_t af;
20034   vl_api_set_punt_t *mp;
20035   u32 protocol = ~0;
20036   u32 port = ~0;
20037   int is_add = 1;
20038   int ret;
20039
20040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20041     {
20042       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20043         ;
20044       else if (unformat (i, "protocol %d", &protocol))
20045         ;
20046       else if (unformat (i, "port %d", &port))
20047         ;
20048       else if (unformat (i, "del"))
20049         is_add = 0;
20050       else
20051         {
20052           clib_warning ("parse error '%U'", format_unformat_error, i);
20053           return -99;
20054         }
20055     }
20056
20057   M (SET_PUNT, mp);
20058
20059   mp->is_add = (u8) is_add;
20060   mp->punt.type = PUNT_API_TYPE_L4;
20061   mp->punt.punt.l4.af = af;
20062   mp->punt.punt.l4.protocol = (u8) protocol;
20063   mp->punt.punt.l4.port = htons ((u16) port);
20064
20065   S (mp);
20066   W (ret);
20067   return ret;
20068 }
20069
20070 static int
20071 api_delete_subif (vat_main_t * vam)
20072 {
20073   unformat_input_t *i = vam->input;
20074   vl_api_delete_subif_t *mp;
20075   u32 sw_if_index = ~0;
20076   int ret;
20077
20078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20079     {
20080       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20081         ;
20082       if (unformat (i, "sw_if_index %d", &sw_if_index))
20083         ;
20084       else
20085         break;
20086     }
20087
20088   if (sw_if_index == ~0)
20089     {
20090       errmsg ("missing sw_if_index");
20091       return -99;
20092     }
20093
20094   /* Construct the API message */
20095   M (DELETE_SUBIF, mp);
20096   mp->sw_if_index = ntohl (sw_if_index);
20097
20098   S (mp);
20099   W (ret);
20100   return ret;
20101 }
20102
20103 #define foreach_pbb_vtr_op      \
20104 _("disable",  L2_VTR_DISABLED)  \
20105 _("pop",  L2_VTR_POP_2)         \
20106 _("push",  L2_VTR_PUSH_2)
20107
20108 static int
20109 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20110 {
20111   unformat_input_t *i = vam->input;
20112   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20113   u32 sw_if_index = ~0, vtr_op = ~0;
20114   u16 outer_tag = ~0;
20115   u8 dmac[6], smac[6];
20116   u8 dmac_set = 0, smac_set = 0;
20117   u16 vlanid = 0;
20118   u32 sid = ~0;
20119   u32 tmp;
20120   int ret;
20121
20122   /* Shut up coverity */
20123   clib_memset (dmac, 0, sizeof (dmac));
20124   clib_memset (smac, 0, sizeof (smac));
20125
20126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20127     {
20128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20129         ;
20130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20131         ;
20132       else if (unformat (i, "vtr_op %d", &vtr_op))
20133         ;
20134 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20135       foreach_pbb_vtr_op
20136 #undef _
20137         else if (unformat (i, "translate_pbb_stag"))
20138         {
20139           if (unformat (i, "%d", &tmp))
20140             {
20141               vtr_op = L2_VTR_TRANSLATE_2_1;
20142               outer_tag = tmp;
20143             }
20144           else
20145             {
20146               errmsg
20147                 ("translate_pbb_stag operation requires outer tag definition");
20148               return -99;
20149             }
20150         }
20151       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20152         dmac_set++;
20153       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20154         smac_set++;
20155       else if (unformat (i, "sid %d", &sid))
20156         ;
20157       else if (unformat (i, "vlanid %d", &tmp))
20158         vlanid = tmp;
20159       else
20160         {
20161           clib_warning ("parse error '%U'", format_unformat_error, i);
20162           return -99;
20163         }
20164     }
20165
20166   if ((sw_if_index == ~0) || (vtr_op == ~0))
20167     {
20168       errmsg ("missing sw_if_index or vtr operation");
20169       return -99;
20170     }
20171   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20172       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20173     {
20174       errmsg
20175         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20176       return -99;
20177     }
20178
20179   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20180   mp->sw_if_index = ntohl (sw_if_index);
20181   mp->vtr_op = ntohl (vtr_op);
20182   mp->outer_tag = ntohs (outer_tag);
20183   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20184   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20185   mp->b_vlanid = ntohs (vlanid);
20186   mp->i_sid = ntohl (sid);
20187
20188   S (mp);
20189   W (ret);
20190   return ret;
20191 }
20192
20193 static int
20194 api_flow_classify_set_interface (vat_main_t * vam)
20195 {
20196   unformat_input_t *i = vam->input;
20197   vl_api_flow_classify_set_interface_t *mp;
20198   u32 sw_if_index;
20199   int sw_if_index_set;
20200   u32 ip4_table_index = ~0;
20201   u32 ip6_table_index = ~0;
20202   u8 is_add = 1;
20203   int ret;
20204
20205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20206     {
20207       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20208         sw_if_index_set = 1;
20209       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20210         sw_if_index_set = 1;
20211       else if (unformat (i, "del"))
20212         is_add = 0;
20213       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20214         ;
20215       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20216         ;
20217       else
20218         {
20219           clib_warning ("parse error '%U'", format_unformat_error, i);
20220           return -99;
20221         }
20222     }
20223
20224   if (sw_if_index_set == 0)
20225     {
20226       errmsg ("missing interface name or sw_if_index");
20227       return -99;
20228     }
20229
20230   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20231
20232   mp->sw_if_index = ntohl (sw_if_index);
20233   mp->ip4_table_index = ntohl (ip4_table_index);
20234   mp->ip6_table_index = ntohl (ip6_table_index);
20235   mp->is_add = is_add;
20236
20237   S (mp);
20238   W (ret);
20239   return ret;
20240 }
20241
20242 static int
20243 api_flow_classify_dump (vat_main_t * vam)
20244 {
20245   unformat_input_t *i = vam->input;
20246   vl_api_flow_classify_dump_t *mp;
20247   vl_api_control_ping_t *mp_ping;
20248   u8 type = FLOW_CLASSIFY_N_TABLES;
20249   int ret;
20250
20251   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20252     ;
20253   else
20254     {
20255       errmsg ("classify table type must be specified");
20256       return -99;
20257     }
20258
20259   if (!vam->json_output)
20260     {
20261       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20262     }
20263
20264   M (FLOW_CLASSIFY_DUMP, mp);
20265   mp->type = type;
20266   /* send it... */
20267   S (mp);
20268
20269   /* Use a control ping for synchronization */
20270   MPING (CONTROL_PING, mp_ping);
20271   S (mp_ping);
20272
20273   /* Wait for a reply... */
20274   W (ret);
20275   return ret;
20276 }
20277
20278 static int
20279 api_feature_enable_disable (vat_main_t * vam)
20280 {
20281   unformat_input_t *i = vam->input;
20282   vl_api_feature_enable_disable_t *mp;
20283   u8 *arc_name = 0;
20284   u8 *feature_name = 0;
20285   u32 sw_if_index = ~0;
20286   u8 enable = 1;
20287   int ret;
20288
20289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20290     {
20291       if (unformat (i, "arc_name %s", &arc_name))
20292         ;
20293       else if (unformat (i, "feature_name %s", &feature_name))
20294         ;
20295       else
20296         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20297         ;
20298       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20299         ;
20300       else if (unformat (i, "disable"))
20301         enable = 0;
20302       else
20303         break;
20304     }
20305
20306   if (arc_name == 0)
20307     {
20308       errmsg ("missing arc name");
20309       return -99;
20310     }
20311   if (vec_len (arc_name) > 63)
20312     {
20313       errmsg ("arc name too long");
20314     }
20315
20316   if (feature_name == 0)
20317     {
20318       errmsg ("missing feature name");
20319       return -99;
20320     }
20321   if (vec_len (feature_name) > 63)
20322     {
20323       errmsg ("feature name too long");
20324     }
20325
20326   if (sw_if_index == ~0)
20327     {
20328       errmsg ("missing interface name or sw_if_index");
20329       return -99;
20330     }
20331
20332   /* Construct the API message */
20333   M (FEATURE_ENABLE_DISABLE, mp);
20334   mp->sw_if_index = ntohl (sw_if_index);
20335   mp->enable = enable;
20336   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20337   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20338   vec_free (arc_name);
20339   vec_free (feature_name);
20340
20341   S (mp);
20342   W (ret);
20343   return ret;
20344 }
20345
20346 static int
20347 api_sw_interface_tag_add_del (vat_main_t * vam)
20348 {
20349   unformat_input_t *i = vam->input;
20350   vl_api_sw_interface_tag_add_del_t *mp;
20351   u32 sw_if_index = ~0;
20352   u8 *tag = 0;
20353   u8 enable = 1;
20354   int ret;
20355
20356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20357     {
20358       if (unformat (i, "tag %s", &tag))
20359         ;
20360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20361         ;
20362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20363         ;
20364       else if (unformat (i, "del"))
20365         enable = 0;
20366       else
20367         break;
20368     }
20369
20370   if (sw_if_index == ~0)
20371     {
20372       errmsg ("missing interface name or sw_if_index");
20373       return -99;
20374     }
20375
20376   if (enable && (tag == 0))
20377     {
20378       errmsg ("no tag specified");
20379       return -99;
20380     }
20381
20382   /* Construct the API message */
20383   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20384   mp->sw_if_index = ntohl (sw_if_index);
20385   mp->is_add = enable;
20386   if (enable)
20387     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20388   vec_free (tag);
20389
20390   S (mp);
20391   W (ret);
20392   return ret;
20393 }
20394
20395 static void vl_api_l2_xconnect_details_t_handler
20396   (vl_api_l2_xconnect_details_t * mp)
20397 {
20398   vat_main_t *vam = &vat_main;
20399
20400   print (vam->ofp, "%15d%15d",
20401          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20402 }
20403
20404 static void vl_api_l2_xconnect_details_t_handler_json
20405   (vl_api_l2_xconnect_details_t * mp)
20406 {
20407   vat_main_t *vam = &vat_main;
20408   vat_json_node_t *node = NULL;
20409
20410   if (VAT_JSON_ARRAY != vam->json_tree.type)
20411     {
20412       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20413       vat_json_init_array (&vam->json_tree);
20414     }
20415   node = vat_json_array_add (&vam->json_tree);
20416
20417   vat_json_init_object (node);
20418   vat_json_object_add_uint (node, "rx_sw_if_index",
20419                             ntohl (mp->rx_sw_if_index));
20420   vat_json_object_add_uint (node, "tx_sw_if_index",
20421                             ntohl (mp->tx_sw_if_index));
20422 }
20423
20424 static int
20425 api_l2_xconnect_dump (vat_main_t * vam)
20426 {
20427   vl_api_l2_xconnect_dump_t *mp;
20428   vl_api_control_ping_t *mp_ping;
20429   int ret;
20430
20431   if (!vam->json_output)
20432     {
20433       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20434     }
20435
20436   M (L2_XCONNECT_DUMP, mp);
20437
20438   S (mp);
20439
20440   /* Use a control ping for synchronization */
20441   MPING (CONTROL_PING, mp_ping);
20442   S (mp_ping);
20443
20444   W (ret);
20445   return ret;
20446 }
20447
20448 static int
20449 api_hw_interface_set_mtu (vat_main_t * vam)
20450 {
20451   unformat_input_t *i = vam->input;
20452   vl_api_hw_interface_set_mtu_t *mp;
20453   u32 sw_if_index = ~0;
20454   u32 mtu = 0;
20455   int ret;
20456
20457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20458     {
20459       if (unformat (i, "mtu %d", &mtu))
20460         ;
20461       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20462         ;
20463       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20464         ;
20465       else
20466         break;
20467     }
20468
20469   if (sw_if_index == ~0)
20470     {
20471       errmsg ("missing interface name or sw_if_index");
20472       return -99;
20473     }
20474
20475   if (mtu == 0)
20476     {
20477       errmsg ("no mtu specified");
20478       return -99;
20479     }
20480
20481   /* Construct the API message */
20482   M (HW_INTERFACE_SET_MTU, mp);
20483   mp->sw_if_index = ntohl (sw_if_index);
20484   mp->mtu = ntohs ((u16) mtu);
20485
20486   S (mp);
20487   W (ret);
20488   return ret;
20489 }
20490
20491 static int
20492 api_p2p_ethernet_add (vat_main_t * vam)
20493 {
20494   unformat_input_t *i = vam->input;
20495   vl_api_p2p_ethernet_add_t *mp;
20496   u32 parent_if_index = ~0;
20497   u32 sub_id = ~0;
20498   u8 remote_mac[6];
20499   u8 mac_set = 0;
20500   int ret;
20501
20502   clib_memset (remote_mac, 0, sizeof (remote_mac));
20503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20504     {
20505       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20506         ;
20507       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20508         ;
20509       else
20510         if (unformat
20511             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20512         mac_set++;
20513       else if (unformat (i, "sub_id %d", &sub_id))
20514         ;
20515       else
20516         {
20517           clib_warning ("parse error '%U'", format_unformat_error, i);
20518           return -99;
20519         }
20520     }
20521
20522   if (parent_if_index == ~0)
20523     {
20524       errmsg ("missing interface name or sw_if_index");
20525       return -99;
20526     }
20527   if (mac_set == 0)
20528     {
20529       errmsg ("missing remote mac address");
20530       return -99;
20531     }
20532   if (sub_id == ~0)
20533     {
20534       errmsg ("missing sub-interface id");
20535       return -99;
20536     }
20537
20538   M (P2P_ETHERNET_ADD, mp);
20539   mp->parent_if_index = ntohl (parent_if_index);
20540   mp->subif_id = ntohl (sub_id);
20541   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20542
20543   S (mp);
20544   W (ret);
20545   return ret;
20546 }
20547
20548 static int
20549 api_p2p_ethernet_del (vat_main_t * vam)
20550 {
20551   unformat_input_t *i = vam->input;
20552   vl_api_p2p_ethernet_del_t *mp;
20553   u32 parent_if_index = ~0;
20554   u8 remote_mac[6];
20555   u8 mac_set = 0;
20556   int ret;
20557
20558   clib_memset (remote_mac, 0, sizeof (remote_mac));
20559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20560     {
20561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20562         ;
20563       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20564         ;
20565       else
20566         if (unformat
20567             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20568         mac_set++;
20569       else
20570         {
20571           clib_warning ("parse error '%U'", format_unformat_error, i);
20572           return -99;
20573         }
20574     }
20575
20576   if (parent_if_index == ~0)
20577     {
20578       errmsg ("missing interface name or sw_if_index");
20579       return -99;
20580     }
20581   if (mac_set == 0)
20582     {
20583       errmsg ("missing remote mac address");
20584       return -99;
20585     }
20586
20587   M (P2P_ETHERNET_DEL, mp);
20588   mp->parent_if_index = ntohl (parent_if_index);
20589   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20590
20591   S (mp);
20592   W (ret);
20593   return ret;
20594 }
20595
20596 static int
20597 api_lldp_config (vat_main_t * vam)
20598 {
20599   unformat_input_t *i = vam->input;
20600   vl_api_lldp_config_t *mp;
20601   int tx_hold = 0;
20602   int tx_interval = 0;
20603   u8 *sys_name = NULL;
20604   int ret;
20605
20606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20607     {
20608       if (unformat (i, "system-name %s", &sys_name))
20609         ;
20610       else if (unformat (i, "tx-hold %d", &tx_hold))
20611         ;
20612       else if (unformat (i, "tx-interval %d", &tx_interval))
20613         ;
20614       else
20615         {
20616           clib_warning ("parse error '%U'", format_unformat_error, i);
20617           return -99;
20618         }
20619     }
20620
20621   vec_add1 (sys_name, 0);
20622
20623   M (LLDP_CONFIG, mp);
20624   mp->tx_hold = htonl (tx_hold);
20625   mp->tx_interval = htonl (tx_interval);
20626   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20627   vec_free (sys_name);
20628
20629   S (mp);
20630   W (ret);
20631   return ret;
20632 }
20633
20634 static int
20635 api_sw_interface_set_lldp (vat_main_t * vam)
20636 {
20637   unformat_input_t *i = vam->input;
20638   vl_api_sw_interface_set_lldp_t *mp;
20639   u32 sw_if_index = ~0;
20640   u32 enable = 1;
20641   u8 *port_desc = NULL, *mgmt_oid = NULL;
20642   ip4_address_t ip4_addr;
20643   ip6_address_t ip6_addr;
20644   int ret;
20645
20646   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20647   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20648
20649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20650     {
20651       if (unformat (i, "disable"))
20652         enable = 0;
20653       else
20654         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20655         ;
20656       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20657         ;
20658       else if (unformat (i, "port-desc %s", &port_desc))
20659         ;
20660       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20661         ;
20662       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20663         ;
20664       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20665         ;
20666       else
20667         break;
20668     }
20669
20670   if (sw_if_index == ~0)
20671     {
20672       errmsg ("missing interface name or sw_if_index");
20673       return -99;
20674     }
20675
20676   /* Construct the API message */
20677   vec_add1 (port_desc, 0);
20678   vec_add1 (mgmt_oid, 0);
20679   M (SW_INTERFACE_SET_LLDP, mp);
20680   mp->sw_if_index = ntohl (sw_if_index);
20681   mp->enable = enable;
20682   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20683   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20684   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20685   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20686   vec_free (port_desc);
20687   vec_free (mgmt_oid);
20688
20689   S (mp);
20690   W (ret);
20691   return ret;
20692 }
20693
20694 static int
20695 api_tcp_configure_src_addresses (vat_main_t * vam)
20696 {
20697   vl_api_tcp_configure_src_addresses_t *mp;
20698   unformat_input_t *i = vam->input;
20699   ip4_address_t v4first, v4last;
20700   ip6_address_t v6first, v6last;
20701   u8 range_set = 0;
20702   u32 vrf_id = 0;
20703   int ret;
20704
20705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20706     {
20707       if (unformat (i, "%U - %U",
20708                     unformat_ip4_address, &v4first,
20709                     unformat_ip4_address, &v4last))
20710         {
20711           if (range_set)
20712             {
20713               errmsg ("one range per message (range already set)");
20714               return -99;
20715             }
20716           range_set = 1;
20717         }
20718       else if (unformat (i, "%U - %U",
20719                          unformat_ip6_address, &v6first,
20720                          unformat_ip6_address, &v6last))
20721         {
20722           if (range_set)
20723             {
20724               errmsg ("one range per message (range already set)");
20725               return -99;
20726             }
20727           range_set = 2;
20728         }
20729       else if (unformat (i, "vrf %d", &vrf_id))
20730         ;
20731       else
20732         break;
20733     }
20734
20735   if (range_set == 0)
20736     {
20737       errmsg ("address range not set");
20738       return -99;
20739     }
20740
20741   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20742   mp->vrf_id = ntohl (vrf_id);
20743   /* ipv6? */
20744   if (range_set == 2)
20745     {
20746       mp->is_ipv6 = 1;
20747       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20748       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20749     }
20750   else
20751     {
20752       mp->is_ipv6 = 0;
20753       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20754       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20755     }
20756   S (mp);
20757   W (ret);
20758   return ret;
20759 }
20760
20761 static void vl_api_app_namespace_add_del_reply_t_handler
20762   (vl_api_app_namespace_add_del_reply_t * mp)
20763 {
20764   vat_main_t *vam = &vat_main;
20765   i32 retval = ntohl (mp->retval);
20766   if (vam->async_mode)
20767     {
20768       vam->async_errors += (retval < 0);
20769     }
20770   else
20771     {
20772       vam->retval = retval;
20773       if (retval == 0)
20774         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20775       vam->result_ready = 1;
20776     }
20777 }
20778
20779 static void vl_api_app_namespace_add_del_reply_t_handler_json
20780   (vl_api_app_namespace_add_del_reply_t * mp)
20781 {
20782   vat_main_t *vam = &vat_main;
20783   vat_json_node_t node;
20784
20785   vat_json_init_object (&node);
20786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20787   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20788
20789   vat_json_print (vam->ofp, &node);
20790   vat_json_free (&node);
20791
20792   vam->retval = ntohl (mp->retval);
20793   vam->result_ready = 1;
20794 }
20795
20796 static int
20797 api_app_namespace_add_del (vat_main_t * vam)
20798 {
20799   vl_api_app_namespace_add_del_t *mp;
20800   unformat_input_t *i = vam->input;
20801   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20802   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20803   u64 secret;
20804   int ret;
20805
20806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20807     {
20808       if (unformat (i, "id %_%v%_", &ns_id))
20809         ;
20810       else if (unformat (i, "secret %lu", &secret))
20811         secret_set = 1;
20812       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20813         sw_if_index_set = 1;
20814       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20815         ;
20816       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20817         ;
20818       else
20819         break;
20820     }
20821   if (!ns_id || !secret_set || !sw_if_index_set)
20822     {
20823       errmsg ("namespace id, secret and sw_if_index must be set");
20824       return -99;
20825     }
20826   if (vec_len (ns_id) > 64)
20827     {
20828       errmsg ("namespace id too long");
20829       return -99;
20830     }
20831   M (APP_NAMESPACE_ADD_DEL, mp);
20832
20833   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20834   mp->namespace_id_len = vec_len (ns_id);
20835   mp->secret = clib_host_to_net_u64 (secret);
20836   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20837   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20838   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20839   vec_free (ns_id);
20840   S (mp);
20841   W (ret);
20842   return ret;
20843 }
20844
20845 static int
20846 api_sock_init_shm (vat_main_t * vam)
20847 {
20848 #if VPP_API_TEST_BUILTIN == 0
20849   unformat_input_t *i = vam->input;
20850   vl_api_shm_elem_config_t *config = 0;
20851   u64 size = 64 << 20;
20852   int rv;
20853
20854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20855     {
20856       if (unformat (i, "size %U", unformat_memory_size, &size))
20857         ;
20858       else
20859         break;
20860     }
20861
20862   /*
20863    * Canned custom ring allocator config.
20864    * Should probably parse all of this
20865    */
20866   vec_validate (config, 6);
20867   config[0].type = VL_API_VLIB_RING;
20868   config[0].size = 256;
20869   config[0].count = 32;
20870
20871   config[1].type = VL_API_VLIB_RING;
20872   config[1].size = 1024;
20873   config[1].count = 16;
20874
20875   config[2].type = VL_API_VLIB_RING;
20876   config[2].size = 4096;
20877   config[2].count = 2;
20878
20879   config[3].type = VL_API_CLIENT_RING;
20880   config[3].size = 256;
20881   config[3].count = 32;
20882
20883   config[4].type = VL_API_CLIENT_RING;
20884   config[4].size = 1024;
20885   config[4].count = 16;
20886
20887   config[5].type = VL_API_CLIENT_RING;
20888   config[5].size = 4096;
20889   config[5].count = 2;
20890
20891   config[6].type = VL_API_QUEUE;
20892   config[6].count = 128;
20893   config[6].size = sizeof (uword);
20894
20895   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20896   if (!rv)
20897     vam->client_index_invalid = 1;
20898   return rv;
20899 #else
20900   return -99;
20901 #endif
20902 }
20903
20904 static void
20905 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20906 {
20907   vat_main_t *vam = &vat_main;
20908
20909   if (mp->is_ip4)
20910     {
20911       print (vam->ofp,
20912              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20913              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20914              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20915              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20916              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20917              clib_net_to_host_u32 (mp->action_index), mp->tag);
20918     }
20919   else
20920     {
20921       print (vam->ofp,
20922              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20923              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20924              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20925              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20926              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20927              clib_net_to_host_u32 (mp->action_index), mp->tag);
20928     }
20929 }
20930
20931 static void
20932 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20933                                              mp)
20934 {
20935   vat_main_t *vam = &vat_main;
20936   vat_json_node_t *node = NULL;
20937   struct in6_addr ip6;
20938   struct in_addr ip4;
20939
20940   if (VAT_JSON_ARRAY != vam->json_tree.type)
20941     {
20942       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20943       vat_json_init_array (&vam->json_tree);
20944     }
20945   node = vat_json_array_add (&vam->json_tree);
20946   vat_json_init_object (node);
20947
20948   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20949   vat_json_object_add_uint (node, "appns_index",
20950                             clib_net_to_host_u32 (mp->appns_index));
20951   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20952   vat_json_object_add_uint (node, "scope", mp->scope);
20953   vat_json_object_add_uint (node, "action_index",
20954                             clib_net_to_host_u32 (mp->action_index));
20955   vat_json_object_add_uint (node, "lcl_port",
20956                             clib_net_to_host_u16 (mp->lcl_port));
20957   vat_json_object_add_uint (node, "rmt_port",
20958                             clib_net_to_host_u16 (mp->rmt_port));
20959   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20960   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20961   vat_json_object_add_string_copy (node, "tag", mp->tag);
20962   if (mp->is_ip4)
20963     {
20964       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20965       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20966       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20967       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20968     }
20969   else
20970     {
20971       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20972       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20973       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20974       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20975     }
20976 }
20977
20978 static int
20979 api_session_rule_add_del (vat_main_t * vam)
20980 {
20981   vl_api_session_rule_add_del_t *mp;
20982   unformat_input_t *i = vam->input;
20983   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20984   u32 appns_index = 0, scope = 0;
20985   ip4_address_t lcl_ip4, rmt_ip4;
20986   ip6_address_t lcl_ip6, rmt_ip6;
20987   u8 is_ip4 = 1, conn_set = 0;
20988   u8 is_add = 1, *tag = 0;
20989   int ret;
20990
20991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20992     {
20993       if (unformat (i, "del"))
20994         is_add = 0;
20995       else if (unformat (i, "add"))
20996         ;
20997       else if (unformat (i, "proto tcp"))
20998         proto = 0;
20999       else if (unformat (i, "proto udp"))
21000         proto = 1;
21001       else if (unformat (i, "appns %d", &appns_index))
21002         ;
21003       else if (unformat (i, "scope %d", &scope))
21004         ;
21005       else if (unformat (i, "tag %_%v%_", &tag))
21006         ;
21007       else
21008         if (unformat
21009             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21010              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21011              &rmt_port))
21012         {
21013           is_ip4 = 1;
21014           conn_set = 1;
21015         }
21016       else
21017         if (unformat
21018             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21019              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21020              &rmt_port))
21021         {
21022           is_ip4 = 0;
21023           conn_set = 1;
21024         }
21025       else if (unformat (i, "action %d", &action))
21026         ;
21027       else
21028         break;
21029     }
21030   if (proto == ~0 || !conn_set || action == ~0)
21031     {
21032       errmsg ("transport proto, connection and action must be set");
21033       return -99;
21034     }
21035
21036   if (scope > 3)
21037     {
21038       errmsg ("scope should be 0-3");
21039       return -99;
21040     }
21041
21042   M (SESSION_RULE_ADD_DEL, mp);
21043
21044   mp->is_ip4 = is_ip4;
21045   mp->transport_proto = proto;
21046   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21047   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21048   mp->lcl_plen = lcl_plen;
21049   mp->rmt_plen = rmt_plen;
21050   mp->action_index = clib_host_to_net_u32 (action);
21051   mp->appns_index = clib_host_to_net_u32 (appns_index);
21052   mp->scope = scope;
21053   mp->is_add = is_add;
21054   if (is_ip4)
21055     {
21056       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21057       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21058     }
21059   else
21060     {
21061       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21062       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21063     }
21064   if (tag)
21065     {
21066       clib_memcpy (mp->tag, tag, vec_len (tag));
21067       vec_free (tag);
21068     }
21069
21070   S (mp);
21071   W (ret);
21072   return ret;
21073 }
21074
21075 static int
21076 api_session_rules_dump (vat_main_t * vam)
21077 {
21078   vl_api_session_rules_dump_t *mp;
21079   vl_api_control_ping_t *mp_ping;
21080   int ret;
21081
21082   if (!vam->json_output)
21083     {
21084       print (vam->ofp, "%=20s", "Session Rules");
21085     }
21086
21087   M (SESSION_RULES_DUMP, mp);
21088   /* send it... */
21089   S (mp);
21090
21091   /* Use a control ping for synchronization */
21092   MPING (CONTROL_PING, mp_ping);
21093   S (mp_ping);
21094
21095   /* Wait for a reply... */
21096   W (ret);
21097   return ret;
21098 }
21099
21100 static int
21101 api_ip_container_proxy_add_del (vat_main_t * vam)
21102 {
21103   vl_api_ip_container_proxy_add_del_t *mp;
21104   unformat_input_t *i = vam->input;
21105   u32 sw_if_index = ~0;
21106   vl_api_prefix_t pfx = { };
21107   u8 is_add = 1;
21108   int ret;
21109
21110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21111     {
21112       if (unformat (i, "del"))
21113         is_add = 0;
21114       else if (unformat (i, "add"))
21115         ;
21116       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21117         ;
21118       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21119         ;
21120       else
21121         break;
21122     }
21123   if (sw_if_index == ~0 || pfx.len == 0)
21124     {
21125       errmsg ("address and sw_if_index must be set");
21126       return -99;
21127     }
21128
21129   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21130
21131   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21132   mp->is_add = is_add;
21133   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21134
21135   S (mp);
21136   W (ret);
21137   return ret;
21138 }
21139
21140 static int
21141 api_qos_record_enable_disable (vat_main_t * vam)
21142 {
21143   unformat_input_t *i = vam->input;
21144   vl_api_qos_record_enable_disable_t *mp;
21145   u32 sw_if_index, qs = 0xff;
21146   u8 sw_if_index_set = 0;
21147   u8 enable = 1;
21148   int ret;
21149
21150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21151     {
21152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21153         sw_if_index_set = 1;
21154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21155         sw_if_index_set = 1;
21156       else if (unformat (i, "%U", unformat_qos_source, &qs))
21157         ;
21158       else if (unformat (i, "disable"))
21159         enable = 0;
21160       else
21161         {
21162           clib_warning ("parse error '%U'", format_unformat_error, i);
21163           return -99;
21164         }
21165     }
21166
21167   if (sw_if_index_set == 0)
21168     {
21169       errmsg ("missing interface name or sw_if_index");
21170       return -99;
21171     }
21172   if (qs == 0xff)
21173     {
21174       errmsg ("input location must be specified");
21175       return -99;
21176     }
21177
21178   M (QOS_RECORD_ENABLE_DISABLE, mp);
21179
21180   mp->record.sw_if_index = ntohl (sw_if_index);
21181   mp->record.input_source = qs;
21182   mp->enable = enable;
21183
21184   S (mp);
21185   W (ret);
21186   return ret;
21187 }
21188
21189
21190 static int
21191 q_or_quit (vat_main_t * vam)
21192 {
21193 #if VPP_API_TEST_BUILTIN == 0
21194   longjmp (vam->jump_buf, 1);
21195 #endif
21196   return 0;                     /* not so much */
21197 }
21198
21199 static int
21200 q (vat_main_t * vam)
21201 {
21202   return q_or_quit (vam);
21203 }
21204
21205 static int
21206 quit (vat_main_t * vam)
21207 {
21208   return q_or_quit (vam);
21209 }
21210
21211 static int
21212 comment (vat_main_t * vam)
21213 {
21214   return 0;
21215 }
21216
21217 static int
21218 elog_save (vat_main_t * vam)
21219 {
21220 #if VPP_API_TEST_BUILTIN == 0
21221   elog_main_t *em = &vam->elog_main;
21222   unformat_input_t *i = vam->input;
21223   char *file, *chroot_file;
21224   clib_error_t *error;
21225
21226   if (!unformat (i, "%s", &file))
21227     {
21228       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21229       return 0;
21230     }
21231
21232   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21233   if (strstr (file, "..") || index (file, '/'))
21234     {
21235       errmsg ("illegal characters in filename '%s'", file);
21236       return 0;
21237     }
21238
21239   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21240
21241   vec_free (file);
21242
21243   errmsg ("Saving %wd of %wd events to %s",
21244           elog_n_events_in_buffer (em),
21245           elog_buffer_capacity (em), chroot_file);
21246
21247   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21248   vec_free (chroot_file);
21249
21250   if (error)
21251     clib_error_report (error);
21252 #else
21253   errmsg ("Use the vpp event loger...");
21254 #endif
21255
21256   return 0;
21257 }
21258
21259 static int
21260 elog_setup (vat_main_t * vam)
21261 {
21262 #if VPP_API_TEST_BUILTIN == 0
21263   elog_main_t *em = &vam->elog_main;
21264   unformat_input_t *i = vam->input;
21265   u32 nevents = 128 << 10;
21266
21267   (void) unformat (i, "nevents %d", &nevents);
21268
21269   elog_init (em, nevents);
21270   vl_api_set_elog_main (em);
21271   vl_api_set_elog_trace_api_messages (1);
21272   errmsg ("Event logger initialized with %u events", nevents);
21273 #else
21274   errmsg ("Use the vpp event loger...");
21275 #endif
21276   return 0;
21277 }
21278
21279 static int
21280 elog_enable (vat_main_t * vam)
21281 {
21282 #if VPP_API_TEST_BUILTIN == 0
21283   elog_main_t *em = &vam->elog_main;
21284
21285   elog_enable_disable (em, 1 /* enable */ );
21286   vl_api_set_elog_trace_api_messages (1);
21287   errmsg ("Event logger enabled...");
21288 #else
21289   errmsg ("Use the vpp event loger...");
21290 #endif
21291   return 0;
21292 }
21293
21294 static int
21295 elog_disable (vat_main_t * vam)
21296 {
21297 #if VPP_API_TEST_BUILTIN == 0
21298   elog_main_t *em = &vam->elog_main;
21299
21300   elog_enable_disable (em, 0 /* enable */ );
21301   vl_api_set_elog_trace_api_messages (1);
21302   errmsg ("Event logger disabled...");
21303 #else
21304   errmsg ("Use the vpp event loger...");
21305 #endif
21306   return 0;
21307 }
21308
21309 static int
21310 statseg (vat_main_t * vam)
21311 {
21312   ssvm_private_t *ssvmp = &vam->stat_segment;
21313   ssvm_shared_header_t *shared_header = ssvmp->sh;
21314   vlib_counter_t **counters;
21315   u64 thread0_index1_packets;
21316   u64 thread0_index1_bytes;
21317   f64 vector_rate, input_rate;
21318   uword *p;
21319
21320   uword *counter_vector_by_name;
21321   if (vam->stat_segment_lockp == 0)
21322     {
21323       errmsg ("Stat segment not mapped...");
21324       return -99;
21325     }
21326
21327   /* look up "/if/rx for sw_if_index 1 as a test */
21328
21329   clib_spinlock_lock (vam->stat_segment_lockp);
21330
21331   counter_vector_by_name = (uword *) shared_header->opaque[1];
21332
21333   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21334   if (p == 0)
21335     {
21336       clib_spinlock_unlock (vam->stat_segment_lockp);
21337       errmsg ("/if/tx not found?");
21338       return -99;
21339     }
21340
21341   /* Fish per-thread vector of combined counters from shared memory */
21342   counters = (vlib_counter_t **) p[0];
21343
21344   if (vec_len (counters[0]) < 2)
21345     {
21346       clib_spinlock_unlock (vam->stat_segment_lockp);
21347       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21348       return -99;
21349     }
21350
21351   /* Read thread 0 sw_if_index 1 counter */
21352   thread0_index1_packets = counters[0][1].packets;
21353   thread0_index1_bytes = counters[0][1].bytes;
21354
21355   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21356   if (p == 0)
21357     {
21358       clib_spinlock_unlock (vam->stat_segment_lockp);
21359       errmsg ("vector_rate not found?");
21360       return -99;
21361     }
21362
21363   vector_rate = *(f64 *) (p[0]);
21364   p = hash_get_mem (counter_vector_by_name, "input_rate");
21365   if (p == 0)
21366     {
21367       clib_spinlock_unlock (vam->stat_segment_lockp);
21368       errmsg ("input_rate not found?");
21369       return -99;
21370     }
21371   input_rate = *(f64 *) (p[0]);
21372
21373   clib_spinlock_unlock (vam->stat_segment_lockp);
21374
21375   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21376          vector_rate, input_rate);
21377   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21378          thread0_index1_packets, thread0_index1_bytes);
21379
21380   return 0;
21381 }
21382
21383 static int
21384 cmd_cmp (void *a1, void *a2)
21385 {
21386   u8 **c1 = a1;
21387   u8 **c2 = a2;
21388
21389   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21390 }
21391
21392 static int
21393 help (vat_main_t * vam)
21394 {
21395   u8 **cmds = 0;
21396   u8 *name = 0;
21397   hash_pair_t *p;
21398   unformat_input_t *i = vam->input;
21399   int j;
21400
21401   if (unformat (i, "%s", &name))
21402     {
21403       uword *hs;
21404
21405       vec_add1 (name, 0);
21406
21407       hs = hash_get_mem (vam->help_by_name, name);
21408       if (hs)
21409         print (vam->ofp, "usage: %s %s", name, hs[0]);
21410       else
21411         print (vam->ofp, "No such msg / command '%s'", name);
21412       vec_free (name);
21413       return 0;
21414     }
21415
21416   print (vam->ofp, "Help is available for the following:");
21417
21418     /* *INDENT-OFF* */
21419     hash_foreach_pair (p, vam->function_by_name,
21420     ({
21421       vec_add1 (cmds, (u8 *)(p->key));
21422     }));
21423     /* *INDENT-ON* */
21424
21425   vec_sort_with_function (cmds, cmd_cmp);
21426
21427   for (j = 0; j < vec_len (cmds); j++)
21428     print (vam->ofp, "%s", cmds[j]);
21429
21430   vec_free (cmds);
21431   return 0;
21432 }
21433
21434 static int
21435 set (vat_main_t * vam)
21436 {
21437   u8 *name = 0, *value = 0;
21438   unformat_input_t *i = vam->input;
21439
21440   if (unformat (i, "%s", &name))
21441     {
21442       /* The input buffer is a vector, not a string. */
21443       value = vec_dup (i->buffer);
21444       vec_delete (value, i->index, 0);
21445       /* Almost certainly has a trailing newline */
21446       if (value[vec_len (value) - 1] == '\n')
21447         value[vec_len (value) - 1] = 0;
21448       /* Make sure it's a proper string, one way or the other */
21449       vec_add1 (value, 0);
21450       (void) clib_macro_set_value (&vam->macro_main,
21451                                    (char *) name, (char *) value);
21452     }
21453   else
21454     errmsg ("usage: set <name> <value>");
21455
21456   vec_free (name);
21457   vec_free (value);
21458   return 0;
21459 }
21460
21461 static int
21462 unset (vat_main_t * vam)
21463 {
21464   u8 *name = 0;
21465
21466   if (unformat (vam->input, "%s", &name))
21467     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21468       errmsg ("unset: %s wasn't set", name);
21469   vec_free (name);
21470   return 0;
21471 }
21472
21473 typedef struct
21474 {
21475   u8 *name;
21476   u8 *value;
21477 } macro_sort_t;
21478
21479
21480 static int
21481 macro_sort_cmp (void *a1, void *a2)
21482 {
21483   macro_sort_t *s1 = a1;
21484   macro_sort_t *s2 = a2;
21485
21486   return strcmp ((char *) (s1->name), (char *) (s2->name));
21487 }
21488
21489 static int
21490 dump_macro_table (vat_main_t * vam)
21491 {
21492   macro_sort_t *sort_me = 0, *sm;
21493   int i;
21494   hash_pair_t *p;
21495
21496     /* *INDENT-OFF* */
21497     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21498     ({
21499       vec_add2 (sort_me, sm, 1);
21500       sm->name = (u8 *)(p->key);
21501       sm->value = (u8 *) (p->value[0]);
21502     }));
21503     /* *INDENT-ON* */
21504
21505   vec_sort_with_function (sort_me, macro_sort_cmp);
21506
21507   if (vec_len (sort_me))
21508     print (vam->ofp, "%-15s%s", "Name", "Value");
21509   else
21510     print (vam->ofp, "The macro table is empty...");
21511
21512   for (i = 0; i < vec_len (sort_me); i++)
21513     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21514   return 0;
21515 }
21516
21517 static int
21518 dump_node_table (vat_main_t * vam)
21519 {
21520   int i, j;
21521   vlib_node_t *node, *next_node;
21522
21523   if (vec_len (vam->graph_nodes) == 0)
21524     {
21525       print (vam->ofp, "Node table empty, issue get_node_graph...");
21526       return 0;
21527     }
21528
21529   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21530     {
21531       node = vam->graph_nodes[0][i];
21532       print (vam->ofp, "[%d] %s", i, node->name);
21533       for (j = 0; j < vec_len (node->next_nodes); j++)
21534         {
21535           if (node->next_nodes[j] != ~0)
21536             {
21537               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21538               print (vam->ofp, "  [%d] %s", j, next_node->name);
21539             }
21540         }
21541     }
21542   return 0;
21543 }
21544
21545 static int
21546 value_sort_cmp (void *a1, void *a2)
21547 {
21548   name_sort_t *n1 = a1;
21549   name_sort_t *n2 = a2;
21550
21551   if (n1->value < n2->value)
21552     return -1;
21553   if (n1->value > n2->value)
21554     return 1;
21555   return 0;
21556 }
21557
21558
21559 static int
21560 dump_msg_api_table (vat_main_t * vam)
21561 {
21562   api_main_t *am = &api_main;
21563   name_sort_t *nses = 0, *ns;
21564   hash_pair_t *hp;
21565   int i;
21566
21567   /* *INDENT-OFF* */
21568   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21569   ({
21570     vec_add2 (nses, ns, 1);
21571     ns->name = (u8 *)(hp->key);
21572     ns->value = (u32) hp->value[0];
21573   }));
21574   /* *INDENT-ON* */
21575
21576   vec_sort_with_function (nses, value_sort_cmp);
21577
21578   for (i = 0; i < vec_len (nses); i++)
21579     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21580   vec_free (nses);
21581   return 0;
21582 }
21583
21584 static int
21585 get_msg_id (vat_main_t * vam)
21586 {
21587   u8 *name_and_crc;
21588   u32 message_index;
21589
21590   if (unformat (vam->input, "%s", &name_and_crc))
21591     {
21592       message_index = vl_msg_api_get_msg_index (name_and_crc);
21593       if (message_index == ~0)
21594         {
21595           print (vam->ofp, " '%s' not found", name_and_crc);
21596           return 0;
21597         }
21598       print (vam->ofp, " '%s' has message index %d",
21599              name_and_crc, message_index);
21600       return 0;
21601     }
21602   errmsg ("name_and_crc required...");
21603   return 0;
21604 }
21605
21606 static int
21607 search_node_table (vat_main_t * vam)
21608 {
21609   unformat_input_t *line_input = vam->input;
21610   u8 *node_to_find;
21611   int j;
21612   vlib_node_t *node, *next_node;
21613   uword *p;
21614
21615   if (vam->graph_node_index_by_name == 0)
21616     {
21617       print (vam->ofp, "Node table empty, issue get_node_graph...");
21618       return 0;
21619     }
21620
21621   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21622     {
21623       if (unformat (line_input, "%s", &node_to_find))
21624         {
21625           vec_add1 (node_to_find, 0);
21626           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21627           if (p == 0)
21628             {
21629               print (vam->ofp, "%s not found...", node_to_find);
21630               goto out;
21631             }
21632           node = vam->graph_nodes[0][p[0]];
21633           print (vam->ofp, "[%d] %s", p[0], node->name);
21634           for (j = 0; j < vec_len (node->next_nodes); j++)
21635             {
21636               if (node->next_nodes[j] != ~0)
21637                 {
21638                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21639                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21640                 }
21641             }
21642         }
21643
21644       else
21645         {
21646           clib_warning ("parse error '%U'", format_unformat_error,
21647                         line_input);
21648           return -99;
21649         }
21650
21651     out:
21652       vec_free (node_to_find);
21653
21654     }
21655
21656   return 0;
21657 }
21658
21659
21660 static int
21661 script (vat_main_t * vam)
21662 {
21663 #if (VPP_API_TEST_BUILTIN==0)
21664   u8 *s = 0;
21665   char *save_current_file;
21666   unformat_input_t save_input;
21667   jmp_buf save_jump_buf;
21668   u32 save_line_number;
21669
21670   FILE *new_fp, *save_ifp;
21671
21672   if (unformat (vam->input, "%s", &s))
21673     {
21674       new_fp = fopen ((char *) s, "r");
21675       if (new_fp == 0)
21676         {
21677           errmsg ("Couldn't open script file %s", s);
21678           vec_free (s);
21679           return -99;
21680         }
21681     }
21682   else
21683     {
21684       errmsg ("Missing script name");
21685       return -99;
21686     }
21687
21688   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21689   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21690   save_ifp = vam->ifp;
21691   save_line_number = vam->input_line_number;
21692   save_current_file = (char *) vam->current_file;
21693
21694   vam->input_line_number = 0;
21695   vam->ifp = new_fp;
21696   vam->current_file = s;
21697   do_one_file (vam);
21698
21699   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21700   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21701   vam->ifp = save_ifp;
21702   vam->input_line_number = save_line_number;
21703   vam->current_file = (u8 *) save_current_file;
21704   vec_free (s);
21705
21706   return 0;
21707 #else
21708   clib_warning ("use the exec command...");
21709   return -99;
21710 #endif
21711 }
21712
21713 static int
21714 echo (vat_main_t * vam)
21715 {
21716   print (vam->ofp, "%v", vam->input->buffer);
21717   return 0;
21718 }
21719
21720 /* List of API message constructors, CLI names map to api_xxx */
21721 #define foreach_vpe_api_msg                                             \
21722 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21723 _(sw_interface_dump,"")                                                 \
21724 _(sw_interface_set_flags,                                               \
21725   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21726 _(sw_interface_add_del_address,                                         \
21727   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21728 _(sw_interface_set_rx_mode,                                             \
21729   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21730 _(sw_interface_set_rx_placement,                                        \
21731   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21732 _(sw_interface_rx_placement_dump,                                       \
21733   "[<intfc> | sw_if_index <id>]")                                         \
21734 _(sw_interface_set_table,                                               \
21735   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21736 _(sw_interface_set_mpls_enable,                                         \
21737   "<intfc> | sw_if_index [disable | dis]")                              \
21738 _(sw_interface_set_vpath,                                               \
21739   "<intfc> | sw_if_index <id> enable | disable")                        \
21740 _(sw_interface_set_vxlan_bypass,                                        \
21741   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21742 _(sw_interface_set_geneve_bypass,                                       \
21743   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21744 _(sw_interface_set_l2_xconnect,                                         \
21745   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21746   "enable | disable")                                                   \
21747 _(sw_interface_set_l2_bridge,                                           \
21748   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21749   "[shg <split-horizon-group>] [bvi]\n"                                 \
21750   "enable | disable")                                                   \
21751 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21752 _(bridge_domain_add_del,                                                \
21753   "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") \
21754 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21755 _(l2fib_add_del,                                                        \
21756   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21757 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21758 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21759 _(l2_flags,                                                             \
21760   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21761 _(bridge_flags,                                                         \
21762   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21763 _(tap_create_v2,                                                        \
21764   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21765 _(tap_delete_v2,                                                        \
21766   "<vpp-if-name> | sw_if_index <id>")                                   \
21767 _(sw_interface_tap_v2_dump, "")                                         \
21768 _(virtio_pci_create,                                                    \
21769   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21770 _(virtio_pci_delete,                                                    \
21771   "<vpp-if-name> | sw_if_index <id>")                                   \
21772 _(sw_interface_virtio_pci_dump, "")                                     \
21773 _(bond_create,                                                          \
21774   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21775   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21776   "[id <if-id>]")                                                       \
21777 _(bond_delete,                                                          \
21778   "<vpp-if-name> | sw_if_index <id>")                                   \
21779 _(bond_enslave,                                                         \
21780   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21781 _(bond_detach_slave,                                                    \
21782   "sw_if_index <n>")                                                    \
21783  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21784 _(sw_interface_bond_dump, "")                                           \
21785 _(sw_interface_slave_dump,                                              \
21786   "<vpp-if-name> | sw_if_index <id>")                                   \
21787 _(ip_table_add_del,                                                     \
21788   "table <n> [ipv6] [add | del]\n")                                     \
21789 _(ip_route_add_del,                                                     \
21790   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21791   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21792   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21793   "[multipath] [count <n>] [del]")                                      \
21794 _(ip_mroute_add_del,                                                    \
21795   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21796   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21797 _(mpls_table_add_del,                                                   \
21798   "table <n> [add | del]\n")                                            \
21799 _(mpls_route_add_del,                                                   \
21800   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21801   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21802   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21803   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21804   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21805   "[count <n>] [del]")                                                  \
21806 _(mpls_ip_bind_unbind,                                                  \
21807   "<label> <addr/len>")                                                 \
21808 _(mpls_tunnel_add_del,                                                  \
21809   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21810   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21811   "[l2-only]  [out-label <n>]")                                         \
21812 _(sr_mpls_policy_add,                                                   \
21813   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21814 _(sr_mpls_policy_del,                                                   \
21815   "bsid <id>")                                                          \
21816 _(bier_table_add_del,                                                   \
21817   "<label> <sub-domain> <set> <bsl> [del]")                             \
21818 _(bier_route_add_del,                                                   \
21819   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21820   "[<intfc> | sw_if_index <id>]"                                        \
21821   "[weight <n>] [del] [multipath]")                                     \
21822 _(proxy_arp_add_del,                                                    \
21823   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21824 _(proxy_arp_intfc_enable_disable,                                       \
21825   "<intfc> | sw_if_index <id> enable | disable")                        \
21826 _(sw_interface_set_unnumbered,                                          \
21827   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21828 _(ip_neighbor_add_del,                                                  \
21829   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21830   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21831 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21832 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21833   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21834   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21835   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21836 _(reset_fib, "vrf <n> [ipv6]")                                          \
21837 _(dhcp_proxy_config,                                                    \
21838   "svr <v46-address> src <v46-address>\n"                               \
21839    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21840 _(dhcp_proxy_set_vss,                                                   \
21841   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21842 _(dhcp_proxy_dump, "ip6")                                               \
21843 _(dhcp_client_config,                                                   \
21844   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21845 _(set_ip_flow_hash,                                                     \
21846   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21847 _(sw_interface_ip6_enable_disable,                                      \
21848   "<intfc> | sw_if_index <id> enable | disable")                        \
21849 _(ip6nd_proxy_add_del,                                                  \
21850   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21851 _(ip6nd_proxy_dump, "")                                                 \
21852 _(sw_interface_ip6nd_ra_prefix,                                         \
21853   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21854   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21855   "[nolink] [isno]")                                                    \
21856 _(sw_interface_ip6nd_ra_config,                                         \
21857   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21858   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21859   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21860 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21861 _(l2_patch_add_del,                                                     \
21862   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21863   "enable | disable")                                                   \
21864 _(sr_localsid_add_del,                                                  \
21865   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21866   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21867 _(classify_add_del_table,                                               \
21868   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21869   " [del] [del-chain] mask <mask-value>\n"                              \
21870   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21871   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21872 _(classify_add_del_session,                                             \
21873   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21874   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21875   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21876   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21877 _(classify_set_interface_ip_table,                                      \
21878   "<intfc> | sw_if_index <nn> table <nn>")                              \
21879 _(classify_set_interface_l2_tables,                                     \
21880   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21881   "  [other-table <nn>]")                                               \
21882 _(get_node_index, "node <node-name")                                    \
21883 _(add_node_next, "node <node-name> next <next-node-name>")              \
21884 _(l2tpv3_create_tunnel,                                                 \
21885   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21886   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21887   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21888 _(l2tpv3_set_tunnel_cookies,                                            \
21889   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21890   "[new_remote_cookie <nn>]\n")                                         \
21891 _(l2tpv3_interface_enable_disable,                                      \
21892   "<intfc> | sw_if_index <nn> enable | disable")                        \
21893 _(l2tpv3_set_lookup_key,                                                \
21894   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21895 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21896 _(vxlan_offload_rx,                                                     \
21897   "hw { <interface name> | hw_if_index <nn>} "                          \
21898   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21899 _(vxlan_add_del_tunnel,                                                 \
21900   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21901   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21902   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21903 _(geneve_add_del_tunnel,                                                \
21904   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21905   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21906   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21907 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21908 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21909 _(gre_tunnel_add_del,                                                   \
21910   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21911   "[teb | erspan <session-id>] [del]")                                  \
21912 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21913 _(l2_fib_clear_table, "")                                               \
21914 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21915 _(l2_interface_vlan_tag_rewrite,                                        \
21916   "<intfc> | sw_if_index <nn> \n"                                       \
21917   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21918   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21919 _(create_vhost_user_if,                                                 \
21920         "socket <filename> [server] [renumber <dev_instance>] "         \
21921         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21922         "[mac <mac_address>]")                                          \
21923 _(modify_vhost_user_if,                                                 \
21924         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21925         "[server] [renumber <dev_instance>] [gso]")                     \
21926 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21927 _(sw_interface_vhost_user_dump, "")                                     \
21928 _(show_version, "")                                                     \
21929 _(show_threads, "")                                                     \
21930 _(vxlan_gpe_add_del_tunnel,                                             \
21931   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21932   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21933   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21934   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21935 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21936 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21937 _(interface_name_renumber,                                              \
21938   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21939 _(input_acl_set_interface,                                              \
21940   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21941   "  [l2-table <nn>] [del]")                                            \
21942 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21943 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21944   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21945 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21946 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21947 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21948 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21949 _(ip_dump, "ipv4 | ipv6")                                               \
21950 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21951 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21952   "  spid_id <n> ")                                                     \
21953 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21954   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21955   "  integ_alg <alg> integ_key <hex>")                                  \
21956 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21957   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21958   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21959   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21960 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21961   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21962   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21963   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21964   "  [instance <n>]")     \
21965 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21966 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21967 _(delete_loopback,"sw_if_index <nn>")                                   \
21968 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21969 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21970 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21971 _(want_interface_events,  "enable|disable")                             \
21972 _(get_first_msg_id, "client <name>")                                    \
21973 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21974 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21975   "fib-id <nn> [ip4][ip6][default]")                                    \
21976 _(get_node_graph, " ")                                                  \
21977 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21978 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21979 _(ioam_disable, "")                                                     \
21980 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21981                             " sw_if_index <sw_if_index> p <priority> "  \
21982                             "w <weight>] [del]")                        \
21983 _(one_add_del_locator, "locator-set <locator_name> "                    \
21984                         "iface <intf> | sw_if_index <sw_if_index> "     \
21985                         "p <priority> w <weight> [del]")                \
21986 _(one_add_del_local_eid,"vni <vni> eid "                                \
21987                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21988                          "locator-set <locator_name> [del]"             \
21989                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21990 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21991 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21992 _(one_enable_disable, "enable|disable")                                 \
21993 _(one_map_register_enable_disable, "enable|disable")                    \
21994 _(one_map_register_fallback_threshold, "<value>")                       \
21995 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21996 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21997                                "[seid <seid>] "                         \
21998                                "rloc <locator> p <prio> "               \
21999                                "w <weight> [rloc <loc> ... ] "          \
22000                                "action <action> [del-all]")             \
22001 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22002                           "<local-eid>")                                \
22003 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22004 _(one_use_petr, "ip-address> | disable")                                \
22005 _(one_map_request_mode, "src-dst|dst-only")                             \
22006 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22007 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22008 _(one_locator_set_dump, "[local | remote]")                             \
22009 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22010 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22011                        "[local] | [remote]")                            \
22012 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22013 _(one_ndp_bd_get, "")                                                   \
22014 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22015 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22016 _(one_l2_arp_bd_get, "")                                                \
22017 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22018 _(one_stats_enable_disable, "enable|disable")                           \
22019 _(show_one_stats_enable_disable, "")                                    \
22020 _(one_eid_table_vni_dump, "")                                           \
22021 _(one_eid_table_map_dump, "l2|l3")                                      \
22022 _(one_map_resolver_dump, "")                                            \
22023 _(one_map_server_dump, "")                                              \
22024 _(one_adjacencies_get, "vni <vni>")                                     \
22025 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22026 _(show_one_rloc_probe_state, "")                                        \
22027 _(show_one_map_register_state, "")                                      \
22028 _(show_one_status, "")                                                  \
22029 _(one_stats_dump, "")                                                   \
22030 _(one_stats_flush, "")                                                  \
22031 _(one_get_map_request_itr_rlocs, "")                                    \
22032 _(one_map_register_set_ttl, "<ttl>")                                    \
22033 _(one_set_transport_protocol, "udp|api")                                \
22034 _(one_get_transport_protocol, "")                                       \
22035 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22036 _(one_show_xtr_mode, "")                                                \
22037 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22038 _(one_show_pitr_mode, "")                                               \
22039 _(one_enable_disable_petr_mode, "enable|disable")                       \
22040 _(one_show_petr_mode, "")                                               \
22041 _(show_one_nsh_mapping, "")                                             \
22042 _(show_one_pitr, "")                                                    \
22043 _(show_one_use_petr, "")                                                \
22044 _(show_one_map_request_mode, "")                                        \
22045 _(show_one_map_register_ttl, "")                                        \
22046 _(show_one_map_register_fallback_threshold, "")                         \
22047 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22048                             " sw_if_index <sw_if_index> p <priority> "  \
22049                             "w <weight>] [del]")                        \
22050 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22051                         "iface <intf> | sw_if_index <sw_if_index> "     \
22052                         "p <priority> w <weight> [del]")                \
22053 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22054                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22055                          "locator-set <locator_name> [del]"             \
22056                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22057 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22058 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22059 _(lisp_enable_disable, "enable|disable")                                \
22060 _(lisp_map_register_enable_disable, "enable|disable")                   \
22061 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22062 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22063                                "[seid <seid>] "                         \
22064                                "rloc <locator> p <prio> "               \
22065                                "w <weight> [rloc <loc> ... ] "          \
22066                                "action <action> [del-all]")             \
22067 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22068                           "<local-eid>")                                \
22069 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22070 _(lisp_use_petr, "<ip-address> | disable")                              \
22071 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22072 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22073 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22074 _(lisp_locator_set_dump, "[local | remote]")                            \
22075 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22076 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22077                        "[local] | [remote]")                            \
22078 _(lisp_eid_table_vni_dump, "")                                          \
22079 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22080 _(lisp_map_resolver_dump, "")                                           \
22081 _(lisp_map_server_dump, "")                                             \
22082 _(lisp_adjacencies_get, "vni <vni>")                                    \
22083 _(gpe_fwd_entry_vnis_get, "")                                           \
22084 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22085 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22086                                 "[table <table-id>]")                   \
22087 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22088 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22089 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22090 _(gpe_get_encap_mode, "")                                               \
22091 _(lisp_gpe_add_del_iface, "up|down")                                    \
22092 _(lisp_gpe_enable_disable, "enable|disable")                            \
22093 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22094   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22095 _(show_lisp_rloc_probe_state, "")                                       \
22096 _(show_lisp_map_register_state, "")                                     \
22097 _(show_lisp_status, "")                                                 \
22098 _(lisp_get_map_request_itr_rlocs, "")                                   \
22099 _(show_lisp_pitr, "")                                                   \
22100 _(show_lisp_use_petr, "")                                               \
22101 _(show_lisp_map_request_mode, "")                                       \
22102 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22103 _(af_packet_delete, "name <host interface name>")                       \
22104 _(af_packet_dump, "")                                                   \
22105 _(policer_add_del, "name <policer name> <params> [del]")                \
22106 _(policer_dump, "[name <policer name>]")                                \
22107 _(policer_classify_set_interface,                                       \
22108   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22109   "  [l2-table <nn>] [del]")                                            \
22110 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22111 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22112     "[master|slave]")                                                   \
22113 _(netmap_delete, "name <interface name>")                               \
22114 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22115 _(mpls_table_dump, "")                                                  \
22116 _(mpls_route_dump, "table-id <ID>")                                     \
22117 _(classify_table_ids, "")                                               \
22118 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22119 _(classify_table_info, "table_id <nn>")                                 \
22120 _(classify_session_dump, "table_id <nn>")                               \
22121 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22122     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22123     "[template_interval <nn>] [udp_checksum]")                          \
22124 _(ipfix_exporter_dump, "")                                              \
22125 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22126 _(ipfix_classify_stream_dump, "")                                       \
22127 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22128 _(ipfix_classify_table_dump, "")                                        \
22129 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22130 _(sw_interface_span_dump, "[l2]")                                           \
22131 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22132 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22133 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22134 _(pg_enable_disable, "[stream <id>] disable")                           \
22135 _(ip_source_and_port_range_check_add_del,                               \
22136   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22137 _(ip_source_and_port_range_check_interface_add_del,                     \
22138   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22139   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22140 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22141 _(l2_interface_pbb_tag_rewrite,                                         \
22142   "<intfc> | sw_if_index <nn> \n"                                       \
22143   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22144   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22145 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22146 _(flow_classify_set_interface,                                          \
22147   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22148 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22149 _(ip_table_dump, "")                                                    \
22150 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22151 _(ip_mtable_dump, "")                                                   \
22152 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22153 _(feature_enable_disable, "arc_name <arc_name> "                        \
22154   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22155 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22156 "[disable]")                                                            \
22157 _(l2_xconnect_dump, "")                                                 \
22158 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22159 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22160 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22161 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22162 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22163 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22164 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22165   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22166 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22167 _(sock_init_shm, "size <nnn>")                                          \
22168 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22169 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22170   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22171 _(session_rules_dump, "")                                               \
22172 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22173 _(output_acl_set_interface,                                             \
22174   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22175   "  [l2-table <nn>] [del]")                                            \
22176 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22177
22178 /* List of command functions, CLI names map directly to functions */
22179 #define foreach_cli_function                                    \
22180 _(comment, "usage: comment <ignore-rest-of-line>")              \
22181 _(dump_interface_table, "usage: dump_interface_table")          \
22182 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22183 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22184 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22185 _(dump_macro_table, "usage: dump_macro_table ")                 \
22186 _(dump_node_table, "usage: dump_node_table")                    \
22187 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22188 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22189 _(elog_disable, "usage: elog_disable")                          \
22190 _(elog_enable, "usage: elog_enable")                            \
22191 _(elog_save, "usage: elog_save <filename>")                     \
22192 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22193 _(echo, "usage: echo <message>")                                \
22194 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22195 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22196 _(help, "usage: help")                                          \
22197 _(q, "usage: quit")                                             \
22198 _(quit, "usage: quit")                                          \
22199 _(search_node_table, "usage: search_node_table <name>...")      \
22200 _(set, "usage: set <variable-name> <value>")                    \
22201 _(script, "usage: script <file-name>")                          \
22202 _(statseg, "usage: statseg")                                    \
22203 _(unset, "usage: unset <variable-name>")
22204
22205 #define _(N,n)                                  \
22206     static void vl_api_##n##_t_handler_uni      \
22207     (vl_api_##n##_t * mp)                       \
22208     {                                           \
22209         vat_main_t * vam = &vat_main;           \
22210         if (vam->json_output) {                 \
22211             vl_api_##n##_t_handler_json(mp);    \
22212         } else {                                \
22213             vl_api_##n##_t_handler(mp);         \
22214         }                                       \
22215     }
22216 foreach_vpe_api_reply_msg;
22217 #if VPP_API_TEST_BUILTIN == 0
22218 foreach_standalone_reply_msg;
22219 #endif
22220 #undef _
22221
22222 void
22223 vat_api_hookup (vat_main_t * vam)
22224 {
22225 #define _(N,n)                                                  \
22226     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22227                            vl_api_##n##_t_handler_uni,          \
22228                            vl_noop_handler,                     \
22229                            vl_api_##n##_t_endian,               \
22230                            vl_api_##n##_t_print,                \
22231                            sizeof(vl_api_##n##_t), 1);
22232   foreach_vpe_api_reply_msg;
22233 #if VPP_API_TEST_BUILTIN == 0
22234   foreach_standalone_reply_msg;
22235 #endif
22236 #undef _
22237
22238 #if (VPP_API_TEST_BUILTIN==0)
22239   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22240
22241   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22242
22243   vam->function_by_name = hash_create_string (0, sizeof (uword));
22244
22245   vam->help_by_name = hash_create_string (0, sizeof (uword));
22246 #endif
22247
22248   /* API messages we can send */
22249 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22250   foreach_vpe_api_msg;
22251 #undef _
22252
22253   /* Help strings */
22254 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22255   foreach_vpe_api_msg;
22256 #undef _
22257
22258   /* CLI functions */
22259 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22260   foreach_cli_function;
22261 #undef _
22262
22263   /* Help strings */
22264 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22265   foreach_cli_function;
22266 #undef _
22267 }
22268
22269 #if VPP_API_TEST_BUILTIN
22270 static clib_error_t *
22271 vat_api_hookup_shim (vlib_main_t * vm)
22272 {
22273   vat_api_hookup (&vat_main);
22274   return 0;
22275 }
22276
22277 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22278 #endif
22279
22280 /*
22281  * fd.io coding-style-patch-verification: ON
22282  *
22283  * Local Variables:
22284  * eval: (c-set-style "gnu")
22285  * End:
22286  */