tap: refactor existing flags
[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 <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.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 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   api_main_t *am = vlibapi_get_main ();
107   vam->socket_client_main = &socket_client_main;
108   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
109                                       "vpp_api_test",
110                                       0 /* default socket rx, tx buffer */ )))
111     return rv;
112
113   /* vpp expects the client index in network order */
114   vam->my_client_index = htonl (socket_client_main.client_index);
115   am->my_client_index = vam->my_client_index;
116   return 0;
117 }
118 #else /* vpp built-in case, we don't do sockets... */
119 int
120 vat_socket_connect (vat_main_t * vam)
121 {
122   return 0;
123 }
124
125 int
126 vl_socket_client_read (int wait)
127 {
128   return -1;
129 };
130
131 int
132 vl_socket_client_write ()
133 {
134   return -1;
135 };
136
137 void *
138 vl_socket_client_msg_alloc (int nbytes)
139 {
140   return 0;
141 }
142 #endif
143
144
145 f64
146 vat_time_now (vat_main_t * vam)
147 {
148 #if VPP_API_TEST_BUILTIN
149   return vlib_time_now (vam->vlib_main);
150 #else
151   return clib_time_now (&vam->clib_time);
152 #endif
153 }
154
155 void
156 errmsg (char *fmt, ...)
157 {
158   vat_main_t *vam = &vat_main;
159   va_list va;
160   u8 *s;
161
162   va_start (va, fmt);
163   s = va_format (0, fmt, &va);
164   va_end (va);
165
166   vec_add1 (s, 0);
167
168 #if VPP_API_TEST_BUILTIN
169   vlib_cli_output (vam->vlib_main, (char *) s);
170 #else
171   {
172     if (vam->ifp != stdin)
173       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
174                vam->input_line_number);
175     else
176       fformat (vam->ofp, "%s\n", (char *) s);
177     fflush (vam->ofp);
178   }
179 #endif
180
181   vec_free (s);
182 }
183
184 #if VPP_API_TEST_BUILTIN == 0
185 static uword
186 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
187 {
188   vat_main_t *vam = va_arg (*args, vat_main_t *);
189   u32 *result = va_arg (*args, u32 *);
190   u8 *if_name;
191   uword *p;
192
193   if (!unformat (input, "%s", &if_name))
194     return 0;
195
196   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
197   if (p == 0)
198     return 0;
199   *result = p[0];
200   return 1;
201 }
202
203 static uword
204 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
205 {
206   return 0;
207 }
208
209 /* Parse an IP4 address %d.%d.%d.%d. */
210 uword
211 unformat_ip4_address (unformat_input_t * input, va_list * args)
212 {
213   u8 *result = va_arg (*args, u8 *);
214   unsigned a[4];
215
216   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
217     return 0;
218
219   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
220     return 0;
221
222   result[0] = a[0];
223   result[1] = a[1];
224   result[2] = a[2];
225   result[3] = a[3];
226
227   return 1;
228 }
229
230 uword
231 unformat_ethernet_address (unformat_input_t * input, va_list * args)
232 {
233   u8 *result = va_arg (*args, u8 *);
234   u32 i, a[6];
235
236   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
237                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
238     return 0;
239
240   /* Check range. */
241   for (i = 0; i < 6; i++)
242     if (a[i] >= (1 << 8))
243       return 0;
244
245   for (i = 0; i < 6; i++)
246     result[i] = a[i];
247
248   return 1;
249 }
250
251 /* Returns ethernet type as an int in host byte order. */
252 uword
253 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
254                                         va_list * args)
255 {
256   u16 *result = va_arg (*args, u16 *);
257   int type;
258
259   /* Numeric type. */
260   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
261     {
262       if (type >= (1 << 16))
263         return 0;
264       *result = type;
265       return 1;
266     }
267   return 0;
268 }
269
270 /* Parse an IP46 address. */
271 uword
272 unformat_ip46_address (unformat_input_t * input, va_list * args)
273 {
274   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
275   ip46_type_t type = va_arg (*args, ip46_type_t);
276   if ((type != IP46_TYPE_IP6) &&
277       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
278     {
279       ip46_address_mask_ip4 (ip46);
280       return 1;
281     }
282   else if ((type != IP46_TYPE_IP4) &&
283            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
284     {
285       return 1;
286     }
287   return 0;
288 }
289
290 /* Parse an IP6 address. */
291 uword
292 unformat_ip6_address (unformat_input_t * input, va_list * args)
293 {
294   ip6_address_t *result = va_arg (*args, ip6_address_t *);
295   u16 hex_quads[8];
296   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
297   uword c, n_colon, double_colon_index;
298
299   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
300   double_colon_index = ARRAY_LEN (hex_quads);
301   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
302     {
303       hex_digit = 16;
304       if (c >= '0' && c <= '9')
305         hex_digit = c - '0';
306       else if (c >= 'a' && c <= 'f')
307         hex_digit = c + 10 - 'a';
308       else if (c >= 'A' && c <= 'F')
309         hex_digit = c + 10 - 'A';
310       else if (c == ':' && n_colon < 2)
311         n_colon++;
312       else
313         {
314           unformat_put_input (input);
315           break;
316         }
317
318       /* Too many hex quads. */
319       if (n_hex_quads >= ARRAY_LEN (hex_quads))
320         return 0;
321
322       if (hex_digit < 16)
323         {
324           hex_quad = (hex_quad << 4) | hex_digit;
325
326           /* Hex quad must fit in 16 bits. */
327           if (n_hex_digits >= 4)
328             return 0;
329
330           n_colon = 0;
331           n_hex_digits++;
332         }
333
334       /* Save position of :: */
335       if (n_colon == 2)
336         {
337           /* More than one :: ? */
338           if (double_colon_index < ARRAY_LEN (hex_quads))
339             return 0;
340           double_colon_index = n_hex_quads;
341         }
342
343       if (n_colon > 0 && n_hex_digits > 0)
344         {
345           hex_quads[n_hex_quads++] = hex_quad;
346           hex_quad = 0;
347           n_hex_digits = 0;
348         }
349     }
350
351   if (n_hex_digits > 0)
352     hex_quads[n_hex_quads++] = hex_quad;
353
354   {
355     word i;
356
357     /* Expand :: to appropriate number of zero hex quads. */
358     if (double_colon_index < ARRAY_LEN (hex_quads))
359       {
360         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
361
362         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
363           hex_quads[n_zero + i] = hex_quads[i];
364
365         for (i = 0; i < n_zero; i++)
366           hex_quads[double_colon_index + i] = 0;
367
368         n_hex_quads = ARRAY_LEN (hex_quads);
369       }
370
371     /* Too few hex quads given. */
372     if (n_hex_quads < ARRAY_LEN (hex_quads))
373       return 0;
374
375     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
376       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
377
378     return 1;
379   }
380 }
381
382 uword
383 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
384 {
385   u32 *r = va_arg (*args, u32 *);
386
387   if (0);
388 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
389   foreach_ipsec_policy_action
390 #undef _
391     else
392     return 0;
393   return 1;
394 }
395
396 u8 *
397 format_ipsec_crypto_alg (u8 * s, va_list * args)
398 {
399   u32 i = va_arg (*args, u32);
400   u8 *t = 0;
401
402   switch (i)
403     {
404 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
405       foreach_ipsec_crypto_alg
406 #undef _
407     default:
408       return format (s, "unknown");
409     }
410   return format (s, "%s", t);
411 }
412
413 u8 *
414 format_ipsec_integ_alg (u8 * s, va_list * args)
415 {
416   u32 i = va_arg (*args, u32);
417   u8 *t = 0;
418
419   switch (i)
420     {
421 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
422       foreach_ipsec_integ_alg
423 #undef _
424     default:
425       return format (s, "unknown");
426     }
427   return format (s, "%s", t);
428 }
429
430 #else /* VPP_API_TEST_BUILTIN == 1 */
431 static uword
432 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
433 {
434   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
435   vnet_main_t *vnm = vnet_get_main ();
436   u32 *result = va_arg (*args, u32 *);
437
438   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
439 }
440
441 static uword
442 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
443 {
444   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
445   vnet_main_t *vnm = vnet_get_main ();
446   u32 *result = va_arg (*args, u32 *);
447
448   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
449 }
450
451 #endif /* VPP_API_TEST_BUILTIN */
452
453 uword
454 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
455 {
456   u32 *r = va_arg (*args, u32 *);
457
458   if (0);
459 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
460   foreach_ipsec_crypto_alg
461 #undef _
462     else
463     return 0;
464   return 1;
465 }
466
467 uword
468 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
469 {
470   u32 *r = va_arg (*args, u32 *);
471
472   if (0);
473 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
474   foreach_ipsec_integ_alg
475 #undef _
476     else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "kbps"))
487     *r = SSE2_QOS_RATE_KBPS;
488   else if (unformat (input, "pps"))
489     *r = SSE2_QOS_RATE_PPS;
490   else
491     return 0;
492   return 1;
493 }
494
495 static uword
496 unformat_policer_round_type (unformat_input_t * input, va_list * args)
497 {
498   u8 *r = va_arg (*args, u8 *);
499
500   if (unformat (input, "closest"))
501     *r = SSE2_QOS_ROUND_TO_CLOSEST;
502   else if (unformat (input, "up"))
503     *r = SSE2_QOS_ROUND_TO_UP;
504   else if (unformat (input, "down"))
505     *r = SSE2_QOS_ROUND_TO_DOWN;
506   else
507     return 0;
508   return 1;
509 }
510
511 static uword
512 unformat_policer_type (unformat_input_t * input, va_list * args)
513 {
514   u8 *r = va_arg (*args, u8 *);
515
516   if (unformat (input, "1r2c"))
517     *r = SSE2_QOS_POLICER_TYPE_1R2C;
518   else if (unformat (input, "1r3c"))
519     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
520   else if (unformat (input, "2r3c-2698"))
521     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
522   else if (unformat (input, "2r3c-4115"))
523     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
524   else if (unformat (input, "2r3c-mef5cf1"))
525     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
526   else
527     return 0;
528   return 1;
529 }
530
531 static uword
532 unformat_dscp (unformat_input_t * input, va_list * va)
533 {
534   u8 *r = va_arg (*va, u8 *);
535
536   if (0);
537 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
538   foreach_vnet_dscp
539 #undef _
540     else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_action_type (unformat_input_t * input, va_list * va)
547 {
548   sse2_qos_pol_action_params_st *a
549     = va_arg (*va, sse2_qos_pol_action_params_st *);
550
551   if (unformat (input, "drop"))
552     a->action_type = SSE2_QOS_ACTION_DROP;
553   else if (unformat (input, "transmit"))
554     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
555   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
556     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
557   else
558     return 0;
559   return 1;
560 }
561
562 static uword
563 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
564 {
565   u32 *r = va_arg (*va, u32 *);
566   u32 tid;
567
568   if (unformat (input, "ip4"))
569     tid = POLICER_CLASSIFY_TABLE_IP4;
570   else if (unformat (input, "ip6"))
571     tid = POLICER_CLASSIFY_TABLE_IP6;
572   else if (unformat (input, "l2"))
573     tid = POLICER_CLASSIFY_TABLE_L2;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static uword
582 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
583 {
584   u32 *r = va_arg (*va, u32 *);
585   u32 tid;
586
587   if (unformat (input, "ip4"))
588     tid = FLOW_CLASSIFY_TABLE_IP4;
589   else if (unformat (input, "ip6"))
590     tid = FLOW_CLASSIFY_TABLE_IP6;
591   else
592     return 0;
593
594   *r = tid;
595   return 1;
596 }
597
598 #if (VPP_API_TEST_BUILTIN==0)
599
600 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
601 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
602 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
603 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
604
605 uword
606 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
607 {
608   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
609   mfib_itf_attribute_t attr;
610
611   old = *iflags;
612   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
613   {
614     if (unformat (input, mfib_itf_flag_long_names[attr]))
615       *iflags |= (1 << attr);
616   }
617   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
618   {
619     if (unformat (input, mfib_itf_flag_names[attr]))
620       *iflags |= (1 << attr);
621   }
622
623   return (old == *iflags ? 0 : 1);
624 }
625
626 uword
627 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
628 {
629   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
630   mfib_entry_attribute_t attr;
631
632   old = *eflags;
633   FOR_EACH_MFIB_ATTRIBUTE (attr)
634   {
635     if (unformat (input, mfib_flag_long_names[attr]))
636       *eflags |= (1 << attr);
637   }
638   FOR_EACH_MFIB_ATTRIBUTE (attr)
639   {
640     if (unformat (input, mfib_flag_names[attr]))
641       *eflags |= (1 << attr);
642   }
643
644   return (old == *eflags ? 0 : 1);
645 }
646
647 u8 *
648 format_ip4_address (u8 * s, va_list * args)
649 {
650   u8 *a = va_arg (*args, u8 *);
651   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
652 }
653
654 u8 *
655 format_ip6_address (u8 * s, va_list * args)
656 {
657   ip6_address_t *a = va_arg (*args, ip6_address_t *);
658   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
659
660   i_max_n_zero = ARRAY_LEN (a->as_u16);
661   max_n_zeros = 0;
662   i_first_zero = i_max_n_zero;
663   n_zeros = 0;
664   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
665     {
666       u32 is_zero = a->as_u16[i] == 0;
667       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
668         {
669           i_first_zero = i;
670           n_zeros = 0;
671         }
672       n_zeros += is_zero;
673       if ((!is_zero && n_zeros > max_n_zeros)
674           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
675         {
676           i_max_n_zero = i_first_zero;
677           max_n_zeros = n_zeros;
678           i_first_zero = ARRAY_LEN (a->as_u16);
679           n_zeros = 0;
680         }
681     }
682
683   last_double_colon = 0;
684   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
685     {
686       if (i == i_max_n_zero && max_n_zeros > 1)
687         {
688           s = format (s, "::");
689           i += max_n_zeros - 1;
690           last_double_colon = 1;
691         }
692       else
693         {
694           s = format (s, "%s%x",
695                       (last_double_colon || i == 0) ? "" : ":",
696                       clib_net_to_host_u16 (a->as_u16[i]));
697           last_double_colon = 0;
698         }
699     }
700
701   return s;
702 }
703
704 /* Format an IP46 address. */
705 u8 *
706 format_ip46_address (u8 * s, va_list * args)
707 {
708   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
709   ip46_type_t type = va_arg (*args, ip46_type_t);
710   int is_ip4 = 1;
711
712   switch (type)
713     {
714     case IP46_TYPE_ANY:
715       is_ip4 = ip46_address_is_ip4 (ip46);
716       break;
717     case IP46_TYPE_IP4:
718       is_ip4 = 1;
719       break;
720     case IP46_TYPE_IP6:
721       is_ip4 = 0;
722       break;
723     }
724
725   return is_ip4 ?
726     format (s, "%U", format_ip4_address, &ip46->ip4) :
727     format (s, "%U", format_ip6_address, &ip46->ip6);
728 }
729
730 u8 *
731 format_ethernet_address (u8 * s, va_list * args)
732 {
733   u8 *a = va_arg (*args, u8 *);
734
735   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
736                  a[0], a[1], a[2], a[3], a[4], a[5]);
737 }
738 #endif
739
740 static void
741 increment_v4_address (vl_api_ip4_address_t * i)
742 {
743   ip4_address_t *a = (ip4_address_t *) i;
744   u32 v;
745
746   v = ntohl (a->as_u32) + 1;
747   a->as_u32 = ntohl (v);
748 }
749
750 static void
751 increment_v6_address (vl_api_ip6_address_t * i)
752 {
753   ip6_address_t *a = (ip6_address_t *) i;
754   u64 v0, v1;
755
756   v0 = clib_net_to_host_u64 (a->as_u64[0]);
757   v1 = clib_net_to_host_u64 (a->as_u64[1]);
758
759   v1 += 1;
760   if (v1 == 0)
761     v0 += 1;
762   a->as_u64[0] = clib_net_to_host_u64 (v0);
763   a->as_u64[1] = clib_net_to_host_u64 (v1);
764 }
765
766 static void
767 increment_address (vl_api_address_t * a)
768 {
769   if (a->af == ADDRESS_IP4)
770     increment_v4_address (&a->un.ip4);
771   else if (a->af == ADDRESS_IP6)
772     increment_v6_address (&a->un.ip6);
773 }
774
775 static void
776 set_ip4_address (vl_api_address_t * a, u32 v)
777 {
778   if (a->af == ADDRESS_IP4)
779     {
780       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
781       i->as_u32 = v;
782     }
783 }
784
785 void
786 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
787 {
788   if (is_ip4)
789     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
790   else
791     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
792                       sizeof (ip6_address_t));
793 }
794
795 static void
796 increment_mac_address (u8 * mac)
797 {
798   u64 tmp = *((u64 *) mac);
799   tmp = clib_net_to_host_u64 (tmp);
800   tmp += 1 << 16;               /* skip unused (least significant) octets */
801   tmp = clib_host_to_net_u64 (tmp);
802
803   clib_memcpy (mac, &tmp, 6);
804 }
805
806 static void
807 vat_json_object_add_address (vat_json_node_t * node,
808                              const char *str, const vl_api_address_t * addr)
809 {
810   if (ADDRESS_IP6 == addr->af)
811     {
812       struct in6_addr ip6;
813
814       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
815       vat_json_object_add_ip6 (node, str, ip6);
816     }
817   else
818     {
819       struct in_addr ip4;
820
821       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
822       vat_json_object_add_ip4 (node, str, ip4);
823     }
824 }
825
826 static void
827 vat_json_object_add_prefix (vat_json_node_t * node,
828                             const vl_api_prefix_t * prefix)
829 {
830   vat_json_object_add_uint (node, "len", prefix->len);
831   vat_json_object_add_address (node, "address", &prefix->address);
832 }
833
834 static void vl_api_create_loopback_reply_t_handler
835   (vl_api_create_loopback_reply_t * mp)
836 {
837   vat_main_t *vam = &vat_main;
838   i32 retval = ntohl (mp->retval);
839
840   vam->retval = retval;
841   vam->regenerate_interface_table = 1;
842   vam->sw_if_index = ntohl (mp->sw_if_index);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_loopback_reply_t_handler_json
847   (vl_api_create_loopback_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   vat_json_node_t node;
851
852   vat_json_init_object (&node);
853   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
854   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
855
856   vat_json_print (vam->ofp, &node);
857   vat_json_free (&node);
858   vam->retval = ntohl (mp->retval);
859   vam->result_ready = 1;
860 }
861
862 static void vl_api_create_loopback_instance_reply_t_handler
863   (vl_api_create_loopback_instance_reply_t * mp)
864 {
865   vat_main_t *vam = &vat_main;
866   i32 retval = ntohl (mp->retval);
867
868   vam->retval = retval;
869   vam->regenerate_interface_table = 1;
870   vam->sw_if_index = ntohl (mp->sw_if_index);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_create_loopback_instance_reply_t_handler_json
875   (vl_api_create_loopback_instance_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   vat_json_node_t node;
879
880   vat_json_init_object (&node);
881   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
882   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
883
884   vat_json_print (vam->ofp, &node);
885   vat_json_free (&node);
886   vam->retval = ntohl (mp->retval);
887   vam->result_ready = 1;
888 }
889
890 static void vl_api_af_packet_create_reply_t_handler
891   (vl_api_af_packet_create_reply_t * mp)
892 {
893   vat_main_t *vam = &vat_main;
894   i32 retval = ntohl (mp->retval);
895
896   vam->retval = retval;
897   vam->regenerate_interface_table = 1;
898   vam->sw_if_index = ntohl (mp->sw_if_index);
899   vam->result_ready = 1;
900 }
901
902 static void vl_api_af_packet_create_reply_t_handler_json
903   (vl_api_af_packet_create_reply_t * mp)
904 {
905   vat_main_t *vam = &vat_main;
906   vat_json_node_t node;
907
908   vat_json_init_object (&node);
909   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
910   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
911
912   vat_json_print (vam->ofp, &node);
913   vat_json_free (&node);
914
915   vam->retval = ntohl (mp->retval);
916   vam->result_ready = 1;
917 }
918
919 static void vl_api_create_vlan_subif_reply_t_handler
920   (vl_api_create_vlan_subif_reply_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   i32 retval = ntohl (mp->retval);
924
925   vam->retval = retval;
926   vam->regenerate_interface_table = 1;
927   vam->sw_if_index = ntohl (mp->sw_if_index);
928   vam->result_ready = 1;
929 }
930
931 static void vl_api_create_vlan_subif_reply_t_handler_json
932   (vl_api_create_vlan_subif_reply_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   vat_json_node_t node;
936
937   vat_json_init_object (&node);
938   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
939   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
940
941   vat_json_print (vam->ofp, &node);
942   vat_json_free (&node);
943
944   vam->retval = ntohl (mp->retval);
945   vam->result_ready = 1;
946 }
947
948 static void vl_api_create_subif_reply_t_handler
949   (vl_api_create_subif_reply_t * mp)
950 {
951   vat_main_t *vam = &vat_main;
952   i32 retval = ntohl (mp->retval);
953
954   vam->retval = retval;
955   vam->regenerate_interface_table = 1;
956   vam->sw_if_index = ntohl (mp->sw_if_index);
957   vam->result_ready = 1;
958 }
959
960 static void vl_api_create_subif_reply_t_handler_json
961   (vl_api_create_subif_reply_t * mp)
962 {
963   vat_main_t *vam = &vat_main;
964   vat_json_node_t node;
965
966   vat_json_init_object (&node);
967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
968   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
969
970   vat_json_print (vam->ofp, &node);
971   vat_json_free (&node);
972
973   vam->retval = ntohl (mp->retval);
974   vam->result_ready = 1;
975 }
976
977 static void vl_api_interface_name_renumber_reply_t_handler
978   (vl_api_interface_name_renumber_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   i32 retval = ntohl (mp->retval);
982
983   vam->retval = retval;
984   vam->regenerate_interface_table = 1;
985   vam->result_ready = 1;
986 }
987
988 static void vl_api_interface_name_renumber_reply_t_handler_json
989   (vl_api_interface_name_renumber_reply_t * mp)
990 {
991   vat_main_t *vam = &vat_main;
992   vat_json_node_t node;
993
994   vat_json_init_object (&node);
995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996
997   vat_json_print (vam->ofp, &node);
998   vat_json_free (&node);
999
1000   vam->retval = ntohl (mp->retval);
1001   vam->result_ready = 1;
1002 }
1003
1004 /*
1005  * Special-case: build the interface table, maintain
1006  * the next loopback sw_if_index vbl.
1007  */
1008 static void vl_api_sw_interface_details_t_handler
1009   (vl_api_sw_interface_details_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1013
1014   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1015                 ntohl (mp->sw_if_index));
1016
1017   /* In sub interface case, fill the sub interface table entry */
1018   if (mp->sw_if_index != mp->sup_sw_if_index)
1019     {
1020       sw_interface_subif_t *sub = NULL;
1021
1022       vec_add2 (vam->sw_if_subif_table, sub, 1);
1023
1024       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1025       strncpy ((char *) sub->interface_name, (char *) s,
1026                vec_len (sub->interface_name));
1027       sub->sw_if_index = ntohl (mp->sw_if_index);
1028       sub->sub_id = ntohl (mp->sub_id);
1029
1030       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1031
1032       sub->sub_number_of_tags = mp->sub_number_of_tags;
1033       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1034       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1035
1036       /* vlan tag rewrite */
1037       sub->vtr_op = ntohl (mp->vtr_op);
1038       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1039       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1040       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1041     }
1042 }
1043
1044 static void vl_api_sw_interface_details_t_handler_json
1045   (vl_api_sw_interface_details_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t *node = NULL;
1049
1050   if (VAT_JSON_ARRAY != vam->json_tree.type)
1051     {
1052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1053       vat_json_init_array (&vam->json_tree);
1054     }
1055   node = vat_json_array_add (&vam->json_tree);
1056
1057   vat_json_init_object (node);
1058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1059   vat_json_object_add_uint (node, "sup_sw_if_index",
1060                             ntohl (mp->sup_sw_if_index));
1061   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1062                              sizeof (mp->l2_address));
1063   vat_json_object_add_string_copy (node, "interface_name",
1064                                    mp->interface_name);
1065   vat_json_object_add_string_copy (node, "interface_dev_type",
1066                                    mp->interface_dev_type);
1067   vat_json_object_add_uint (node, "flags", mp->flags);
1068   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1069   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1070   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1071   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1072   vat_json_object_add_uint (node, "sub_number_of_tags",
1073                             mp->sub_number_of_tags);
1074   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1075                             ntohs (mp->sub_outer_vlan_id));
1076   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1077                             ntohs (mp->sub_inner_vlan_id));
1078   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1079   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1080   vat_json_object_add_uint (node, "vtr_push_dot1q",
1081                             ntohl (mp->vtr_push_dot1q));
1082   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1083   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1084   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1085     {
1086       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1087                                        format (0, "%U",
1088                                                format_ethernet_address,
1089                                                &mp->b_dmac));
1090       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1091                                        format (0, "%U",
1092                                                format_ethernet_address,
1093                                                &mp->b_smac));
1094       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1095       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1096     }
1097 }
1098
1099 #if VPP_API_TEST_BUILTIN == 0
1100 static void vl_api_sw_interface_event_t_handler
1101   (vl_api_sw_interface_event_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   if (vam->interface_event_display)
1105     errmsg ("interface flags: sw_if_index %d %s %s",
1106             ntohl (mp->sw_if_index),
1107             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1108             "admin-up" : "admin-down",
1109             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1110             "link-up" : "link-down");
1111 }
1112 #endif
1113
1114 __clib_unused static void
1115 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1116 {
1117   /* JSON output not supported */
1118 }
1119
1120 static void
1121 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1122 {
1123   vat_main_t *vam = &vat_main;
1124   i32 retval = ntohl (mp->retval);
1125
1126   vam->retval = retval;
1127   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1128   vam->result_ready = 1;
1129 }
1130
1131 static void
1132 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   vat_json_node_t node;
1136   void *oldheap;
1137   u8 *reply;
1138
1139   vat_json_init_object (&node);
1140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1141   vat_json_object_add_uint (&node, "reply_in_shmem",
1142                             ntohl (mp->reply_in_shmem));
1143   /* Toss the shared-memory original... */
1144   oldheap = vl_msg_push_heap ();
1145
1146   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1147   vec_free (reply);
1148
1149   vl_msg_pop_heap (oldheap);
1150
1151   vat_json_print (vam->ofp, &node);
1152   vat_json_free (&node);
1153
1154   vam->retval = ntohl (mp->retval);
1155   vam->result_ready = 1;
1156 }
1157
1158 static void
1159 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1160 {
1161   vat_main_t *vam = &vat_main;
1162   i32 retval = ntohl (mp->retval);
1163
1164   vec_reset_length (vam->cmd_reply);
1165
1166   vam->retval = retval;
1167   if (retval == 0)
1168     vam->cmd_reply = vl_api_from_api_to_new_vec (&mp->reply);
1169   vam->result_ready = 1;
1170 }
1171
1172 static void
1173 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177   u8 *reply = 0;                /* reply vector */
1178
1179   reply = vl_api_from_api_to_new_vec (&mp->reply);
1180   vec_reset_length (vam->cmd_reply);
1181
1182   vat_json_init_object (&node);
1183   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184   vat_json_object_add_string_copy (&node, "reply", reply);
1185
1186   vat_json_print (vam->ofp, &node);
1187   vat_json_free (&node);
1188   vec_free (reply);
1189
1190   vam->retval = ntohl (mp->retval);
1191   vam->result_ready = 1;
1192 }
1193
1194 static void vl_api_classify_add_del_table_reply_t_handler
1195   (vl_api_classify_add_del_table_reply_t * mp)
1196 {
1197   vat_main_t *vam = &vat_main;
1198   i32 retval = ntohl (mp->retval);
1199   if (vam->async_mode)
1200     {
1201       vam->async_errors += (retval < 0);
1202     }
1203   else
1204     {
1205       vam->retval = retval;
1206       if (retval == 0 &&
1207           ((mp->new_table_index != 0xFFFFFFFF) ||
1208            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1209            (mp->match_n_vectors != 0xFFFFFFFF)))
1210         /*
1211          * Note: this is just barely thread-safe, depends on
1212          * the main thread spinning waiting for an answer...
1213          */
1214         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1215                 ntohl (mp->new_table_index),
1216                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1217       vam->result_ready = 1;
1218     }
1219 }
1220
1221 static void vl_api_classify_add_del_table_reply_t_handler_json
1222   (vl_api_classify_add_del_table_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   vat_json_node_t node;
1226
1227   vat_json_init_object (&node);
1228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1229   vat_json_object_add_uint (&node, "new_table_index",
1230                             ntohl (mp->new_table_index));
1231   vat_json_object_add_uint (&node, "skip_n_vectors",
1232                             ntohl (mp->skip_n_vectors));
1233   vat_json_object_add_uint (&node, "match_n_vectors",
1234                             ntohl (mp->match_n_vectors));
1235
1236   vat_json_print (vam->ofp, &node);
1237   vat_json_free (&node);
1238
1239   vam->retval = ntohl (mp->retval);
1240   vam->result_ready = 1;
1241 }
1242
1243 static void vl_api_get_node_index_reply_t_handler
1244   (vl_api_get_node_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   i32 retval = ntohl (mp->retval);
1248   if (vam->async_mode)
1249     {
1250       vam->async_errors += (retval < 0);
1251     }
1252   else
1253     {
1254       vam->retval = retval;
1255       if (retval == 0)
1256         errmsg ("node index %d", ntohl (mp->node_index));
1257       vam->result_ready = 1;
1258     }
1259 }
1260
1261 static void vl_api_get_node_index_reply_t_handler_json
1262   (vl_api_get_node_index_reply_t * mp)
1263 {
1264   vat_main_t *vam = &vat_main;
1265   vat_json_node_t node;
1266
1267   vat_json_init_object (&node);
1268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1269   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1270
1271   vat_json_print (vam->ofp, &node);
1272   vat_json_free (&node);
1273
1274   vam->retval = ntohl (mp->retval);
1275   vam->result_ready = 1;
1276 }
1277
1278 static void vl_api_get_next_index_reply_t_handler
1279   (vl_api_get_next_index_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       if (retval == 0)
1291         errmsg ("next node index %d", ntohl (mp->next_index));
1292       vam->result_ready = 1;
1293     }
1294 }
1295
1296 static void vl_api_get_next_index_reply_t_handler_json
1297   (vl_api_get_next_index_reply_t * mp)
1298 {
1299   vat_main_t *vam = &vat_main;
1300   vat_json_node_t node;
1301
1302   vat_json_init_object (&node);
1303   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1304   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1305
1306   vat_json_print (vam->ofp, &node);
1307   vat_json_free (&node);
1308
1309   vam->retval = ntohl (mp->retval);
1310   vam->result_ready = 1;
1311 }
1312
1313 static void vl_api_add_node_next_reply_t_handler
1314   (vl_api_add_node_next_reply_t * mp)
1315 {
1316   vat_main_t *vam = &vat_main;
1317   i32 retval = ntohl (mp->retval);
1318   if (vam->async_mode)
1319     {
1320       vam->async_errors += (retval < 0);
1321     }
1322   else
1323     {
1324       vam->retval = retval;
1325       if (retval == 0)
1326         errmsg ("next index %d", ntohl (mp->next_index));
1327       vam->result_ready = 1;
1328     }
1329 }
1330
1331 static void vl_api_add_node_next_reply_t_handler_json
1332   (vl_api_add_node_next_reply_t * mp)
1333 {
1334   vat_main_t *vam = &vat_main;
1335   vat_json_node_t node;
1336
1337   vat_json_init_object (&node);
1338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1339   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1340
1341   vat_json_print (vam->ofp, &node);
1342   vat_json_free (&node);
1343
1344   vam->retval = ntohl (mp->retval);
1345   vam->result_ready = 1;
1346 }
1347
1348 static void vl_api_show_version_reply_t_handler
1349   (vl_api_show_version_reply_t * mp)
1350 {
1351   vat_main_t *vam = &vat_main;
1352   i32 retval = ntohl (mp->retval);
1353
1354   if (retval >= 0)
1355     {
1356       errmsg ("        program: %s", mp->program);
1357       errmsg ("        version: %s", mp->version);
1358       errmsg ("     build date: %s", mp->build_date);
1359       errmsg ("build directory: %s", mp->build_directory);
1360     }
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void vl_api_show_version_reply_t_handler_json
1366   (vl_api_show_version_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t node;
1370
1371   vat_json_init_object (&node);
1372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1373   vat_json_object_add_string_copy (&node, "program", mp->program);
1374   vat_json_object_add_string_copy (&node, "version", mp->version);
1375   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1376   vat_json_object_add_string_copy (&node, "build_directory",
1377                                    mp->build_directory);
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_show_threads_reply_t_handler
1387   (vl_api_show_threads_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   int i, count = 0;
1392
1393   if (retval >= 0)
1394     count = ntohl (mp->count);
1395
1396   for (i = 0; i < count; i++)
1397     print (vam->ofp,
1398            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1399            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1400            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1401            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1402            ntohl (mp->thread_data[i].cpu_socket));
1403
1404   vam->retval = retval;
1405   vam->result_ready = 1;
1406 }
1407
1408 static void vl_api_show_threads_reply_t_handler_json
1409   (vl_api_show_threads_reply_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t node;
1413   vl_api_thread_data_t *td;
1414   i32 retval = ntohl (mp->retval);
1415   int i, count = 0;
1416
1417   if (retval >= 0)
1418     count = ntohl (mp->count);
1419
1420   vat_json_init_object (&node);
1421   vat_json_object_add_int (&node, "retval", retval);
1422   vat_json_object_add_uint (&node, "count", count);
1423
1424   for (i = 0; i < count; i++)
1425     {
1426       td = &mp->thread_data[i];
1427       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1428       vat_json_object_add_string_copy (&node, "name", td->name);
1429       vat_json_object_add_string_copy (&node, "type", td->type);
1430       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1431       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1432       vat_json_object_add_int (&node, "core", ntohl (td->id));
1433       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1434     }
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = retval;
1440   vam->result_ready = 1;
1441 }
1442
1443 static int
1444 api_show_threads (vat_main_t * vam)
1445 {
1446   vl_api_show_threads_t *mp;
1447   int ret;
1448
1449   print (vam->ofp,
1450          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1451          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1452
1453   M (SHOW_THREADS, mp);
1454
1455   S (mp);
1456   W (ret);
1457   return ret;
1458 }
1459
1460 static void
1461 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1462 {
1463   u32 n_macs = ntohl (mp->n_macs);
1464   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1465           ntohl (mp->pid), mp->client_index, n_macs);
1466   int i;
1467   for (i = 0; i < n_macs; i++)
1468     {
1469       vl_api_mac_entry_t *mac = &mp->mac[i];
1470       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1471               i + 1, ntohl (mac->sw_if_index),
1472               format_ethernet_address, mac->mac_addr, mac->action);
1473       if (i == 1000)
1474         break;
1475     }
1476 }
1477
1478 static void
1479 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1480 {
1481   /* JSON output not supported */
1482 }
1483
1484 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1485 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1486
1487 /*
1488  * Special-case: build the bridge domain table, maintain
1489  * the next bd id vbl.
1490  */
1491 static void vl_api_bridge_domain_details_t_handler
1492   (vl_api_bridge_domain_details_t * mp)
1493 {
1494   vat_main_t *vam = &vat_main;
1495   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1496   int i;
1497
1498   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1499          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1500
1501   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1502          ntohl (mp->bd_id), mp->learn, mp->forward,
1503          mp->flood, ntohl (mp->bvi_sw_if_index),
1504          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1505
1506   if (n_sw_ifs)
1507     {
1508       vl_api_bridge_domain_sw_if_t *sw_ifs;
1509       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1510              "Interface Name");
1511
1512       sw_ifs = mp->sw_if_details;
1513       for (i = 0; i < n_sw_ifs; i++)
1514         {
1515           u8 *sw_if_name = 0;
1516           u32 sw_if_index;
1517           hash_pair_t *p;
1518
1519           sw_if_index = ntohl (sw_ifs->sw_if_index);
1520
1521           /* *INDENT-OFF* */
1522           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1523                              ({
1524                                if ((u32) p->value[0] == sw_if_index)
1525                                  {
1526                                    sw_if_name = (u8 *)(p->key);
1527                                    break;
1528                                  }
1529                              }));
1530           /* *INDENT-ON* */
1531           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1532                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1533                  "sw_if_index not found!");
1534
1535           sw_ifs++;
1536         }
1537     }
1538 }
1539
1540 static void vl_api_bridge_domain_details_t_handler_json
1541   (vl_api_bridge_domain_details_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   vat_json_node_t *node, *array = NULL;
1545   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1546
1547   if (VAT_JSON_ARRAY != vam->json_tree.type)
1548     {
1549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1550       vat_json_init_array (&vam->json_tree);
1551     }
1552   node = vat_json_array_add (&vam->json_tree);
1553
1554   vat_json_init_object (node);
1555   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1556   vat_json_object_add_uint (node, "flood", mp->flood);
1557   vat_json_object_add_uint (node, "forward", mp->forward);
1558   vat_json_object_add_uint (node, "learn", mp->learn);
1559   vat_json_object_add_uint (node, "bvi_sw_if_index",
1560                             ntohl (mp->bvi_sw_if_index));
1561   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1562   array = vat_json_object_add (node, "sw_if");
1563   vat_json_init_array (array);
1564
1565
1566
1567   if (n_sw_ifs)
1568     {
1569       vl_api_bridge_domain_sw_if_t *sw_ifs;
1570       int i;
1571
1572       sw_ifs = mp->sw_if_details;
1573       for (i = 0; i < n_sw_ifs; i++)
1574         {
1575           node = vat_json_array_add (array);
1576           vat_json_init_object (node);
1577           vat_json_object_add_uint (node, "sw_if_index",
1578                                     ntohl (sw_ifs->sw_if_index));
1579           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1580           sw_ifs++;
1581         }
1582     }
1583 }
1584
1585 static void vl_api_control_ping_reply_t_handler
1586   (vl_api_control_ping_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   i32 retval = ntohl (mp->retval);
1590   if (vam->async_mode)
1591     {
1592       vam->async_errors += (retval < 0);
1593     }
1594   else
1595     {
1596       vam->retval = retval;
1597       vam->result_ready = 1;
1598     }
1599   if (vam->socket_client_main)
1600     vam->socket_client_main->control_pings_outstanding--;
1601 }
1602
1603 static void vl_api_control_ping_reply_t_handler_json
1604   (vl_api_control_ping_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   i32 retval = ntohl (mp->retval);
1608
1609   if (VAT_JSON_NONE != vam->json_tree.type)
1610     {
1611       vat_json_print (vam->ofp, &vam->json_tree);
1612       vat_json_free (&vam->json_tree);
1613       vam->json_tree.type = VAT_JSON_NONE;
1614     }
1615   else
1616     {
1617       /* just print [] */
1618       vat_json_init_array (&vam->json_tree);
1619       vat_json_print (vam->ofp, &vam->json_tree);
1620       vam->json_tree.type = VAT_JSON_NONE;
1621     }
1622
1623   vam->retval = retval;
1624   vam->result_ready = 1;
1625 }
1626
1627 static void
1628   vl_api_bridge_domain_set_mac_age_reply_t_handler
1629   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   i32 retval = ntohl (mp->retval);
1633   if (vam->async_mode)
1634     {
1635       vam->async_errors += (retval < 0);
1636     }
1637   else
1638     {
1639       vam->retval = retval;
1640       vam->result_ready = 1;
1641     }
1642 }
1643
1644 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1645   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   vat_json_node_t node;
1649
1650   vat_json_init_object (&node);
1651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void
1661 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_l2_flags_reply_t_handler_json
1677   (vl_api_l2_flags_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1685                             ntohl (mp->resulting_feature_bitmap));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void vl_api_bridge_flags_reply_t_handler
1695   (vl_api_bridge_flags_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   i32 retval = ntohl (mp->retval);
1699   if (vam->async_mode)
1700     {
1701       vam->async_errors += (retval < 0);
1702     }
1703   else
1704     {
1705       vam->retval = retval;
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_bridge_flags_reply_t_handler_json
1711   (vl_api_bridge_flags_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1719                             ntohl (mp->resulting_feature_bitmap));
1720
1721   vat_json_print (vam->ofp, &node);
1722   vat_json_free (&node);
1723
1724   vam->retval = ntohl (mp->retval);
1725   vam->result_ready = 1;
1726 }
1727
1728 static void
1729 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   i32 retval = ntohl (mp->retval);
1733   if (vam->async_mode)
1734     {
1735       vam->async_errors += (retval < 0);
1736     }
1737   else
1738     {
1739       vam->retval = retval;
1740       vam->sw_if_index = ntohl (mp->sw_if_index);
1741       vam->result_ready = 1;
1742     }
1743
1744 }
1745
1746 static void vl_api_tap_create_v2_reply_t_handler_json
1747   (vl_api_tap_create_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   vat_json_node_t node;
1751
1752   vat_json_init_object (&node);
1753   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1754   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1755
1756   vat_json_print (vam->ofp, &node);
1757   vat_json_free (&node);
1758
1759   vam->retval = ntohl (mp->retval);
1760   vam->result_ready = 1;
1761
1762 }
1763
1764 static void
1765 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->result_ready = 1;
1777     }
1778 }
1779
1780 static void vl_api_tap_delete_v2_reply_t_handler_json
1781   (vl_api_tap_delete_v2_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788
1789   vat_json_print (vam->ofp, &node);
1790   vat_json_free (&node);
1791
1792   vam->retval = ntohl (mp->retval);
1793   vam->result_ready = 1;
1794 }
1795
1796 static void
1797 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1798                                           mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   i32 retval = ntohl (mp->retval);
1802   if (vam->async_mode)
1803     {
1804       vam->async_errors += (retval < 0);
1805     }
1806   else
1807     {
1808       vam->retval = retval;
1809       vam->sw_if_index = ntohl (mp->sw_if_index);
1810       vam->result_ready = 1;
1811     }
1812 }
1813
1814 static void vl_api_virtio_pci_create_reply_t_handler_json
1815   (vl_api_virtio_pci_create_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   vat_json_node_t node;
1819
1820   vat_json_init_object (&node);
1821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1822   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1823
1824   vat_json_print (vam->ofp, &node);
1825   vat_json_free (&node);
1826
1827   vam->retval = ntohl (mp->retval);
1828   vam->result_ready = 1;
1829
1830 }
1831
1832 static void
1833 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1834                                           mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_virtio_pci_delete_reply_t_handler_json
1850   (vl_api_virtio_pci_delete_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857
1858   vat_json_print (vam->ofp, &node);
1859   vat_json_free (&node);
1860
1861   vam->retval = ntohl (mp->retval);
1862   vam->result_ready = 1;
1863 }
1864
1865 static void
1866 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   i32 retval = ntohl (mp->retval);
1870
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->sw_if_index = ntohl (mp->sw_if_index);
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_bond_create_reply_t_handler_json
1884   (vl_api_bond_create_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1892
1893   vat_json_print (vam->ofp, &node);
1894   vat_json_free (&node);
1895
1896   vam->retval = ntohl (mp->retval);
1897   vam->result_ready = 1;
1898 }
1899
1900 static void
1901 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1902 {
1903   vat_main_t *vam = &vat_main;
1904   i32 retval = ntohl (mp->retval);
1905
1906   if (vam->async_mode)
1907     {
1908       vam->async_errors += (retval < 0);
1909     }
1910   else
1911     {
1912       vam->retval = retval;
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_delete_reply_t_handler_json
1918   (vl_api_bond_delete_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922
1923   vat_json_init_object (&node);
1924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925
1926   vat_json_print (vam->ofp, &node);
1927   vat_json_free (&node);
1928
1929   vam->retval = ntohl (mp->retval);
1930   vam->result_ready = 1;
1931 }
1932
1933 static void
1934 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   i32 retval = ntohl (mp->retval);
1938
1939   if (vam->async_mode)
1940     {
1941       vam->async_errors += (retval < 0);
1942     }
1943   else
1944     {
1945       vam->retval = retval;
1946       vam->result_ready = 1;
1947     }
1948 }
1949
1950 static void vl_api_bond_enslave_reply_t_handler_json
1951   (vl_api_bond_enslave_reply_t * mp)
1952 {
1953   vat_main_t *vam = &vat_main;
1954   vat_json_node_t node;
1955
1956   vat_json_init_object (&node);
1957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1958
1959   vat_json_print (vam->ofp, &node);
1960   vat_json_free (&node);
1961
1962   vam->retval = ntohl (mp->retval);
1963   vam->result_ready = 1;
1964 }
1965
1966 static void
1967 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1968                                           mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   i32 retval = ntohl (mp->retval);
1972
1973   if (vam->async_mode)
1974     {
1975       vam->async_errors += (retval < 0);
1976     }
1977   else
1978     {
1979       vam->retval = retval;
1980       vam->result_ready = 1;
1981     }
1982 }
1983
1984 static void vl_api_bond_detach_slave_reply_t_handler_json
1985   (vl_api_bond_detach_slave_reply_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t node;
1989
1990   vat_json_init_object (&node);
1991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993   vat_json_print (vam->ofp, &node);
1994   vat_json_free (&node);
1995
1996   vam->retval = ntohl (mp->retval);
1997   vam->result_ready = 1;
1998 }
1999
2000 static int
2001 api_sw_interface_set_bond_weight (vat_main_t * vam)
2002 {
2003   unformat_input_t *i = vam->input;
2004   vl_api_sw_interface_set_bond_weight_t *mp;
2005   u32 sw_if_index = ~0;
2006   u32 weight = 0;
2007   u8 weight_enter = 0;
2008   int ret;
2009
2010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2011     {
2012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2013         ;
2014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2015         ;
2016       else if (unformat (i, "weight %u", &weight))
2017         weight_enter = 1;
2018       else
2019         break;
2020     }
2021
2022   if (sw_if_index == ~0)
2023     {
2024       errmsg ("missing interface name or sw_if_index");
2025       return -99;
2026     }
2027   if (weight_enter == 0)
2028     {
2029       errmsg ("missing valid weight");
2030       return -99;
2031     }
2032
2033   /* Construct the API message */
2034   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2035   mp->sw_if_index = ntohl (sw_if_index);
2036   mp->weight = ntohl (weight);
2037
2038   S (mp);
2039   W (ret);
2040   return ret;
2041 }
2042
2043 static void vl_api_sw_interface_bond_details_t_handler
2044   (vl_api_sw_interface_bond_details_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047
2048   print (vam->ofp,
2049          "%-16s %-12d %-12U %-13U %-14u %-14u",
2050          mp->interface_name, ntohl (mp->sw_if_index),
2051          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2052          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2053 }
2054
2055 static void vl_api_sw_interface_bond_details_t_handler_json
2056   (vl_api_sw_interface_bond_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vat_json_node_t *node = NULL;
2060
2061   if (VAT_JSON_ARRAY != vam->json_tree.type)
2062     {
2063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064       vat_json_init_array (&vam->json_tree);
2065     }
2066   node = vat_json_array_add (&vam->json_tree);
2067
2068   vat_json_init_object (node);
2069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070   vat_json_object_add_string_copy (node, "interface_name",
2071                                    mp->interface_name);
2072   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2073   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2074   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076 }
2077
2078 static int
2079 api_sw_interface_bond_dump (vat_main_t * vam)
2080 {
2081   vl_api_sw_interface_bond_dump_t *mp;
2082   vl_api_control_ping_t *mp_ping;
2083   int ret;
2084
2085   print (vam->ofp,
2086          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087          "interface name", "sw_if_index", "mode", "load balance",
2088          "active slaves", "slaves");
2089
2090   /* Get list of bond interfaces */
2091   M (SW_INTERFACE_BOND_DUMP, mp);
2092   S (mp);
2093
2094   /* Use a control ping for synchronization */
2095   MPING (CONTROL_PING, mp_ping);
2096   S (mp_ping);
2097
2098   W (ret);
2099   return ret;
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106
2107   print (vam->ofp,
2108          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2109          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2110          ntohl (mp->weight), mp->is_local_numa);
2111 }
2112
2113 static void vl_api_sw_interface_slave_details_t_handler_json
2114   (vl_api_sw_interface_slave_details_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   vat_json_node_t *node = NULL;
2118
2119   if (VAT_JSON_ARRAY != vam->json_tree.type)
2120     {
2121       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2122       vat_json_init_array (&vam->json_tree);
2123     }
2124   node = vat_json_array_add (&vam->json_tree);
2125
2126   vat_json_init_object (node);
2127   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2128   vat_json_object_add_string_copy (node, "interface_name",
2129                                    mp->interface_name);
2130   vat_json_object_add_uint (node, "passive", mp->is_passive);
2131   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2132   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2133   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2134 }
2135
2136 static int
2137 api_sw_interface_slave_dump (vat_main_t * vam)
2138 {
2139   unformat_input_t *i = vam->input;
2140   vl_api_sw_interface_slave_dump_t *mp;
2141   vl_api_control_ping_t *mp_ping;
2142   u32 sw_if_index = ~0;
2143   u8 sw_if_index_set = 0;
2144   int ret;
2145
2146   /* Parse args required to build the message */
2147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2148     {
2149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2150         sw_if_index_set = 1;
2151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2152         sw_if_index_set = 1;
2153       else
2154         break;
2155     }
2156
2157   if (sw_if_index_set == 0)
2158     {
2159       errmsg ("missing vpp interface name. ");
2160       return -99;
2161     }
2162
2163   print (vam->ofp,
2164          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2165          "slave interface name", "sw_if_index", "passive", "long_timeout",
2166          "weight", "local numa");
2167
2168   /* Get list of bond interfaces */
2169   M (SW_INTERFACE_SLAVE_DUMP, mp);
2170   mp->sw_if_index = ntohl (sw_if_index);
2171   S (mp);
2172
2173   /* Use a control ping for synchronization */
2174   MPING (CONTROL_PING, mp_ping);
2175   S (mp_ping);
2176
2177   W (ret);
2178   return ret;
2179 }
2180
2181 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2182   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   i32 retval = ntohl (mp->retval);
2186   if (vam->async_mode)
2187     {
2188       vam->async_errors += (retval < 0);
2189     }
2190   else
2191     {
2192       vam->retval = retval;
2193       vam->sw_if_index = ntohl (mp->sw_if_index);
2194       vam->result_ready = 1;
2195     }
2196   vam->regenerate_interface_table = 1;
2197 }
2198
2199 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2200   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vat_json_node_t node;
2204
2205   vat_json_init_object (&node);
2206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2207   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2208                             ntohl (mp->sw_if_index));
2209
2210   vat_json_print (vam->ofp, &node);
2211   vat_json_free (&node);
2212
2213   vam->retval = ntohl (mp->retval);
2214   vam->result_ready = 1;
2215 }
2216
2217 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2218   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2219 {
2220   vat_main_t *vam = &vat_main;
2221   i32 retval = ntohl (mp->retval);
2222   if (vam->async_mode)
2223     {
2224       vam->async_errors += (retval < 0);
2225     }
2226   else
2227     {
2228       vam->retval = retval;
2229       vam->sw_if_index = ntohl (mp->sw_if_index);
2230       vam->result_ready = 1;
2231     }
2232 }
2233
2234 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2235   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2236 {
2237   vat_main_t *vam = &vat_main;
2238   vat_json_node_t node;
2239
2240   vat_json_init_object (&node);
2241   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2242   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2243
2244   vat_json_print (vam->ofp, &node);
2245   vat_json_free (&node);
2246
2247   vam->retval = ntohl (mp->retval);
2248   vam->result_ready = 1;
2249 }
2250
2251 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2252   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2253 {
2254   vat_main_t *vam = &vat_main;
2255   i32 retval = ntohl (mp->retval);
2256   if (vam->async_mode)
2257     {
2258       vam->async_errors += (retval < 0);
2259     }
2260   else
2261     {
2262       vam->retval = retval;
2263       vam->result_ready = 1;
2264     }
2265 }
2266
2267 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2268   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2269 {
2270   vat_main_t *vam = &vat_main;
2271   vat_json_node_t node;
2272
2273   vat_json_init_object (&node);
2274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2275   vat_json_object_add_uint (&node, "fwd_entry_index",
2276                             clib_net_to_host_u32 (mp->fwd_entry_index));
2277
2278   vat_json_print (vam->ofp, &node);
2279   vat_json_free (&node);
2280
2281   vam->retval = ntohl (mp->retval);
2282   vam->result_ready = 1;
2283 }
2284
2285 u8 *
2286 format_lisp_transport_protocol (u8 * s, va_list * args)
2287 {
2288   u32 proto = va_arg (*args, u32);
2289
2290   switch (proto)
2291     {
2292     case 1:
2293       return format (s, "udp");
2294     case 2:
2295       return format (s, "api");
2296     default:
2297       return 0;
2298     }
2299   return 0;
2300 }
2301
2302 static void vl_api_one_get_transport_protocol_reply_t_handler
2303   (vl_api_one_get_transport_protocol_reply_t * mp)
2304 {
2305   vat_main_t *vam = &vat_main;
2306   i32 retval = ntohl (mp->retval);
2307   if (vam->async_mode)
2308     {
2309       vam->async_errors += (retval < 0);
2310     }
2311   else
2312     {
2313       u32 proto = mp->protocol;
2314       print (vam->ofp, "Transport protocol: %U",
2315              format_lisp_transport_protocol, proto);
2316       vam->retval = retval;
2317       vam->result_ready = 1;
2318     }
2319 }
2320
2321 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2322   (vl_api_one_get_transport_protocol_reply_t * mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   vat_json_node_t node;
2326   u8 *s;
2327
2328   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2329   vec_add1 (s, 0);
2330
2331   vat_json_init_object (&node);
2332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2333   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2334
2335   vec_free (s);
2336   vat_json_print (vam->ofp, &node);
2337   vat_json_free (&node);
2338
2339   vam->retval = ntohl (mp->retval);
2340   vam->result_ready = 1;
2341 }
2342
2343 static void vl_api_one_add_del_locator_set_reply_t_handler
2344   (vl_api_one_add_del_locator_set_reply_t * mp)
2345 {
2346   vat_main_t *vam = &vat_main;
2347   i32 retval = ntohl (mp->retval);
2348   if (vam->async_mode)
2349     {
2350       vam->async_errors += (retval < 0);
2351     }
2352   else
2353     {
2354       vam->retval = retval;
2355       vam->result_ready = 1;
2356     }
2357 }
2358
2359 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2360   (vl_api_one_add_del_locator_set_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   vat_json_node_t node;
2364
2365   vat_json_init_object (&node);
2366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2367   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2368
2369   vat_json_print (vam->ofp, &node);
2370   vat_json_free (&node);
2371
2372   vam->retval = ntohl (mp->retval);
2373   vam->result_ready = 1;
2374 }
2375
2376 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2377   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   i32 retval = ntohl (mp->retval);
2381   if (vam->async_mode)
2382     {
2383       vam->async_errors += (retval < 0);
2384     }
2385   else
2386     {
2387       vam->retval = retval;
2388       vam->sw_if_index = ntohl (mp->sw_if_index);
2389       vam->result_ready = 1;
2390     }
2391   vam->regenerate_interface_table = 1;
2392 }
2393
2394 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2395   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2396 {
2397   vat_main_t *vam = &vat_main;
2398   vat_json_node_t node;
2399
2400   vat_json_init_object (&node);
2401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2403
2404   vat_json_print (vam->ofp, &node);
2405   vat_json_free (&node);
2406
2407   vam->retval = ntohl (mp->retval);
2408   vam->result_ready = 1;
2409 }
2410
2411 static void vl_api_vxlan_offload_rx_reply_t_handler
2412   (vl_api_vxlan_offload_rx_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416   if (vam->async_mode)
2417     {
2418       vam->async_errors += (retval < 0);
2419     }
2420   else
2421     {
2422       vam->retval = retval;
2423       vam->result_ready = 1;
2424     }
2425 }
2426
2427 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2428   (vl_api_vxlan_offload_rx_reply_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t node;
2432
2433   vat_json_init_object (&node);
2434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2435
2436   vat_json_print (vam->ofp, &node);
2437   vat_json_free (&node);
2438
2439   vam->retval = ntohl (mp->retval);
2440   vam->result_ready = 1;
2441 }
2442
2443 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2444   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447   i32 retval = ntohl (mp->retval);
2448   if (vam->async_mode)
2449     {
2450       vam->async_errors += (retval < 0);
2451     }
2452   else
2453     {
2454       vam->retval = retval;
2455       vam->sw_if_index = ntohl (mp->sw_if_index);
2456       vam->result_ready = 1;
2457     }
2458 }
2459
2460 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2461   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464   vat_json_node_t node;
2465
2466   vat_json_init_object (&node);
2467   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2468   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2478   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   i32 retval = ntohl (mp->retval);
2482   if (vam->async_mode)
2483     {
2484       vam->async_errors += (retval < 0);
2485     }
2486   else
2487     {
2488       vam->retval = retval;
2489       vam->sw_if_index = ntohl (mp->sw_if_index);
2490       vam->result_ready = 1;
2491     }
2492   vam->regenerate_interface_table = 1;
2493 }
2494
2495 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2496   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t node;
2500
2501   vat_json_init_object (&node);
2502   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2503   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2504
2505   vat_json_print (vam->ofp, &node);
2506   vat_json_free (&node);
2507
2508   vam->retval = ntohl (mp->retval);
2509   vam->result_ready = 1;
2510 }
2511
2512 static void vl_api_gre_tunnel_add_del_reply_t_handler
2513   (vl_api_gre_tunnel_add_del_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   i32 retval = ntohl (mp->retval);
2517   if (vam->async_mode)
2518     {
2519       vam->async_errors += (retval < 0);
2520     }
2521   else
2522     {
2523       vam->retval = retval;
2524       vam->sw_if_index = ntohl (mp->sw_if_index);
2525       vam->result_ready = 1;
2526     }
2527 }
2528
2529 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2530   (vl_api_gre_tunnel_add_del_reply_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   vat_json_node_t node;
2534
2535   vat_json_init_object (&node);
2536   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2537   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2538
2539   vat_json_print (vam->ofp, &node);
2540   vat_json_free (&node);
2541
2542   vam->retval = ntohl (mp->retval);
2543   vam->result_ready = 1;
2544 }
2545
2546 static void vl_api_create_vhost_user_if_reply_t_handler
2547   (vl_api_create_vhost_user_if_reply_t * mp)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   i32 retval = ntohl (mp->retval);
2551   if (vam->async_mode)
2552     {
2553       vam->async_errors += (retval < 0);
2554     }
2555   else
2556     {
2557       vam->retval = retval;
2558       vam->sw_if_index = ntohl (mp->sw_if_index);
2559       vam->result_ready = 1;
2560     }
2561   vam->regenerate_interface_table = 1;
2562 }
2563
2564 static void vl_api_create_vhost_user_if_reply_t_handler_json
2565   (vl_api_create_vhost_user_if_reply_t * mp)
2566 {
2567   vat_main_t *vam = &vat_main;
2568   vat_json_node_t node;
2569
2570   vat_json_init_object (&node);
2571   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2572   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2573
2574   vat_json_print (vam->ofp, &node);
2575   vat_json_free (&node);
2576
2577   vam->retval = ntohl (mp->retval);
2578   vam->result_ready = 1;
2579 }
2580
2581 static void vl_api_ip_address_details_t_handler
2582   (vl_api_ip_address_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   static ip_address_details_t empty_ip_address_details = { {0} };
2586   ip_address_details_t *address = NULL;
2587   ip_details_t *current_ip_details = NULL;
2588   ip_details_t *details = NULL;
2589
2590   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2591
2592   if (!details || vam->current_sw_if_index >= vec_len (details)
2593       || !details[vam->current_sw_if_index].present)
2594     {
2595       errmsg ("ip address details arrived but not stored");
2596       errmsg ("ip_dump should be called first");
2597       return;
2598     }
2599
2600   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2601
2602 #define addresses (current_ip_details->addr)
2603
2604   vec_validate_init_empty (addresses, vec_len (addresses),
2605                            empty_ip_address_details);
2606
2607   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2608
2609   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2610   address->prefix_length = mp->prefix.len;
2611 #undef addresses
2612 }
2613
2614 static void vl_api_ip_address_details_t_handler_json
2615   (vl_api_ip_address_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618   vat_json_node_t *node = NULL;
2619
2620   if (VAT_JSON_ARRAY != vam->json_tree.type)
2621     {
2622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2623       vat_json_init_array (&vam->json_tree);
2624     }
2625   node = vat_json_array_add (&vam->json_tree);
2626
2627   vat_json_init_object (node);
2628   vat_json_object_add_prefix (node, &mp->prefix);
2629 }
2630
2631 static void
2632 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2633 {
2634   vat_main_t *vam = &vat_main;
2635   static ip_details_t empty_ip_details = { 0 };
2636   ip_details_t *ip = NULL;
2637   u32 sw_if_index = ~0;
2638
2639   sw_if_index = ntohl (mp->sw_if_index);
2640
2641   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2642                            sw_if_index, empty_ip_details);
2643
2644   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2645                          sw_if_index);
2646
2647   ip->present = 1;
2648 }
2649
2650 static void
2651 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2652 {
2653   vat_main_t *vam = &vat_main;
2654
2655   if (VAT_JSON_ARRAY != vam->json_tree.type)
2656     {
2657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2658       vat_json_init_array (&vam->json_tree);
2659     }
2660   vat_json_array_add_uint (&vam->json_tree,
2661                            clib_net_to_host_u32 (mp->sw_if_index));
2662 }
2663
2664 static void vl_api_get_first_msg_id_reply_t_handler
2665   (vl_api_get_first_msg_id_reply_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   i32 retval = ntohl (mp->retval);
2669
2670   if (vam->async_mode)
2671     {
2672       vam->async_errors += (retval < 0);
2673     }
2674   else
2675     {
2676       vam->retval = retval;
2677       vam->result_ready = 1;
2678     }
2679   if (retval >= 0)
2680     {
2681       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2682     }
2683 }
2684
2685 static void vl_api_get_first_msg_id_reply_t_handler_json
2686   (vl_api_get_first_msg_id_reply_t * mp)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   vat_json_node_t node;
2690
2691   vat_json_init_object (&node);
2692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2693   vat_json_object_add_uint (&node, "first_msg_id",
2694                             (uint) ntohs (mp->first_msg_id));
2695
2696   vat_json_print (vam->ofp, &node);
2697   vat_json_free (&node);
2698
2699   vam->retval = ntohl (mp->retval);
2700   vam->result_ready = 1;
2701 }
2702
2703 static void vl_api_get_node_graph_reply_t_handler
2704   (vl_api_get_node_graph_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   i32 retval = ntohl (mp->retval);
2708   u8 *pvt_copy, *reply;
2709   void *oldheap;
2710   vlib_node_t *node;
2711   int i;
2712
2713   if (vam->async_mode)
2714     {
2715       vam->async_errors += (retval < 0);
2716     }
2717   else
2718     {
2719       vam->retval = retval;
2720       vam->result_ready = 1;
2721     }
2722
2723   /* "Should never happen..." */
2724   if (retval != 0)
2725     return;
2726
2727   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2728   pvt_copy = vec_dup (reply);
2729
2730   /* Toss the shared-memory original... */
2731   oldheap = vl_msg_push_heap ();
2732
2733   vec_free (reply);
2734
2735   vl_msg_pop_heap (oldheap);
2736
2737   if (vam->graph_nodes)
2738     {
2739       hash_free (vam->graph_node_index_by_name);
2740
2741       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2742         {
2743           node = vam->graph_nodes[0][i];
2744           vec_free (node->name);
2745           vec_free (node->next_nodes);
2746           vec_free (node);
2747         }
2748       vec_free (vam->graph_nodes[0]);
2749       vec_free (vam->graph_nodes);
2750     }
2751
2752   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2753   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2754   vec_free (pvt_copy);
2755
2756   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2757     {
2758       node = vam->graph_nodes[0][i];
2759       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2760     }
2761 }
2762
2763 static void vl_api_get_node_graph_reply_t_handler_json
2764   (vl_api_get_node_graph_reply_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   void *oldheap;
2768   vat_json_node_t node;
2769   u8 *reply;
2770
2771   /* $$$$ make this real? */
2772   vat_json_init_object (&node);
2773   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2774   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2775
2776   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2777
2778   /* Toss the shared-memory original... */
2779   oldheap = vl_msg_push_heap ();
2780
2781   vec_free (reply);
2782
2783   vl_msg_pop_heap (oldheap);
2784
2785   vat_json_print (vam->ofp, &node);
2786   vat_json_free (&node);
2787
2788   vam->retval = ntohl (mp->retval);
2789   vam->result_ready = 1;
2790 }
2791
2792 static void
2793 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   u8 *s = 0;
2797
2798   if (mp->local)
2799     {
2800       s = format (s, "%=16d%=16d%=16d",
2801                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2802     }
2803   else
2804     {
2805       s = format (s, "%=16U%=16d%=16d",
2806                   format_ip46_address,
2807                   mp->ip_address, mp->priority, mp->weight);
2808     }
2809
2810   print (vam->ofp, "%v", s);
2811   vec_free (s);
2812 }
2813
2814 static void
2815 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2816 {
2817   vat_main_t *vam = &vat_main;
2818   vat_json_node_t *node = NULL;
2819   struct in6_addr ip6;
2820   struct in_addr ip4;
2821
2822   if (VAT_JSON_ARRAY != vam->json_tree.type)
2823     {
2824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2825       vat_json_init_array (&vam->json_tree);
2826     }
2827   node = vat_json_array_add (&vam->json_tree);
2828   vat_json_init_object (node);
2829
2830   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2831   vat_json_object_add_uint (node, "priority", mp->priority);
2832   vat_json_object_add_uint (node, "weight", mp->weight);
2833
2834   if (mp->local)
2835     vat_json_object_add_uint (node, "sw_if_index",
2836                               clib_net_to_host_u32 (mp->sw_if_index));
2837   else
2838     {
2839       if (mp->ip_address.af)
2840         {
2841           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2842           vat_json_object_add_ip6 (node, "address", ip6);
2843         }
2844       else
2845         {
2846           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2847           vat_json_object_add_ip4 (node, "address", ip4);
2848         }
2849     }
2850 }
2851
2852 static void
2853 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2854                                           mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   u8 *ls_name = 0;
2858
2859   ls_name = format (0, "%s", mp->ls_name);
2860
2861   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2862          ls_name);
2863   vec_free (ls_name);
2864 }
2865
2866 static void
2867   vl_api_one_locator_set_details_t_handler_json
2868   (vl_api_one_locator_set_details_t * mp)
2869 {
2870   vat_main_t *vam = &vat_main;
2871   vat_json_node_t *node = 0;
2872   u8 *ls_name = 0;
2873
2874   ls_name = format (0, "%s", mp->ls_name);
2875   vec_add1 (ls_name, 0);
2876
2877   if (VAT_JSON_ARRAY != vam->json_tree.type)
2878     {
2879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2880       vat_json_init_array (&vam->json_tree);
2881     }
2882   node = vat_json_array_add (&vam->json_tree);
2883
2884   vat_json_init_object (node);
2885   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2886   vat_json_object_add_uint (node, "ls_index",
2887                             clib_net_to_host_u32 (mp->ls_index));
2888   vec_free (ls_name);
2889 }
2890
2891 typedef struct
2892 {
2893   u32 spi;
2894   u8 si;
2895 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2896
2897 uword
2898 unformat_nsh_address (unformat_input_t * input, va_list * args)
2899 {
2900   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2901   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2902 }
2903
2904 u8 *
2905 format_nsh_address_vat (u8 * s, va_list * args)
2906 {
2907   nsh_t *a = va_arg (*args, nsh_t *);
2908   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2909 }
2910
2911 static u8 *
2912 format_lisp_flat_eid (u8 * s, va_list * args)
2913 {
2914   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2915
2916   switch (eid->type)
2917     {
2918     case EID_TYPE_API_PREFIX:
2919       if (eid->address.prefix.address.af)
2920         return format (s, "%U/%d", format_ip6_address,
2921                        eid->address.prefix.address.un.ip6,
2922                        eid->address.prefix.len);
2923       return format (s, "%U/%d", format_ip4_address,
2924                      eid->address.prefix.address.un.ip4,
2925                      eid->address.prefix.len);
2926     case EID_TYPE_API_MAC:
2927       return format (s, "%U", format_ethernet_address, eid->address.mac);
2928     case EID_TYPE_API_NSH:
2929       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2930     }
2931   return 0;
2932 }
2933
2934 static u8 *
2935 format_lisp_eid_vat (u8 * s, va_list * args)
2936 {
2937   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2938   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2939   u8 is_src_dst = (u8) va_arg (*args, int);
2940
2941   if (is_src_dst)
2942     s = format (s, "%U|", format_lisp_flat_eid, seid);
2943
2944   s = format (s, "%U", format_lisp_flat_eid, deid);
2945
2946   return s;
2947 }
2948
2949 static void
2950 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2951 {
2952   vat_main_t *vam = &vat_main;
2953   u8 *s = 0, *eid = 0;
2954
2955   if (~0 == mp->locator_set_index)
2956     s = format (0, "action: %d", mp->action);
2957   else
2958     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2959
2960   eid = format (0, "%U", format_lisp_eid_vat,
2961                 mp->deid, mp->seid, mp->is_src_dst);
2962   vec_add1 (eid, 0);
2963
2964   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2965          clib_net_to_host_u32 (mp->vni),
2966          eid,
2967          mp->is_local ? "local" : "remote",
2968          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2969          clib_net_to_host_u16 (mp->key.id), mp->key.key);
2970
2971   vec_free (s);
2972   vec_free (eid);
2973 }
2974
2975 static void
2976 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2977                                              * mp)
2978 {
2979   vat_main_t *vam = &vat_main;
2980   vat_json_node_t *node = 0;
2981   u8 *eid = 0;
2982
2983   if (VAT_JSON_ARRAY != vam->json_tree.type)
2984     {
2985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2986       vat_json_init_array (&vam->json_tree);
2987     }
2988   node = vat_json_array_add (&vam->json_tree);
2989
2990   vat_json_init_object (node);
2991   if (~0 == mp->locator_set_index)
2992     vat_json_object_add_uint (node, "action", mp->action);
2993   else
2994     vat_json_object_add_uint (node, "locator_set_index",
2995                               clib_net_to_host_u32 (mp->locator_set_index));
2996
2997   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2998   if (mp->deid.type == 3)
2999     {
3000       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3001       vat_json_init_object (nsh_json);
3002       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3003       vat_json_object_add_uint (nsh_json, "spi",
3004                                 clib_net_to_host_u32 (nsh->spi));
3005       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3006     }
3007   else
3008     {
3009       eid = format (0, "%U", format_lisp_eid_vat,
3010                     mp->deid, mp->seid, mp->is_src_dst);
3011       vec_add1 (eid, 0);
3012       vat_json_object_add_string_copy (node, "eid", eid);
3013       vec_free (eid);
3014     }
3015   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3016   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3017   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3018
3019   if (mp->key.id)
3020     {
3021       vat_json_object_add_uint (node, "key_id",
3022                                 clib_net_to_host_u16 (mp->key.id));
3023       vat_json_object_add_string_copy (node, "key", mp->key.key);
3024     }
3025 }
3026
3027 static void
3028 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031   u8 *seid = 0, *deid = 0;
3032   ip46_address_t lloc, rloc;
3033
3034   deid = format (0, "%U", format_lisp_eid_vat, mp->deid, 0);
3035
3036   seid = format (0, "%U", format_lisp_eid_vat, mp->seid, 0);
3037
3038   vec_add1 (deid, 0);
3039   vec_add1 (seid, 0);
3040
3041   if (mp->lloc.af)
3042     {
3043       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3044       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3045     }
3046   else
3047     {
3048       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3049       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3050     }
3051
3052
3053   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3054          clib_net_to_host_u32 (mp->vni),
3055          seid, deid,
3056          format_ip46_address, lloc,
3057          format_ip46_address, rloc,
3058          clib_net_to_host_u32 (mp->pkt_count),
3059          clib_net_to_host_u32 (mp->bytes));
3060
3061   vec_free (deid);
3062   vec_free (seid);
3063 }
3064
3065 static void
3066 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3067 {
3068   struct in6_addr ip6;
3069   struct in_addr ip4;
3070   vat_main_t *vam = &vat_main;
3071   vat_json_node_t *node = 0;
3072   u8 *deid = 0, *seid = 0;
3073
3074   if (VAT_JSON_ARRAY != vam->json_tree.type)
3075     {
3076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3077       vat_json_init_array (&vam->json_tree);
3078     }
3079   node = vat_json_array_add (&vam->json_tree);
3080
3081   vat_json_init_object (node);
3082   deid = format (0, "%U", format_lisp_eid_vat, mp->deid, 0);
3083
3084   seid = format (0, "%U", format_lisp_eid_vat, mp->seid, 0);
3085
3086   vec_add1 (deid, 0);
3087   vec_add1 (seid, 0);
3088
3089   vat_json_object_add_string_copy (node, "seid", seid);
3090   vat_json_object_add_string_copy (node, "deid", deid);
3091   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3092
3093   if (mp->lloc.af)
3094     {
3095       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3096       vat_json_object_add_ip6 (node, "lloc", ip6);
3097       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3098       vat_json_object_add_ip6 (node, "rloc", ip6);
3099
3100     }
3101   else
3102     {
3103       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3104       vat_json_object_add_ip4 (node, "lloc", ip4);
3105       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3106       vat_json_object_add_ip4 (node, "rloc", ip4);
3107     }
3108   vat_json_object_add_uint (node, "pkt_count",
3109                             clib_net_to_host_u32 (mp->pkt_count));
3110   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3111
3112   vec_free (deid);
3113   vec_free (seid);
3114 }
3115
3116 static void
3117   vl_api_one_eid_table_map_details_t_handler
3118   (vl_api_one_eid_table_map_details_t * mp)
3119 {
3120   vat_main_t *vam = &vat_main;
3121
3122   u8 *line = format (0, "%=10d%=10d",
3123                      clib_net_to_host_u32 (mp->vni),
3124                      clib_net_to_host_u32 (mp->dp_table));
3125   print (vam->ofp, "%v", line);
3126   vec_free (line);
3127 }
3128
3129 static void
3130   vl_api_one_eid_table_map_details_t_handler_json
3131   (vl_api_one_eid_table_map_details_t * mp)
3132 {
3133   vat_main_t *vam = &vat_main;
3134   vat_json_node_t *node = NULL;
3135
3136   if (VAT_JSON_ARRAY != vam->json_tree.type)
3137     {
3138       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3139       vat_json_init_array (&vam->json_tree);
3140     }
3141   node = vat_json_array_add (&vam->json_tree);
3142   vat_json_init_object (node);
3143   vat_json_object_add_uint (node, "dp_table",
3144                             clib_net_to_host_u32 (mp->dp_table));
3145   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3146 }
3147
3148 static void
3149   vl_api_one_eid_table_vni_details_t_handler
3150   (vl_api_one_eid_table_vni_details_t * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153
3154   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3155   print (vam->ofp, "%v", line);
3156   vec_free (line);
3157 }
3158
3159 static void
3160   vl_api_one_eid_table_vni_details_t_handler_json
3161   (vl_api_one_eid_table_vni_details_t * mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164   vat_json_node_t *node = NULL;
3165
3166   if (VAT_JSON_ARRAY != vam->json_tree.type)
3167     {
3168       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3169       vat_json_init_array (&vam->json_tree);
3170     }
3171   node = vat_json_array_add (&vam->json_tree);
3172   vat_json_init_object (node);
3173   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3174 }
3175
3176 static void
3177   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3178   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   int retval = clib_net_to_host_u32 (mp->retval);
3182
3183   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3184   print (vam->ofp, "fallback threshold value: %d", mp->value);
3185
3186   vam->retval = retval;
3187   vam->result_ready = 1;
3188 }
3189
3190 static void
3191   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3192   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3193 {
3194   vat_main_t *vam = &vat_main;
3195   vat_json_node_t _node, *node = &_node;
3196   int retval = clib_net_to_host_u32 (mp->retval);
3197
3198   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3199   vat_json_init_object (node);
3200   vat_json_object_add_uint (node, "value", mp->value);
3201
3202   vat_json_print (vam->ofp, node);
3203   vat_json_free (node);
3204
3205   vam->retval = retval;
3206   vam->result_ready = 1;
3207 }
3208
3209 static void
3210   vl_api_show_one_map_register_state_reply_t_handler
3211   (vl_api_show_one_map_register_state_reply_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   int retval = clib_net_to_host_u32 (mp->retval);
3215
3216   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3217
3218   vam->retval = retval;
3219   vam->result_ready = 1;
3220 }
3221
3222 static void
3223   vl_api_show_one_map_register_state_reply_t_handler_json
3224   (vl_api_show_one_map_register_state_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   vat_json_node_t _node, *node = &_node;
3228   int retval = clib_net_to_host_u32 (mp->retval);
3229
3230   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3231
3232   vat_json_init_object (node);
3233   vat_json_object_add_string_copy (node, "state", s);
3234
3235   vat_json_print (vam->ofp, node);
3236   vat_json_free (node);
3237
3238   vam->retval = retval;
3239   vam->result_ready = 1;
3240   vec_free (s);
3241 }
3242
3243 static void
3244   vl_api_show_one_rloc_probe_state_reply_t_handler
3245   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3246 {
3247   vat_main_t *vam = &vat_main;
3248   int retval = clib_net_to_host_u32 (mp->retval);
3249
3250   if (retval)
3251     goto end;
3252
3253   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3254 end:
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257 }
3258
3259 static void
3260   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3261   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   vat_json_node_t _node, *node = &_node;
3265   int retval = clib_net_to_host_u32 (mp->retval);
3266
3267   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3268   vat_json_init_object (node);
3269   vat_json_object_add_string_copy (node, "state", s);
3270
3271   vat_json_print (vam->ofp, node);
3272   vat_json_free (node);
3273
3274   vam->retval = retval;
3275   vam->result_ready = 1;
3276   vec_free (s);
3277 }
3278
3279 static void
3280   vl_api_show_one_stats_enable_disable_reply_t_handler
3281   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3282 {
3283   vat_main_t *vam = &vat_main;
3284   int retval = clib_net_to_host_u32 (mp->retval);
3285
3286   if (retval)
3287     goto end;
3288
3289   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3290 end:
3291   vam->retval = retval;
3292   vam->result_ready = 1;
3293 }
3294
3295 static void
3296   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3297   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300   vat_json_node_t _node, *node = &_node;
3301   int retval = clib_net_to_host_u32 (mp->retval);
3302
3303   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3304   vat_json_init_object (node);
3305   vat_json_object_add_string_copy (node, "state", s);
3306
3307   vat_json_print (vam->ofp, node);
3308   vat_json_free (node);
3309
3310   vam->retval = retval;
3311   vam->result_ready = 1;
3312   vec_free (s);
3313 }
3314
3315 static void
3316 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3317 {
3318   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3319   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3320   e->vni = clib_net_to_host_u32 (e->vni);
3321 }
3322
3323 static void
3324   gpe_fwd_entries_get_reply_t_net_to_host
3325   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3326 {
3327   u32 i;
3328
3329   mp->count = clib_net_to_host_u32 (mp->count);
3330   for (i = 0; i < mp->count; i++)
3331     {
3332       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3333     }
3334 }
3335
3336 static u8 *
3337 format_gpe_encap_mode (u8 * s, va_list * args)
3338 {
3339   u32 mode = va_arg (*args, u32);
3340
3341   switch (mode)
3342     {
3343     case 0:
3344       return format (s, "lisp");
3345     case 1:
3346       return format (s, "vxlan");
3347     }
3348   return 0;
3349 }
3350
3351 static void
3352   vl_api_gpe_get_encap_mode_reply_t_handler
3353   (vl_api_gpe_get_encap_mode_reply_t * mp)
3354 {
3355   vat_main_t *vam = &vat_main;
3356
3357   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3358   vam->retval = ntohl (mp->retval);
3359   vam->result_ready = 1;
3360 }
3361
3362 static void
3363   vl_api_gpe_get_encap_mode_reply_t_handler_json
3364   (vl_api_gpe_get_encap_mode_reply_t * mp)
3365 {
3366   vat_main_t *vam = &vat_main;
3367   vat_json_node_t node;
3368
3369   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3370   vec_add1 (encap_mode, 0);
3371
3372   vat_json_init_object (&node);
3373   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3374
3375   vec_free (encap_mode);
3376   vat_json_print (vam->ofp, &node);
3377   vat_json_free (&node);
3378
3379   vam->retval = ntohl (mp->retval);
3380   vam->result_ready = 1;
3381 }
3382
3383 static void
3384   vl_api_gpe_fwd_entry_path_details_t_handler
3385   (vl_api_gpe_fwd_entry_path_details_t * mp)
3386 {
3387   vat_main_t *vam = &vat_main;
3388   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3389
3390   if (mp->lcl_loc.addr.af)
3391     format_ip_address_fcn = format_ip6_address;
3392   else
3393     format_ip_address_fcn = format_ip4_address;
3394
3395   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3396          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3397          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3398 }
3399
3400 static void
3401 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3402 {
3403   struct in6_addr ip6;
3404   struct in_addr ip4;
3405
3406   if (loc->addr.af)
3407     {
3408       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3409       vat_json_object_add_ip6 (n, "address", ip6);
3410     }
3411   else
3412     {
3413       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3414       vat_json_object_add_ip4 (n, "address", ip4);
3415     }
3416   vat_json_object_add_uint (n, "weight", loc->weight);
3417 }
3418
3419 static void
3420   vl_api_gpe_fwd_entry_path_details_t_handler_json
3421   (vl_api_gpe_fwd_entry_path_details_t * mp)
3422 {
3423   vat_main_t *vam = &vat_main;
3424   vat_json_node_t *node = NULL;
3425   vat_json_node_t *loc_node;
3426
3427   if (VAT_JSON_ARRAY != vam->json_tree.type)
3428     {
3429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3430       vat_json_init_array (&vam->json_tree);
3431     }
3432   node = vat_json_array_add (&vam->json_tree);
3433   vat_json_init_object (node);
3434
3435   loc_node = vat_json_object_add (node, "local_locator");
3436   vat_json_init_object (loc_node);
3437   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3438
3439   loc_node = vat_json_object_add (node, "remote_locator");
3440   vat_json_init_object (loc_node);
3441   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3442 }
3443
3444 static void
3445   vl_api_gpe_fwd_entries_get_reply_t_handler
3446   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3447 {
3448   vat_main_t *vam = &vat_main;
3449   u32 i;
3450   int retval = clib_net_to_host_u32 (mp->retval);
3451   vl_api_gpe_fwd_entry_t *e;
3452
3453   if (retval)
3454     goto end;
3455
3456   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3457
3458   for (i = 0; i < mp->count; i++)
3459     {
3460       e = &mp->entries[i];
3461       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3462              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3463     }
3464
3465 end:
3466   vam->retval = retval;
3467   vam->result_ready = 1;
3468 }
3469
3470 static void
3471   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   u8 *s = 0;
3475   vat_main_t *vam = &vat_main;
3476   vat_json_node_t *e = 0, root;
3477   u32 i;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479   vl_api_gpe_fwd_entry_t *fwd;
3480
3481   if (retval)
3482     goto end;
3483
3484   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3485   vat_json_init_array (&root);
3486
3487   for (i = 0; i < mp->count; i++)
3488     {
3489       e = vat_json_array_add (&root);
3490       fwd = &mp->entries[i];
3491
3492       vat_json_init_object (e);
3493       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3494       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3495       vat_json_object_add_int (e, "vni", fwd->vni);
3496       vat_json_object_add_int (e, "action", fwd->action);
3497
3498       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3499       vec_add1 (s, 0);
3500       vat_json_object_add_string_copy (e, "leid", s);
3501       vec_free (s);
3502
3503       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3504       vec_add1 (s, 0);
3505       vat_json_object_add_string_copy (e, "reid", s);
3506       vec_free (s);
3507     }
3508
3509   vat_json_print (vam->ofp, &root);
3510   vat_json_free (&root);
3511
3512 end:
3513   vam->retval = retval;
3514   vam->result_ready = 1;
3515 }
3516
3517 static void
3518   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3519   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3520 {
3521   vat_main_t *vam = &vat_main;
3522   u32 i, n;
3523   int retval = clib_net_to_host_u32 (mp->retval);
3524   vl_api_gpe_native_fwd_rpath_t *r;
3525
3526   if (retval)
3527     goto end;
3528
3529   n = clib_net_to_host_u32 (mp->count);
3530
3531   for (i = 0; i < n; i++)
3532     {
3533       r = &mp->entries[i];
3534       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3535              clib_net_to_host_u32 (r->fib_index),
3536              clib_net_to_host_u32 (r->nh_sw_if_index),
3537              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3538              r->nh_addr.un);
3539     }
3540
3541 end:
3542   vam->retval = retval;
3543   vam->result_ready = 1;
3544 }
3545
3546 static void
3547   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3548   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3549 {
3550   vat_main_t *vam = &vat_main;
3551   vat_json_node_t root, *e;
3552   u32 i, n;
3553   int retval = clib_net_to_host_u32 (mp->retval);
3554   vl_api_gpe_native_fwd_rpath_t *r;
3555   u8 *s;
3556
3557   if (retval)
3558     goto end;
3559
3560   n = clib_net_to_host_u32 (mp->count);
3561   vat_json_init_array (&root);
3562
3563   for (i = 0; i < n; i++)
3564     {
3565       e = vat_json_array_add (&root);
3566       vat_json_init_object (e);
3567       r = &mp->entries[i];
3568       s =
3569         format (0, "%U",
3570                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3571                 r->nh_addr.un);
3572       vec_add1 (s, 0);
3573       vat_json_object_add_string_copy (e, "ip4", s);
3574       vec_free (s);
3575
3576       vat_json_object_add_uint (e, "fib_index",
3577                                 clib_net_to_host_u32 (r->fib_index));
3578       vat_json_object_add_uint (e, "nh_sw_if_index",
3579                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3580     }
3581
3582   vat_json_print (vam->ofp, &root);
3583   vat_json_free (&root);
3584
3585 end:
3586   vam->retval = retval;
3587   vam->result_ready = 1;
3588 }
3589
3590 static void
3591   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3592   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   u32 i, n;
3596   int retval = clib_net_to_host_u32 (mp->retval);
3597
3598   if (retval)
3599     goto end;
3600
3601   n = clib_net_to_host_u32 (mp->count);
3602
3603   for (i = 0; i < n; i++)
3604     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3605
3606 end:
3607   vam->retval = retval;
3608   vam->result_ready = 1;
3609 }
3610
3611 static void
3612   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3613   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3614 {
3615   vat_main_t *vam = &vat_main;
3616   vat_json_node_t root;
3617   u32 i, n;
3618   int retval = clib_net_to_host_u32 (mp->retval);
3619
3620   if (retval)
3621     goto end;
3622
3623   n = clib_net_to_host_u32 (mp->count);
3624   vat_json_init_array (&root);
3625
3626   for (i = 0; i < n; i++)
3627     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3628
3629   vat_json_print (vam->ofp, &root);
3630   vat_json_free (&root);
3631
3632 end:
3633   vam->retval = retval;
3634   vam->result_ready = 1;
3635 }
3636
3637 static void
3638   vl_api_one_ndp_entries_get_reply_t_handler
3639   (vl_api_one_ndp_entries_get_reply_t * mp)
3640 {
3641   vat_main_t *vam = &vat_main;
3642   u32 i, n;
3643   int retval = clib_net_to_host_u32 (mp->retval);
3644
3645   if (retval)
3646     goto end;
3647
3648   n = clib_net_to_host_u32 (mp->count);
3649
3650   for (i = 0; i < n; i++)
3651     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3652            format_ethernet_address, mp->entries[i].mac);
3653
3654 end:
3655   vam->retval = retval;
3656   vam->result_ready = 1;
3657 }
3658
3659 static void
3660   vl_api_one_ndp_entries_get_reply_t_handler_json
3661   (vl_api_one_ndp_entries_get_reply_t * mp)
3662 {
3663   u8 *s = 0;
3664   vat_main_t *vam = &vat_main;
3665   vat_json_node_t *e = 0, root;
3666   u32 i, n;
3667   int retval = clib_net_to_host_u32 (mp->retval);
3668   vl_api_one_ndp_entry_t *arp_entry;
3669
3670   if (retval)
3671     goto end;
3672
3673   n = clib_net_to_host_u32 (mp->count);
3674   vat_json_init_array (&root);
3675
3676   for (i = 0; i < n; i++)
3677     {
3678       e = vat_json_array_add (&root);
3679       arp_entry = &mp->entries[i];
3680
3681       vat_json_init_object (e);
3682       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3683       vec_add1 (s, 0);
3684
3685       vat_json_object_add_string_copy (e, "mac", s);
3686       vec_free (s);
3687
3688       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3689       vec_add1 (s, 0);
3690       vat_json_object_add_string_copy (e, "ip6", s);
3691       vec_free (s);
3692     }
3693
3694   vat_json_print (vam->ofp, &root);
3695   vat_json_free (&root);
3696
3697 end:
3698   vam->retval = retval;
3699   vam->result_ready = 1;
3700 }
3701
3702 static void
3703   vl_api_one_l2_arp_entries_get_reply_t_handler
3704   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3705 {
3706   vat_main_t *vam = &vat_main;
3707   u32 i, n;
3708   int retval = clib_net_to_host_u32 (mp->retval);
3709
3710   if (retval)
3711     goto end;
3712
3713   n = clib_net_to_host_u32 (mp->count);
3714
3715   for (i = 0; i < n; i++)
3716     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3717            format_ethernet_address, mp->entries[i].mac);
3718
3719 end:
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3726   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3727 {
3728   u8 *s = 0;
3729   vat_main_t *vam = &vat_main;
3730   vat_json_node_t *e = 0, root;
3731   u32 i, n;
3732   int retval = clib_net_to_host_u32 (mp->retval);
3733   vl_api_one_l2_arp_entry_t *arp_entry;
3734
3735   if (retval)
3736     goto end;
3737
3738   n = clib_net_to_host_u32 (mp->count);
3739   vat_json_init_array (&root);
3740
3741   for (i = 0; i < n; i++)
3742     {
3743       e = vat_json_array_add (&root);
3744       arp_entry = &mp->entries[i];
3745
3746       vat_json_init_object (e);
3747       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3748       vec_add1 (s, 0);
3749
3750       vat_json_object_add_string_copy (e, "mac", s);
3751       vec_free (s);
3752
3753       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3754       vec_add1 (s, 0);
3755       vat_json_object_add_string_copy (e, "ip4", s);
3756       vec_free (s);
3757     }
3758
3759   vat_json_print (vam->ofp, &root);
3760   vat_json_free (&root);
3761
3762 end:
3763   vam->retval = retval;
3764   vam->result_ready = 1;
3765 }
3766
3767 static void
3768 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3769 {
3770   vat_main_t *vam = &vat_main;
3771   u32 i, n;
3772   int retval = clib_net_to_host_u32 (mp->retval);
3773
3774   if (retval)
3775     goto end;
3776
3777   n = clib_net_to_host_u32 (mp->count);
3778
3779   for (i = 0; i < n; i++)
3780     {
3781       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3782     }
3783
3784 end:
3785   vam->retval = retval;
3786   vam->result_ready = 1;
3787 }
3788
3789 static void
3790   vl_api_one_ndp_bd_get_reply_t_handler_json
3791   (vl_api_one_ndp_bd_get_reply_t * mp)
3792 {
3793   vat_main_t *vam = &vat_main;
3794   vat_json_node_t root;
3795   u32 i, n;
3796   int retval = clib_net_to_host_u32 (mp->retval);
3797
3798   if (retval)
3799     goto end;
3800
3801   n = clib_net_to_host_u32 (mp->count);
3802   vat_json_init_array (&root);
3803
3804   for (i = 0; i < n; i++)
3805     {
3806       vat_json_array_add_uint (&root,
3807                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3808     }
3809
3810   vat_json_print (vam->ofp, &root);
3811   vat_json_free (&root);
3812
3813 end:
3814   vam->retval = retval;
3815   vam->result_ready = 1;
3816 }
3817
3818 static void
3819   vl_api_one_l2_arp_bd_get_reply_t_handler
3820   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   u32 i, n;
3824   int retval = clib_net_to_host_u32 (mp->retval);
3825
3826   if (retval)
3827     goto end;
3828
3829   n = clib_net_to_host_u32 (mp->count);
3830
3831   for (i = 0; i < n; i++)
3832     {
3833       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3834     }
3835
3836 end:
3837   vam->retval = retval;
3838   vam->result_ready = 1;
3839 }
3840
3841 static void
3842   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3843   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3844 {
3845   vat_main_t *vam = &vat_main;
3846   vat_json_node_t root;
3847   u32 i, n;
3848   int retval = clib_net_to_host_u32 (mp->retval);
3849
3850   if (retval)
3851     goto end;
3852
3853   n = clib_net_to_host_u32 (mp->count);
3854   vat_json_init_array (&root);
3855
3856   for (i = 0; i < n; i++)
3857     {
3858       vat_json_array_add_uint (&root,
3859                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3860     }
3861
3862   vat_json_print (vam->ofp, &root);
3863   vat_json_free (&root);
3864
3865 end:
3866   vam->retval = retval;
3867   vam->result_ready = 1;
3868 }
3869
3870 static void
3871   vl_api_one_adjacencies_get_reply_t_handler
3872   (vl_api_one_adjacencies_get_reply_t * mp)
3873 {
3874   vat_main_t *vam = &vat_main;
3875   u32 i, n;
3876   int retval = clib_net_to_host_u32 (mp->retval);
3877   vl_api_one_adjacency_t *a;
3878
3879   if (retval)
3880     goto end;
3881
3882   n = clib_net_to_host_u32 (mp->count);
3883
3884   for (i = 0; i < n; i++)
3885     {
3886       a = &mp->adjacencies[i];
3887       print (vam->ofp, "%U %40U",
3888              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3889     }
3890
3891 end:
3892   vam->retval = retval;
3893   vam->result_ready = 1;
3894 }
3895
3896 static void
3897   vl_api_one_adjacencies_get_reply_t_handler_json
3898   (vl_api_one_adjacencies_get_reply_t * mp)
3899 {
3900   u8 *s = 0;
3901   vat_main_t *vam = &vat_main;
3902   vat_json_node_t *e = 0, root;
3903   u32 i, n;
3904   int retval = clib_net_to_host_u32 (mp->retval);
3905   vl_api_one_adjacency_t *a;
3906
3907   if (retval)
3908     goto end;
3909
3910   n = clib_net_to_host_u32 (mp->count);
3911   vat_json_init_array (&root);
3912
3913   for (i = 0; i < n; i++)
3914     {
3915       e = vat_json_array_add (&root);
3916       a = &mp->adjacencies[i];
3917
3918       vat_json_init_object (e);
3919       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3920       vec_add1 (s, 0);
3921       vat_json_object_add_string_copy (e, "leid", s);
3922       vec_free (s);
3923
3924       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3925       vec_add1 (s, 0);
3926       vat_json_object_add_string_copy (e, "reid", s);
3927       vec_free (s);
3928     }
3929
3930   vat_json_print (vam->ofp, &root);
3931   vat_json_free (&root);
3932
3933 end:
3934   vam->retval = retval;
3935   vam->result_ready = 1;
3936 }
3937
3938 static void
3939 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942
3943   print (vam->ofp, "%=20U",
3944          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3945          mp->ip_address.un);
3946 }
3947
3948 static void
3949   vl_api_one_map_server_details_t_handler_json
3950   (vl_api_one_map_server_details_t * mp)
3951 {
3952   vat_main_t *vam = &vat_main;
3953   vat_json_node_t *node = NULL;
3954   struct in6_addr ip6;
3955   struct in_addr ip4;
3956
3957   if (VAT_JSON_ARRAY != vam->json_tree.type)
3958     {
3959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3960       vat_json_init_array (&vam->json_tree);
3961     }
3962   node = vat_json_array_add (&vam->json_tree);
3963
3964   vat_json_init_object (node);
3965   if (mp->ip_address.af)
3966     {
3967       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3968       vat_json_object_add_ip6 (node, "map-server", ip6);
3969     }
3970   else
3971     {
3972       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3973       vat_json_object_add_ip4 (node, "map-server", ip4);
3974     }
3975 }
3976
3977 static void
3978 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3979                                            * mp)
3980 {
3981   vat_main_t *vam = &vat_main;
3982
3983   print (vam->ofp, "%=20U",
3984          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3985          mp->ip_address.un);
3986 }
3987
3988 static void
3989   vl_api_one_map_resolver_details_t_handler_json
3990   (vl_api_one_map_resolver_details_t * mp)
3991 {
3992   vat_main_t *vam = &vat_main;
3993   vat_json_node_t *node = NULL;
3994   struct in6_addr ip6;
3995   struct in_addr ip4;
3996
3997   if (VAT_JSON_ARRAY != vam->json_tree.type)
3998     {
3999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4000       vat_json_init_array (&vam->json_tree);
4001     }
4002   node = vat_json_array_add (&vam->json_tree);
4003
4004   vat_json_init_object (node);
4005   if (mp->ip_address.af)
4006     {
4007       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4008       vat_json_object_add_ip6 (node, "map resolver", ip6);
4009     }
4010   else
4011     {
4012       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4013       vat_json_object_add_ip4 (node, "map resolver", ip4);
4014     }
4015 }
4016
4017 static void
4018 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4019 {
4020   vat_main_t *vam = &vat_main;
4021   i32 retval = ntohl (mp->retval);
4022
4023   if (0 <= retval)
4024     {
4025       print (vam->ofp, "feature: %s\ngpe: %s",
4026              mp->feature_status ? "enabled" : "disabled",
4027              mp->gpe_status ? "enabled" : "disabled");
4028     }
4029
4030   vam->retval = retval;
4031   vam->result_ready = 1;
4032 }
4033
4034 static void
4035   vl_api_show_one_status_reply_t_handler_json
4036   (vl_api_show_one_status_reply_t * mp)
4037 {
4038   vat_main_t *vam = &vat_main;
4039   vat_json_node_t node;
4040   u8 *gpe_status = NULL;
4041   u8 *feature_status = NULL;
4042
4043   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4044   feature_status = format (0, "%s",
4045                            mp->feature_status ? "enabled" : "disabled");
4046   vec_add1 (gpe_status, 0);
4047   vec_add1 (feature_status, 0);
4048
4049   vat_json_init_object (&node);
4050   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4051   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4052
4053   vec_free (gpe_status);
4054   vec_free (feature_status);
4055
4056   vat_json_print (vam->ofp, &node);
4057   vat_json_free (&node);
4058
4059   vam->retval = ntohl (mp->retval);
4060   vam->result_ready = 1;
4061 }
4062
4063 static void
4064   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4065   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4066 {
4067   vat_main_t *vam = &vat_main;
4068   i32 retval = ntohl (mp->retval);
4069
4070   if (retval >= 0)
4071     {
4072       print (vam->ofp, "%=20s", mp->locator_set_name);
4073     }
4074
4075   vam->retval = retval;
4076   vam->result_ready = 1;
4077 }
4078
4079 static void
4080   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4081   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4082 {
4083   vat_main_t *vam = &vat_main;
4084   vat_json_node_t *node = NULL;
4085
4086   if (VAT_JSON_ARRAY != vam->json_tree.type)
4087     {
4088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4089       vat_json_init_array (&vam->json_tree);
4090     }
4091   node = vat_json_array_add (&vam->json_tree);
4092
4093   vat_json_init_object (node);
4094   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4095
4096   vat_json_print (vam->ofp, node);
4097   vat_json_free (node);
4098
4099   vam->retval = ntohl (mp->retval);
4100   vam->result_ready = 1;
4101 }
4102
4103 static u8 *
4104 format_lisp_map_request_mode (u8 * s, va_list * args)
4105 {
4106   u32 mode = va_arg (*args, u32);
4107
4108   switch (mode)
4109     {
4110     case 0:
4111       return format (0, "dst-only");
4112     case 1:
4113       return format (0, "src-dst");
4114     }
4115   return 0;
4116 }
4117
4118 static void
4119   vl_api_show_one_map_request_mode_reply_t_handler
4120   (vl_api_show_one_map_request_mode_reply_t * mp)
4121 {
4122   vat_main_t *vam = &vat_main;
4123   i32 retval = ntohl (mp->retval);
4124
4125   if (0 <= retval)
4126     {
4127       u32 mode = mp->mode;
4128       print (vam->ofp, "map_request_mode: %U",
4129              format_lisp_map_request_mode, mode);
4130     }
4131
4132   vam->retval = retval;
4133   vam->result_ready = 1;
4134 }
4135
4136 static void
4137   vl_api_show_one_map_request_mode_reply_t_handler_json
4138   (vl_api_show_one_map_request_mode_reply_t * mp)
4139 {
4140   vat_main_t *vam = &vat_main;
4141   vat_json_node_t node;
4142   u8 *s = 0;
4143   u32 mode;
4144
4145   mode = mp->mode;
4146   s = format (0, "%U", format_lisp_map_request_mode, mode);
4147   vec_add1 (s, 0);
4148
4149   vat_json_init_object (&node);
4150   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4151   vat_json_print (vam->ofp, &node);
4152   vat_json_free (&node);
4153
4154   vec_free (s);
4155   vam->retval = ntohl (mp->retval);
4156   vam->result_ready = 1;
4157 }
4158
4159 static void
4160   vl_api_one_show_xtr_mode_reply_t_handler
4161   (vl_api_one_show_xtr_mode_reply_t * mp)
4162 {
4163   vat_main_t *vam = &vat_main;
4164   i32 retval = ntohl (mp->retval);
4165
4166   if (0 <= retval)
4167     {
4168       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4169     }
4170
4171   vam->retval = retval;
4172   vam->result_ready = 1;
4173 }
4174
4175 static void
4176   vl_api_one_show_xtr_mode_reply_t_handler_json
4177   (vl_api_one_show_xtr_mode_reply_t * mp)
4178 {
4179   vat_main_t *vam = &vat_main;
4180   vat_json_node_t node;
4181   u8 *status = 0;
4182
4183   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4184   vec_add1 (status, 0);
4185
4186   vat_json_init_object (&node);
4187   vat_json_object_add_string_copy (&node, "status", status);
4188
4189   vec_free (status);
4190
4191   vat_json_print (vam->ofp, &node);
4192   vat_json_free (&node);
4193
4194   vam->retval = ntohl (mp->retval);
4195   vam->result_ready = 1;
4196 }
4197
4198 static void
4199   vl_api_one_show_pitr_mode_reply_t_handler
4200   (vl_api_one_show_pitr_mode_reply_t * mp)
4201 {
4202   vat_main_t *vam = &vat_main;
4203   i32 retval = ntohl (mp->retval);
4204
4205   if (0 <= retval)
4206     {
4207       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4208     }
4209
4210   vam->retval = retval;
4211   vam->result_ready = 1;
4212 }
4213
4214 static void
4215   vl_api_one_show_pitr_mode_reply_t_handler_json
4216   (vl_api_one_show_pitr_mode_reply_t * mp)
4217 {
4218   vat_main_t *vam = &vat_main;
4219   vat_json_node_t node;
4220   u8 *status = 0;
4221
4222   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4223   vec_add1 (status, 0);
4224
4225   vat_json_init_object (&node);
4226   vat_json_object_add_string_copy (&node, "status", status);
4227
4228   vec_free (status);
4229
4230   vat_json_print (vam->ofp, &node);
4231   vat_json_free (&node);
4232
4233   vam->retval = ntohl (mp->retval);
4234   vam->result_ready = 1;
4235 }
4236
4237 static void
4238   vl_api_one_show_petr_mode_reply_t_handler
4239   (vl_api_one_show_petr_mode_reply_t * mp)
4240 {
4241   vat_main_t *vam = &vat_main;
4242   i32 retval = ntohl (mp->retval);
4243
4244   if (0 <= retval)
4245     {
4246       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4247     }
4248
4249   vam->retval = retval;
4250   vam->result_ready = 1;
4251 }
4252
4253 static void
4254   vl_api_one_show_petr_mode_reply_t_handler_json
4255   (vl_api_one_show_petr_mode_reply_t * mp)
4256 {
4257   vat_main_t *vam = &vat_main;
4258   vat_json_node_t node;
4259   u8 *status = 0;
4260
4261   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4262   vec_add1 (status, 0);
4263
4264   vat_json_init_object (&node);
4265   vat_json_object_add_string_copy (&node, "status", status);
4266
4267   vec_free (status);
4268
4269   vat_json_print (vam->ofp, &node);
4270   vat_json_free (&node);
4271
4272   vam->retval = ntohl (mp->retval);
4273   vam->result_ready = 1;
4274 }
4275
4276 static void
4277   vl_api_show_one_use_petr_reply_t_handler
4278   (vl_api_show_one_use_petr_reply_t * mp)
4279 {
4280   vat_main_t *vam = &vat_main;
4281   i32 retval = ntohl (mp->retval);
4282
4283   if (0 <= retval)
4284     {
4285       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4286       if (mp->status)
4287         {
4288           print (vam->ofp, "Proxy-ETR address; %U",
4289                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4290                  mp->ip_address.un);
4291         }
4292     }
4293
4294   vam->retval = retval;
4295   vam->result_ready = 1;
4296 }
4297
4298 static void
4299   vl_api_show_one_use_petr_reply_t_handler_json
4300   (vl_api_show_one_use_petr_reply_t * mp)
4301 {
4302   vat_main_t *vam = &vat_main;
4303   vat_json_node_t node;
4304   u8 *status = 0;
4305   struct in_addr ip4;
4306   struct in6_addr ip6;
4307
4308   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4309   vec_add1 (status, 0);
4310
4311   vat_json_init_object (&node);
4312   vat_json_object_add_string_copy (&node, "status", status);
4313   if (mp->status)
4314     {
4315       if (mp->ip_address.af)
4316         {
4317           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4318           vat_json_object_add_ip6 (&node, "address", ip6);
4319         }
4320       else
4321         {
4322           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4323           vat_json_object_add_ip4 (&node, "address", ip4);
4324         }
4325     }
4326
4327   vec_free (status);
4328
4329   vat_json_print (vam->ofp, &node);
4330   vat_json_free (&node);
4331
4332   vam->retval = ntohl (mp->retval);
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_show_one_nsh_mapping_reply_t_handler
4338   (vl_api_show_one_nsh_mapping_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   i32 retval = ntohl (mp->retval);
4342
4343   if (0 <= retval)
4344     {
4345       print (vam->ofp, "%-20s%-16s",
4346              mp->is_set ? "set" : "not-set",
4347              mp->is_set ? (char *) mp->locator_set_name : "");
4348     }
4349
4350   vam->retval = retval;
4351   vam->result_ready = 1;
4352 }
4353
4354 static void
4355   vl_api_show_one_nsh_mapping_reply_t_handler_json
4356   (vl_api_show_one_nsh_mapping_reply_t * mp)
4357 {
4358   vat_main_t *vam = &vat_main;
4359   vat_json_node_t node;
4360   u8 *status = 0;
4361
4362   status = format (0, "%s", mp->is_set ? "yes" : "no");
4363   vec_add1 (status, 0);
4364
4365   vat_json_init_object (&node);
4366   vat_json_object_add_string_copy (&node, "is_set", status);
4367   if (mp->is_set)
4368     {
4369       vat_json_object_add_string_copy (&node, "locator_set",
4370                                        mp->locator_set_name);
4371     }
4372
4373   vec_free (status);
4374
4375   vat_json_print (vam->ofp, &node);
4376   vat_json_free (&node);
4377
4378   vam->retval = ntohl (mp->retval);
4379   vam->result_ready = 1;
4380 }
4381
4382 static void
4383   vl_api_show_one_map_register_ttl_reply_t_handler
4384   (vl_api_show_one_map_register_ttl_reply_t * mp)
4385 {
4386   vat_main_t *vam = &vat_main;
4387   i32 retval = ntohl (mp->retval);
4388
4389   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4390
4391   if (0 <= retval)
4392     {
4393       print (vam->ofp, "ttl: %u", mp->ttl);
4394     }
4395
4396   vam->retval = retval;
4397   vam->result_ready = 1;
4398 }
4399
4400 static void
4401   vl_api_show_one_map_register_ttl_reply_t_handler_json
4402   (vl_api_show_one_map_register_ttl_reply_t * mp)
4403 {
4404   vat_main_t *vam = &vat_main;
4405   vat_json_node_t node;
4406
4407   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4408   vat_json_init_object (&node);
4409   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4410
4411   vat_json_print (vam->ofp, &node);
4412   vat_json_free (&node);
4413
4414   vam->retval = ntohl (mp->retval);
4415   vam->result_ready = 1;
4416 }
4417
4418 static void
4419 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4420 {
4421   vat_main_t *vam = &vat_main;
4422   i32 retval = ntohl (mp->retval);
4423
4424   if (0 <= retval)
4425     {
4426       print (vam->ofp, "%-20s%-16s",
4427              mp->status ? "enabled" : "disabled",
4428              mp->status ? (char *) mp->locator_set_name : "");
4429     }
4430
4431   vam->retval = retval;
4432   vam->result_ready = 1;
4433 }
4434
4435 static void
4436 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4437 {
4438   vat_main_t *vam = &vat_main;
4439   vat_json_node_t node;
4440   u8 *status = 0;
4441
4442   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4443   vec_add1 (status, 0);
4444
4445   vat_json_init_object (&node);
4446   vat_json_object_add_string_copy (&node, "status", status);
4447   if (mp->status)
4448     {
4449       vat_json_object_add_string_copy (&node, "locator_set",
4450                                        mp->locator_set_name);
4451     }
4452
4453   vec_free (status);
4454
4455   vat_json_print (vam->ofp, &node);
4456   vat_json_free (&node);
4457
4458   vam->retval = ntohl (mp->retval);
4459   vam->result_ready = 1;
4460 }
4461
4462 static u8 *
4463 format_policer_type (u8 * s, va_list * va)
4464 {
4465   u32 i = va_arg (*va, u32);
4466
4467   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4468     s = format (s, "1r2c");
4469   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4470     s = format (s, "1r3c");
4471   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4472     s = format (s, "2r3c-2698");
4473   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4474     s = format (s, "2r3c-4115");
4475   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4476     s = format (s, "2r3c-mef5cf1");
4477   else
4478     s = format (s, "ILLEGAL");
4479   return s;
4480 }
4481
4482 static u8 *
4483 format_policer_rate_type (u8 * s, va_list * va)
4484 {
4485   u32 i = va_arg (*va, u32);
4486
4487   if (i == SSE2_QOS_RATE_KBPS)
4488     s = format (s, "kbps");
4489   else if (i == SSE2_QOS_RATE_PPS)
4490     s = format (s, "pps");
4491   else
4492     s = format (s, "ILLEGAL");
4493   return s;
4494 }
4495
4496 static u8 *
4497 format_policer_round_type (u8 * s, va_list * va)
4498 {
4499   u32 i = va_arg (*va, u32);
4500
4501   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4502     s = format (s, "closest");
4503   else if (i == SSE2_QOS_ROUND_TO_UP)
4504     s = format (s, "up");
4505   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4506     s = format (s, "down");
4507   else
4508     s = format (s, "ILLEGAL");
4509   return s;
4510 }
4511
4512 static u8 *
4513 format_policer_action_type (u8 * s, va_list * va)
4514 {
4515   u32 i = va_arg (*va, u32);
4516
4517   if (i == SSE2_QOS_ACTION_DROP)
4518     s = format (s, "drop");
4519   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4520     s = format (s, "transmit");
4521   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4522     s = format (s, "mark-and-transmit");
4523   else
4524     s = format (s, "ILLEGAL");
4525   return s;
4526 }
4527
4528 static u8 *
4529 format_dscp (u8 * s, va_list * va)
4530 {
4531   u32 i = va_arg (*va, u32);
4532   char *t = 0;
4533
4534   switch (i)
4535     {
4536 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4537       foreach_vnet_dscp
4538 #undef _
4539     default:
4540       return format (s, "ILLEGAL");
4541     }
4542   s = format (s, "%s", t);
4543   return s;
4544 }
4545
4546 static void
4547 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4548 {
4549   vat_main_t *vam = &vat_main;
4550   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4551
4552   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4553     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4554   else
4555     conform_dscp_str = format (0, "");
4556
4557   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4558     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4559   else
4560     exceed_dscp_str = format (0, "");
4561
4562   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4563     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4564   else
4565     violate_dscp_str = format (0, "");
4566
4567   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4568          "rate type %U, round type %U, %s rate, %s color-aware, "
4569          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4570          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4571          "conform action %U%s, exceed action %U%s, violate action %U%s",
4572          mp->name,
4573          format_policer_type, mp->type,
4574          ntohl (mp->cir),
4575          ntohl (mp->eir),
4576          clib_net_to_host_u64 (mp->cb),
4577          clib_net_to_host_u64 (mp->eb),
4578          format_policer_rate_type, mp->rate_type,
4579          format_policer_round_type, mp->round_type,
4580          mp->single_rate ? "single" : "dual",
4581          mp->color_aware ? "is" : "not",
4582          ntohl (mp->cir_tokens_per_period),
4583          ntohl (mp->pir_tokens_per_period),
4584          ntohl (mp->scale),
4585          ntohl (mp->current_limit),
4586          ntohl (mp->current_bucket),
4587          ntohl (mp->extended_limit),
4588          ntohl (mp->extended_bucket),
4589          clib_net_to_host_u64 (mp->last_update_time),
4590          format_policer_action_type, mp->conform_action.type,
4591          conform_dscp_str,
4592          format_policer_action_type, mp->exceed_action.type,
4593          exceed_dscp_str,
4594          format_policer_action_type, mp->violate_action.type,
4595          violate_dscp_str);
4596
4597   vec_free (conform_dscp_str);
4598   vec_free (exceed_dscp_str);
4599   vec_free (violate_dscp_str);
4600 }
4601
4602 static void vl_api_policer_details_t_handler_json
4603   (vl_api_policer_details_t * mp)
4604 {
4605   vat_main_t *vam = &vat_main;
4606   vat_json_node_t *node;
4607   u8 *rate_type_str, *round_type_str, *type_str;
4608   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4609
4610   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4611   round_type_str =
4612     format (0, "%U", format_policer_round_type, mp->round_type);
4613   type_str = format (0, "%U", format_policer_type, mp->type);
4614   conform_action_str = format (0, "%U", format_policer_action_type,
4615                                mp->conform_action.type);
4616   exceed_action_str = format (0, "%U", format_policer_action_type,
4617                               mp->exceed_action.type);
4618   violate_action_str = format (0, "%U", format_policer_action_type,
4619                                mp->violate_action.type);
4620
4621   if (VAT_JSON_ARRAY != vam->json_tree.type)
4622     {
4623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4624       vat_json_init_array (&vam->json_tree);
4625     }
4626   node = vat_json_array_add (&vam->json_tree);
4627
4628   vat_json_init_object (node);
4629   vat_json_object_add_string_copy (node, "name", mp->name);
4630   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4631   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4632   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4633   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4634   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4635   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4636   vat_json_object_add_string_copy (node, "type", type_str);
4637   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4638   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4639   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4640   vat_json_object_add_uint (node, "cir_tokens_per_period",
4641                             ntohl (mp->cir_tokens_per_period));
4642   vat_json_object_add_uint (node, "eir_tokens_per_period",
4643                             ntohl (mp->pir_tokens_per_period));
4644   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4645   vat_json_object_add_uint (node, "current_bucket",
4646                             ntohl (mp->current_bucket));
4647   vat_json_object_add_uint (node, "extended_limit",
4648                             ntohl (mp->extended_limit));
4649   vat_json_object_add_uint (node, "extended_bucket",
4650                             ntohl (mp->extended_bucket));
4651   vat_json_object_add_uint (node, "last_update_time",
4652                             ntohl (mp->last_update_time));
4653   vat_json_object_add_string_copy (node, "conform_action",
4654                                    conform_action_str);
4655   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4656     {
4657       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4658       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4659       vec_free (dscp_str);
4660     }
4661   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4662   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4663     {
4664       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4665       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4666       vec_free (dscp_str);
4667     }
4668   vat_json_object_add_string_copy (node, "violate_action",
4669                                    violate_action_str);
4670   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4671     {
4672       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4673       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4674       vec_free (dscp_str);
4675     }
4676
4677   vec_free (rate_type_str);
4678   vec_free (round_type_str);
4679   vec_free (type_str);
4680   vec_free (conform_action_str);
4681   vec_free (exceed_action_str);
4682   vec_free (violate_action_str);
4683 }
4684
4685 static void
4686 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4687                                            mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   int i, count = ntohl (mp->count);
4691
4692   if (count > 0)
4693     print (vam->ofp, "classify table ids (%d) : ", count);
4694   for (i = 0; i < count; i++)
4695     {
4696       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4697       print (vam->ofp, (i < count - 1) ? "," : "");
4698     }
4699   vam->retval = ntohl (mp->retval);
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704   vl_api_classify_table_ids_reply_t_handler_json
4705   (vl_api_classify_table_ids_reply_t * mp)
4706 {
4707   vat_main_t *vam = &vat_main;
4708   int i, count = ntohl (mp->count);
4709
4710   if (count > 0)
4711     {
4712       vat_json_node_t node;
4713
4714       vat_json_init_object (&node);
4715       for (i = 0; i < count; i++)
4716         {
4717           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4718         }
4719       vat_json_print (vam->ofp, &node);
4720       vat_json_free (&node);
4721     }
4722   vam->retval = ntohl (mp->retval);
4723   vam->result_ready = 1;
4724 }
4725
4726 static void
4727   vl_api_classify_table_by_interface_reply_t_handler
4728   (vl_api_classify_table_by_interface_reply_t * mp)
4729 {
4730   vat_main_t *vam = &vat_main;
4731   u32 table_id;
4732
4733   table_id = ntohl (mp->l2_table_id);
4734   if (table_id != ~0)
4735     print (vam->ofp, "l2 table id : %d", table_id);
4736   else
4737     print (vam->ofp, "l2 table id : No input ACL tables configured");
4738   table_id = ntohl (mp->ip4_table_id);
4739   if (table_id != ~0)
4740     print (vam->ofp, "ip4 table id : %d", table_id);
4741   else
4742     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4743   table_id = ntohl (mp->ip6_table_id);
4744   if (table_id != ~0)
4745     print (vam->ofp, "ip6 table id : %d", table_id);
4746   else
4747     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4748   vam->retval = ntohl (mp->retval);
4749   vam->result_ready = 1;
4750 }
4751
4752 static void
4753   vl_api_classify_table_by_interface_reply_t_handler_json
4754   (vl_api_classify_table_by_interface_reply_t * mp)
4755 {
4756   vat_main_t *vam = &vat_main;
4757   vat_json_node_t node;
4758
4759   vat_json_init_object (&node);
4760
4761   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4762   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4763   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4764
4765   vat_json_print (vam->ofp, &node);
4766   vat_json_free (&node);
4767
4768   vam->retval = ntohl (mp->retval);
4769   vam->result_ready = 1;
4770 }
4771
4772 static void vl_api_policer_add_del_reply_t_handler
4773   (vl_api_policer_add_del_reply_t * mp)
4774 {
4775   vat_main_t *vam = &vat_main;
4776   i32 retval = ntohl (mp->retval);
4777   if (vam->async_mode)
4778     {
4779       vam->async_errors += (retval < 0);
4780     }
4781   else
4782     {
4783       vam->retval = retval;
4784       vam->result_ready = 1;
4785       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4786         /*
4787          * Note: this is just barely thread-safe, depends on
4788          * the main thread spinning waiting for an answer...
4789          */
4790         errmsg ("policer index %d", ntohl (mp->policer_index));
4791     }
4792 }
4793
4794 static void vl_api_policer_add_del_reply_t_handler_json
4795   (vl_api_policer_add_del_reply_t * mp)
4796 {
4797   vat_main_t *vam = &vat_main;
4798   vat_json_node_t node;
4799
4800   vat_json_init_object (&node);
4801   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4802   vat_json_object_add_uint (&node, "policer_index",
4803                             ntohl (mp->policer_index));
4804
4805   vat_json_print (vam->ofp, &node);
4806   vat_json_free (&node);
4807
4808   vam->retval = ntohl (mp->retval);
4809   vam->result_ready = 1;
4810 }
4811
4812 /* Format hex dump. */
4813 u8 *
4814 format_hex_bytes (u8 * s, va_list * va)
4815 {
4816   u8 *bytes = va_arg (*va, u8 *);
4817   int n_bytes = va_arg (*va, int);
4818   uword i;
4819
4820   /* Print short or long form depending on byte count. */
4821   uword short_form = n_bytes <= 32;
4822   u32 indent = format_get_indent (s);
4823
4824   if (n_bytes == 0)
4825     return s;
4826
4827   for (i = 0; i < n_bytes; i++)
4828     {
4829       if (!short_form && (i % 32) == 0)
4830         s = format (s, "%08x: ", i);
4831       s = format (s, "%02x", bytes[i]);
4832       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4833         s = format (s, "\n%U", format_white_space, indent);
4834     }
4835
4836   return s;
4837 }
4838
4839 static void
4840 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4841                                             * mp)
4842 {
4843   vat_main_t *vam = &vat_main;
4844   i32 retval = ntohl (mp->retval);
4845   if (retval == 0)
4846     {
4847       print (vam->ofp, "classify table info :");
4848       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4849              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4850              ntohl (mp->miss_next_index));
4851       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4852              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4853              ntohl (mp->match_n_vectors));
4854       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4855              ntohl (mp->mask_length));
4856     }
4857   vam->retval = retval;
4858   vam->result_ready = 1;
4859 }
4860
4861 static void
4862   vl_api_classify_table_info_reply_t_handler_json
4863   (vl_api_classify_table_info_reply_t * mp)
4864 {
4865   vat_main_t *vam = &vat_main;
4866   vat_json_node_t node;
4867
4868   i32 retval = ntohl (mp->retval);
4869   if (retval == 0)
4870     {
4871       vat_json_init_object (&node);
4872
4873       vat_json_object_add_int (&node, "sessions",
4874                                ntohl (mp->active_sessions));
4875       vat_json_object_add_int (&node, "nexttbl",
4876                                ntohl (mp->next_table_index));
4877       vat_json_object_add_int (&node, "nextnode",
4878                                ntohl (mp->miss_next_index));
4879       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4880       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4881       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4882       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4883                       ntohl (mp->mask_length), 0);
4884       vat_json_object_add_string_copy (&node, "mask", s);
4885
4886       vat_json_print (vam->ofp, &node);
4887       vat_json_free (&node);
4888     }
4889   vam->retval = ntohl (mp->retval);
4890   vam->result_ready = 1;
4891 }
4892
4893 static void
4894 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4895                                            mp)
4896 {
4897   vat_main_t *vam = &vat_main;
4898
4899   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4900          ntohl (mp->hit_next_index), ntohl (mp->advance),
4901          ntohl (mp->opaque_index));
4902   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4903          ntohl (mp->match_length));
4904 }
4905
4906 static void
4907   vl_api_classify_session_details_t_handler_json
4908   (vl_api_classify_session_details_t * mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911   vat_json_node_t *node = NULL;
4912
4913   if (VAT_JSON_ARRAY != vam->json_tree.type)
4914     {
4915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4916       vat_json_init_array (&vam->json_tree);
4917     }
4918   node = vat_json_array_add (&vam->json_tree);
4919
4920   vat_json_init_object (node);
4921   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4922   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4923   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4924   u8 *s =
4925     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4926             0);
4927   vat_json_object_add_string_copy (node, "match", s);
4928 }
4929
4930 static void vl_api_pg_create_interface_reply_t_handler
4931   (vl_api_pg_create_interface_reply_t * mp)
4932 {
4933   vat_main_t *vam = &vat_main;
4934
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void vl_api_pg_create_interface_reply_t_handler_json
4940   (vl_api_pg_create_interface_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   vat_json_node_t node;
4944
4945   i32 retval = ntohl (mp->retval);
4946   if (retval == 0)
4947     {
4948       vat_json_init_object (&node);
4949
4950       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4951
4952       vat_json_print (vam->ofp, &node);
4953       vat_json_free (&node);
4954     }
4955   vam->retval = ntohl (mp->retval);
4956   vam->result_ready = 1;
4957 }
4958
4959 static void vl_api_policer_classify_details_t_handler
4960   (vl_api_policer_classify_details_t * mp)
4961 {
4962   vat_main_t *vam = &vat_main;
4963
4964   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4965          ntohl (mp->table_index));
4966 }
4967
4968 static void vl_api_policer_classify_details_t_handler_json
4969   (vl_api_policer_classify_details_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972   vat_json_node_t *node;
4973
4974   if (VAT_JSON_ARRAY != vam->json_tree.type)
4975     {
4976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4977       vat_json_init_array (&vam->json_tree);
4978     }
4979   node = vat_json_array_add (&vam->json_tree);
4980
4981   vat_json_init_object (node);
4982   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4983   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4984 }
4985
4986 static void vl_api_flow_classify_details_t_handler
4987   (vl_api_flow_classify_details_t * mp)
4988 {
4989   vat_main_t *vam = &vat_main;
4990
4991   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4992          ntohl (mp->table_index));
4993 }
4994
4995 static void vl_api_flow_classify_details_t_handler_json
4996   (vl_api_flow_classify_details_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   vat_json_node_t *node;
5000
5001   if (VAT_JSON_ARRAY != vam->json_tree.type)
5002     {
5003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5004       vat_json_init_array (&vam->json_tree);
5005     }
5006   node = vat_json_array_add (&vam->json_tree);
5007
5008   vat_json_init_object (node);
5009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5010   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5011 }
5012
5013 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5014 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5015 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5016 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5017 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5018 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5019 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5020 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5021 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5022 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5023
5024 /*
5025  * Generate boilerplate reply handlers, which
5026  * dig the return value out of the xxx_reply_t API message,
5027  * stick it into vam->retval, and set vam->result_ready
5028  *
5029  * Could also do this by pointing N message decode slots at
5030  * a single function, but that could break in subtle ways.
5031  */
5032
5033 #define foreach_standard_reply_retval_handler           \
5034 _(sw_interface_set_flags_reply)                         \
5035 _(sw_interface_add_del_address_reply)                   \
5036 _(sw_interface_set_rx_mode_reply)                       \
5037 _(sw_interface_set_rx_placement_reply)                  \
5038 _(sw_interface_set_table_reply)                         \
5039 _(sw_interface_set_mpls_enable_reply)                   \
5040 _(sw_interface_set_vpath_reply)                         \
5041 _(sw_interface_set_vxlan_bypass_reply)                  \
5042 _(sw_interface_set_geneve_bypass_reply)                 \
5043 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5044 _(sw_interface_set_l2_bridge_reply)                     \
5045 _(sw_interface_set_bond_weight_reply)                   \
5046 _(bridge_domain_add_del_reply)                          \
5047 _(sw_interface_set_l2_xconnect_reply)                   \
5048 _(l2fib_add_del_reply)                                  \
5049 _(l2fib_flush_int_reply)                                \
5050 _(l2fib_flush_bd_reply)                                 \
5051 _(ip_route_add_del_reply)                               \
5052 _(ip_table_add_del_reply)                               \
5053 _(ip_table_replace_begin_reply)                         \
5054 _(ip_table_flush_reply)                                 \
5055 _(ip_table_replace_end_reply)                           \
5056 _(ip_mroute_add_del_reply)                              \
5057 _(mpls_route_add_del_reply)                             \
5058 _(mpls_table_add_del_reply)                             \
5059 _(mpls_ip_bind_unbind_reply)                            \
5060 _(bier_route_add_del_reply)                             \
5061 _(bier_table_add_del_reply)                             \
5062 _(sw_interface_set_unnumbered_reply)                    \
5063 _(set_ip_flow_hash_reply)                               \
5064 _(sw_interface_ip6_enable_disable_reply)                \
5065 _(l2_patch_add_del_reply)                               \
5066 _(sr_mpls_policy_add_reply)                             \
5067 _(sr_mpls_policy_mod_reply)                             \
5068 _(sr_mpls_policy_del_reply)                             \
5069 _(sr_policy_add_reply)                                  \
5070 _(sr_policy_mod_reply)                                  \
5071 _(sr_policy_del_reply)                                  \
5072 _(sr_localsid_add_del_reply)                            \
5073 _(sr_steering_add_del_reply)                            \
5074 _(classify_add_del_session_reply)                       \
5075 _(classify_set_interface_ip_table_reply)                \
5076 _(classify_set_interface_l2_tables_reply)               \
5077 _(l2tpv3_set_tunnel_cookies_reply)                      \
5078 _(l2tpv3_interface_enable_disable_reply)                \
5079 _(l2tpv3_set_lookup_key_reply)                          \
5080 _(l2_fib_clear_table_reply)                             \
5081 _(l2_interface_efp_filter_reply)                        \
5082 _(l2_interface_vlan_tag_rewrite_reply)                  \
5083 _(modify_vhost_user_if_reply)                           \
5084 _(delete_vhost_user_if_reply)                           \
5085 _(want_l2_macs_events_reply)                            \
5086 _(input_acl_set_interface_reply)                        \
5087 _(ipsec_spd_add_del_reply)                              \
5088 _(ipsec_interface_add_del_spd_reply)                    \
5089 _(ipsec_spd_entry_add_del_reply)                        \
5090 _(ipsec_sad_entry_add_del_reply)                        \
5091 _(ipsec_tunnel_if_add_del_reply)                        \
5092 _(ipsec_tunnel_if_set_sa_reply)                         \
5093 _(delete_loopback_reply)                                \
5094 _(bd_ip_mac_add_del_reply)                              \
5095 _(bd_ip_mac_flush_reply)                                \
5096 _(want_interface_events_reply)                          \
5097 _(cop_interface_enable_disable_reply)                   \
5098 _(cop_whitelist_enable_disable_reply)                   \
5099 _(sw_interface_clear_stats_reply)                       \
5100 _(ioam_enable_reply)                                    \
5101 _(ioam_disable_reply)                                   \
5102 _(one_add_del_locator_reply)                            \
5103 _(one_add_del_local_eid_reply)                          \
5104 _(one_add_del_remote_mapping_reply)                     \
5105 _(one_add_del_adjacency_reply)                          \
5106 _(one_add_del_map_resolver_reply)                       \
5107 _(one_add_del_map_server_reply)                         \
5108 _(one_enable_disable_reply)                             \
5109 _(one_rloc_probe_enable_disable_reply)                  \
5110 _(one_map_register_enable_disable_reply)                \
5111 _(one_map_register_set_ttl_reply)                       \
5112 _(one_set_transport_protocol_reply)                     \
5113 _(one_map_register_fallback_threshold_reply)            \
5114 _(one_pitr_set_locator_set_reply)                       \
5115 _(one_map_request_mode_reply)                           \
5116 _(one_add_del_map_request_itr_rlocs_reply)              \
5117 _(one_eid_table_add_del_map_reply)                      \
5118 _(one_use_petr_reply)                                   \
5119 _(one_stats_enable_disable_reply)                       \
5120 _(one_add_del_l2_arp_entry_reply)                       \
5121 _(one_add_del_ndp_entry_reply)                          \
5122 _(one_stats_flush_reply)                                \
5123 _(one_enable_disable_xtr_mode_reply)                    \
5124 _(one_enable_disable_pitr_mode_reply)                   \
5125 _(one_enable_disable_petr_mode_reply)                   \
5126 _(gpe_enable_disable_reply)                             \
5127 _(gpe_set_encap_mode_reply)                             \
5128 _(gpe_add_del_iface_reply)                              \
5129 _(gpe_add_del_native_fwd_rpath_reply)                   \
5130 _(af_packet_delete_reply)                               \
5131 _(policer_classify_set_interface_reply)                 \
5132 _(set_ipfix_exporter_reply)                             \
5133 _(set_ipfix_classify_stream_reply)                      \
5134 _(ipfix_classify_table_add_del_reply)                   \
5135 _(flow_classify_set_interface_reply)                    \
5136 _(sw_interface_span_enable_disable_reply)               \
5137 _(pg_capture_reply)                                     \
5138 _(pg_enable_disable_reply)                              \
5139 _(ip_source_and_port_range_check_add_del_reply)         \
5140 _(ip_source_and_port_range_check_interface_add_del_reply)\
5141 _(delete_subif_reply)                                   \
5142 _(l2_interface_pbb_tag_rewrite_reply)                   \
5143 _(set_punt_reply)                                       \
5144 _(feature_enable_disable_reply)                         \
5145 _(feature_gso_enable_disable_reply)                     \
5146 _(sw_interface_tag_add_del_reply)                       \
5147 _(sw_interface_add_del_mac_address_reply)               \
5148 _(hw_interface_set_mtu_reply)                           \
5149 _(p2p_ethernet_add_reply)                               \
5150 _(p2p_ethernet_del_reply)                               \
5151 _(lldp_config_reply)                                    \
5152 _(sw_interface_set_lldp_reply)                          \
5153 _(tcp_configure_src_addresses_reply)                    \
5154 _(session_rule_add_del_reply)                           \
5155 _(ip_container_proxy_add_del_reply)                     \
5156 _(output_acl_set_interface_reply)                       \
5157 _(qos_record_enable_disable_reply)
5158
5159 #define _(n)                                    \
5160     static void vl_api_##n##_t_handler          \
5161     (vl_api_##n##_t * mp)                       \
5162     {                                           \
5163         vat_main_t * vam = &vat_main;           \
5164         i32 retval = ntohl(mp->retval);         \
5165         if (vam->async_mode) {                  \
5166             vam->async_errors += (retval < 0);  \
5167         } else {                                \
5168             vam->retval = retval;               \
5169             vam->result_ready = 1;              \
5170         }                                       \
5171     }
5172 foreach_standard_reply_retval_handler;
5173 #undef _
5174
5175 #define _(n)                                    \
5176     static void vl_api_##n##_t_handler_json     \
5177     (vl_api_##n##_t * mp)                       \
5178     {                                           \
5179         vat_main_t * vam = &vat_main;           \
5180         vat_json_node_t node;                   \
5181         vat_json_init_object(&node);            \
5182         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5183         vat_json_print(vam->ofp, &node);        \
5184         vam->retval = ntohl(mp->retval);        \
5185         vam->result_ready = 1;                  \
5186     }
5187 foreach_standard_reply_retval_handler;
5188 #undef _
5189
5190 /*
5191  * Table of message reply handlers, must include boilerplate handlers
5192  * we just generated
5193  */
5194
5195 #define foreach_vpe_api_reply_msg                                       \
5196 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5197 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5198 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5199 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5200 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5201 _(CLI_REPLY, cli_reply)                                                 \
5202 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5203 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5204   sw_interface_add_del_address_reply)                                   \
5205 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5206 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5207 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5208 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5209 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5210 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5211 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5212 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5213 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5214 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5215   sw_interface_set_l2_xconnect_reply)                                   \
5216 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5217   sw_interface_set_l2_bridge_reply)                                     \
5218 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5219 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5220 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5221 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5222 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5223 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5224 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5225 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5226 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5227 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5228 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5229 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5230 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5231 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5232 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5233 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5234 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5235 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5236 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5237 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5238 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5239 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5240 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5241 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5242 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5243 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5244 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5245 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5246 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5247 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5248 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5249 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5250 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5251 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5252   sw_interface_set_unnumbered_reply)                                    \
5253 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5254 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5255 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5256 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5257   sw_interface_ip6_enable_disable_reply)                                \
5258 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5259 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5260 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5261 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5262 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5263 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5264 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5265 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5266 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5267 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5268 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5269 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5270 classify_set_interface_ip_table_reply)                                  \
5271 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5272   classify_set_interface_l2_tables_reply)                               \
5273 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5274 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5275 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5276 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5277 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5278   l2tpv3_interface_enable_disable_reply)                                \
5279 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5280 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5281 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5282 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5283 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5284 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5285 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5286 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5287 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5288 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5289 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5290 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5291 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5292 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5293 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5294 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5295 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5296 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5297 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5298 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5299 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5300 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5301 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5302 _(L2_MACS_EVENT, l2_macs_event)                                         \
5303 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5304 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5305 _(IP_DETAILS, ip_details)                                               \
5306 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5307 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5308 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5309 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5310 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5311 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5312 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5313 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5314 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5315 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5316 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5317 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5318 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5319 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5320 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5321 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5322 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5323 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5324 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5325 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5326 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5327 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5328 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5329 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5330 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5331 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5332 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5333 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5334   one_map_register_enable_disable_reply)                                \
5335 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5336 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5337 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5338 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5339   one_map_register_fallback_threshold_reply)                            \
5340 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5341   one_rloc_probe_enable_disable_reply)                                  \
5342 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5343 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5344 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5345 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5346 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5347 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5348 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5349 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5350 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5351 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5352 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5353 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5354 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5355 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5356 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5357 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5358   show_one_stats_enable_disable_reply)                                  \
5359 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5360 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5361 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5362 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5363 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5364 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5365 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5366 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5367   one_enable_disable_pitr_mode_reply)                                   \
5368 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5369   one_enable_disable_petr_mode_reply)                                   \
5370 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5371 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5372 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5373 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5374 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5375 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5376 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5377 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5378 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5379 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5380 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5381 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5382   gpe_add_del_native_fwd_rpath_reply)                                   \
5383 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5384   gpe_fwd_entry_path_details)                                           \
5385 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5386 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5387   one_add_del_map_request_itr_rlocs_reply)                              \
5388 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5389   one_get_map_request_itr_rlocs_reply)                                  \
5390 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5391 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5392 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5393 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5394 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5395 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5396   show_one_map_register_state_reply)                                    \
5397 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5398 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5399   show_one_map_register_fallback_threshold_reply)                       \
5400 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5401 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5402 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5403 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5404 _(POLICER_DETAILS, policer_details)                                     \
5405 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5406 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5407 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5408 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5409 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5410 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5411 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5412 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5413 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5414 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5415 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5416 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5417 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5418 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5419 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5420 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5421 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5422 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5423 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5424 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5425 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5426 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5427 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5428 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5429  ip_source_and_port_range_check_add_del_reply)                          \
5430 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5431  ip_source_and_port_range_check_interface_add_del_reply)                \
5432 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5433 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5434 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5435 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5436 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5437 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5438 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5439 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5440 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5441 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5442 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5443 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5444 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5445 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5446 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5447 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5448 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5449 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5450 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5451 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5452 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5453 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5454 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5455
5456 #define foreach_standalone_reply_msg                                    \
5457 _(SW_INTERFACE_EVENT, sw_interface_event)
5458
5459 typedef struct
5460 {
5461   u8 *name;
5462   u32 value;
5463 } name_sort_t;
5464
5465 #define STR_VTR_OP_CASE(op)     \
5466     case L2_VTR_ ## op:         \
5467         return "" # op;
5468
5469 static const char *
5470 str_vtr_op (u32 vtr_op)
5471 {
5472   switch (vtr_op)
5473     {
5474       STR_VTR_OP_CASE (DISABLED);
5475       STR_VTR_OP_CASE (PUSH_1);
5476       STR_VTR_OP_CASE (PUSH_2);
5477       STR_VTR_OP_CASE (POP_1);
5478       STR_VTR_OP_CASE (POP_2);
5479       STR_VTR_OP_CASE (TRANSLATE_1_1);
5480       STR_VTR_OP_CASE (TRANSLATE_1_2);
5481       STR_VTR_OP_CASE (TRANSLATE_2_1);
5482       STR_VTR_OP_CASE (TRANSLATE_2_2);
5483     }
5484
5485   return "UNKNOWN";
5486 }
5487
5488 static int
5489 dump_sub_interface_table (vat_main_t * vam)
5490 {
5491   const sw_interface_subif_t *sub = NULL;
5492
5493   if (vam->json_output)
5494     {
5495       clib_warning
5496         ("JSON output supported only for VPE API calls and dump_stats_table");
5497       return -99;
5498     }
5499
5500   print (vam->ofp,
5501          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5502          "Interface", "sw_if_index",
5503          "sub id", "dot1ad", "tags", "outer id",
5504          "inner id", "exact", "default", "outer any", "inner any");
5505
5506   vec_foreach (sub, vam->sw_if_subif_table)
5507   {
5508     print (vam->ofp,
5509            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5510            sub->interface_name,
5511            sub->sw_if_index,
5512            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5513            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5514            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5515            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5516     if (sub->vtr_op != L2_VTR_DISABLED)
5517       {
5518         print (vam->ofp,
5519                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5520                "tag1: %d tag2: %d ]",
5521                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5522                sub->vtr_tag1, sub->vtr_tag2);
5523       }
5524   }
5525
5526   return 0;
5527 }
5528
5529 static int
5530 name_sort_cmp (void *a1, void *a2)
5531 {
5532   name_sort_t *n1 = a1;
5533   name_sort_t *n2 = a2;
5534
5535   return strcmp ((char *) n1->name, (char *) n2->name);
5536 }
5537
5538 static int
5539 dump_interface_table (vat_main_t * vam)
5540 {
5541   hash_pair_t *p;
5542   name_sort_t *nses = 0, *ns;
5543
5544   if (vam->json_output)
5545     {
5546       clib_warning
5547         ("JSON output supported only for VPE API calls and dump_stats_table");
5548       return -99;
5549     }
5550
5551   /* *INDENT-OFF* */
5552   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5553   ({
5554     vec_add2 (nses, ns, 1);
5555     ns->name = (u8 *)(p->key);
5556     ns->value = (u32) p->value[0];
5557   }));
5558   /* *INDENT-ON* */
5559
5560   vec_sort_with_function (nses, name_sort_cmp);
5561
5562   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5563   vec_foreach (ns, nses)
5564   {
5565     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5566   }
5567   vec_free (nses);
5568   return 0;
5569 }
5570
5571 static int
5572 dump_ip_table (vat_main_t * vam, int is_ipv6)
5573 {
5574   const ip_details_t *det = NULL;
5575   const ip_address_details_t *address = NULL;
5576   u32 i = ~0;
5577
5578   print (vam->ofp, "%-12s", "sw_if_index");
5579
5580   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5581   {
5582     i++;
5583     if (!det->present)
5584       {
5585         continue;
5586       }
5587     print (vam->ofp, "%-12d", i);
5588     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5589     if (!det->addr)
5590       {
5591         continue;
5592       }
5593     vec_foreach (address, det->addr)
5594     {
5595       print (vam->ofp,
5596              "            %-30U%-13d",
5597              is_ipv6 ? format_ip6_address : format_ip4_address,
5598              address->ip, address->prefix_length);
5599     }
5600   }
5601
5602   return 0;
5603 }
5604
5605 static int
5606 dump_ipv4_table (vat_main_t * vam)
5607 {
5608   if (vam->json_output)
5609     {
5610       clib_warning
5611         ("JSON output supported only for VPE API calls and dump_stats_table");
5612       return -99;
5613     }
5614
5615   return dump_ip_table (vam, 0);
5616 }
5617
5618 static int
5619 dump_ipv6_table (vat_main_t * vam)
5620 {
5621   if (vam->json_output)
5622     {
5623       clib_warning
5624         ("JSON output supported only for VPE API calls and dump_stats_table");
5625       return -99;
5626     }
5627
5628   return dump_ip_table (vam, 1);
5629 }
5630
5631 /*
5632  * Pass CLI buffers directly in the CLI_INBAND API message,
5633  * instead of an additional shared memory area.
5634  */
5635 static int
5636 exec_inband (vat_main_t * vam)
5637 {
5638   vl_api_cli_inband_t *mp;
5639   unformat_input_t *i = vam->input;
5640   int ret;
5641
5642   if (vec_len (i->buffer) == 0)
5643     return -1;
5644
5645   if (vam->exec_mode == 0 && unformat (i, "mode"))
5646     {
5647       vam->exec_mode = 1;
5648       return 0;
5649     }
5650   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5651     {
5652       vam->exec_mode = 0;
5653       return 0;
5654     }
5655
5656   /*
5657    * In order for the CLI command to work, it
5658    * must be a vector ending in \n, not a C-string ending
5659    * in \n\0.
5660    */
5661   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5662   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5663
5664   S (mp);
5665   W (ret);
5666   /* json responses may or may not include a useful reply... */
5667   if (vec_len (vam->cmd_reply))
5668     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5669   return ret;
5670 }
5671
5672 int
5673 exec (vat_main_t * vam)
5674 {
5675   return exec_inband (vam);
5676 }
5677
5678 static int
5679 api_create_loopback (vat_main_t * vam)
5680 {
5681   unformat_input_t *i = vam->input;
5682   vl_api_create_loopback_t *mp;
5683   vl_api_create_loopback_instance_t *mp_lbi;
5684   u8 mac_address[6];
5685   u8 mac_set = 0;
5686   u8 is_specified = 0;
5687   u32 user_instance = 0;
5688   int ret;
5689
5690   clib_memset (mac_address, 0, sizeof (mac_address));
5691
5692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5693     {
5694       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5695         mac_set = 1;
5696       if (unformat (i, "instance %d", &user_instance))
5697         is_specified = 1;
5698       else
5699         break;
5700     }
5701
5702   if (is_specified)
5703     {
5704       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5705       mp_lbi->is_specified = is_specified;
5706       if (is_specified)
5707         mp_lbi->user_instance = htonl (user_instance);
5708       if (mac_set)
5709         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5710       S (mp_lbi);
5711     }
5712   else
5713     {
5714       /* Construct the API message */
5715       M (CREATE_LOOPBACK, mp);
5716       if (mac_set)
5717         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5718       S (mp);
5719     }
5720
5721   W (ret);
5722   return ret;
5723 }
5724
5725 static int
5726 api_delete_loopback (vat_main_t * vam)
5727 {
5728   unformat_input_t *i = vam->input;
5729   vl_api_delete_loopback_t *mp;
5730   u32 sw_if_index = ~0;
5731   int ret;
5732
5733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5734     {
5735       if (unformat (i, "sw_if_index %d", &sw_if_index))
5736         ;
5737       else
5738         break;
5739     }
5740
5741   if (sw_if_index == ~0)
5742     {
5743       errmsg ("missing sw_if_index");
5744       return -99;
5745     }
5746
5747   /* Construct the API message */
5748   M (DELETE_LOOPBACK, mp);
5749   mp->sw_if_index = ntohl (sw_if_index);
5750
5751   S (mp);
5752   W (ret);
5753   return ret;
5754 }
5755
5756 static int
5757 api_want_interface_events (vat_main_t * vam)
5758 {
5759   unformat_input_t *i = vam->input;
5760   vl_api_want_interface_events_t *mp;
5761   int enable = -1;
5762   int ret;
5763
5764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5765     {
5766       if (unformat (i, "enable"))
5767         enable = 1;
5768       else if (unformat (i, "disable"))
5769         enable = 0;
5770       else
5771         break;
5772     }
5773
5774   if (enable == -1)
5775     {
5776       errmsg ("missing enable|disable");
5777       return -99;
5778     }
5779
5780   M (WANT_INTERFACE_EVENTS, mp);
5781   mp->enable_disable = enable;
5782
5783   vam->interface_event_display = enable;
5784
5785   S (mp);
5786   W (ret);
5787   return ret;
5788 }
5789
5790
5791 /* Note: non-static, called once to set up the initial intfc table */
5792 int
5793 api_sw_interface_dump (vat_main_t * vam)
5794 {
5795   vl_api_sw_interface_dump_t *mp;
5796   vl_api_control_ping_t *mp_ping;
5797   hash_pair_t *p;
5798   name_sort_t *nses = 0, *ns;
5799   sw_interface_subif_t *sub = NULL;
5800   int ret;
5801
5802   /* Toss the old name table */
5803   /* *INDENT-OFF* */
5804   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5805   ({
5806     vec_add2 (nses, ns, 1);
5807     ns->name = (u8 *)(p->key);
5808     ns->value = (u32) p->value[0];
5809   }));
5810   /* *INDENT-ON* */
5811
5812   hash_free (vam->sw_if_index_by_interface_name);
5813
5814   vec_foreach (ns, nses) vec_free (ns->name);
5815
5816   vec_free (nses);
5817
5818   vec_foreach (sub, vam->sw_if_subif_table)
5819   {
5820     vec_free (sub->interface_name);
5821   }
5822   vec_free (vam->sw_if_subif_table);
5823
5824   /* recreate the interface name hash table */
5825   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5826
5827   /*
5828    * Ask for all interface names. Otherwise, the epic catalog of
5829    * name filters becomes ridiculously long, and vat ends up needing
5830    * to be taught about new interface types.
5831    */
5832   M (SW_INTERFACE_DUMP, mp);
5833   S (mp);
5834
5835   /* Use a control ping for synchronization */
5836   MPING (CONTROL_PING, mp_ping);
5837   S (mp_ping);
5838
5839   W (ret);
5840   return ret;
5841 }
5842
5843 static int
5844 api_sw_interface_set_flags (vat_main_t * vam)
5845 {
5846   unformat_input_t *i = vam->input;
5847   vl_api_sw_interface_set_flags_t *mp;
5848   u32 sw_if_index;
5849   u8 sw_if_index_set = 0;
5850   u8 admin_up = 0;
5851   int ret;
5852
5853   /* Parse args required to build the message */
5854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5855     {
5856       if (unformat (i, "admin-up"))
5857         admin_up = 1;
5858       else if (unformat (i, "admin-down"))
5859         admin_up = 0;
5860       else
5861         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5862         sw_if_index_set = 1;
5863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5864         sw_if_index_set = 1;
5865       else
5866         break;
5867     }
5868
5869   if (sw_if_index_set == 0)
5870     {
5871       errmsg ("missing interface name or sw_if_index");
5872       return -99;
5873     }
5874
5875   /* Construct the API message */
5876   M (SW_INTERFACE_SET_FLAGS, mp);
5877   mp->sw_if_index = ntohl (sw_if_index);
5878   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5879
5880   /* send it... */
5881   S (mp);
5882
5883   /* Wait for a reply, return the good/bad news... */
5884   W (ret);
5885   return ret;
5886 }
5887
5888 static int
5889 api_sw_interface_set_rx_mode (vat_main_t * vam)
5890 {
5891   unformat_input_t *i = vam->input;
5892   vl_api_sw_interface_set_rx_mode_t *mp;
5893   u32 sw_if_index;
5894   u8 sw_if_index_set = 0;
5895   int ret;
5896   u8 queue_id_valid = 0;
5897   u32 queue_id;
5898   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5899
5900   /* Parse args required to build the message */
5901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5902     {
5903       if (unformat (i, "queue %d", &queue_id))
5904         queue_id_valid = 1;
5905       else if (unformat (i, "polling"))
5906         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5907       else if (unformat (i, "interrupt"))
5908         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5909       else if (unformat (i, "adaptive"))
5910         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5911       else
5912         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5913         sw_if_index_set = 1;
5914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5915         sw_if_index_set = 1;
5916       else
5917         break;
5918     }
5919
5920   if (sw_if_index_set == 0)
5921     {
5922       errmsg ("missing interface name or sw_if_index");
5923       return -99;
5924     }
5925   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5926     {
5927       errmsg ("missing rx-mode");
5928       return -99;
5929     }
5930
5931   /* Construct the API message */
5932   M (SW_INTERFACE_SET_RX_MODE, mp);
5933   mp->sw_if_index = ntohl (sw_if_index);
5934   mp->mode = (vl_api_rx_mode_t) mode;
5935   mp->queue_id_valid = queue_id_valid;
5936   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5937
5938   /* send it... */
5939   S (mp);
5940
5941   /* Wait for a reply, return the good/bad news... */
5942   W (ret);
5943   return ret;
5944 }
5945
5946 static int
5947 api_sw_interface_set_rx_placement (vat_main_t * vam)
5948 {
5949   unformat_input_t *i = vam->input;
5950   vl_api_sw_interface_set_rx_placement_t *mp;
5951   u32 sw_if_index;
5952   u8 sw_if_index_set = 0;
5953   int ret;
5954   u8 is_main = 0;
5955   u32 queue_id, thread_index;
5956
5957   /* Parse args required to build the message */
5958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5959     {
5960       if (unformat (i, "queue %d", &queue_id))
5961         ;
5962       else if (unformat (i, "main"))
5963         is_main = 1;
5964       else if (unformat (i, "worker %d", &thread_index))
5965         ;
5966       else
5967         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5968         sw_if_index_set = 1;
5969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5970         sw_if_index_set = 1;
5971       else
5972         break;
5973     }
5974
5975   if (sw_if_index_set == 0)
5976     {
5977       errmsg ("missing interface name or sw_if_index");
5978       return -99;
5979     }
5980
5981   if (is_main)
5982     thread_index = 0;
5983   /* Construct the API message */
5984   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5985   mp->sw_if_index = ntohl (sw_if_index);
5986   mp->worker_id = ntohl (thread_index);
5987   mp->queue_id = ntohl (queue_id);
5988   mp->is_main = is_main;
5989
5990   /* send it... */
5991   S (mp);
5992   /* Wait for a reply, return the good/bad news... */
5993   W (ret);
5994   return ret;
5995 }
5996
5997 static void vl_api_sw_interface_rx_placement_details_t_handler
5998   (vl_api_sw_interface_rx_placement_details_t * mp)
5999 {
6000   vat_main_t *vam = &vat_main;
6001   u32 worker_id = ntohl (mp->worker_id);
6002
6003   print (vam->ofp,
6004          "\n%-11d %-11s %-6d %-5d %-9s",
6005          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6006          worker_id, ntohl (mp->queue_id),
6007          (mp->mode ==
6008           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6009 }
6010
6011 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6012   (vl_api_sw_interface_rx_placement_details_t * mp)
6013 {
6014   vat_main_t *vam = &vat_main;
6015   vat_json_node_t *node = NULL;
6016
6017   if (VAT_JSON_ARRAY != vam->json_tree.type)
6018     {
6019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6020       vat_json_init_array (&vam->json_tree);
6021     }
6022   node = vat_json_array_add (&vam->json_tree);
6023
6024   vat_json_init_object (node);
6025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6026   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6027   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6028   vat_json_object_add_uint (node, "mode", mp->mode);
6029 }
6030
6031 static int
6032 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6033 {
6034   unformat_input_t *i = vam->input;
6035   vl_api_sw_interface_rx_placement_dump_t *mp;
6036   vl_api_control_ping_t *mp_ping;
6037   int ret;
6038   u32 sw_if_index;
6039   u8 sw_if_index_set = 0;
6040
6041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6042     {
6043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6044         sw_if_index_set++;
6045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6046         sw_if_index_set++;
6047       else
6048         break;
6049     }
6050
6051   print (vam->ofp,
6052          "\n%-11s %-11s %-6s %-5s %-4s",
6053          "sw_if_index", "main/worker", "thread", "queue", "mode");
6054
6055   /* Dump Interface rx placement */
6056   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6057
6058   if (sw_if_index_set)
6059     mp->sw_if_index = htonl (sw_if_index);
6060   else
6061     mp->sw_if_index = ~0;
6062
6063   S (mp);
6064
6065   /* Use a control ping for synchronization */
6066   MPING (CONTROL_PING, mp_ping);
6067   S (mp_ping);
6068
6069   W (ret);
6070   return ret;
6071 }
6072
6073 static int
6074 api_sw_interface_clear_stats (vat_main_t * vam)
6075 {
6076   unformat_input_t *i = vam->input;
6077   vl_api_sw_interface_clear_stats_t *mp;
6078   u32 sw_if_index;
6079   u8 sw_if_index_set = 0;
6080   int ret;
6081
6082   /* Parse args required to build the message */
6083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6084     {
6085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6086         sw_if_index_set = 1;
6087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6088         sw_if_index_set = 1;
6089       else
6090         break;
6091     }
6092
6093   /* Construct the API message */
6094   M (SW_INTERFACE_CLEAR_STATS, mp);
6095
6096   if (sw_if_index_set == 1)
6097     mp->sw_if_index = ntohl (sw_if_index);
6098   else
6099     mp->sw_if_index = ~0;
6100
6101   /* send it... */
6102   S (mp);
6103
6104   /* Wait for a reply, return the good/bad news... */
6105   W (ret);
6106   return ret;
6107 }
6108
6109 static int
6110 api_sw_interface_add_del_address (vat_main_t * vam)
6111 {
6112   unformat_input_t *i = vam->input;
6113   vl_api_sw_interface_add_del_address_t *mp;
6114   u32 sw_if_index;
6115   u8 sw_if_index_set = 0;
6116   u8 is_add = 1, del_all = 0;
6117   u32 address_length = 0;
6118   u8 v4_address_set = 0;
6119   u8 v6_address_set = 0;
6120   ip4_address_t v4address;
6121   ip6_address_t v6address;
6122   int ret;
6123
6124   /* Parse args required to build the message */
6125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6126     {
6127       if (unformat (i, "del-all"))
6128         del_all = 1;
6129       else if (unformat (i, "del"))
6130         is_add = 0;
6131       else
6132         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6133         sw_if_index_set = 1;
6134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6135         sw_if_index_set = 1;
6136       else if (unformat (i, "%U/%d",
6137                          unformat_ip4_address, &v4address, &address_length))
6138         v4_address_set = 1;
6139       else if (unformat (i, "%U/%d",
6140                          unformat_ip6_address, &v6address, &address_length))
6141         v6_address_set = 1;
6142       else
6143         break;
6144     }
6145
6146   if (sw_if_index_set == 0)
6147     {
6148       errmsg ("missing interface name or sw_if_index");
6149       return -99;
6150     }
6151   if (v4_address_set && v6_address_set)
6152     {
6153       errmsg ("both v4 and v6 addresses set");
6154       return -99;
6155     }
6156   if (!v4_address_set && !v6_address_set && !del_all)
6157     {
6158       errmsg ("no addresses set");
6159       return -99;
6160     }
6161
6162   /* Construct the API message */
6163   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6164
6165   mp->sw_if_index = ntohl (sw_if_index);
6166   mp->is_add = is_add;
6167   mp->del_all = del_all;
6168   if (v6_address_set)
6169     {
6170       mp->prefix.address.af = ADDRESS_IP6;
6171       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6172     }
6173   else
6174     {
6175       mp->prefix.address.af = ADDRESS_IP4;
6176       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6177     }
6178   mp->prefix.len = address_length;
6179
6180   /* send it... */
6181   S (mp);
6182
6183   /* Wait for a reply, return good/bad news  */
6184   W (ret);
6185   return ret;
6186 }
6187
6188 static int
6189 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6190 {
6191   unformat_input_t *i = vam->input;
6192   vl_api_sw_interface_set_mpls_enable_t *mp;
6193   u32 sw_if_index;
6194   u8 sw_if_index_set = 0;
6195   u8 enable = 1;
6196   int ret;
6197
6198   /* Parse args required to build the message */
6199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6200     {
6201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6202         sw_if_index_set = 1;
6203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6204         sw_if_index_set = 1;
6205       else if (unformat (i, "disable"))
6206         enable = 0;
6207       else if (unformat (i, "dis"))
6208         enable = 0;
6209       else
6210         break;
6211     }
6212
6213   if (sw_if_index_set == 0)
6214     {
6215       errmsg ("missing interface name or sw_if_index");
6216       return -99;
6217     }
6218
6219   /* Construct the API message */
6220   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6221
6222   mp->sw_if_index = ntohl (sw_if_index);
6223   mp->enable = enable;
6224
6225   /* send it... */
6226   S (mp);
6227
6228   /* Wait for a reply... */
6229   W (ret);
6230   return ret;
6231 }
6232
6233 static int
6234 api_sw_interface_set_table (vat_main_t * vam)
6235 {
6236   unformat_input_t *i = vam->input;
6237   vl_api_sw_interface_set_table_t *mp;
6238   u32 sw_if_index, vrf_id = 0;
6239   u8 sw_if_index_set = 0;
6240   u8 is_ipv6 = 0;
6241   int ret;
6242
6243   /* Parse args required to build the message */
6244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6245     {
6246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6247         sw_if_index_set = 1;
6248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6249         sw_if_index_set = 1;
6250       else if (unformat (i, "vrf %d", &vrf_id))
6251         ;
6252       else if (unformat (i, "ipv6"))
6253         is_ipv6 = 1;
6254       else
6255         break;
6256     }
6257
6258   if (sw_if_index_set == 0)
6259     {
6260       errmsg ("missing interface name or sw_if_index");
6261       return -99;
6262     }
6263
6264   /* Construct the API message */
6265   M (SW_INTERFACE_SET_TABLE, mp);
6266
6267   mp->sw_if_index = ntohl (sw_if_index);
6268   mp->is_ipv6 = is_ipv6;
6269   mp->vrf_id = ntohl (vrf_id);
6270
6271   /* send it... */
6272   S (mp);
6273
6274   /* Wait for a reply... */
6275   W (ret);
6276   return ret;
6277 }
6278
6279 static void vl_api_sw_interface_get_table_reply_t_handler
6280   (vl_api_sw_interface_get_table_reply_t * mp)
6281 {
6282   vat_main_t *vam = &vat_main;
6283
6284   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6285
6286   vam->retval = ntohl (mp->retval);
6287   vam->result_ready = 1;
6288
6289 }
6290
6291 static void vl_api_sw_interface_get_table_reply_t_handler_json
6292   (vl_api_sw_interface_get_table_reply_t * mp)
6293 {
6294   vat_main_t *vam = &vat_main;
6295   vat_json_node_t node;
6296
6297   vat_json_init_object (&node);
6298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6299   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6300
6301   vat_json_print (vam->ofp, &node);
6302   vat_json_free (&node);
6303
6304   vam->retval = ntohl (mp->retval);
6305   vam->result_ready = 1;
6306 }
6307
6308 static int
6309 api_sw_interface_get_table (vat_main_t * vam)
6310 {
6311   unformat_input_t *i = vam->input;
6312   vl_api_sw_interface_get_table_t *mp;
6313   u32 sw_if_index;
6314   u8 sw_if_index_set = 0;
6315   u8 is_ipv6 = 0;
6316   int ret;
6317
6318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6319     {
6320       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6321         sw_if_index_set = 1;
6322       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6323         sw_if_index_set = 1;
6324       else if (unformat (i, "ipv6"))
6325         is_ipv6 = 1;
6326       else
6327         break;
6328     }
6329
6330   if (sw_if_index_set == 0)
6331     {
6332       errmsg ("missing interface name or sw_if_index");
6333       return -99;
6334     }
6335
6336   M (SW_INTERFACE_GET_TABLE, mp);
6337   mp->sw_if_index = htonl (sw_if_index);
6338   mp->is_ipv6 = is_ipv6;
6339
6340   S (mp);
6341   W (ret);
6342   return ret;
6343 }
6344
6345 static int
6346 api_sw_interface_set_vpath (vat_main_t * vam)
6347 {
6348   unformat_input_t *i = vam->input;
6349   vl_api_sw_interface_set_vpath_t *mp;
6350   u32 sw_if_index = 0;
6351   u8 sw_if_index_set = 0;
6352   u8 is_enable = 0;
6353   int ret;
6354
6355   /* Parse args required to build the message */
6356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6357     {
6358       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6359         sw_if_index_set = 1;
6360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6361         sw_if_index_set = 1;
6362       else if (unformat (i, "enable"))
6363         is_enable = 1;
6364       else if (unformat (i, "disable"))
6365         is_enable = 0;
6366       else
6367         break;
6368     }
6369
6370   if (sw_if_index_set == 0)
6371     {
6372       errmsg ("missing interface name or sw_if_index");
6373       return -99;
6374     }
6375
6376   /* Construct the API message */
6377   M (SW_INTERFACE_SET_VPATH, mp);
6378
6379   mp->sw_if_index = ntohl (sw_if_index);
6380   mp->enable = is_enable;
6381
6382   /* send it... */
6383   S (mp);
6384
6385   /* Wait for a reply... */
6386   W (ret);
6387   return ret;
6388 }
6389
6390 static int
6391 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6392 {
6393   unformat_input_t *i = vam->input;
6394   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6395   u32 sw_if_index = 0;
6396   u8 sw_if_index_set = 0;
6397   u8 is_enable = 1;
6398   u8 is_ipv6 = 0;
6399   int ret;
6400
6401   /* Parse args required to build the message */
6402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6403     {
6404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6405         sw_if_index_set = 1;
6406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "enable"))
6409         is_enable = 1;
6410       else if (unformat (i, "disable"))
6411         is_enable = 0;
6412       else if (unformat (i, "ip4"))
6413         is_ipv6 = 0;
6414       else if (unformat (i, "ip6"))
6415         is_ipv6 = 1;
6416       else
6417         break;
6418     }
6419
6420   if (sw_if_index_set == 0)
6421     {
6422       errmsg ("missing interface name or sw_if_index");
6423       return -99;
6424     }
6425
6426   /* Construct the API message */
6427   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6428
6429   mp->sw_if_index = ntohl (sw_if_index);
6430   mp->enable = is_enable;
6431   mp->is_ipv6 = is_ipv6;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_geneve_bypass_t *mp;
6446   u32 sw_if_index = 0;
6447   u8 sw_if_index_set = 0;
6448   u8 is_enable = 1;
6449   u8 is_ipv6 = 0;
6450   int ret;
6451
6452   /* Parse args required to build the message */
6453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6454     {
6455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6456         sw_if_index_set = 1;
6457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "enable"))
6460         is_enable = 1;
6461       else if (unformat (i, "disable"))
6462         is_enable = 0;
6463       else if (unformat (i, "ip4"))
6464         is_ipv6 = 0;
6465       else if (unformat (i, "ip6"))
6466         is_ipv6 = 1;
6467       else
6468         break;
6469     }
6470
6471   if (sw_if_index_set == 0)
6472     {
6473       errmsg ("missing interface name or sw_if_index");
6474       return -99;
6475     }
6476
6477   /* Construct the API message */
6478   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6479
6480   mp->sw_if_index = ntohl (sw_if_index);
6481   mp->enable = is_enable;
6482   mp->is_ipv6 = is_ipv6;
6483
6484   /* send it... */
6485   S (mp);
6486
6487   /* Wait for a reply... */
6488   W (ret);
6489   return ret;
6490 }
6491
6492 static int
6493 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6494 {
6495   unformat_input_t *i = vam->input;
6496   vl_api_sw_interface_set_l2_xconnect_t *mp;
6497   u32 rx_sw_if_index;
6498   u8 rx_sw_if_index_set = 0;
6499   u32 tx_sw_if_index;
6500   u8 tx_sw_if_index_set = 0;
6501   u8 enable = 1;
6502   int ret;
6503
6504   /* Parse args required to build the message */
6505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6506     {
6507       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6508         rx_sw_if_index_set = 1;
6509       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6510         tx_sw_if_index_set = 1;
6511       else if (unformat (i, "rx"))
6512         {
6513           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6514             {
6515               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6516                             &rx_sw_if_index))
6517                 rx_sw_if_index_set = 1;
6518             }
6519           else
6520             break;
6521         }
6522       else if (unformat (i, "tx"))
6523         {
6524           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6525             {
6526               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6527                             &tx_sw_if_index))
6528                 tx_sw_if_index_set = 1;
6529             }
6530           else
6531             break;
6532         }
6533       else if (unformat (i, "enable"))
6534         enable = 1;
6535       else if (unformat (i, "disable"))
6536         enable = 0;
6537       else
6538         break;
6539     }
6540
6541   if (rx_sw_if_index_set == 0)
6542     {
6543       errmsg ("missing rx interface name or rx_sw_if_index");
6544       return -99;
6545     }
6546
6547   if (enable && (tx_sw_if_index_set == 0))
6548     {
6549       errmsg ("missing tx interface name or tx_sw_if_index");
6550       return -99;
6551     }
6552
6553   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6554
6555   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6556   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6557   mp->enable = enable;
6558
6559   S (mp);
6560   W (ret);
6561   return ret;
6562 }
6563
6564 static int
6565 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6566 {
6567   unformat_input_t *i = vam->input;
6568   vl_api_sw_interface_set_l2_bridge_t *mp;
6569   vl_api_l2_port_type_t port_type;
6570   u32 rx_sw_if_index;
6571   u8 rx_sw_if_index_set = 0;
6572   u32 bd_id;
6573   u8 bd_id_set = 0;
6574   u32 shg = 0;
6575   u8 enable = 1;
6576   int ret;
6577
6578   port_type = L2_API_PORT_TYPE_NORMAL;
6579
6580   /* Parse args required to build the message */
6581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6582     {
6583       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6584         rx_sw_if_index_set = 1;
6585       else if (unformat (i, "bd_id %d", &bd_id))
6586         bd_id_set = 1;
6587       else
6588         if (unformat
6589             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6590         rx_sw_if_index_set = 1;
6591       else if (unformat (i, "shg %d", &shg))
6592         ;
6593       else if (unformat (i, "bvi"))
6594         port_type = L2_API_PORT_TYPE_BVI;
6595       else if (unformat (i, "uu-fwd"))
6596         port_type = L2_API_PORT_TYPE_UU_FWD;
6597       else if (unformat (i, "enable"))
6598         enable = 1;
6599       else if (unformat (i, "disable"))
6600         enable = 0;
6601       else
6602         break;
6603     }
6604
6605   if (rx_sw_if_index_set == 0)
6606     {
6607       errmsg ("missing rx interface name or sw_if_index");
6608       return -99;
6609     }
6610
6611   if (enable && (bd_id_set == 0))
6612     {
6613       errmsg ("missing bridge domain");
6614       return -99;
6615     }
6616
6617   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6618
6619   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6620   mp->bd_id = ntohl (bd_id);
6621   mp->shg = (u8) shg;
6622   mp->port_type = ntohl (port_type);
6623   mp->enable = enable;
6624
6625   S (mp);
6626   W (ret);
6627   return ret;
6628 }
6629
6630 static int
6631 api_bridge_domain_dump (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_bridge_domain_dump_t *mp;
6635   vl_api_control_ping_t *mp_ping;
6636   u32 bd_id = ~0;
6637   int ret;
6638
6639   /* Parse args required to build the message */
6640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6641     {
6642       if (unformat (i, "bd_id %d", &bd_id))
6643         ;
6644       else
6645         break;
6646     }
6647
6648   M (BRIDGE_DOMAIN_DUMP, mp);
6649   mp->bd_id = ntohl (bd_id);
6650   S (mp);
6651
6652   /* Use a control ping for synchronization */
6653   MPING (CONTROL_PING, mp_ping);
6654   S (mp_ping);
6655
6656   W (ret);
6657   return ret;
6658 }
6659
6660 static int
6661 api_bridge_domain_add_del (vat_main_t * vam)
6662 {
6663   unformat_input_t *i = vam->input;
6664   vl_api_bridge_domain_add_del_t *mp;
6665   u32 bd_id = ~0;
6666   u8 is_add = 1;
6667   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6668   u8 *bd_tag = NULL;
6669   u32 mac_age = 0;
6670   int ret;
6671
6672   /* Parse args required to build the message */
6673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6674     {
6675       if (unformat (i, "bd_id %d", &bd_id))
6676         ;
6677       else if (unformat (i, "flood %d", &flood))
6678         ;
6679       else if (unformat (i, "uu-flood %d", &uu_flood))
6680         ;
6681       else if (unformat (i, "forward %d", &forward))
6682         ;
6683       else if (unformat (i, "learn %d", &learn))
6684         ;
6685       else if (unformat (i, "arp-term %d", &arp_term))
6686         ;
6687       else if (unformat (i, "mac-age %d", &mac_age))
6688         ;
6689       else if (unformat (i, "bd-tag %s", &bd_tag))
6690         ;
6691       else if (unformat (i, "del"))
6692         {
6693           is_add = 0;
6694           flood = uu_flood = forward = learn = 0;
6695         }
6696       else
6697         break;
6698     }
6699
6700   if (bd_id == ~0)
6701     {
6702       errmsg ("missing bridge domain");
6703       ret = -99;
6704       goto done;
6705     }
6706
6707   if (mac_age > 255)
6708     {
6709       errmsg ("mac age must be less than 256 ");
6710       ret = -99;
6711       goto done;
6712     }
6713
6714   if ((bd_tag) && (vec_len (bd_tag) > 63))
6715     {
6716       errmsg ("bd-tag cannot be longer than 63");
6717       ret = -99;
6718       goto done;
6719     }
6720
6721   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6722
6723   mp->bd_id = ntohl (bd_id);
6724   mp->flood = flood;
6725   mp->uu_flood = uu_flood;
6726   mp->forward = forward;
6727   mp->learn = learn;
6728   mp->arp_term = arp_term;
6729   mp->is_add = is_add;
6730   mp->mac_age = (u8) mac_age;
6731   if (bd_tag)
6732     {
6733       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6734       mp->bd_tag[vec_len (bd_tag)] = 0;
6735     }
6736   S (mp);
6737   W (ret);
6738
6739 done:
6740   vec_free (bd_tag);
6741   return ret;
6742 }
6743
6744 static int
6745 api_l2fib_flush_bd (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_l2fib_flush_bd_t *mp;
6749   u32 bd_id = ~0;
6750   int ret;
6751
6752   /* Parse args required to build the message */
6753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6754     {
6755       if (unformat (i, "bd_id %d", &bd_id));
6756       else
6757         break;
6758     }
6759
6760   if (bd_id == ~0)
6761     {
6762       errmsg ("missing bridge domain");
6763       return -99;
6764     }
6765
6766   M (L2FIB_FLUSH_BD, mp);
6767
6768   mp->bd_id = htonl (bd_id);
6769
6770   S (mp);
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_l2fib_flush_int (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_l2fib_flush_int_t *mp;
6780   u32 sw_if_index = ~0;
6781   int ret;
6782
6783   /* Parse args required to build the message */
6784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6785     {
6786       if (unformat (i, "sw_if_index %d", &sw_if_index));
6787       else
6788         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6789       else
6790         break;
6791     }
6792
6793   if (sw_if_index == ~0)
6794     {
6795       errmsg ("missing interface name or sw_if_index");
6796       return -99;
6797     }
6798
6799   M (L2FIB_FLUSH_INT, mp);
6800
6801   mp->sw_if_index = ntohl (sw_if_index);
6802
6803   S (mp);
6804   W (ret);
6805   return ret;
6806 }
6807
6808 static int
6809 api_l2fib_add_del (vat_main_t * vam)
6810 {
6811   unformat_input_t *i = vam->input;
6812   vl_api_l2fib_add_del_t *mp;
6813   f64 timeout;
6814   u8 mac[6] = { 0 };
6815   u8 mac_set = 0;
6816   u32 bd_id;
6817   u8 bd_id_set = 0;
6818   u32 sw_if_index = 0;
6819   u8 sw_if_index_set = 0;
6820   u8 is_add = 1;
6821   u8 static_mac = 0;
6822   u8 filter_mac = 0;
6823   u8 bvi_mac = 0;
6824   int count = 1;
6825   f64 before = 0;
6826   int j;
6827
6828   /* Parse args required to build the message */
6829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6830     {
6831       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6832         mac_set = 1;
6833       else if (unformat (i, "bd_id %d", &bd_id))
6834         bd_id_set = 1;
6835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6836         sw_if_index_set = 1;
6837       else if (unformat (i, "sw_if"))
6838         {
6839           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6840             {
6841               if (unformat
6842                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6843                 sw_if_index_set = 1;
6844             }
6845           else
6846             break;
6847         }
6848       else if (unformat (i, "static"))
6849         static_mac = 1;
6850       else if (unformat (i, "filter"))
6851         {
6852           filter_mac = 1;
6853           static_mac = 1;
6854         }
6855       else if (unformat (i, "bvi"))
6856         {
6857           bvi_mac = 1;
6858           static_mac = 1;
6859         }
6860       else if (unformat (i, "del"))
6861         is_add = 0;
6862       else if (unformat (i, "count %d", &count))
6863         ;
6864       else
6865         break;
6866     }
6867
6868   if (mac_set == 0)
6869     {
6870       errmsg ("missing mac address");
6871       return -99;
6872     }
6873
6874   if (bd_id_set == 0)
6875     {
6876       errmsg ("missing bridge domain");
6877       return -99;
6878     }
6879
6880   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6881     {
6882       errmsg ("missing interface name or sw_if_index");
6883       return -99;
6884     }
6885
6886   if (count > 1)
6887     {
6888       /* Turn on async mode */
6889       vam->async_mode = 1;
6890       vam->async_errors = 0;
6891       before = vat_time_now (vam);
6892     }
6893
6894   for (j = 0; j < count; j++)
6895     {
6896       M (L2FIB_ADD_DEL, mp);
6897
6898       clib_memcpy (mp->mac, mac, 6);
6899       mp->bd_id = ntohl (bd_id);
6900       mp->is_add = is_add;
6901       mp->sw_if_index = ntohl (sw_if_index);
6902
6903       if (is_add)
6904         {
6905           mp->static_mac = static_mac;
6906           mp->filter_mac = filter_mac;
6907           mp->bvi_mac = bvi_mac;
6908         }
6909       increment_mac_address (mac);
6910       /* send it... */
6911       S (mp);
6912     }
6913
6914   if (count > 1)
6915     {
6916       vl_api_control_ping_t *mp_ping;
6917       f64 after;
6918
6919       /* Shut off async mode */
6920       vam->async_mode = 0;
6921
6922       MPING (CONTROL_PING, mp_ping);
6923       S (mp_ping);
6924
6925       timeout = vat_time_now (vam) + 1.0;
6926       while (vat_time_now (vam) < timeout)
6927         if (vam->result_ready == 1)
6928           goto out;
6929       vam->retval = -99;
6930
6931     out:
6932       if (vam->retval == -99)
6933         errmsg ("timeout");
6934
6935       if (vam->async_errors > 0)
6936         {
6937           errmsg ("%d asynchronous errors", vam->async_errors);
6938           vam->retval = -98;
6939         }
6940       vam->async_errors = 0;
6941       after = vat_time_now (vam);
6942
6943       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6944              count, after - before, count / (after - before));
6945     }
6946   else
6947     {
6948       int ret;
6949
6950       /* Wait for a reply... */
6951       W (ret);
6952       return ret;
6953     }
6954   /* Return the good/bad news */
6955   return (vam->retval);
6956 }
6957
6958 static int
6959 api_bridge_domain_set_mac_age (vat_main_t * vam)
6960 {
6961   unformat_input_t *i = vam->input;
6962   vl_api_bridge_domain_set_mac_age_t *mp;
6963   u32 bd_id = ~0;
6964   u32 mac_age = 0;
6965   int ret;
6966
6967   /* Parse args required to build the message */
6968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6969     {
6970       if (unformat (i, "bd_id %d", &bd_id));
6971       else if (unformat (i, "mac-age %d", &mac_age));
6972       else
6973         break;
6974     }
6975
6976   if (bd_id == ~0)
6977     {
6978       errmsg ("missing bridge domain");
6979       return -99;
6980     }
6981
6982   if (mac_age > 255)
6983     {
6984       errmsg ("mac age must be less than 256 ");
6985       return -99;
6986     }
6987
6988   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6989
6990   mp->bd_id = htonl (bd_id);
6991   mp->mac_age = (u8) mac_age;
6992
6993   S (mp);
6994   W (ret);
6995   return ret;
6996 }
6997
6998 static int
6999 api_l2_flags (vat_main_t * vam)
7000 {
7001   unformat_input_t *i = vam->input;
7002   vl_api_l2_flags_t *mp;
7003   u32 sw_if_index;
7004   u32 flags = 0;
7005   u8 sw_if_index_set = 0;
7006   u8 is_set = 0;
7007   int ret;
7008
7009   /* Parse args required to build the message */
7010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7011     {
7012       if (unformat (i, "sw_if_index %d", &sw_if_index))
7013         sw_if_index_set = 1;
7014       else if (unformat (i, "sw_if"))
7015         {
7016           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017             {
7018               if (unformat
7019                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7020                 sw_if_index_set = 1;
7021             }
7022           else
7023             break;
7024         }
7025       else if (unformat (i, "learn"))
7026         flags |= L2_LEARN;
7027       else if (unformat (i, "forward"))
7028         flags |= L2_FWD;
7029       else if (unformat (i, "flood"))
7030         flags |= L2_FLOOD;
7031       else if (unformat (i, "uu-flood"))
7032         flags |= L2_UU_FLOOD;
7033       else if (unformat (i, "arp-term"))
7034         flags |= L2_ARP_TERM;
7035       else if (unformat (i, "off"))
7036         is_set = 0;
7037       else if (unformat (i, "disable"))
7038         is_set = 0;
7039       else
7040         break;
7041     }
7042
7043   if (sw_if_index_set == 0)
7044     {
7045       errmsg ("missing interface name or sw_if_index");
7046       return -99;
7047     }
7048
7049   M (L2_FLAGS, mp);
7050
7051   mp->sw_if_index = ntohl (sw_if_index);
7052   mp->feature_bitmap = ntohl (flags);
7053   mp->is_set = is_set;
7054
7055   S (mp);
7056   W (ret);
7057   return ret;
7058 }
7059
7060 static int
7061 api_bridge_flags (vat_main_t * vam)
7062 {
7063   unformat_input_t *i = vam->input;
7064   vl_api_bridge_flags_t *mp;
7065   u32 bd_id;
7066   u8 bd_id_set = 0;
7067   u8 is_set = 1;
7068   bd_flags_t flags = 0;
7069   int ret;
7070
7071   /* Parse args required to build the message */
7072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7073     {
7074       if (unformat (i, "bd_id %d", &bd_id))
7075         bd_id_set = 1;
7076       else if (unformat (i, "learn"))
7077         flags |= BRIDGE_API_FLAG_LEARN;
7078       else if (unformat (i, "forward"))
7079         flags |= BRIDGE_API_FLAG_FWD;
7080       else if (unformat (i, "flood"))
7081         flags |= BRIDGE_API_FLAG_FLOOD;
7082       else if (unformat (i, "uu-flood"))
7083         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7084       else if (unformat (i, "arp-term"))
7085         flags |= BRIDGE_API_FLAG_ARP_TERM;
7086       else if (unformat (i, "off"))
7087         is_set = 0;
7088       else if (unformat (i, "disable"))
7089         is_set = 0;
7090       else
7091         break;
7092     }
7093
7094   if (bd_id_set == 0)
7095     {
7096       errmsg ("missing bridge domain");
7097       return -99;
7098     }
7099
7100   M (BRIDGE_FLAGS, mp);
7101
7102   mp->bd_id = ntohl (bd_id);
7103   mp->flags = ntohl (flags);
7104   mp->is_set = is_set;
7105
7106   S (mp);
7107   W (ret);
7108   return ret;
7109 }
7110
7111 static int
7112 api_bd_ip_mac_add_del (vat_main_t * vam)
7113 {
7114   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7115   vl_api_mac_address_t mac = { 0 };
7116   unformat_input_t *i = vam->input;
7117   vl_api_bd_ip_mac_add_del_t *mp;
7118   u32 bd_id;
7119   u8 is_add = 1;
7120   u8 bd_id_set = 0;
7121   u8 ip_set = 0;
7122   u8 mac_set = 0;
7123   int ret;
7124
7125
7126   /* Parse args required to build the message */
7127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7128     {
7129       if (unformat (i, "bd_id %d", &bd_id))
7130         {
7131           bd_id_set++;
7132         }
7133       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7134         {
7135           ip_set++;
7136         }
7137       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7138         {
7139           mac_set++;
7140         }
7141       else if (unformat (i, "del"))
7142         is_add = 0;
7143       else
7144         break;
7145     }
7146
7147   if (bd_id_set == 0)
7148     {
7149       errmsg ("missing bridge domain");
7150       return -99;
7151     }
7152   else if (ip_set == 0)
7153     {
7154       errmsg ("missing IP address");
7155       return -99;
7156     }
7157   else if (mac_set == 0)
7158     {
7159       errmsg ("missing MAC address");
7160       return -99;
7161     }
7162
7163   M (BD_IP_MAC_ADD_DEL, mp);
7164
7165   mp->entry.bd_id = ntohl (bd_id);
7166   mp->is_add = is_add;
7167
7168   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7169   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7170
7171   S (mp);
7172   W (ret);
7173   return ret;
7174 }
7175
7176 static int
7177 api_bd_ip_mac_flush (vat_main_t * vam)
7178 {
7179   unformat_input_t *i = vam->input;
7180   vl_api_bd_ip_mac_flush_t *mp;
7181   u32 bd_id;
7182   u8 bd_id_set = 0;
7183   int ret;
7184
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "bd_id %d", &bd_id))
7188         {
7189           bd_id_set++;
7190         }
7191       else
7192         break;
7193     }
7194
7195   if (bd_id_set == 0)
7196     {
7197       errmsg ("missing bridge domain");
7198       return -99;
7199     }
7200
7201   M (BD_IP_MAC_FLUSH, mp);
7202
7203   mp->bd_id = ntohl (bd_id);
7204
7205   S (mp);
7206   W (ret);
7207   return ret;
7208 }
7209
7210 static void vl_api_bd_ip_mac_details_t_handler
7211   (vl_api_bd_ip_mac_details_t * mp)
7212 {
7213   vat_main_t *vam = &vat_main;
7214
7215   print (vam->ofp,
7216          "\n%-5d %U %U",
7217          ntohl (mp->entry.bd_id),
7218          format_vl_api_mac_address, mp->entry.mac,
7219          format_vl_api_address, &mp->entry.ip);
7220 }
7221
7222 static void vl_api_bd_ip_mac_details_t_handler_json
7223   (vl_api_bd_ip_mac_details_t * mp)
7224 {
7225   vat_main_t *vam = &vat_main;
7226   vat_json_node_t *node = NULL;
7227
7228   if (VAT_JSON_ARRAY != vam->json_tree.type)
7229     {
7230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7231       vat_json_init_array (&vam->json_tree);
7232     }
7233   node = vat_json_array_add (&vam->json_tree);
7234
7235   vat_json_init_object (node);
7236   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7237   vat_json_object_add_string_copy (node, "mac_address",
7238                                    format (0, "%U", format_vl_api_mac_address,
7239                                            &mp->entry.mac));
7240   u8 *ip = 0;
7241
7242   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7243   vat_json_object_add_string_copy (node, "ip_address", ip);
7244   vec_free (ip);
7245 }
7246
7247 static int
7248 api_bd_ip_mac_dump (vat_main_t * vam)
7249 {
7250   unformat_input_t *i = vam->input;
7251   vl_api_bd_ip_mac_dump_t *mp;
7252   vl_api_control_ping_t *mp_ping;
7253   int ret;
7254   u32 bd_id;
7255   u8 bd_id_set = 0;
7256
7257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7258     {
7259       if (unformat (i, "bd_id %d", &bd_id))
7260         {
7261           bd_id_set++;
7262         }
7263       else
7264         break;
7265     }
7266
7267   print (vam->ofp,
7268          "\n%-5s %-7s %-20s %-30s",
7269          "bd_id", "is_ipv6", "mac_address", "ip_address");
7270
7271   /* Dump Bridge Domain Ip to Mac entries */
7272   M (BD_IP_MAC_DUMP, mp);
7273
7274   if (bd_id_set)
7275     mp->bd_id = htonl (bd_id);
7276   else
7277     mp->bd_id = ~0;
7278
7279   S (mp);
7280
7281   /* Use a control ping for synchronization */
7282   MPING (CONTROL_PING, mp_ping);
7283   S (mp_ping);
7284
7285   W (ret);
7286   return ret;
7287 }
7288
7289 static int
7290 api_tap_create_v2 (vat_main_t * vam)
7291 {
7292   unformat_input_t *i = vam->input;
7293   vl_api_tap_create_v2_t *mp;
7294   u8 mac_address[6];
7295   u8 random_mac = 1;
7296   u32 id = ~0;
7297   u32 num_rx_queues = 0;
7298   u8 *host_if_name = 0;
7299   u8 host_if_name_set = 0;
7300   u8 *host_ns = 0;
7301   u8 host_ns_set = 0;
7302   u8 host_mac_addr[6];
7303   u8 host_mac_addr_set = 0;
7304   u8 *host_bridge = 0;
7305   u8 host_bridge_set = 0;
7306   u8 host_ip4_prefix_set = 0;
7307   u8 host_ip6_prefix_set = 0;
7308   ip4_address_t host_ip4_addr;
7309   ip4_address_t host_ip4_gw;
7310   u8 host_ip4_gw_set = 0;
7311   u32 host_ip4_prefix_len = 0;
7312   ip6_address_t host_ip6_addr;
7313   ip6_address_t host_ip6_gw;
7314   u8 host_ip6_gw_set = 0;
7315   u32 host_ip6_prefix_len = 0;
7316   u32 host_mtu_size = 0;
7317   u8 host_mtu_set = 0;
7318   u32 tap_flags = 0;
7319   int ret;
7320   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7321
7322   clib_memset (mac_address, 0, sizeof (mac_address));
7323
7324   /* Parse args required to build the message */
7325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326     {
7327       if (unformat (i, "id %u", &id))
7328         ;
7329       else
7330         if (unformat
7331             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7332         random_mac = 0;
7333       else if (unformat (i, "host-if-name %s", &host_if_name))
7334         host_if_name_set = 1;
7335       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7336         ;
7337       else if (unformat (i, "host-ns %s", &host_ns))
7338         host_ns_set = 1;
7339       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7340                          host_mac_addr))
7341         host_mac_addr_set = 1;
7342       else if (unformat (i, "host-bridge %s", &host_bridge))
7343         host_bridge_set = 1;
7344       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7345                          &host_ip4_addr, &host_ip4_prefix_len))
7346         host_ip4_prefix_set = 1;
7347       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7348                          &host_ip6_addr, &host_ip6_prefix_len))
7349         host_ip6_prefix_set = 1;
7350       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7351                          &host_ip4_gw))
7352         host_ip4_gw_set = 1;
7353       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7354                          &host_ip6_gw))
7355         host_ip6_gw_set = 1;
7356       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7357         ;
7358       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7359         ;
7360       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7361         host_mtu_set = 1;
7362       else if (unformat (i, "no-gso"))
7363         tap_flags &= ~TAP_API_FLAG_GSO;
7364       else if (unformat (i, "gso"))
7365         tap_flags |= TAP_API_FLAG_GSO;
7366       else if (unformat (i, "csum-offload"))
7367         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7368       else if (unformat (i, "persist"))
7369         tap_flags |= TAP_API_FLAG_PERSIST;
7370       else if (unformat (i, "attach"))
7371         tap_flags |= TAP_API_FLAG_ATTACH;
7372       else if (unformat (i, "tun"))
7373         tap_flags |= TAP_API_FLAG_TUN;
7374       else if (unformat (i, "gro-coalesce"))
7375         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7376       else
7377         break;
7378     }
7379
7380   if (vec_len (host_if_name) > 63)
7381     {
7382       errmsg ("tap name too long. ");
7383       return -99;
7384     }
7385   if (vec_len (host_ns) > 63)
7386     {
7387       errmsg ("host name space too long. ");
7388       return -99;
7389     }
7390   if (vec_len (host_bridge) > 63)
7391     {
7392       errmsg ("host bridge name too long. ");
7393       return -99;
7394     }
7395   if (host_ip4_prefix_len > 32)
7396     {
7397       errmsg ("host ip4 prefix length not valid. ");
7398       return -99;
7399     }
7400   if (host_ip6_prefix_len > 128)
7401     {
7402       errmsg ("host ip6 prefix length not valid. ");
7403       return -99;
7404     }
7405   if (!is_pow2 (rx_ring_sz))
7406     {
7407       errmsg ("rx ring size must be power of 2. ");
7408       return -99;
7409     }
7410   if (rx_ring_sz > 32768)
7411     {
7412       errmsg ("rx ring size must be 32768 or lower. ");
7413       return -99;
7414     }
7415   if (!is_pow2 (tx_ring_sz))
7416     {
7417       errmsg ("tx ring size must be power of 2. ");
7418       return -99;
7419     }
7420   if (tx_ring_sz > 32768)
7421     {
7422       errmsg ("tx ring size must be 32768 or lower. ");
7423       return -99;
7424     }
7425   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7426     {
7427       errmsg ("host MTU size must be in between 64 and 65355. ");
7428       return -99;
7429     }
7430
7431   /* Construct the API message */
7432   M (TAP_CREATE_V2, mp);
7433
7434   mp->id = ntohl (id);
7435   mp->use_random_mac = random_mac;
7436   mp->num_rx_queues = (u8) num_rx_queues;
7437   mp->tx_ring_sz = ntohs (tx_ring_sz);
7438   mp->rx_ring_sz = ntohs (rx_ring_sz);
7439   mp->host_mtu_set = host_mtu_set;
7440   mp->host_mtu_size = ntohl (host_mtu_size);
7441   mp->host_mac_addr_set = host_mac_addr_set;
7442   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7443   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7444   mp->host_ip4_gw_set = host_ip4_gw_set;
7445   mp->host_ip6_gw_set = host_ip6_gw_set;
7446   mp->tap_flags = ntohl (tap_flags);
7447   mp->host_namespace_set = host_ns_set;
7448   mp->host_if_name_set = host_if_name_set;
7449   mp->host_bridge_set = host_bridge_set;
7450
7451   if (random_mac == 0)
7452     clib_memcpy (mp->mac_address, mac_address, 6);
7453   if (host_mac_addr_set)
7454     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7455   if (host_if_name_set)
7456     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7457   if (host_ns_set)
7458     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7459   if (host_bridge_set)
7460     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7461   if (host_ip4_prefix_set)
7462     {
7463       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7464       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7465     }
7466   if (host_ip6_prefix_set)
7467     {
7468       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7469       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7470     }
7471   if (host_ip4_gw_set)
7472     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7473   if (host_ip6_gw_set)
7474     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7475
7476   vec_free (host_ns);
7477   vec_free (host_if_name);
7478   vec_free (host_bridge);
7479
7480   /* send it... */
7481   S (mp);
7482
7483   /* Wait for a reply... */
7484   W (ret);
7485   return ret;
7486 }
7487
7488 static int
7489 api_tap_delete_v2 (vat_main_t * vam)
7490 {
7491   unformat_input_t *i = vam->input;
7492   vl_api_tap_delete_v2_t *mp;
7493   u32 sw_if_index = ~0;
7494   u8 sw_if_index_set = 0;
7495   int ret;
7496
7497   /* Parse args required to build the message */
7498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7499     {
7500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7501         sw_if_index_set = 1;
7502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7503         sw_if_index_set = 1;
7504       else
7505         break;
7506     }
7507
7508   if (sw_if_index_set == 0)
7509     {
7510       errmsg ("missing vpp interface name. ");
7511       return -99;
7512     }
7513
7514   /* Construct the API message */
7515   M (TAP_DELETE_V2, mp);
7516
7517   mp->sw_if_index = ntohl (sw_if_index);
7518
7519   /* send it... */
7520   S (mp);
7521
7522   /* Wait for a reply... */
7523   W (ret);
7524   return ret;
7525 }
7526
7527 uword
7528 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7529 {
7530   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7531   u32 x[4];
7532
7533   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7534     return 0;
7535
7536   addr->domain = x[0];
7537   addr->bus = x[1];
7538   addr->slot = x[2];
7539   addr->function = x[3];
7540
7541   return 1;
7542 }
7543
7544 static int
7545 api_virtio_pci_create (vat_main_t * vam)
7546 {
7547   unformat_input_t *i = vam->input;
7548   vl_api_virtio_pci_create_t *mp;
7549   u8 mac_address[6];
7550   u8 random_mac = 1;
7551   u8 gso_enabled = 0;
7552   u8 checksum_offload_enabled = 0;
7553   u32 pci_addr = 0;
7554   u64 features = (u64) ~ (0ULL);
7555   int ret;
7556
7557   clib_memset (mac_address, 0, sizeof (mac_address));
7558
7559   /* Parse args required to build the message */
7560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7561     {
7562       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7563         {
7564           random_mac = 0;
7565         }
7566       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7567         ;
7568       else if (unformat (i, "features 0x%llx", &features))
7569         ;
7570       else if (unformat (i, "gso-enabled"))
7571         gso_enabled = 1;
7572       else if (unformat (i, "csum-offload-enabled"))
7573         checksum_offload_enabled = 1;
7574       else
7575         break;
7576     }
7577
7578   if (pci_addr == 0)
7579     {
7580       errmsg ("pci address must be non zero. ");
7581       return -99;
7582     }
7583
7584   /* Construct the API message */
7585   M (VIRTIO_PCI_CREATE, mp);
7586
7587   mp->use_random_mac = random_mac;
7588
7589   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7590   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7591   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7592   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7593
7594   mp->features = clib_host_to_net_u64 (features);
7595   mp->gso_enabled = gso_enabled;
7596   mp->checksum_offload_enabled = checksum_offload_enabled;
7597
7598   if (random_mac == 0)
7599     clib_memcpy (mp->mac_address, mac_address, 6);
7600
7601   /* send it... */
7602   S (mp);
7603
7604   /* Wait for a reply... */
7605   W (ret);
7606   return ret;
7607 }
7608
7609 static int
7610 api_virtio_pci_delete (vat_main_t * vam)
7611 {
7612   unformat_input_t *i = vam->input;
7613   vl_api_virtio_pci_delete_t *mp;
7614   u32 sw_if_index = ~0;
7615   u8 sw_if_index_set = 0;
7616   int ret;
7617
7618   /* Parse args required to build the message */
7619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7620     {
7621       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7622         sw_if_index_set = 1;
7623       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7624         sw_if_index_set = 1;
7625       else
7626         break;
7627     }
7628
7629   if (sw_if_index_set == 0)
7630     {
7631       errmsg ("missing vpp interface name. ");
7632       return -99;
7633     }
7634
7635   /* Construct the API message */
7636   M (VIRTIO_PCI_DELETE, mp);
7637
7638   mp->sw_if_index = htonl (sw_if_index);
7639
7640   /* send it... */
7641   S (mp);
7642
7643   /* Wait for a reply... */
7644   W (ret);
7645   return ret;
7646 }
7647
7648 static int
7649 api_bond_create (vat_main_t * vam)
7650 {
7651   unformat_input_t *i = vam->input;
7652   vl_api_bond_create_t *mp;
7653   u8 mac_address[6];
7654   u8 custom_mac = 0;
7655   int ret;
7656   u8 mode;
7657   u8 lb;
7658   u8 mode_is_set = 0;
7659   u32 id = ~0;
7660   u8 numa_only = 0;
7661
7662   clib_memset (mac_address, 0, sizeof (mac_address));
7663   lb = BOND_LB_L2;
7664
7665   /* Parse args required to build the message */
7666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7667     {
7668       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7669         mode_is_set = 1;
7670       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7671                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7672         ;
7673       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7674                          mac_address))
7675         custom_mac = 1;
7676       else if (unformat (i, "numa-only"))
7677         numa_only = 1;
7678       else if (unformat (i, "id %u", &id))
7679         ;
7680       else
7681         break;
7682     }
7683
7684   if (mode_is_set == 0)
7685     {
7686       errmsg ("Missing bond mode. ");
7687       return -99;
7688     }
7689
7690   /* Construct the API message */
7691   M (BOND_CREATE, mp);
7692
7693   mp->use_custom_mac = custom_mac;
7694
7695   mp->mode = htonl (mode);
7696   mp->lb = htonl (lb);
7697   mp->id = htonl (id);
7698   mp->numa_only = numa_only;
7699
7700   if (custom_mac)
7701     clib_memcpy (mp->mac_address, mac_address, 6);
7702
7703   /* send it... */
7704   S (mp);
7705
7706   /* Wait for a reply... */
7707   W (ret);
7708   return ret;
7709 }
7710
7711 static int
7712 api_bond_delete (vat_main_t * vam)
7713 {
7714   unformat_input_t *i = vam->input;
7715   vl_api_bond_delete_t *mp;
7716   u32 sw_if_index = ~0;
7717   u8 sw_if_index_set = 0;
7718   int ret;
7719
7720   /* Parse args required to build the message */
7721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7722     {
7723       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7724         sw_if_index_set = 1;
7725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7726         sw_if_index_set = 1;
7727       else
7728         break;
7729     }
7730
7731   if (sw_if_index_set == 0)
7732     {
7733       errmsg ("missing vpp interface name. ");
7734       return -99;
7735     }
7736
7737   /* Construct the API message */
7738   M (BOND_DELETE, mp);
7739
7740   mp->sw_if_index = ntohl (sw_if_index);
7741
7742   /* send it... */
7743   S (mp);
7744
7745   /* Wait for a reply... */
7746   W (ret);
7747   return ret;
7748 }
7749
7750 static int
7751 api_bond_enslave (vat_main_t * vam)
7752 {
7753   unformat_input_t *i = vam->input;
7754   vl_api_bond_enslave_t *mp;
7755   u32 bond_sw_if_index;
7756   int ret;
7757   u8 is_passive;
7758   u8 is_long_timeout;
7759   u32 bond_sw_if_index_is_set = 0;
7760   u32 sw_if_index;
7761   u8 sw_if_index_is_set = 0;
7762
7763   /* Parse args required to build the message */
7764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7765     {
7766       if (unformat (i, "sw_if_index %d", &sw_if_index))
7767         sw_if_index_is_set = 1;
7768       else if (unformat (i, "bond %u", &bond_sw_if_index))
7769         bond_sw_if_index_is_set = 1;
7770       else if (unformat (i, "passive %d", &is_passive))
7771         ;
7772       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7773         ;
7774       else
7775         break;
7776     }
7777
7778   if (bond_sw_if_index_is_set == 0)
7779     {
7780       errmsg ("Missing bond sw_if_index. ");
7781       return -99;
7782     }
7783   if (sw_if_index_is_set == 0)
7784     {
7785       errmsg ("Missing slave sw_if_index. ");
7786       return -99;
7787     }
7788
7789   /* Construct the API message */
7790   M (BOND_ENSLAVE, mp);
7791
7792   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7793   mp->sw_if_index = ntohl (sw_if_index);
7794   mp->is_long_timeout = is_long_timeout;
7795   mp->is_passive = is_passive;
7796
7797   /* send it... */
7798   S (mp);
7799
7800   /* Wait for a reply... */
7801   W (ret);
7802   return ret;
7803 }
7804
7805 static int
7806 api_bond_detach_slave (vat_main_t * vam)
7807 {
7808   unformat_input_t *i = vam->input;
7809   vl_api_bond_detach_slave_t *mp;
7810   u32 sw_if_index = ~0;
7811   u8 sw_if_index_set = 0;
7812   int ret;
7813
7814   /* Parse args required to build the message */
7815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7816     {
7817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7818         sw_if_index_set = 1;
7819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7820         sw_if_index_set = 1;
7821       else
7822         break;
7823     }
7824
7825   if (sw_if_index_set == 0)
7826     {
7827       errmsg ("missing vpp interface name. ");
7828       return -99;
7829     }
7830
7831   /* Construct the API message */
7832   M (BOND_DETACH_SLAVE, mp);
7833
7834   mp->sw_if_index = ntohl (sw_if_index);
7835
7836   /* send it... */
7837   S (mp);
7838
7839   /* Wait for a reply... */
7840   W (ret);
7841   return ret;
7842 }
7843
7844 static int
7845 api_ip_table_add_del (vat_main_t * vam)
7846 {
7847   unformat_input_t *i = vam->input;
7848   vl_api_ip_table_add_del_t *mp;
7849   u32 table_id = ~0;
7850   u8 is_ipv6 = 0;
7851   u8 is_add = 1;
7852   int ret = 0;
7853
7854   /* Parse args required to build the message */
7855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7856     {
7857       if (unformat (i, "ipv6"))
7858         is_ipv6 = 1;
7859       else if (unformat (i, "del"))
7860         is_add = 0;
7861       else if (unformat (i, "add"))
7862         is_add = 1;
7863       else if (unformat (i, "table %d", &table_id))
7864         ;
7865       else
7866         {
7867           clib_warning ("parse error '%U'", format_unformat_error, i);
7868           return -99;
7869         }
7870     }
7871
7872   if (~0 == table_id)
7873     {
7874       errmsg ("missing table-ID");
7875       return -99;
7876     }
7877
7878   /* Construct the API message */
7879   M (IP_TABLE_ADD_DEL, mp);
7880
7881   mp->table.table_id = ntohl (table_id);
7882   mp->table.is_ip6 = is_ipv6;
7883   mp->is_add = is_add;
7884
7885   /* send it... */
7886   S (mp);
7887
7888   /* Wait for a reply... */
7889   W (ret);
7890
7891   return ret;
7892 }
7893
7894 uword
7895 unformat_fib_path (unformat_input_t * input, va_list * args)
7896 {
7897   vat_main_t *vam = va_arg (*args, vat_main_t *);
7898   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7899   u32 weight, preference;
7900   mpls_label_t out_label;
7901
7902   clib_memset (path, 0, sizeof (*path));
7903   path->weight = 1;
7904   path->sw_if_index = ~0;
7905   path->rpf_id = ~0;
7906   path->n_labels = 0;
7907
7908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7909     {
7910       if (unformat (input, "%U %U",
7911                     unformat_vl_api_ip4_address,
7912                     &path->nh.address.ip4,
7913                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7914         {
7915           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7916         }
7917       else if (unformat (input, "%U %U",
7918                          unformat_vl_api_ip6_address,
7919                          &path->nh.address.ip6,
7920                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7921         {
7922           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7923         }
7924       else if (unformat (input, "weight %u", &weight))
7925         {
7926           path->weight = weight;
7927         }
7928       else if (unformat (input, "preference %u", &preference))
7929         {
7930           path->preference = preference;
7931         }
7932       else if (unformat (input, "%U next-hop-table %d",
7933                          unformat_vl_api_ip4_address,
7934                          &path->nh.address.ip4, &path->table_id))
7935         {
7936           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7937         }
7938       else if (unformat (input, "%U next-hop-table %d",
7939                          unformat_vl_api_ip6_address,
7940                          &path->nh.address.ip6, &path->table_id))
7941         {
7942           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7943         }
7944       else if (unformat (input, "%U",
7945                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7946         {
7947           /*
7948            * the recursive next-hops are by default in the default table
7949            */
7950           path->table_id = 0;
7951           path->sw_if_index = ~0;
7952           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7953         }
7954       else if (unformat (input, "%U",
7955                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7956         {
7957           /*
7958            * the recursive next-hops are by default in the default table
7959            */
7960           path->table_id = 0;
7961           path->sw_if_index = ~0;
7962           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7963         }
7964       else if (unformat (input, "resolve-via-host"))
7965         {
7966           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7967         }
7968       else if (unformat (input, "resolve-via-attached"))
7969         {
7970           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7971         }
7972       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7973         {
7974           path->type = FIB_API_PATH_TYPE_LOCAL;
7975           path->sw_if_index = ~0;
7976           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7977         }
7978       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7979         {
7980           path->type = FIB_API_PATH_TYPE_LOCAL;
7981           path->sw_if_index = ~0;
7982           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7983         }
7984       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7985         ;
7986       else if (unformat (input, "via-label %d", &path->nh.via_label))
7987         {
7988           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7989           path->sw_if_index = ~0;
7990         }
7991       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7992         {
7993           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7994           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7995         }
7996       else if (unformat (input, "local"))
7997         {
7998           path->type = FIB_API_PATH_TYPE_LOCAL;
7999         }
8000       else if (unformat (input, "out-labels"))
8001         {
8002           while (unformat (input, "%d", &out_label))
8003             {
8004               path->label_stack[path->n_labels].label = out_label;
8005               path->label_stack[path->n_labels].is_uniform = 0;
8006               path->label_stack[path->n_labels].ttl = 64;
8007               path->n_labels++;
8008             }
8009         }
8010       else if (unformat (input, "via"))
8011         {
8012           /* new path, back up and return */
8013           unformat_put_input (input);
8014           unformat_put_input (input);
8015           unformat_put_input (input);
8016           unformat_put_input (input);
8017           break;
8018         }
8019       else
8020         {
8021           return (0);
8022         }
8023     }
8024
8025   path->proto = ntohl (path->proto);
8026   path->type = ntohl (path->type);
8027   path->flags = ntohl (path->flags);
8028   path->table_id = ntohl (path->table_id);
8029   path->sw_if_index = ntohl (path->sw_if_index);
8030
8031   return (1);
8032 }
8033
8034 static int
8035 api_ip_route_add_del (vat_main_t * vam)
8036 {
8037   unformat_input_t *i = vam->input;
8038   vl_api_ip_route_add_del_t *mp;
8039   u32 vrf_id = 0;
8040   u8 is_add = 1;
8041   u8 is_multipath = 0;
8042   u8 prefix_set = 0;
8043   u8 path_count = 0;
8044   vl_api_prefix_t pfx = { };
8045   vl_api_fib_path_t paths[8];
8046   int count = 1;
8047   int j;
8048   f64 before = 0;
8049   u32 random_add_del = 0;
8050   u32 *random_vector = 0;
8051   u32 random_seed = 0xdeaddabe;
8052
8053   /* Parse args required to build the message */
8054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8055     {
8056       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8057         prefix_set = 1;
8058       else if (unformat (i, "del"))
8059         is_add = 0;
8060       else if (unformat (i, "add"))
8061         is_add = 1;
8062       else if (unformat (i, "vrf %d", &vrf_id))
8063         ;
8064       else if (unformat (i, "count %d", &count))
8065         ;
8066       else if (unformat (i, "random"))
8067         random_add_del = 1;
8068       else if (unformat (i, "multipath"))
8069         is_multipath = 1;
8070       else if (unformat (i, "seed %d", &random_seed))
8071         ;
8072       else
8073         if (unformat
8074             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8075         {
8076           path_count++;
8077           if (8 == path_count)
8078             {
8079               errmsg ("max 8 paths");
8080               return -99;
8081             }
8082         }
8083       else
8084         {
8085           clib_warning ("parse error '%U'", format_unformat_error, i);
8086           return -99;
8087         }
8088     }
8089
8090   if (!path_count)
8091     {
8092       errmsg ("specify a path; via ...");
8093       return -99;
8094     }
8095   if (prefix_set == 0)
8096     {
8097       errmsg ("missing prefix");
8098       return -99;
8099     }
8100
8101   /* Generate a pile of unique, random routes */
8102   if (random_add_del)
8103     {
8104       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8105       u32 this_random_address;
8106       uword *random_hash;
8107
8108       random_hash = hash_create (count, sizeof (uword));
8109
8110       hash_set (random_hash, i->as_u32, 1);
8111       for (j = 0; j <= count; j++)
8112         {
8113           do
8114             {
8115               this_random_address = random_u32 (&random_seed);
8116               this_random_address =
8117                 clib_host_to_net_u32 (this_random_address);
8118             }
8119           while (hash_get (random_hash, this_random_address));
8120           vec_add1 (random_vector, this_random_address);
8121           hash_set (random_hash, this_random_address, 1);
8122         }
8123       hash_free (random_hash);
8124       set_ip4_address (&pfx.address, random_vector[0]);
8125     }
8126
8127   if (count > 1)
8128     {
8129       /* Turn on async mode */
8130       vam->async_mode = 1;
8131       vam->async_errors = 0;
8132       before = vat_time_now (vam);
8133     }
8134
8135   for (j = 0; j < count; j++)
8136     {
8137       /* Construct the API message */
8138       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8139
8140       mp->is_add = is_add;
8141       mp->is_multipath = is_multipath;
8142
8143       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8144       mp->route.table_id = ntohl (vrf_id);
8145       mp->route.n_paths = path_count;
8146
8147       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8148
8149       if (random_add_del)
8150         set_ip4_address (&pfx.address, random_vector[j + 1]);
8151       else
8152         increment_address (&pfx.address);
8153       /* send it... */
8154       S (mp);
8155       /* If we receive SIGTERM, stop now... */
8156       if (vam->do_exit)
8157         break;
8158     }
8159
8160   /* When testing multiple add/del ops, use a control-ping to sync */
8161   if (count > 1)
8162     {
8163       vl_api_control_ping_t *mp_ping;
8164       f64 after;
8165       f64 timeout;
8166
8167       /* Shut off async mode */
8168       vam->async_mode = 0;
8169
8170       MPING (CONTROL_PING, mp_ping);
8171       S (mp_ping);
8172
8173       timeout = vat_time_now (vam) + 1.0;
8174       while (vat_time_now (vam) < timeout)
8175         if (vam->result_ready == 1)
8176           goto out;
8177       vam->retval = -99;
8178
8179     out:
8180       if (vam->retval == -99)
8181         errmsg ("timeout");
8182
8183       if (vam->async_errors > 0)
8184         {
8185           errmsg ("%d asynchronous errors", vam->async_errors);
8186           vam->retval = -98;
8187         }
8188       vam->async_errors = 0;
8189       after = vat_time_now (vam);
8190
8191       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8192       if (j > 0)
8193         count = j;
8194
8195       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8196              count, after - before, count / (after - before));
8197     }
8198   else
8199     {
8200       int ret;
8201
8202       /* Wait for a reply... */
8203       W (ret);
8204       return ret;
8205     }
8206
8207   /* Return the good/bad news */
8208   return (vam->retval);
8209 }
8210
8211 static int
8212 api_ip_mroute_add_del (vat_main_t * vam)
8213 {
8214   unformat_input_t *i = vam->input;
8215   u8 path_set = 0, prefix_set = 0, is_add = 1;
8216   vl_api_ip_mroute_add_del_t *mp;
8217   mfib_entry_flags_t eflags = 0;
8218   vl_api_mfib_path_t path;
8219   vl_api_mprefix_t pfx = { };
8220   u32 vrf_id = 0;
8221   int ret;
8222
8223   /* Parse args required to build the message */
8224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8225     {
8226       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8227         {
8228           prefix_set = 1;
8229           pfx.grp_address_length = htons (pfx.grp_address_length);
8230         }
8231       else if (unformat (i, "del"))
8232         is_add = 0;
8233       else if (unformat (i, "add"))
8234         is_add = 1;
8235       else if (unformat (i, "vrf %d", &vrf_id))
8236         ;
8237       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8238         path.itf_flags = htonl (path.itf_flags);
8239       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8240         ;
8241       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8242         path_set = 1;
8243       else
8244         {
8245           clib_warning ("parse error '%U'", format_unformat_error, i);
8246           return -99;
8247         }
8248     }
8249
8250   if (prefix_set == 0)
8251     {
8252       errmsg ("missing addresses\n");
8253       return -99;
8254     }
8255   if (path_set == 0)
8256     {
8257       errmsg ("missing path\n");
8258       return -99;
8259     }
8260
8261   /* Construct the API message */
8262   M (IP_MROUTE_ADD_DEL, mp);
8263
8264   mp->is_add = is_add;
8265   mp->is_multipath = 1;
8266
8267   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8268   mp->route.table_id = htonl (vrf_id);
8269   mp->route.n_paths = 1;
8270   mp->route.entry_flags = htonl (eflags);
8271
8272   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8273
8274   /* send it... */
8275   S (mp);
8276   /* Wait for a reply... */
8277   W (ret);
8278   return ret;
8279 }
8280
8281 static int
8282 api_mpls_table_add_del (vat_main_t * vam)
8283 {
8284   unformat_input_t *i = vam->input;
8285   vl_api_mpls_table_add_del_t *mp;
8286   u32 table_id = ~0;
8287   u8 is_add = 1;
8288   int ret = 0;
8289
8290   /* Parse args required to build the message */
8291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8292     {
8293       if (unformat (i, "table %d", &table_id))
8294         ;
8295       else if (unformat (i, "del"))
8296         is_add = 0;
8297       else if (unformat (i, "add"))
8298         is_add = 1;
8299       else
8300         {
8301           clib_warning ("parse error '%U'", format_unformat_error, i);
8302           return -99;
8303         }
8304     }
8305
8306   if (~0 == table_id)
8307     {
8308       errmsg ("missing table-ID");
8309       return -99;
8310     }
8311
8312   /* Construct the API message */
8313   M (MPLS_TABLE_ADD_DEL, mp);
8314
8315   mp->mt_table.mt_table_id = ntohl (table_id);
8316   mp->mt_is_add = is_add;
8317
8318   /* send it... */
8319   S (mp);
8320
8321   /* Wait for a reply... */
8322   W (ret);
8323
8324   return ret;
8325 }
8326
8327 static int
8328 api_mpls_route_add_del (vat_main_t * vam)
8329 {
8330   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8331   mpls_label_t local_label = MPLS_LABEL_INVALID;
8332   unformat_input_t *i = vam->input;
8333   vl_api_mpls_route_add_del_t *mp;
8334   vl_api_fib_path_t paths[8];
8335   int count = 1, j;
8336   f64 before = 0;
8337
8338   /* Parse args required to build the message */
8339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8340     {
8341       if (unformat (i, "%d", &local_label))
8342         ;
8343       else if (unformat (i, "eos"))
8344         is_eos = 1;
8345       else if (unformat (i, "non-eos"))
8346         is_eos = 0;
8347       else if (unformat (i, "del"))
8348         is_add = 0;
8349       else if (unformat (i, "add"))
8350         is_add = 1;
8351       else if (unformat (i, "multipath"))
8352         is_multipath = 1;
8353       else if (unformat (i, "count %d", &count))
8354         ;
8355       else
8356         if (unformat
8357             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8358         {
8359           path_count++;
8360           if (8 == path_count)
8361             {
8362               errmsg ("max 8 paths");
8363               return -99;
8364             }
8365         }
8366       else
8367         {
8368           clib_warning ("parse error '%U'", format_unformat_error, i);
8369           return -99;
8370         }
8371     }
8372
8373   if (!path_count)
8374     {
8375       errmsg ("specify a path; via ...");
8376       return -99;
8377     }
8378
8379   if (MPLS_LABEL_INVALID == local_label)
8380     {
8381       errmsg ("missing label");
8382       return -99;
8383     }
8384
8385   if (count > 1)
8386     {
8387       /* Turn on async mode */
8388       vam->async_mode = 1;
8389       vam->async_errors = 0;
8390       before = vat_time_now (vam);
8391     }
8392
8393   for (j = 0; j < count; j++)
8394     {
8395       /* Construct the API message */
8396       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8397
8398       mp->mr_is_add = is_add;
8399       mp->mr_is_multipath = is_multipath;
8400
8401       mp->mr_route.mr_label = local_label;
8402       mp->mr_route.mr_eos = is_eos;
8403       mp->mr_route.mr_table_id = 0;
8404       mp->mr_route.mr_n_paths = path_count;
8405
8406       clib_memcpy (&mp->mr_route.mr_paths, paths,
8407                    sizeof (paths[0]) * path_count);
8408
8409       local_label++;
8410
8411       /* send it... */
8412       S (mp);
8413       /* If we receive SIGTERM, stop now... */
8414       if (vam->do_exit)
8415         break;
8416     }
8417
8418   /* When testing multiple add/del ops, use a control-ping to sync */
8419   if (count > 1)
8420     {
8421       vl_api_control_ping_t *mp_ping;
8422       f64 after;
8423       f64 timeout;
8424
8425       /* Shut off async mode */
8426       vam->async_mode = 0;
8427
8428       MPING (CONTROL_PING, mp_ping);
8429       S (mp_ping);
8430
8431       timeout = vat_time_now (vam) + 1.0;
8432       while (vat_time_now (vam) < timeout)
8433         if (vam->result_ready == 1)
8434           goto out;
8435       vam->retval = -99;
8436
8437     out:
8438       if (vam->retval == -99)
8439         errmsg ("timeout");
8440
8441       if (vam->async_errors > 0)
8442         {
8443           errmsg ("%d asynchronous errors", vam->async_errors);
8444           vam->retval = -98;
8445         }
8446       vam->async_errors = 0;
8447       after = vat_time_now (vam);
8448
8449       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8450       if (j > 0)
8451         count = j;
8452
8453       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8454              count, after - before, count / (after - before));
8455     }
8456   else
8457     {
8458       int ret;
8459
8460       /* Wait for a reply... */
8461       W (ret);
8462       return ret;
8463     }
8464
8465   /* Return the good/bad news */
8466   return (vam->retval);
8467   return (0);
8468 }
8469
8470 static int
8471 api_mpls_ip_bind_unbind (vat_main_t * vam)
8472 {
8473   unformat_input_t *i = vam->input;
8474   vl_api_mpls_ip_bind_unbind_t *mp;
8475   u32 ip_table_id = 0;
8476   u8 is_bind = 1;
8477   vl_api_prefix_t pfx;
8478   u8 prefix_set = 0;
8479   mpls_label_t local_label = MPLS_LABEL_INVALID;
8480   int ret;
8481
8482   /* Parse args required to build the message */
8483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8484     {
8485       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8486         prefix_set = 1;
8487       else if (unformat (i, "%d", &local_label))
8488         ;
8489       else if (unformat (i, "table-id %d", &ip_table_id))
8490         ;
8491       else if (unformat (i, "unbind"))
8492         is_bind = 0;
8493       else if (unformat (i, "bind"))
8494         is_bind = 1;
8495       else
8496         {
8497           clib_warning ("parse error '%U'", format_unformat_error, i);
8498           return -99;
8499         }
8500     }
8501
8502   if (!prefix_set)
8503     {
8504       errmsg ("IP prefix not set");
8505       return -99;
8506     }
8507
8508   if (MPLS_LABEL_INVALID == local_label)
8509     {
8510       errmsg ("missing label");
8511       return -99;
8512     }
8513
8514   /* Construct the API message */
8515   M (MPLS_IP_BIND_UNBIND, mp);
8516
8517   mp->mb_is_bind = is_bind;
8518   mp->mb_ip_table_id = ntohl (ip_table_id);
8519   mp->mb_mpls_table_id = 0;
8520   mp->mb_label = ntohl (local_label);
8521   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8522
8523   /* send it... */
8524   S (mp);
8525
8526   /* Wait for a reply... */
8527   W (ret);
8528   return ret;
8529   return (0);
8530 }
8531
8532 static int
8533 api_sr_mpls_policy_add (vat_main_t * vam)
8534 {
8535   unformat_input_t *i = vam->input;
8536   vl_api_sr_mpls_policy_add_t *mp;
8537   u32 bsid = 0;
8538   u32 weight = 1;
8539   u8 type = 0;
8540   u8 n_segments = 0;
8541   u32 sid;
8542   u32 *segments = NULL;
8543   int ret;
8544
8545   /* Parse args required to build the message */
8546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8547     {
8548       if (unformat (i, "bsid %d", &bsid))
8549         ;
8550       else if (unformat (i, "weight %d", &weight))
8551         ;
8552       else if (unformat (i, "spray"))
8553         type = 1;
8554       else if (unformat (i, "next %d", &sid))
8555         {
8556           n_segments += 1;
8557           vec_add1 (segments, htonl (sid));
8558         }
8559       else
8560         {
8561           clib_warning ("parse error '%U'", format_unformat_error, i);
8562           return -99;
8563         }
8564     }
8565
8566   if (bsid == 0)
8567     {
8568       errmsg ("bsid not set");
8569       return -99;
8570     }
8571
8572   if (n_segments == 0)
8573     {
8574       errmsg ("no sid in segment stack");
8575       return -99;
8576     }
8577
8578   /* Construct the API message */
8579   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8580
8581   mp->bsid = htonl (bsid);
8582   mp->weight = htonl (weight);
8583   mp->is_spray = type;
8584   mp->n_segments = n_segments;
8585   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8586   vec_free (segments);
8587
8588   /* send it... */
8589   S (mp);
8590
8591   /* Wait for a reply... */
8592   W (ret);
8593   return ret;
8594 }
8595
8596 static int
8597 api_sr_mpls_policy_del (vat_main_t * vam)
8598 {
8599   unformat_input_t *i = vam->input;
8600   vl_api_sr_mpls_policy_del_t *mp;
8601   u32 bsid = 0;
8602   int ret;
8603
8604   /* Parse args required to build the message */
8605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8606     {
8607       if (unformat (i, "bsid %d", &bsid))
8608         ;
8609       else
8610         {
8611           clib_warning ("parse error '%U'", format_unformat_error, i);
8612           return -99;
8613         }
8614     }
8615
8616   if (bsid == 0)
8617     {
8618       errmsg ("bsid not set");
8619       return -99;
8620     }
8621
8622   /* Construct the API message */
8623   M (SR_MPLS_POLICY_DEL, mp);
8624
8625   mp->bsid = htonl (bsid);
8626
8627   /* send it... */
8628   S (mp);
8629
8630   /* Wait for a reply... */
8631   W (ret);
8632   return ret;
8633 }
8634
8635 static int
8636 api_bier_table_add_del (vat_main_t * vam)
8637 {
8638   unformat_input_t *i = vam->input;
8639   vl_api_bier_table_add_del_t *mp;
8640   u8 is_add = 1;
8641   u32 set = 0, sub_domain = 0, hdr_len = 3;
8642   mpls_label_t local_label = MPLS_LABEL_INVALID;
8643   int ret;
8644
8645   /* Parse args required to build the message */
8646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8647     {
8648       if (unformat (i, "sub-domain %d", &sub_domain))
8649         ;
8650       else if (unformat (i, "set %d", &set))
8651         ;
8652       else if (unformat (i, "label %d", &local_label))
8653         ;
8654       else if (unformat (i, "hdr-len %d", &hdr_len))
8655         ;
8656       else if (unformat (i, "add"))
8657         is_add = 1;
8658       else if (unformat (i, "del"))
8659         is_add = 0;
8660       else
8661         {
8662           clib_warning ("parse error '%U'", format_unformat_error, i);
8663           return -99;
8664         }
8665     }
8666
8667   if (MPLS_LABEL_INVALID == local_label)
8668     {
8669       errmsg ("missing label\n");
8670       return -99;
8671     }
8672
8673   /* Construct the API message */
8674   M (BIER_TABLE_ADD_DEL, mp);
8675
8676   mp->bt_is_add = is_add;
8677   mp->bt_label = ntohl (local_label);
8678   mp->bt_tbl_id.bt_set = set;
8679   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8680   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8681
8682   /* send it... */
8683   S (mp);
8684
8685   /* Wait for a reply... */
8686   W (ret);
8687
8688   return (ret);
8689 }
8690
8691 static int
8692 api_bier_route_add_del (vat_main_t * vam)
8693 {
8694   unformat_input_t *i = vam->input;
8695   vl_api_bier_route_add_del_t *mp;
8696   u8 is_add = 1;
8697   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8698   ip4_address_t v4_next_hop_address;
8699   ip6_address_t v6_next_hop_address;
8700   u8 next_hop_set = 0;
8701   u8 next_hop_proto_is_ip4 = 1;
8702   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8703   int ret;
8704
8705   /* Parse args required to build the message */
8706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8707     {
8708       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8709         {
8710           next_hop_proto_is_ip4 = 1;
8711           next_hop_set = 1;
8712         }
8713       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8714         {
8715           next_hop_proto_is_ip4 = 0;
8716           next_hop_set = 1;
8717         }
8718       if (unformat (i, "sub-domain %d", &sub_domain))
8719         ;
8720       else if (unformat (i, "set %d", &set))
8721         ;
8722       else if (unformat (i, "hdr-len %d", &hdr_len))
8723         ;
8724       else if (unformat (i, "bp %d", &bp))
8725         ;
8726       else if (unformat (i, "add"))
8727         is_add = 1;
8728       else if (unformat (i, "del"))
8729         is_add = 0;
8730       else if (unformat (i, "out-label %d", &next_hop_out_label))
8731         ;
8732       else
8733         {
8734           clib_warning ("parse error '%U'", format_unformat_error, i);
8735           return -99;
8736         }
8737     }
8738
8739   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8740     {
8741       errmsg ("next hop / label set\n");
8742       return -99;
8743     }
8744   if (0 == bp)
8745     {
8746       errmsg ("bit=position not set\n");
8747       return -99;
8748     }
8749
8750   /* Construct the API message */
8751   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8752
8753   mp->br_is_add = is_add;
8754   mp->br_route.br_tbl_id.bt_set = set;
8755   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8756   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8757   mp->br_route.br_bp = ntohs (bp);
8758   mp->br_route.br_n_paths = 1;
8759   mp->br_route.br_paths[0].n_labels = 1;
8760   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8761   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8762                                     FIB_API_PATH_NH_PROTO_IP4 :
8763                                     FIB_API_PATH_NH_PROTO_IP6);
8764
8765   if (next_hop_proto_is_ip4)
8766     {
8767       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8768                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8769     }
8770   else
8771     {
8772       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8773                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8774     }
8775
8776   /* send it... */
8777   S (mp);
8778
8779   /* Wait for a reply... */
8780   W (ret);
8781
8782   return (ret);
8783 }
8784
8785 static int
8786 api_mpls_tunnel_add_del (vat_main_t * vam)
8787 {
8788   unformat_input_t *i = vam->input;
8789   vl_api_mpls_tunnel_add_del_t *mp;
8790
8791   vl_api_fib_path_t paths[8];
8792   u32 sw_if_index = ~0;
8793   u8 path_count = 0;
8794   u8 l2_only = 0;
8795   u8 is_add = 1;
8796   int ret;
8797
8798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8799     {
8800       if (unformat (i, "add"))
8801         is_add = 1;
8802       else
8803         if (unformat
8804             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8805         is_add = 0;
8806       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8807         is_add = 0;
8808       else if (unformat (i, "l2-only"))
8809         l2_only = 1;
8810       else
8811         if (unformat
8812             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8813         {
8814           path_count++;
8815           if (8 == path_count)
8816             {
8817               errmsg ("max 8 paths");
8818               return -99;
8819             }
8820         }
8821       else
8822         {
8823           clib_warning ("parse error '%U'", format_unformat_error, i);
8824           return -99;
8825         }
8826     }
8827
8828   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8829
8830   mp->mt_is_add = is_add;
8831   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8832   mp->mt_tunnel.mt_l2_only = l2_only;
8833   mp->mt_tunnel.mt_is_multicast = 0;
8834   mp->mt_tunnel.mt_n_paths = path_count;
8835
8836   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8837                sizeof (paths[0]) * path_count);
8838
8839   S (mp);
8840   W (ret);
8841   return ret;
8842 }
8843
8844 static int
8845 api_sw_interface_set_unnumbered (vat_main_t * vam)
8846 {
8847   unformat_input_t *i = vam->input;
8848   vl_api_sw_interface_set_unnumbered_t *mp;
8849   u32 sw_if_index;
8850   u32 unnum_sw_index = ~0;
8851   u8 is_add = 1;
8852   u8 sw_if_index_set = 0;
8853   int ret;
8854
8855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8856     {
8857       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8858         sw_if_index_set = 1;
8859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8860         sw_if_index_set = 1;
8861       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8862         ;
8863       else if (unformat (i, "del"))
8864         is_add = 0;
8865       else
8866         {
8867           clib_warning ("parse error '%U'", format_unformat_error, i);
8868           return -99;
8869         }
8870     }
8871
8872   if (sw_if_index_set == 0)
8873     {
8874       errmsg ("missing interface name or sw_if_index");
8875       return -99;
8876     }
8877
8878   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8879
8880   mp->sw_if_index = ntohl (sw_if_index);
8881   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8882   mp->is_add = is_add;
8883
8884   S (mp);
8885   W (ret);
8886   return ret;
8887 }
8888
8889
8890 static int
8891 api_create_vlan_subif (vat_main_t * vam)
8892 {
8893   unformat_input_t *i = vam->input;
8894   vl_api_create_vlan_subif_t *mp;
8895   u32 sw_if_index;
8896   u8 sw_if_index_set = 0;
8897   u32 vlan_id;
8898   u8 vlan_id_set = 0;
8899   int ret;
8900
8901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8902     {
8903       if (unformat (i, "sw_if_index %d", &sw_if_index))
8904         sw_if_index_set = 1;
8905       else
8906         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8907         sw_if_index_set = 1;
8908       else if (unformat (i, "vlan %d", &vlan_id))
8909         vlan_id_set = 1;
8910       else
8911         {
8912           clib_warning ("parse error '%U'", format_unformat_error, i);
8913           return -99;
8914         }
8915     }
8916
8917   if (sw_if_index_set == 0)
8918     {
8919       errmsg ("missing interface name or sw_if_index");
8920       return -99;
8921     }
8922
8923   if (vlan_id_set == 0)
8924     {
8925       errmsg ("missing vlan_id");
8926       return -99;
8927     }
8928   M (CREATE_VLAN_SUBIF, mp);
8929
8930   mp->sw_if_index = ntohl (sw_if_index);
8931   mp->vlan_id = ntohl (vlan_id);
8932
8933   S (mp);
8934   W (ret);
8935   return ret;
8936 }
8937
8938 #define foreach_create_subif_bit                \
8939 _(no_tags)                                      \
8940 _(one_tag)                                      \
8941 _(two_tags)                                     \
8942 _(dot1ad)                                       \
8943 _(exact_match)                                  \
8944 _(default_sub)                                  \
8945 _(outer_vlan_id_any)                            \
8946 _(inner_vlan_id_any)
8947
8948 #define foreach_create_subif_flag               \
8949 _(0, "no_tags")                                 \
8950 _(1, "one_tag")                                 \
8951 _(2, "two_tags")                                \
8952 _(3, "dot1ad")                                  \
8953 _(4, "exact_match")                             \
8954 _(5, "default_sub")                             \
8955 _(6, "outer_vlan_id_any")                       \
8956 _(7, "inner_vlan_id_any")
8957
8958 static int
8959 api_create_subif (vat_main_t * vam)
8960 {
8961   unformat_input_t *i = vam->input;
8962   vl_api_create_subif_t *mp;
8963   u32 sw_if_index;
8964   u8 sw_if_index_set = 0;
8965   u32 sub_id;
8966   u8 sub_id_set = 0;
8967   u32 __attribute__ ((unused)) no_tags = 0;
8968   u32 __attribute__ ((unused)) one_tag = 0;
8969   u32 __attribute__ ((unused)) two_tags = 0;
8970   u32 __attribute__ ((unused)) dot1ad = 0;
8971   u32 __attribute__ ((unused)) exact_match = 0;
8972   u32 __attribute__ ((unused)) default_sub = 0;
8973   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8974   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8975   u32 tmp;
8976   u16 outer_vlan_id = 0;
8977   u16 inner_vlan_id = 0;
8978   int ret;
8979
8980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8981     {
8982       if (unformat (i, "sw_if_index %d", &sw_if_index))
8983         sw_if_index_set = 1;
8984       else
8985         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8986         sw_if_index_set = 1;
8987       else if (unformat (i, "sub_id %d", &sub_id))
8988         sub_id_set = 1;
8989       else if (unformat (i, "outer_vlan_id %d", &tmp))
8990         outer_vlan_id = tmp;
8991       else if (unformat (i, "inner_vlan_id %d", &tmp))
8992         inner_vlan_id = tmp;
8993
8994 #define _(a) else if (unformat (i, #a)) a = 1 ;
8995       foreach_create_subif_bit
8996 #undef _
8997         else
8998         {
8999           clib_warning ("parse error '%U'", format_unformat_error, i);
9000           return -99;
9001         }
9002     }
9003
9004   if (sw_if_index_set == 0)
9005     {
9006       errmsg ("missing interface name or sw_if_index");
9007       return -99;
9008     }
9009
9010   if (sub_id_set == 0)
9011     {
9012       errmsg ("missing sub_id");
9013       return -99;
9014     }
9015   M (CREATE_SUBIF, mp);
9016
9017   mp->sw_if_index = ntohl (sw_if_index);
9018   mp->sub_id = ntohl (sub_id);
9019
9020 #define _(a,b) mp->sub_if_flags |= (1 << a);
9021   foreach_create_subif_flag;
9022 #undef _
9023
9024   mp->outer_vlan_id = ntohs (outer_vlan_id);
9025   mp->inner_vlan_id = ntohs (inner_vlan_id);
9026
9027   S (mp);
9028   W (ret);
9029   return ret;
9030 }
9031
9032 static int
9033 api_ip_table_replace_begin (vat_main_t * vam)
9034 {
9035   unformat_input_t *i = vam->input;
9036   vl_api_ip_table_replace_begin_t *mp;
9037   u32 table_id = 0;
9038   u8 is_ipv6 = 0;
9039
9040   int ret;
9041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9042     {
9043       if (unformat (i, "table %d", &table_id))
9044         ;
9045       else if (unformat (i, "ipv6"))
9046         is_ipv6 = 1;
9047       else
9048         {
9049           clib_warning ("parse error '%U'", format_unformat_error, i);
9050           return -99;
9051         }
9052     }
9053
9054   M (IP_TABLE_REPLACE_BEGIN, mp);
9055
9056   mp->table.table_id = ntohl (table_id);
9057   mp->table.is_ip6 = is_ipv6;
9058
9059   S (mp);
9060   W (ret);
9061   return ret;
9062 }
9063
9064 static int
9065 api_ip_table_flush (vat_main_t * vam)
9066 {
9067   unformat_input_t *i = vam->input;
9068   vl_api_ip_table_flush_t *mp;
9069   u32 table_id = 0;
9070   u8 is_ipv6 = 0;
9071
9072   int ret;
9073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9074     {
9075       if (unformat (i, "table %d", &table_id))
9076         ;
9077       else if (unformat (i, "ipv6"))
9078         is_ipv6 = 1;
9079       else
9080         {
9081           clib_warning ("parse error '%U'", format_unformat_error, i);
9082           return -99;
9083         }
9084     }
9085
9086   M (IP_TABLE_FLUSH, mp);
9087
9088   mp->table.table_id = ntohl (table_id);
9089   mp->table.is_ip6 = is_ipv6;
9090
9091   S (mp);
9092   W (ret);
9093   return ret;
9094 }
9095
9096 static int
9097 api_ip_table_replace_end (vat_main_t * vam)
9098 {
9099   unformat_input_t *i = vam->input;
9100   vl_api_ip_table_replace_end_t *mp;
9101   u32 table_id = 0;
9102   u8 is_ipv6 = 0;
9103
9104   int ret;
9105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9106     {
9107       if (unformat (i, "table %d", &table_id))
9108         ;
9109       else if (unformat (i, "ipv6"))
9110         is_ipv6 = 1;
9111       else
9112         {
9113           clib_warning ("parse error '%U'", format_unformat_error, i);
9114           return -99;
9115         }
9116     }
9117
9118   M (IP_TABLE_REPLACE_END, mp);
9119
9120   mp->table.table_id = ntohl (table_id);
9121   mp->table.is_ip6 = is_ipv6;
9122
9123   S (mp);
9124   W (ret);
9125   return ret;
9126 }
9127
9128 static int
9129 api_set_ip_flow_hash (vat_main_t * vam)
9130 {
9131   unformat_input_t *i = vam->input;
9132   vl_api_set_ip_flow_hash_t *mp;
9133   u32 vrf_id = 0;
9134   u8 is_ipv6 = 0;
9135   u8 vrf_id_set = 0;
9136   u8 src = 0;
9137   u8 dst = 0;
9138   u8 sport = 0;
9139   u8 dport = 0;
9140   u8 proto = 0;
9141   u8 reverse = 0;
9142   int ret;
9143
9144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9145     {
9146       if (unformat (i, "vrf %d", &vrf_id))
9147         vrf_id_set = 1;
9148       else if (unformat (i, "ipv6"))
9149         is_ipv6 = 1;
9150       else if (unformat (i, "src"))
9151         src = 1;
9152       else if (unformat (i, "dst"))
9153         dst = 1;
9154       else if (unformat (i, "sport"))
9155         sport = 1;
9156       else if (unformat (i, "dport"))
9157         dport = 1;
9158       else if (unformat (i, "proto"))
9159         proto = 1;
9160       else if (unformat (i, "reverse"))
9161         reverse = 1;
9162
9163       else
9164         {
9165           clib_warning ("parse error '%U'", format_unformat_error, i);
9166           return -99;
9167         }
9168     }
9169
9170   if (vrf_id_set == 0)
9171     {
9172       errmsg ("missing vrf id");
9173       return -99;
9174     }
9175
9176   M (SET_IP_FLOW_HASH, mp);
9177   mp->src = src;
9178   mp->dst = dst;
9179   mp->sport = sport;
9180   mp->dport = dport;
9181   mp->proto = proto;
9182   mp->reverse = reverse;
9183   mp->vrf_id = ntohl (vrf_id);
9184   mp->is_ipv6 = is_ipv6;
9185
9186   S (mp);
9187   W (ret);
9188   return ret;
9189 }
9190
9191 static int
9192 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9193 {
9194   unformat_input_t *i = vam->input;
9195   vl_api_sw_interface_ip6_enable_disable_t *mp;
9196   u32 sw_if_index;
9197   u8 sw_if_index_set = 0;
9198   u8 enable = 0;
9199   int ret;
9200
9201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9202     {
9203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9204         sw_if_index_set = 1;
9205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9206         sw_if_index_set = 1;
9207       else if (unformat (i, "enable"))
9208         enable = 1;
9209       else if (unformat (i, "disable"))
9210         enable = 0;
9211       else
9212         {
9213           clib_warning ("parse error '%U'", format_unformat_error, i);
9214           return -99;
9215         }
9216     }
9217
9218   if (sw_if_index_set == 0)
9219     {
9220       errmsg ("missing interface name or sw_if_index");
9221       return -99;
9222     }
9223
9224   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9225
9226   mp->sw_if_index = ntohl (sw_if_index);
9227   mp->enable = enable;
9228
9229   S (mp);
9230   W (ret);
9231   return ret;
9232 }
9233
9234
9235 static int
9236 api_l2_patch_add_del (vat_main_t * vam)
9237 {
9238   unformat_input_t *i = vam->input;
9239   vl_api_l2_patch_add_del_t *mp;
9240   u32 rx_sw_if_index;
9241   u8 rx_sw_if_index_set = 0;
9242   u32 tx_sw_if_index;
9243   u8 tx_sw_if_index_set = 0;
9244   u8 is_add = 1;
9245   int ret;
9246
9247   /* Parse args required to build the message */
9248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9249     {
9250       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9251         rx_sw_if_index_set = 1;
9252       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9253         tx_sw_if_index_set = 1;
9254       else if (unformat (i, "rx"))
9255         {
9256           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9257             {
9258               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9259                             &rx_sw_if_index))
9260                 rx_sw_if_index_set = 1;
9261             }
9262           else
9263             break;
9264         }
9265       else if (unformat (i, "tx"))
9266         {
9267           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9268             {
9269               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9270                             &tx_sw_if_index))
9271                 tx_sw_if_index_set = 1;
9272             }
9273           else
9274             break;
9275         }
9276       else if (unformat (i, "del"))
9277         is_add = 0;
9278       else
9279         break;
9280     }
9281
9282   if (rx_sw_if_index_set == 0)
9283     {
9284       errmsg ("missing rx interface name or rx_sw_if_index");
9285       return -99;
9286     }
9287
9288   if (tx_sw_if_index_set == 0)
9289     {
9290       errmsg ("missing tx interface name or tx_sw_if_index");
9291       return -99;
9292     }
9293
9294   M (L2_PATCH_ADD_DEL, mp);
9295
9296   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9297   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9298   mp->is_add = is_add;
9299
9300   S (mp);
9301   W (ret);
9302   return ret;
9303 }
9304
9305 u8 is_del;
9306 u8 localsid_addr[16];
9307 u8 end_psp;
9308 u8 behavior;
9309 u32 sw_if_index;
9310 u32 vlan_index;
9311 u32 fib_table;
9312 u8 nh_addr[16];
9313
9314 static int
9315 api_sr_localsid_add_del (vat_main_t * vam)
9316 {
9317   unformat_input_t *i = vam->input;
9318   vl_api_sr_localsid_add_del_t *mp;
9319
9320   u8 is_del;
9321   ip6_address_t localsid;
9322   u8 end_psp = 0;
9323   u8 behavior = ~0;
9324   u32 sw_if_index;
9325   u32 fib_table = ~(u32) 0;
9326   ip46_address_t nh_addr;
9327   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9328
9329   bool nexthop_set = 0;
9330
9331   int ret;
9332
9333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9334     {
9335       if (unformat (i, "del"))
9336         is_del = 1;
9337       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9338       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9339         nexthop_set = 1;
9340       else if (unformat (i, "behavior %u", &behavior));
9341       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9342       else if (unformat (i, "fib-table %u", &fib_table));
9343       else if (unformat (i, "end.psp %u", &behavior));
9344       else
9345         break;
9346     }
9347
9348   M (SR_LOCALSID_ADD_DEL, mp);
9349
9350   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9351
9352   if (nexthop_set)
9353     {
9354       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9355     }
9356   mp->behavior = behavior;
9357   mp->sw_if_index = ntohl (sw_if_index);
9358   mp->fib_table = ntohl (fib_table);
9359   mp->end_psp = end_psp;
9360   mp->is_del = is_del;
9361
9362   S (mp);
9363   W (ret);
9364   return ret;
9365 }
9366
9367 static int
9368 api_ioam_enable (vat_main_t * vam)
9369 {
9370   unformat_input_t *input = vam->input;
9371   vl_api_ioam_enable_t *mp;
9372   u32 id = 0;
9373   int has_trace_option = 0;
9374   int has_pot_option = 0;
9375   int has_seqno_option = 0;
9376   int has_analyse_option = 0;
9377   int ret;
9378
9379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9380     {
9381       if (unformat (input, "trace"))
9382         has_trace_option = 1;
9383       else if (unformat (input, "pot"))
9384         has_pot_option = 1;
9385       else if (unformat (input, "seqno"))
9386         has_seqno_option = 1;
9387       else if (unformat (input, "analyse"))
9388         has_analyse_option = 1;
9389       else
9390         break;
9391     }
9392   M (IOAM_ENABLE, mp);
9393   mp->id = htons (id);
9394   mp->seqno = has_seqno_option;
9395   mp->analyse = has_analyse_option;
9396   mp->pot_enable = has_pot_option;
9397   mp->trace_enable = has_trace_option;
9398
9399   S (mp);
9400   W (ret);
9401   return ret;
9402 }
9403
9404
9405 static int
9406 api_ioam_disable (vat_main_t * vam)
9407 {
9408   vl_api_ioam_disable_t *mp;
9409   int ret;
9410
9411   M (IOAM_DISABLE, mp);
9412   S (mp);
9413   W (ret);
9414   return ret;
9415 }
9416
9417 #define foreach_tcp_proto_field                 \
9418 _(src_port)                                     \
9419 _(dst_port)
9420
9421 #define foreach_udp_proto_field                 \
9422 _(src_port)                                     \
9423 _(dst_port)
9424
9425 #define foreach_ip4_proto_field                 \
9426 _(src_address)                                  \
9427 _(dst_address)                                  \
9428 _(tos)                                          \
9429 _(length)                                       \
9430 _(fragment_id)                                  \
9431 _(ttl)                                          \
9432 _(protocol)                                     \
9433 _(checksum)
9434
9435 typedef struct
9436 {
9437   u16 src_port, dst_port;
9438 } tcpudp_header_t;
9439
9440 #if VPP_API_TEST_BUILTIN == 0
9441 uword
9442 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9443 {
9444   u8 **maskp = va_arg (*args, u8 **);
9445   u8 *mask = 0;
9446   u8 found_something = 0;
9447   tcp_header_t *tcp;
9448
9449 #define _(a) u8 a=0;
9450   foreach_tcp_proto_field;
9451 #undef _
9452
9453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9454     {
9455       if (0);
9456 #define _(a) else if (unformat (input, #a)) a=1;
9457       foreach_tcp_proto_field
9458 #undef _
9459         else
9460         break;
9461     }
9462
9463 #define _(a) found_something += a;
9464   foreach_tcp_proto_field;
9465 #undef _
9466
9467   if (found_something == 0)
9468     return 0;
9469
9470   vec_validate (mask, sizeof (*tcp) - 1);
9471
9472   tcp = (tcp_header_t *) mask;
9473
9474 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9475   foreach_tcp_proto_field;
9476 #undef _
9477
9478   *maskp = mask;
9479   return 1;
9480 }
9481
9482 uword
9483 unformat_udp_mask (unformat_input_t * input, va_list * args)
9484 {
9485   u8 **maskp = va_arg (*args, u8 **);
9486   u8 *mask = 0;
9487   u8 found_something = 0;
9488   udp_header_t *udp;
9489
9490 #define _(a) u8 a=0;
9491   foreach_udp_proto_field;
9492 #undef _
9493
9494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9495     {
9496       if (0);
9497 #define _(a) else if (unformat (input, #a)) a=1;
9498       foreach_udp_proto_field
9499 #undef _
9500         else
9501         break;
9502     }
9503
9504 #define _(a) found_something += a;
9505   foreach_udp_proto_field;
9506 #undef _
9507
9508   if (found_something == 0)
9509     return 0;
9510
9511   vec_validate (mask, sizeof (*udp) - 1);
9512
9513   udp = (udp_header_t *) mask;
9514
9515 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9516   foreach_udp_proto_field;
9517 #undef _
9518
9519   *maskp = mask;
9520   return 1;
9521 }
9522
9523 uword
9524 unformat_l4_mask (unformat_input_t * input, va_list * args)
9525 {
9526   u8 **maskp = va_arg (*args, u8 **);
9527   u16 src_port = 0, dst_port = 0;
9528   tcpudp_header_t *tcpudp;
9529
9530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9531     {
9532       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9533         return 1;
9534       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9535         return 1;
9536       else if (unformat (input, "src_port"))
9537         src_port = 0xFFFF;
9538       else if (unformat (input, "dst_port"))
9539         dst_port = 0xFFFF;
9540       else
9541         return 0;
9542     }
9543
9544   if (!src_port && !dst_port)
9545     return 0;
9546
9547   u8 *mask = 0;
9548   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9549
9550   tcpudp = (tcpudp_header_t *) mask;
9551   tcpudp->src_port = src_port;
9552   tcpudp->dst_port = dst_port;
9553
9554   *maskp = mask;
9555
9556   return 1;
9557 }
9558
9559 uword
9560 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9561 {
9562   u8 **maskp = va_arg (*args, u8 **);
9563   u8 *mask = 0;
9564   u8 found_something = 0;
9565   ip4_header_t *ip;
9566
9567 #define _(a) u8 a=0;
9568   foreach_ip4_proto_field;
9569 #undef _
9570   u8 version = 0;
9571   u8 hdr_length = 0;
9572
9573
9574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (input, "version"))
9577         version = 1;
9578       else if (unformat (input, "hdr_length"))
9579         hdr_length = 1;
9580       else if (unformat (input, "src"))
9581         src_address = 1;
9582       else if (unformat (input, "dst"))
9583         dst_address = 1;
9584       else if (unformat (input, "proto"))
9585         protocol = 1;
9586
9587 #define _(a) else if (unformat (input, #a)) a=1;
9588       foreach_ip4_proto_field
9589 #undef _
9590         else
9591         break;
9592     }
9593
9594 #define _(a) found_something += a;
9595   foreach_ip4_proto_field;
9596 #undef _
9597
9598   if (found_something == 0)
9599     return 0;
9600
9601   vec_validate (mask, sizeof (*ip) - 1);
9602
9603   ip = (ip4_header_t *) mask;
9604
9605 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9606   foreach_ip4_proto_field;
9607 #undef _
9608
9609   ip->ip_version_and_header_length = 0;
9610
9611   if (version)
9612     ip->ip_version_and_header_length |= 0xF0;
9613
9614   if (hdr_length)
9615     ip->ip_version_and_header_length |= 0x0F;
9616
9617   *maskp = mask;
9618   return 1;
9619 }
9620
9621 #define foreach_ip6_proto_field                 \
9622 _(src_address)                                  \
9623 _(dst_address)                                  \
9624 _(payload_length)                               \
9625 _(hop_limit)                                    \
9626 _(protocol)
9627
9628 uword
9629 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9630 {
9631   u8 **maskp = va_arg (*args, u8 **);
9632   u8 *mask = 0;
9633   u8 found_something = 0;
9634   ip6_header_t *ip;
9635   u32 ip_version_traffic_class_and_flow_label;
9636
9637 #define _(a) u8 a=0;
9638   foreach_ip6_proto_field;
9639 #undef _
9640   u8 version = 0;
9641   u8 traffic_class = 0;
9642   u8 flow_label = 0;
9643
9644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (input, "version"))
9647         version = 1;
9648       else if (unformat (input, "traffic-class"))
9649         traffic_class = 1;
9650       else if (unformat (input, "flow-label"))
9651         flow_label = 1;
9652       else if (unformat (input, "src"))
9653         src_address = 1;
9654       else if (unformat (input, "dst"))
9655         dst_address = 1;
9656       else if (unformat (input, "proto"))
9657         protocol = 1;
9658
9659 #define _(a) else if (unformat (input, #a)) a=1;
9660       foreach_ip6_proto_field
9661 #undef _
9662         else
9663         break;
9664     }
9665
9666 #define _(a) found_something += a;
9667   foreach_ip6_proto_field;
9668 #undef _
9669
9670   if (found_something == 0)
9671     return 0;
9672
9673   vec_validate (mask, sizeof (*ip) - 1);
9674
9675   ip = (ip6_header_t *) mask;
9676
9677 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9678   foreach_ip6_proto_field;
9679 #undef _
9680
9681   ip_version_traffic_class_and_flow_label = 0;
9682
9683   if (version)
9684     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9685
9686   if (traffic_class)
9687     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9688
9689   if (flow_label)
9690     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9691
9692   ip->ip_version_traffic_class_and_flow_label =
9693     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9694
9695   *maskp = mask;
9696   return 1;
9697 }
9698
9699 uword
9700 unformat_l3_mask (unformat_input_t * input, va_list * args)
9701 {
9702   u8 **maskp = va_arg (*args, u8 **);
9703
9704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9705     {
9706       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9707         return 1;
9708       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9709         return 1;
9710       else
9711         break;
9712     }
9713   return 0;
9714 }
9715
9716 uword
9717 unformat_l2_mask (unformat_input_t * input, va_list * args)
9718 {
9719   u8 **maskp = va_arg (*args, u8 **);
9720   u8 *mask = 0;
9721   u8 src = 0;
9722   u8 dst = 0;
9723   u8 proto = 0;
9724   u8 tag1 = 0;
9725   u8 tag2 = 0;
9726   u8 ignore_tag1 = 0;
9727   u8 ignore_tag2 = 0;
9728   u8 cos1 = 0;
9729   u8 cos2 = 0;
9730   u8 dot1q = 0;
9731   u8 dot1ad = 0;
9732   int len = 14;
9733
9734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9735     {
9736       if (unformat (input, "src"))
9737         src = 1;
9738       else if (unformat (input, "dst"))
9739         dst = 1;
9740       else if (unformat (input, "proto"))
9741         proto = 1;
9742       else if (unformat (input, "tag1"))
9743         tag1 = 1;
9744       else if (unformat (input, "tag2"))
9745         tag2 = 1;
9746       else if (unformat (input, "ignore-tag1"))
9747         ignore_tag1 = 1;
9748       else if (unformat (input, "ignore-tag2"))
9749         ignore_tag2 = 1;
9750       else if (unformat (input, "cos1"))
9751         cos1 = 1;
9752       else if (unformat (input, "cos2"))
9753         cos2 = 1;
9754       else if (unformat (input, "dot1q"))
9755         dot1q = 1;
9756       else if (unformat (input, "dot1ad"))
9757         dot1ad = 1;
9758       else
9759         break;
9760     }
9761   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9762        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9763     return 0;
9764
9765   if (tag1 || ignore_tag1 || cos1 || dot1q)
9766     len = 18;
9767   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9768     len = 22;
9769
9770   vec_validate (mask, len - 1);
9771
9772   if (dst)
9773     clib_memset (mask, 0xff, 6);
9774
9775   if (src)
9776     clib_memset (mask + 6, 0xff, 6);
9777
9778   if (tag2 || dot1ad)
9779     {
9780       /* inner vlan tag */
9781       if (tag2)
9782         {
9783           mask[19] = 0xff;
9784           mask[18] = 0x0f;
9785         }
9786       if (cos2)
9787         mask[18] |= 0xe0;
9788       if (proto)
9789         mask[21] = mask[20] = 0xff;
9790       if (tag1)
9791         {
9792           mask[15] = 0xff;
9793           mask[14] = 0x0f;
9794         }
9795       if (cos1)
9796         mask[14] |= 0xe0;
9797       *maskp = mask;
9798       return 1;
9799     }
9800   if (tag1 | dot1q)
9801     {
9802       if (tag1)
9803         {
9804           mask[15] = 0xff;
9805           mask[14] = 0x0f;
9806         }
9807       if (cos1)
9808         mask[14] |= 0xe0;
9809       if (proto)
9810         mask[16] = mask[17] = 0xff;
9811
9812       *maskp = mask;
9813       return 1;
9814     }
9815   if (cos2)
9816     mask[18] |= 0xe0;
9817   if (cos1)
9818     mask[14] |= 0xe0;
9819   if (proto)
9820     mask[12] = mask[13] = 0xff;
9821
9822   *maskp = mask;
9823   return 1;
9824 }
9825
9826 uword
9827 unformat_classify_mask (unformat_input_t * input, va_list * args)
9828 {
9829   u8 **maskp = va_arg (*args, u8 **);
9830   u32 *skipp = va_arg (*args, u32 *);
9831   u32 *matchp = va_arg (*args, u32 *);
9832   u32 match;
9833   u8 *mask = 0;
9834   u8 *l2 = 0;
9835   u8 *l3 = 0;
9836   u8 *l4 = 0;
9837   int i;
9838
9839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9840     {
9841       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9842         ;
9843       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9844         ;
9845       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9846         ;
9847       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9848         ;
9849       else
9850         break;
9851     }
9852
9853   if (l4 && !l3)
9854     {
9855       vec_free (mask);
9856       vec_free (l2);
9857       vec_free (l4);
9858       return 0;
9859     }
9860
9861   if (mask || l2 || l3 || l4)
9862     {
9863       if (l2 || l3 || l4)
9864         {
9865           /* "With a free Ethernet header in every package" */
9866           if (l2 == 0)
9867             vec_validate (l2, 13);
9868           mask = l2;
9869           if (vec_len (l3))
9870             {
9871               vec_append (mask, l3);
9872               vec_free (l3);
9873             }
9874           if (vec_len (l4))
9875             {
9876               vec_append (mask, l4);
9877               vec_free (l4);
9878             }
9879         }
9880
9881       /* Scan forward looking for the first significant mask octet */
9882       for (i = 0; i < vec_len (mask); i++)
9883         if (mask[i])
9884           break;
9885
9886       /* compute (skip, match) params */
9887       *skipp = i / sizeof (u32x4);
9888       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9889
9890       /* Pad mask to an even multiple of the vector size */
9891       while (vec_len (mask) % sizeof (u32x4))
9892         vec_add1 (mask, 0);
9893
9894       match = vec_len (mask) / sizeof (u32x4);
9895
9896       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9897         {
9898           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9899           if (*tmp || *(tmp + 1))
9900             break;
9901           match--;
9902         }
9903       if (match == 0)
9904         clib_warning ("BUG: match 0");
9905
9906       _vec_len (mask) = match * sizeof (u32x4);
9907
9908       *matchp = match;
9909       *maskp = mask;
9910
9911       return 1;
9912     }
9913
9914   return 0;
9915 }
9916 #endif /* VPP_API_TEST_BUILTIN */
9917
9918 #define foreach_l2_next                         \
9919 _(drop, DROP)                                   \
9920 _(ethernet, ETHERNET_INPUT)                     \
9921 _(ip4, IP4_INPUT)                               \
9922 _(ip6, IP6_INPUT)
9923
9924 uword
9925 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9926 {
9927   u32 *miss_next_indexp = va_arg (*args, u32 *);
9928   u32 next_index = 0;
9929   u32 tmp;
9930
9931 #define _(n,N) \
9932   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9933   foreach_l2_next;
9934 #undef _
9935
9936   if (unformat (input, "%d", &tmp))
9937     {
9938       next_index = tmp;
9939       goto out;
9940     }
9941
9942   return 0;
9943
9944 out:
9945   *miss_next_indexp = next_index;
9946   return 1;
9947 }
9948
9949 #define foreach_ip_next                         \
9950 _(drop, DROP)                                   \
9951 _(local, LOCAL)                                 \
9952 _(rewrite, REWRITE)
9953
9954 uword
9955 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9956 {
9957   u32 *miss_next_indexp = va_arg (*args, u32 *);
9958   u32 next_index = 0;
9959   u32 tmp;
9960
9961 #define _(n,N) \
9962   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9963   foreach_ip_next;
9964 #undef _
9965
9966   if (unformat (input, "%d", &tmp))
9967     {
9968       next_index = tmp;
9969       goto out;
9970     }
9971
9972   return 0;
9973
9974 out:
9975   *miss_next_indexp = next_index;
9976   return 1;
9977 }
9978
9979 #define foreach_acl_next                        \
9980 _(deny, DENY)
9981
9982 uword
9983 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9984 {
9985   u32 *miss_next_indexp = va_arg (*args, u32 *);
9986   u32 next_index = 0;
9987   u32 tmp;
9988
9989 #define _(n,N) \
9990   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9991   foreach_acl_next;
9992 #undef _
9993
9994   if (unformat (input, "permit"))
9995     {
9996       next_index = ~0;
9997       goto out;
9998     }
9999   else if (unformat (input, "%d", &tmp))
10000     {
10001       next_index = tmp;
10002       goto out;
10003     }
10004
10005   return 0;
10006
10007 out:
10008   *miss_next_indexp = next_index;
10009   return 1;
10010 }
10011
10012 uword
10013 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10014 {
10015   u32 *r = va_arg (*args, u32 *);
10016
10017   if (unformat (input, "conform-color"))
10018     *r = POLICE_CONFORM;
10019   else if (unformat (input, "exceed-color"))
10020     *r = POLICE_EXCEED;
10021   else
10022     return 0;
10023
10024   return 1;
10025 }
10026
10027 static int
10028 api_classify_add_del_table (vat_main_t * vam)
10029 {
10030   unformat_input_t *i = vam->input;
10031   vl_api_classify_add_del_table_t *mp;
10032
10033   u32 nbuckets = 2;
10034   u32 skip = ~0;
10035   u32 match = ~0;
10036   int is_add = 1;
10037   int del_chain = 0;
10038   u32 table_index = ~0;
10039   u32 next_table_index = ~0;
10040   u32 miss_next_index = ~0;
10041   u32 memory_size = 32 << 20;
10042   u8 *mask = 0;
10043   u32 current_data_flag = 0;
10044   int current_data_offset = 0;
10045   int ret;
10046
10047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10048     {
10049       if (unformat (i, "del"))
10050         is_add = 0;
10051       else if (unformat (i, "del-chain"))
10052         {
10053           is_add = 0;
10054           del_chain = 1;
10055         }
10056       else if (unformat (i, "buckets %d", &nbuckets))
10057         ;
10058       else if (unformat (i, "memory_size %d", &memory_size))
10059         ;
10060       else if (unformat (i, "skip %d", &skip))
10061         ;
10062       else if (unformat (i, "match %d", &match))
10063         ;
10064       else if (unformat (i, "table %d", &table_index))
10065         ;
10066       else if (unformat (i, "mask %U", unformat_classify_mask,
10067                          &mask, &skip, &match))
10068         ;
10069       else if (unformat (i, "next-table %d", &next_table_index))
10070         ;
10071       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10072                          &miss_next_index))
10073         ;
10074       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10075                          &miss_next_index))
10076         ;
10077       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10078                          &miss_next_index))
10079         ;
10080       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10081         ;
10082       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10083         ;
10084       else
10085         break;
10086     }
10087
10088   if (is_add && mask == 0)
10089     {
10090       errmsg ("Mask required");
10091       return -99;
10092     }
10093
10094   if (is_add && skip == ~0)
10095     {
10096       errmsg ("skip count required");
10097       return -99;
10098     }
10099
10100   if (is_add && match == ~0)
10101     {
10102       errmsg ("match count required");
10103       return -99;
10104     }
10105
10106   if (!is_add && table_index == ~0)
10107     {
10108       errmsg ("table index required for delete");
10109       return -99;
10110     }
10111
10112   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10113
10114   mp->is_add = is_add;
10115   mp->del_chain = del_chain;
10116   mp->table_index = ntohl (table_index);
10117   mp->nbuckets = ntohl (nbuckets);
10118   mp->memory_size = ntohl (memory_size);
10119   mp->skip_n_vectors = ntohl (skip);
10120   mp->match_n_vectors = ntohl (match);
10121   mp->next_table_index = ntohl (next_table_index);
10122   mp->miss_next_index = ntohl (miss_next_index);
10123   mp->current_data_flag = ntohl (current_data_flag);
10124   mp->current_data_offset = ntohl (current_data_offset);
10125   mp->mask_len = ntohl (vec_len (mask));
10126   clib_memcpy (mp->mask, mask, vec_len (mask));
10127
10128   vec_free (mask);
10129
10130   S (mp);
10131   W (ret);
10132   return ret;
10133 }
10134
10135 #if VPP_API_TEST_BUILTIN == 0
10136 uword
10137 unformat_l4_match (unformat_input_t * input, va_list * args)
10138 {
10139   u8 **matchp = va_arg (*args, u8 **);
10140
10141   u8 *proto_header = 0;
10142   int src_port = 0;
10143   int dst_port = 0;
10144
10145   tcpudp_header_t h;
10146
10147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10148     {
10149       if (unformat (input, "src_port %d", &src_port))
10150         ;
10151       else if (unformat (input, "dst_port %d", &dst_port))
10152         ;
10153       else
10154         return 0;
10155     }
10156
10157   h.src_port = clib_host_to_net_u16 (src_port);
10158   h.dst_port = clib_host_to_net_u16 (dst_port);
10159   vec_validate (proto_header, sizeof (h) - 1);
10160   memcpy (proto_header, &h, sizeof (h));
10161
10162   *matchp = proto_header;
10163
10164   return 1;
10165 }
10166
10167 uword
10168 unformat_ip4_match (unformat_input_t * input, va_list * args)
10169 {
10170   u8 **matchp = va_arg (*args, u8 **);
10171   u8 *match = 0;
10172   ip4_header_t *ip;
10173   int version = 0;
10174   u32 version_val;
10175   int hdr_length = 0;
10176   u32 hdr_length_val;
10177   int src = 0, dst = 0;
10178   ip4_address_t src_val, dst_val;
10179   int proto = 0;
10180   u32 proto_val;
10181   int tos = 0;
10182   u32 tos_val;
10183   int length = 0;
10184   u32 length_val;
10185   int fragment_id = 0;
10186   u32 fragment_id_val;
10187   int ttl = 0;
10188   int ttl_val;
10189   int checksum = 0;
10190   u32 checksum_val;
10191
10192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10193     {
10194       if (unformat (input, "version %d", &version_val))
10195         version = 1;
10196       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10197         hdr_length = 1;
10198       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10199         src = 1;
10200       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10201         dst = 1;
10202       else if (unformat (input, "proto %d", &proto_val))
10203         proto = 1;
10204       else if (unformat (input, "tos %d", &tos_val))
10205         tos = 1;
10206       else if (unformat (input, "length %d", &length_val))
10207         length = 1;
10208       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10209         fragment_id = 1;
10210       else if (unformat (input, "ttl %d", &ttl_val))
10211         ttl = 1;
10212       else if (unformat (input, "checksum %d", &checksum_val))
10213         checksum = 1;
10214       else
10215         break;
10216     }
10217
10218   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10219       + ttl + checksum == 0)
10220     return 0;
10221
10222   /*
10223    * Aligned because we use the real comparison functions
10224    */
10225   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10226
10227   ip = (ip4_header_t *) match;
10228
10229   /* These are realistically matched in practice */
10230   if (src)
10231     ip->src_address.as_u32 = src_val.as_u32;
10232
10233   if (dst)
10234     ip->dst_address.as_u32 = dst_val.as_u32;
10235
10236   if (proto)
10237     ip->protocol = proto_val;
10238
10239
10240   /* These are not, but they're included for completeness */
10241   if (version)
10242     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10243
10244   if (hdr_length)
10245     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10246
10247   if (tos)
10248     ip->tos = tos_val;
10249
10250   if (length)
10251     ip->length = clib_host_to_net_u16 (length_val);
10252
10253   if (ttl)
10254     ip->ttl = ttl_val;
10255
10256   if (checksum)
10257     ip->checksum = clib_host_to_net_u16 (checksum_val);
10258
10259   *matchp = match;
10260   return 1;
10261 }
10262
10263 uword
10264 unformat_ip6_match (unformat_input_t * input, va_list * args)
10265 {
10266   u8 **matchp = va_arg (*args, u8 **);
10267   u8 *match = 0;
10268   ip6_header_t *ip;
10269   int version = 0;
10270   u32 version_val;
10271   u8 traffic_class = 0;
10272   u32 traffic_class_val = 0;
10273   u8 flow_label = 0;
10274   u8 flow_label_val;
10275   int src = 0, dst = 0;
10276   ip6_address_t src_val, dst_val;
10277   int proto = 0;
10278   u32 proto_val;
10279   int payload_length = 0;
10280   u32 payload_length_val;
10281   int hop_limit = 0;
10282   int hop_limit_val;
10283   u32 ip_version_traffic_class_and_flow_label;
10284
10285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10286     {
10287       if (unformat (input, "version %d", &version_val))
10288         version = 1;
10289       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10290         traffic_class = 1;
10291       else if (unformat (input, "flow_label %d", &flow_label_val))
10292         flow_label = 1;
10293       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10294         src = 1;
10295       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10296         dst = 1;
10297       else if (unformat (input, "proto %d", &proto_val))
10298         proto = 1;
10299       else if (unformat (input, "payload_length %d", &payload_length_val))
10300         payload_length = 1;
10301       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10302         hop_limit = 1;
10303       else
10304         break;
10305     }
10306
10307   if (version + traffic_class + flow_label + src + dst + proto +
10308       payload_length + hop_limit == 0)
10309     return 0;
10310
10311   /*
10312    * Aligned because we use the real comparison functions
10313    */
10314   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10315
10316   ip = (ip6_header_t *) match;
10317
10318   if (src)
10319     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10320
10321   if (dst)
10322     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10323
10324   if (proto)
10325     ip->protocol = proto_val;
10326
10327   ip_version_traffic_class_and_flow_label = 0;
10328
10329   if (version)
10330     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10331
10332   if (traffic_class)
10333     ip_version_traffic_class_and_flow_label |=
10334       (traffic_class_val & 0xFF) << 20;
10335
10336   if (flow_label)
10337     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10338
10339   ip->ip_version_traffic_class_and_flow_label =
10340     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10341
10342   if (payload_length)
10343     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10344
10345   if (hop_limit)
10346     ip->hop_limit = hop_limit_val;
10347
10348   *matchp = match;
10349   return 1;
10350 }
10351
10352 uword
10353 unformat_l3_match (unformat_input_t * input, va_list * args)
10354 {
10355   u8 **matchp = va_arg (*args, u8 **);
10356
10357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10358     {
10359       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10360         return 1;
10361       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10362         return 1;
10363       else
10364         break;
10365     }
10366   return 0;
10367 }
10368
10369 uword
10370 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10371 {
10372   u8 *tagp = va_arg (*args, u8 *);
10373   u32 tag;
10374
10375   if (unformat (input, "%d", &tag))
10376     {
10377       tagp[0] = (tag >> 8) & 0x0F;
10378       tagp[1] = tag & 0xFF;
10379       return 1;
10380     }
10381
10382   return 0;
10383 }
10384
10385 uword
10386 unformat_l2_match (unformat_input_t * input, va_list * args)
10387 {
10388   u8 **matchp = va_arg (*args, u8 **);
10389   u8 *match = 0;
10390   u8 src = 0;
10391   u8 src_val[6];
10392   u8 dst = 0;
10393   u8 dst_val[6];
10394   u8 proto = 0;
10395   u16 proto_val;
10396   u8 tag1 = 0;
10397   u8 tag1_val[2];
10398   u8 tag2 = 0;
10399   u8 tag2_val[2];
10400   int len = 14;
10401   u8 ignore_tag1 = 0;
10402   u8 ignore_tag2 = 0;
10403   u8 cos1 = 0;
10404   u8 cos2 = 0;
10405   u32 cos1_val = 0;
10406   u32 cos2_val = 0;
10407
10408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10409     {
10410       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10411         src = 1;
10412       else
10413         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10414         dst = 1;
10415       else if (unformat (input, "proto %U",
10416                          unformat_ethernet_type_host_byte_order, &proto_val))
10417         proto = 1;
10418       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10419         tag1 = 1;
10420       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10421         tag2 = 1;
10422       else if (unformat (input, "ignore-tag1"))
10423         ignore_tag1 = 1;
10424       else if (unformat (input, "ignore-tag2"))
10425         ignore_tag2 = 1;
10426       else if (unformat (input, "cos1 %d", &cos1_val))
10427         cos1 = 1;
10428       else if (unformat (input, "cos2 %d", &cos2_val))
10429         cos2 = 1;
10430       else
10431         break;
10432     }
10433   if ((src + dst + proto + tag1 + tag2 +
10434        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10435     return 0;
10436
10437   if (tag1 || ignore_tag1 || cos1)
10438     len = 18;
10439   if (tag2 || ignore_tag2 || cos2)
10440     len = 22;
10441
10442   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10443
10444   if (dst)
10445     clib_memcpy (match, dst_val, 6);
10446
10447   if (src)
10448     clib_memcpy (match + 6, src_val, 6);
10449
10450   if (tag2)
10451     {
10452       /* inner vlan tag */
10453       match[19] = tag2_val[1];
10454       match[18] = tag2_val[0];
10455       if (cos2)
10456         match[18] |= (cos2_val & 0x7) << 5;
10457       if (proto)
10458         {
10459           match[21] = proto_val & 0xff;
10460           match[20] = proto_val >> 8;
10461         }
10462       if (tag1)
10463         {
10464           match[15] = tag1_val[1];
10465           match[14] = tag1_val[0];
10466         }
10467       if (cos1)
10468         match[14] |= (cos1_val & 0x7) << 5;
10469       *matchp = match;
10470       return 1;
10471     }
10472   if (tag1)
10473     {
10474       match[15] = tag1_val[1];
10475       match[14] = tag1_val[0];
10476       if (proto)
10477         {
10478           match[17] = proto_val & 0xff;
10479           match[16] = proto_val >> 8;
10480         }
10481       if (cos1)
10482         match[14] |= (cos1_val & 0x7) << 5;
10483
10484       *matchp = match;
10485       return 1;
10486     }
10487   if (cos2)
10488     match[18] |= (cos2_val & 0x7) << 5;
10489   if (cos1)
10490     match[14] |= (cos1_val & 0x7) << 5;
10491   if (proto)
10492     {
10493       match[13] = proto_val & 0xff;
10494       match[12] = proto_val >> 8;
10495     }
10496
10497   *matchp = match;
10498   return 1;
10499 }
10500
10501 uword
10502 unformat_qos_source (unformat_input_t * input, va_list * args)
10503 {
10504   int *qs = va_arg (*args, int *);
10505
10506   if (unformat (input, "ip"))
10507     *qs = QOS_SOURCE_IP;
10508   else if (unformat (input, "mpls"))
10509     *qs = QOS_SOURCE_MPLS;
10510   else if (unformat (input, "ext"))
10511     *qs = QOS_SOURCE_EXT;
10512   else if (unformat (input, "vlan"))
10513     *qs = QOS_SOURCE_VLAN;
10514   else
10515     return 0;
10516
10517   return 1;
10518 }
10519 #endif
10520
10521 uword
10522 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10523 {
10524   u8 **matchp = va_arg (*args, u8 **);
10525   u32 skip_n_vectors = va_arg (*args, u32);
10526   u32 match_n_vectors = va_arg (*args, u32);
10527
10528   u8 *match = 0;
10529   u8 *l2 = 0;
10530   u8 *l3 = 0;
10531   u8 *l4 = 0;
10532
10533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10534     {
10535       if (unformat (input, "hex %U", unformat_hex_string, &match))
10536         ;
10537       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10538         ;
10539       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10540         ;
10541       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10542         ;
10543       else
10544         break;
10545     }
10546
10547   if (l4 && !l3)
10548     {
10549       vec_free (match);
10550       vec_free (l2);
10551       vec_free (l4);
10552       return 0;
10553     }
10554
10555   if (match || l2 || l3 || l4)
10556     {
10557       if (l2 || l3 || l4)
10558         {
10559           /* "Win a free Ethernet header in every packet" */
10560           if (l2 == 0)
10561             vec_validate_aligned (l2, 13, sizeof (u32x4));
10562           match = l2;
10563           if (vec_len (l3))
10564             {
10565               vec_append_aligned (match, l3, sizeof (u32x4));
10566               vec_free (l3);
10567             }
10568           if (vec_len (l4))
10569             {
10570               vec_append_aligned (match, l4, sizeof (u32x4));
10571               vec_free (l4);
10572             }
10573         }
10574
10575       /* Make sure the vector is big enough even if key is all 0's */
10576       vec_validate_aligned
10577         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10578          sizeof (u32x4));
10579
10580       /* Set size, include skipped vectors */
10581       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10582
10583       *matchp = match;
10584
10585       return 1;
10586     }
10587
10588   return 0;
10589 }
10590
10591 static int
10592 api_classify_add_del_session (vat_main_t * vam)
10593 {
10594   unformat_input_t *i = vam->input;
10595   vl_api_classify_add_del_session_t *mp;
10596   int is_add = 1;
10597   u32 table_index = ~0;
10598   u32 hit_next_index = ~0;
10599   u32 opaque_index = ~0;
10600   u8 *match = 0;
10601   i32 advance = 0;
10602   u32 skip_n_vectors = 0;
10603   u32 match_n_vectors = 0;
10604   u32 action = 0;
10605   u32 metadata = 0;
10606   int ret;
10607
10608   /*
10609    * Warning: you have to supply skip_n and match_n
10610    * because the API client cant simply look at the classify
10611    * table object.
10612    */
10613
10614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10615     {
10616       if (unformat (i, "del"))
10617         is_add = 0;
10618       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10619                          &hit_next_index))
10620         ;
10621       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10622                          &hit_next_index))
10623         ;
10624       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10625                          &hit_next_index))
10626         ;
10627       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10628         ;
10629       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10630         ;
10631       else if (unformat (i, "opaque-index %d", &opaque_index))
10632         ;
10633       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10634         ;
10635       else if (unformat (i, "match_n %d", &match_n_vectors))
10636         ;
10637       else if (unformat (i, "match %U", api_unformat_classify_match,
10638                          &match, skip_n_vectors, match_n_vectors))
10639         ;
10640       else if (unformat (i, "advance %d", &advance))
10641         ;
10642       else if (unformat (i, "table-index %d", &table_index))
10643         ;
10644       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10645         action = 1;
10646       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10647         action = 2;
10648       else if (unformat (i, "action %d", &action))
10649         ;
10650       else if (unformat (i, "metadata %d", &metadata))
10651         ;
10652       else
10653         break;
10654     }
10655
10656   if (table_index == ~0)
10657     {
10658       errmsg ("Table index required");
10659       return -99;
10660     }
10661
10662   if (is_add && match == 0)
10663     {
10664       errmsg ("Match value required");
10665       return -99;
10666     }
10667
10668   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10669
10670   mp->is_add = is_add;
10671   mp->table_index = ntohl (table_index);
10672   mp->hit_next_index = ntohl (hit_next_index);
10673   mp->opaque_index = ntohl (opaque_index);
10674   mp->advance = ntohl (advance);
10675   mp->action = action;
10676   mp->metadata = ntohl (metadata);
10677   mp->match_len = ntohl (vec_len (match));
10678   clib_memcpy (mp->match, match, vec_len (match));
10679   vec_free (match);
10680
10681   S (mp);
10682   W (ret);
10683   return ret;
10684 }
10685
10686 static int
10687 api_classify_set_interface_ip_table (vat_main_t * vam)
10688 {
10689   unformat_input_t *i = vam->input;
10690   vl_api_classify_set_interface_ip_table_t *mp;
10691   u32 sw_if_index;
10692   int sw_if_index_set;
10693   u32 table_index = ~0;
10694   u8 is_ipv6 = 0;
10695   int ret;
10696
10697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10698     {
10699       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10700         sw_if_index_set = 1;
10701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10702         sw_if_index_set = 1;
10703       else if (unformat (i, "table %d", &table_index))
10704         ;
10705       else
10706         {
10707           clib_warning ("parse error '%U'", format_unformat_error, i);
10708           return -99;
10709         }
10710     }
10711
10712   if (sw_if_index_set == 0)
10713     {
10714       errmsg ("missing interface name or sw_if_index");
10715       return -99;
10716     }
10717
10718
10719   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10720
10721   mp->sw_if_index = ntohl (sw_if_index);
10722   mp->table_index = ntohl (table_index);
10723   mp->is_ipv6 = is_ipv6;
10724
10725   S (mp);
10726   W (ret);
10727   return ret;
10728 }
10729
10730 static int
10731 api_classify_set_interface_l2_tables (vat_main_t * vam)
10732 {
10733   unformat_input_t *i = vam->input;
10734   vl_api_classify_set_interface_l2_tables_t *mp;
10735   u32 sw_if_index;
10736   int sw_if_index_set;
10737   u32 ip4_table_index = ~0;
10738   u32 ip6_table_index = ~0;
10739   u32 other_table_index = ~0;
10740   u32 is_input = 1;
10741   int ret;
10742
10743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10744     {
10745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10746         sw_if_index_set = 1;
10747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10748         sw_if_index_set = 1;
10749       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10750         ;
10751       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10752         ;
10753       else if (unformat (i, "other-table %d", &other_table_index))
10754         ;
10755       else if (unformat (i, "is-input %d", &is_input))
10756         ;
10757       else
10758         {
10759           clib_warning ("parse error '%U'", format_unformat_error, i);
10760           return -99;
10761         }
10762     }
10763
10764   if (sw_if_index_set == 0)
10765     {
10766       errmsg ("missing interface name or sw_if_index");
10767       return -99;
10768     }
10769
10770
10771   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10772
10773   mp->sw_if_index = ntohl (sw_if_index);
10774   mp->ip4_table_index = ntohl (ip4_table_index);
10775   mp->ip6_table_index = ntohl (ip6_table_index);
10776   mp->other_table_index = ntohl (other_table_index);
10777   mp->is_input = (u8) is_input;
10778
10779   S (mp);
10780   W (ret);
10781   return ret;
10782 }
10783
10784 static int
10785 api_set_ipfix_exporter (vat_main_t * vam)
10786 {
10787   unformat_input_t *i = vam->input;
10788   vl_api_set_ipfix_exporter_t *mp;
10789   ip4_address_t collector_address;
10790   u8 collector_address_set = 0;
10791   u32 collector_port = ~0;
10792   ip4_address_t src_address;
10793   u8 src_address_set = 0;
10794   u32 vrf_id = ~0;
10795   u32 path_mtu = ~0;
10796   u32 template_interval = ~0;
10797   u8 udp_checksum = 0;
10798   int ret;
10799
10800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10801     {
10802       if (unformat (i, "collector_address %U", unformat_ip4_address,
10803                     &collector_address))
10804         collector_address_set = 1;
10805       else if (unformat (i, "collector_port %d", &collector_port))
10806         ;
10807       else if (unformat (i, "src_address %U", unformat_ip4_address,
10808                          &src_address))
10809         src_address_set = 1;
10810       else if (unformat (i, "vrf_id %d", &vrf_id))
10811         ;
10812       else if (unformat (i, "path_mtu %d", &path_mtu))
10813         ;
10814       else if (unformat (i, "template_interval %d", &template_interval))
10815         ;
10816       else if (unformat (i, "udp_checksum"))
10817         udp_checksum = 1;
10818       else
10819         break;
10820     }
10821
10822   if (collector_address_set == 0)
10823     {
10824       errmsg ("collector_address required");
10825       return -99;
10826     }
10827
10828   if (src_address_set == 0)
10829     {
10830       errmsg ("src_address required");
10831       return -99;
10832     }
10833
10834   M (SET_IPFIX_EXPORTER, mp);
10835
10836   memcpy (mp->collector_address.un.ip4, collector_address.data,
10837           sizeof (collector_address.data));
10838   mp->collector_port = htons ((u16) collector_port);
10839   memcpy (mp->src_address.un.ip4, src_address.data,
10840           sizeof (src_address.data));
10841   mp->vrf_id = htonl (vrf_id);
10842   mp->path_mtu = htonl (path_mtu);
10843   mp->template_interval = htonl (template_interval);
10844   mp->udp_checksum = udp_checksum;
10845
10846   S (mp);
10847   W (ret);
10848   return ret;
10849 }
10850
10851 static int
10852 api_set_ipfix_classify_stream (vat_main_t * vam)
10853 {
10854   unformat_input_t *i = vam->input;
10855   vl_api_set_ipfix_classify_stream_t *mp;
10856   u32 domain_id = 0;
10857   u32 src_port = UDP_DST_PORT_ipfix;
10858   int ret;
10859
10860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10861     {
10862       if (unformat (i, "domain %d", &domain_id))
10863         ;
10864       else if (unformat (i, "src_port %d", &src_port))
10865         ;
10866       else
10867         {
10868           errmsg ("unknown input `%U'", format_unformat_error, i);
10869           return -99;
10870         }
10871     }
10872
10873   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10874
10875   mp->domain_id = htonl (domain_id);
10876   mp->src_port = htons ((u16) src_port);
10877
10878   S (mp);
10879   W (ret);
10880   return ret;
10881 }
10882
10883 static int
10884 api_ipfix_classify_table_add_del (vat_main_t * vam)
10885 {
10886   unformat_input_t *i = vam->input;
10887   vl_api_ipfix_classify_table_add_del_t *mp;
10888   int is_add = -1;
10889   u32 classify_table_index = ~0;
10890   u8 ip_version = 0;
10891   u8 transport_protocol = 255;
10892   int ret;
10893
10894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10895     {
10896       if (unformat (i, "add"))
10897         is_add = 1;
10898       else if (unformat (i, "del"))
10899         is_add = 0;
10900       else if (unformat (i, "table %d", &classify_table_index))
10901         ;
10902       else if (unformat (i, "ip4"))
10903         ip_version = 4;
10904       else if (unformat (i, "ip6"))
10905         ip_version = 6;
10906       else if (unformat (i, "tcp"))
10907         transport_protocol = 6;
10908       else if (unformat (i, "udp"))
10909         transport_protocol = 17;
10910       else
10911         {
10912           errmsg ("unknown input `%U'", format_unformat_error, i);
10913           return -99;
10914         }
10915     }
10916
10917   if (is_add == -1)
10918     {
10919       errmsg ("expecting: add|del");
10920       return -99;
10921     }
10922   if (classify_table_index == ~0)
10923     {
10924       errmsg ("classifier table not specified");
10925       return -99;
10926     }
10927   if (ip_version == 0)
10928     {
10929       errmsg ("IP version not specified");
10930       return -99;
10931     }
10932
10933   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10934
10935   mp->is_add = is_add;
10936   mp->table_id = htonl (classify_table_index);
10937   mp->ip_version = ip_version;
10938   mp->transport_protocol = transport_protocol;
10939
10940   S (mp);
10941   W (ret);
10942   return ret;
10943 }
10944
10945 static int
10946 api_get_node_index (vat_main_t * vam)
10947 {
10948   unformat_input_t *i = vam->input;
10949   vl_api_get_node_index_t *mp;
10950   u8 *name = 0;
10951   int ret;
10952
10953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10954     {
10955       if (unformat (i, "node %s", &name))
10956         ;
10957       else
10958         break;
10959     }
10960   if (name == 0)
10961     {
10962       errmsg ("node name required");
10963       return -99;
10964     }
10965   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10966     {
10967       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10968       return -99;
10969     }
10970
10971   M (GET_NODE_INDEX, mp);
10972   clib_memcpy (mp->node_name, name, vec_len (name));
10973   vec_free (name);
10974
10975   S (mp);
10976   W (ret);
10977   return ret;
10978 }
10979
10980 static int
10981 api_get_next_index (vat_main_t * vam)
10982 {
10983   unformat_input_t *i = vam->input;
10984   vl_api_get_next_index_t *mp;
10985   u8 *node_name = 0, *next_node_name = 0;
10986   int ret;
10987
10988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10989     {
10990       if (unformat (i, "node-name %s", &node_name))
10991         ;
10992       else if (unformat (i, "next-node-name %s", &next_node_name))
10993         break;
10994     }
10995
10996   if (node_name == 0)
10997     {
10998       errmsg ("node name required");
10999       return -99;
11000     }
11001   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11002     {
11003       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11004       return -99;
11005     }
11006
11007   if (next_node_name == 0)
11008     {
11009       errmsg ("next node name required");
11010       return -99;
11011     }
11012   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11013     {
11014       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11015       return -99;
11016     }
11017
11018   M (GET_NEXT_INDEX, mp);
11019   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11020   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11021   vec_free (node_name);
11022   vec_free (next_node_name);
11023
11024   S (mp);
11025   W (ret);
11026   return ret;
11027 }
11028
11029 static int
11030 api_add_node_next (vat_main_t * vam)
11031 {
11032   unformat_input_t *i = vam->input;
11033   vl_api_add_node_next_t *mp;
11034   u8 *name = 0;
11035   u8 *next = 0;
11036   int ret;
11037
11038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11039     {
11040       if (unformat (i, "node %s", &name))
11041         ;
11042       else if (unformat (i, "next %s", &next))
11043         ;
11044       else
11045         break;
11046     }
11047   if (name == 0)
11048     {
11049       errmsg ("node name required");
11050       return -99;
11051     }
11052   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11053     {
11054       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11055       return -99;
11056     }
11057   if (next == 0)
11058     {
11059       errmsg ("next node required");
11060       return -99;
11061     }
11062   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11063     {
11064       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11065       return -99;
11066     }
11067
11068   M (ADD_NODE_NEXT, mp);
11069   clib_memcpy (mp->node_name, name, vec_len (name));
11070   clib_memcpy (mp->next_name, next, vec_len (next));
11071   vec_free (name);
11072   vec_free (next);
11073
11074   S (mp);
11075   W (ret);
11076   return ret;
11077 }
11078
11079 static int
11080 api_l2tpv3_create_tunnel (vat_main_t * vam)
11081 {
11082   unformat_input_t *i = vam->input;
11083   ip6_address_t client_address, our_address;
11084   int client_address_set = 0;
11085   int our_address_set = 0;
11086   u32 local_session_id = 0;
11087   u32 remote_session_id = 0;
11088   u64 local_cookie = 0;
11089   u64 remote_cookie = 0;
11090   u8 l2_sublayer_present = 0;
11091   vl_api_l2tpv3_create_tunnel_t *mp;
11092   int ret;
11093
11094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11095     {
11096       if (unformat (i, "client_address %U", unformat_ip6_address,
11097                     &client_address))
11098         client_address_set = 1;
11099       else if (unformat (i, "our_address %U", unformat_ip6_address,
11100                          &our_address))
11101         our_address_set = 1;
11102       else if (unformat (i, "local_session_id %d", &local_session_id))
11103         ;
11104       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11105         ;
11106       else if (unformat (i, "local_cookie %lld", &local_cookie))
11107         ;
11108       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11109         ;
11110       else if (unformat (i, "l2-sublayer-present"))
11111         l2_sublayer_present = 1;
11112       else
11113         break;
11114     }
11115
11116   if (client_address_set == 0)
11117     {
11118       errmsg ("client_address required");
11119       return -99;
11120     }
11121
11122   if (our_address_set == 0)
11123     {
11124       errmsg ("our_address required");
11125       return -99;
11126     }
11127
11128   M (L2TPV3_CREATE_TUNNEL, mp);
11129
11130   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11131                sizeof (ip6_address_t));
11132
11133   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11134                sizeof (ip6_address_t));
11135
11136   mp->local_session_id = ntohl (local_session_id);
11137   mp->remote_session_id = ntohl (remote_session_id);
11138   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11139   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11140   mp->l2_sublayer_present = l2_sublayer_present;
11141
11142   S (mp);
11143   W (ret);
11144   return ret;
11145 }
11146
11147 static int
11148 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11149 {
11150   unformat_input_t *i = vam->input;
11151   u32 sw_if_index;
11152   u8 sw_if_index_set = 0;
11153   u64 new_local_cookie = 0;
11154   u64 new_remote_cookie = 0;
11155   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11156   int ret;
11157
11158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11159     {
11160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11161         sw_if_index_set = 1;
11162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11163         sw_if_index_set = 1;
11164       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11165         ;
11166       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11167         ;
11168       else
11169         break;
11170     }
11171
11172   if (sw_if_index_set == 0)
11173     {
11174       errmsg ("missing interface name or sw_if_index");
11175       return -99;
11176     }
11177
11178   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11179
11180   mp->sw_if_index = ntohl (sw_if_index);
11181   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11182   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11183
11184   S (mp);
11185   W (ret);
11186   return ret;
11187 }
11188
11189 static int
11190 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11191 {
11192   unformat_input_t *i = vam->input;
11193   vl_api_l2tpv3_interface_enable_disable_t *mp;
11194   u32 sw_if_index;
11195   u8 sw_if_index_set = 0;
11196   u8 enable_disable = 1;
11197   int ret;
11198
11199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11200     {
11201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11202         sw_if_index_set = 1;
11203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11204         sw_if_index_set = 1;
11205       else if (unformat (i, "enable"))
11206         enable_disable = 1;
11207       else if (unformat (i, "disable"))
11208         enable_disable = 0;
11209       else
11210         break;
11211     }
11212
11213   if (sw_if_index_set == 0)
11214     {
11215       errmsg ("missing interface name or sw_if_index");
11216       return -99;
11217     }
11218
11219   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11220
11221   mp->sw_if_index = ntohl (sw_if_index);
11222   mp->enable_disable = enable_disable;
11223
11224   S (mp);
11225   W (ret);
11226   return ret;
11227 }
11228
11229 static int
11230 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11231 {
11232   unformat_input_t *i = vam->input;
11233   vl_api_l2tpv3_set_lookup_key_t *mp;
11234   u8 key = ~0;
11235   int ret;
11236
11237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11238     {
11239       if (unformat (i, "lookup_v6_src"))
11240         key = L2T_LOOKUP_SRC_ADDRESS;
11241       else if (unformat (i, "lookup_v6_dst"))
11242         key = L2T_LOOKUP_DST_ADDRESS;
11243       else if (unformat (i, "lookup_session_id"))
11244         key = L2T_LOOKUP_SESSION_ID;
11245       else
11246         break;
11247     }
11248
11249   if (key == (u8) ~ 0)
11250     {
11251       errmsg ("l2tp session lookup key unset");
11252       return -99;
11253     }
11254
11255   M (L2TPV3_SET_LOOKUP_KEY, mp);
11256
11257   mp->key = key;
11258
11259   S (mp);
11260   W (ret);
11261   return ret;
11262 }
11263
11264 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11265   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11266 {
11267   vat_main_t *vam = &vat_main;
11268
11269   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11270          format_ip6_address, mp->our_address,
11271          format_ip6_address, mp->client_address,
11272          clib_net_to_host_u32 (mp->sw_if_index));
11273
11274   print (vam->ofp,
11275          "   local cookies %016llx %016llx remote cookie %016llx",
11276          clib_net_to_host_u64 (mp->local_cookie[0]),
11277          clib_net_to_host_u64 (mp->local_cookie[1]),
11278          clib_net_to_host_u64 (mp->remote_cookie));
11279
11280   print (vam->ofp, "   local session-id %d remote session-id %d",
11281          clib_net_to_host_u32 (mp->local_session_id),
11282          clib_net_to_host_u32 (mp->remote_session_id));
11283
11284   print (vam->ofp, "   l2 specific sublayer %s\n",
11285          mp->l2_sublayer_present ? "preset" : "absent");
11286
11287 }
11288
11289 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11290   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11291 {
11292   vat_main_t *vam = &vat_main;
11293   vat_json_node_t *node = NULL;
11294   struct in6_addr addr;
11295
11296   if (VAT_JSON_ARRAY != vam->json_tree.type)
11297     {
11298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11299       vat_json_init_array (&vam->json_tree);
11300     }
11301   node = vat_json_array_add (&vam->json_tree);
11302
11303   vat_json_init_object (node);
11304
11305   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11306   vat_json_object_add_ip6 (node, "our_address", addr);
11307   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11308   vat_json_object_add_ip6 (node, "client_address", addr);
11309
11310   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11311   vat_json_init_array (lc);
11312   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11313   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11314   vat_json_object_add_uint (node, "remote_cookie",
11315                             clib_net_to_host_u64 (mp->remote_cookie));
11316
11317   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11318   vat_json_object_add_uint (node, "local_session_id",
11319                             clib_net_to_host_u32 (mp->local_session_id));
11320   vat_json_object_add_uint (node, "remote_session_id",
11321                             clib_net_to_host_u32 (mp->remote_session_id));
11322   vat_json_object_add_string_copy (node, "l2_sublayer",
11323                                    mp->l2_sublayer_present ? (u8 *) "present"
11324                                    : (u8 *) "absent");
11325 }
11326
11327 static int
11328 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11329 {
11330   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11331   vl_api_control_ping_t *mp_ping;
11332   int ret;
11333
11334   /* Get list of l2tpv3-tunnel interfaces */
11335   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11336   S (mp);
11337
11338   /* Use a control ping for synchronization */
11339   MPING (CONTROL_PING, mp_ping);
11340   S (mp_ping);
11341
11342   W (ret);
11343   return ret;
11344 }
11345
11346
11347 static void vl_api_sw_interface_tap_v2_details_t_handler
11348   (vl_api_sw_interface_tap_v2_details_t * mp)
11349 {
11350   vat_main_t *vam = &vat_main;
11351
11352   u8 *ip4 =
11353     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11354             mp->host_ip4_prefix.len);
11355   u8 *ip6 =
11356     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11357             mp->host_ip6_prefix.len);
11358
11359   print (vam->ofp,
11360          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11361          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11362          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11363          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11364          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11365
11366   vec_free (ip4);
11367   vec_free (ip6);
11368 }
11369
11370 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11371   (vl_api_sw_interface_tap_v2_details_t * mp)
11372 {
11373   vat_main_t *vam = &vat_main;
11374   vat_json_node_t *node = NULL;
11375
11376   if (VAT_JSON_ARRAY != vam->json_tree.type)
11377     {
11378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11379       vat_json_init_array (&vam->json_tree);
11380     }
11381   node = vat_json_array_add (&vam->json_tree);
11382
11383   vat_json_init_object (node);
11384   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11385   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11386   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11387   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11388   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11389   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11390   vat_json_object_add_string_copy (node, "host_mac_addr",
11391                                    format (0, "%U", format_ethernet_address,
11392                                            &mp->host_mac_addr));
11393   vat_json_object_add_string_copy (node, "host_namespace",
11394                                    mp->host_namespace);
11395   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11396   vat_json_object_add_string_copy (node, "host_ip4_addr",
11397                                    format (0, "%U/%d", format_ip4_address,
11398                                            mp->host_ip4_prefix.address,
11399                                            mp->host_ip4_prefix.len));
11400   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11401                                    format (0, "%U/%d", format_ip6_address,
11402                                            mp->host_ip6_prefix.address,
11403                                            mp->host_ip6_prefix.len));
11404
11405 }
11406
11407 static int
11408 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11409 {
11410   vl_api_sw_interface_tap_v2_dump_t *mp;
11411   vl_api_control_ping_t *mp_ping;
11412   int ret;
11413
11414   print (vam->ofp,
11415          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11416          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11417          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11418          "host_ip6_addr");
11419
11420   /* Get list of tap interfaces */
11421   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11422   S (mp);
11423
11424   /* Use a control ping for synchronization */
11425   MPING (CONTROL_PING, mp_ping);
11426   S (mp_ping);
11427
11428   W (ret);
11429   return ret;
11430 }
11431
11432 static void vl_api_sw_interface_virtio_pci_details_t_handler
11433   (vl_api_sw_interface_virtio_pci_details_t * mp)
11434 {
11435   vat_main_t *vam = &vat_main;
11436
11437   typedef union
11438   {
11439     struct
11440     {
11441       u16 domain;
11442       u8 bus;
11443       u8 slot:5;
11444       u8 function:3;
11445     };
11446     u32 as_u32;
11447   } pci_addr_t;
11448   pci_addr_t addr;
11449
11450   addr.domain = ntohs (mp->pci_addr.domain);
11451   addr.bus = mp->pci_addr.bus;
11452   addr.slot = mp->pci_addr.slot;
11453   addr.function = mp->pci_addr.function;
11454
11455   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11456                          addr.slot, addr.function);
11457
11458   print (vam->ofp,
11459          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11460          pci_addr, ntohl (mp->sw_if_index),
11461          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11462          format_ethernet_address, mp->mac_addr,
11463          clib_net_to_host_u64 (mp->features));
11464   vec_free (pci_addr);
11465 }
11466
11467 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11468   (vl_api_sw_interface_virtio_pci_details_t * mp)
11469 {
11470   vat_main_t *vam = &vat_main;
11471   vat_json_node_t *node = NULL;
11472   vlib_pci_addr_t pci_addr;
11473
11474   if (VAT_JSON_ARRAY != vam->json_tree.type)
11475     {
11476       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11477       vat_json_init_array (&vam->json_tree);
11478     }
11479   node = vat_json_array_add (&vam->json_tree);
11480
11481   pci_addr.domain = ntohs (mp->pci_addr.domain);
11482   pci_addr.bus = mp->pci_addr.bus;
11483   pci_addr.slot = mp->pci_addr.slot;
11484   pci_addr.function = mp->pci_addr.function;
11485
11486   vat_json_init_object (node);
11487   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11488   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11489   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11490   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11491   vat_json_object_add_uint (node, "features",
11492                             clib_net_to_host_u64 (mp->features));
11493   vat_json_object_add_string_copy (node, "mac_addr",
11494                                    format (0, "%U", format_ethernet_address,
11495                                            &mp->mac_addr));
11496 }
11497
11498 static int
11499 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11500 {
11501   vl_api_sw_interface_virtio_pci_dump_t *mp;
11502   vl_api_control_ping_t *mp_ping;
11503   int ret;
11504
11505   print (vam->ofp,
11506          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11507          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11508          "mac_addr", "features");
11509
11510   /* Get list of tap interfaces */
11511   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11512   S (mp);
11513
11514   /* Use a control ping for synchronization */
11515   MPING (CONTROL_PING, mp_ping);
11516   S (mp_ping);
11517
11518   W (ret);
11519   return ret;
11520 }
11521
11522 static int
11523 api_vxlan_offload_rx (vat_main_t * vam)
11524 {
11525   unformat_input_t *line_input = vam->input;
11526   vl_api_vxlan_offload_rx_t *mp;
11527   u32 hw_if_index = ~0, rx_if_index = ~0;
11528   u8 is_add = 1;
11529   int ret;
11530
11531   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11532     {
11533       if (unformat (line_input, "del"))
11534         is_add = 0;
11535       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11536                          &hw_if_index))
11537         ;
11538       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11539         ;
11540       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11541                          &rx_if_index))
11542         ;
11543       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11544         ;
11545       else
11546         {
11547           errmsg ("parse error '%U'", format_unformat_error, line_input);
11548           return -99;
11549         }
11550     }
11551
11552   if (hw_if_index == ~0)
11553     {
11554       errmsg ("no hw interface");
11555       return -99;
11556     }
11557
11558   if (rx_if_index == ~0)
11559     {
11560       errmsg ("no rx tunnel");
11561       return -99;
11562     }
11563
11564   M (VXLAN_OFFLOAD_RX, mp);
11565
11566   mp->hw_if_index = ntohl (hw_if_index);
11567   mp->sw_if_index = ntohl (rx_if_index);
11568   mp->enable = is_add;
11569
11570   S (mp);
11571   W (ret);
11572   return ret;
11573 }
11574
11575 static uword unformat_vxlan_decap_next
11576   (unformat_input_t * input, va_list * args)
11577 {
11578   u32 *result = va_arg (*args, u32 *);
11579   u32 tmp;
11580
11581   if (unformat (input, "l2"))
11582     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11583   else if (unformat (input, "%d", &tmp))
11584     *result = tmp;
11585   else
11586     return 0;
11587   return 1;
11588 }
11589
11590 static int
11591 api_vxlan_add_del_tunnel (vat_main_t * vam)
11592 {
11593   unformat_input_t *line_input = vam->input;
11594   vl_api_vxlan_add_del_tunnel_t *mp;
11595   ip46_address_t src, dst;
11596   u8 is_add = 1;
11597   u8 ipv4_set = 0, ipv6_set = 0;
11598   u8 src_set = 0;
11599   u8 dst_set = 0;
11600   u8 grp_set = 0;
11601   u32 instance = ~0;
11602   u32 mcast_sw_if_index = ~0;
11603   u32 encap_vrf_id = 0;
11604   u32 decap_next_index = ~0;
11605   u32 vni = 0;
11606   int ret;
11607
11608   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11609   clib_memset (&src, 0, sizeof src);
11610   clib_memset (&dst, 0, sizeof dst);
11611
11612   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11613     {
11614       if (unformat (line_input, "del"))
11615         is_add = 0;
11616       else if (unformat (line_input, "instance %d", &instance))
11617         ;
11618       else
11619         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11620         {
11621           ipv4_set = 1;
11622           src_set = 1;
11623         }
11624       else
11625         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11626         {
11627           ipv4_set = 1;
11628           dst_set = 1;
11629         }
11630       else
11631         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11632         {
11633           ipv6_set = 1;
11634           src_set = 1;
11635         }
11636       else
11637         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11638         {
11639           ipv6_set = 1;
11640           dst_set = 1;
11641         }
11642       else if (unformat (line_input, "group %U %U",
11643                          unformat_ip4_address, &dst.ip4,
11644                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11645         {
11646           grp_set = dst_set = 1;
11647           ipv4_set = 1;
11648         }
11649       else if (unformat (line_input, "group %U",
11650                          unformat_ip4_address, &dst.ip4))
11651         {
11652           grp_set = dst_set = 1;
11653           ipv4_set = 1;
11654         }
11655       else if (unformat (line_input, "group %U %U",
11656                          unformat_ip6_address, &dst.ip6,
11657                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11658         {
11659           grp_set = dst_set = 1;
11660           ipv6_set = 1;
11661         }
11662       else if (unformat (line_input, "group %U",
11663                          unformat_ip6_address, &dst.ip6))
11664         {
11665           grp_set = dst_set = 1;
11666           ipv6_set = 1;
11667         }
11668       else
11669         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11670         ;
11671       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11672         ;
11673       else if (unformat (line_input, "decap-next %U",
11674                          unformat_vxlan_decap_next, &decap_next_index))
11675         ;
11676       else if (unformat (line_input, "vni %d", &vni))
11677         ;
11678       else
11679         {
11680           errmsg ("parse error '%U'", format_unformat_error, line_input);
11681           return -99;
11682         }
11683     }
11684
11685   if (src_set == 0)
11686     {
11687       errmsg ("tunnel src address not specified");
11688       return -99;
11689     }
11690   if (dst_set == 0)
11691     {
11692       errmsg ("tunnel dst address not specified");
11693       return -99;
11694     }
11695
11696   if (grp_set && !ip46_address_is_multicast (&dst))
11697     {
11698       errmsg ("tunnel group address not multicast");
11699       return -99;
11700     }
11701   if (grp_set && mcast_sw_if_index == ~0)
11702     {
11703       errmsg ("tunnel nonexistent multicast device");
11704       return -99;
11705     }
11706   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11707     {
11708       errmsg ("tunnel dst address must be unicast");
11709       return -99;
11710     }
11711
11712
11713   if (ipv4_set && ipv6_set)
11714     {
11715       errmsg ("both IPv4 and IPv6 addresses specified");
11716       return -99;
11717     }
11718
11719   if ((vni == 0) || (vni >> 24))
11720     {
11721       errmsg ("vni not specified or out of range");
11722       return -99;
11723     }
11724
11725   M (VXLAN_ADD_DEL_TUNNEL, mp);
11726
11727   if (ipv6_set)
11728     {
11729       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11730       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11731     }
11732   else
11733     {
11734       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11735       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11736     }
11737   mp->src_address.af = ipv6_set;
11738   mp->dst_address.af = ipv6_set;
11739
11740   mp->instance = htonl (instance);
11741   mp->encap_vrf_id = ntohl (encap_vrf_id);
11742   mp->decap_next_index = ntohl (decap_next_index);
11743   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11744   mp->vni = ntohl (vni);
11745   mp->is_add = is_add;
11746
11747   S (mp);
11748   W (ret);
11749   return ret;
11750 }
11751
11752 static void vl_api_vxlan_tunnel_details_t_handler
11753   (vl_api_vxlan_tunnel_details_t * mp)
11754 {
11755   vat_main_t *vam = &vat_main;
11756   ip46_address_t src =
11757     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11758   ip46_address_t dst =
11759     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11760
11761   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11762          ntohl (mp->sw_if_index),
11763          ntohl (mp->instance),
11764          format_ip46_address, &src, IP46_TYPE_ANY,
11765          format_ip46_address, &dst, IP46_TYPE_ANY,
11766          ntohl (mp->encap_vrf_id),
11767          ntohl (mp->decap_next_index), ntohl (mp->vni),
11768          ntohl (mp->mcast_sw_if_index));
11769 }
11770
11771 static void vl_api_vxlan_tunnel_details_t_handler_json
11772   (vl_api_vxlan_tunnel_details_t * mp)
11773 {
11774   vat_main_t *vam = &vat_main;
11775   vat_json_node_t *node = NULL;
11776
11777   if (VAT_JSON_ARRAY != vam->json_tree.type)
11778     {
11779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11780       vat_json_init_array (&vam->json_tree);
11781     }
11782   node = vat_json_array_add (&vam->json_tree);
11783
11784   vat_json_init_object (node);
11785   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11786
11787   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11788
11789   if (mp->src_address.af)
11790     {
11791       struct in6_addr ip6;
11792
11793       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11794       vat_json_object_add_ip6 (node, "src_address", ip6);
11795       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11796       vat_json_object_add_ip6 (node, "dst_address", ip6);
11797     }
11798   else
11799     {
11800       struct in_addr ip4;
11801
11802       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11803       vat_json_object_add_ip4 (node, "src_address", ip4);
11804       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11805       vat_json_object_add_ip4 (node, "dst_address", ip4);
11806     }
11807   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11808   vat_json_object_add_uint (node, "decap_next_index",
11809                             ntohl (mp->decap_next_index));
11810   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11811   vat_json_object_add_uint (node, "mcast_sw_if_index",
11812                             ntohl (mp->mcast_sw_if_index));
11813 }
11814
11815 static int
11816 api_vxlan_tunnel_dump (vat_main_t * vam)
11817 {
11818   unformat_input_t *i = vam->input;
11819   vl_api_vxlan_tunnel_dump_t *mp;
11820   vl_api_control_ping_t *mp_ping;
11821   u32 sw_if_index;
11822   u8 sw_if_index_set = 0;
11823   int ret;
11824
11825   /* Parse args required to build the message */
11826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11827     {
11828       if (unformat (i, "sw_if_index %d", &sw_if_index))
11829         sw_if_index_set = 1;
11830       else
11831         break;
11832     }
11833
11834   if (sw_if_index_set == 0)
11835     {
11836       sw_if_index = ~0;
11837     }
11838
11839   if (!vam->json_output)
11840     {
11841       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11842              "sw_if_index", "instance", "src_address", "dst_address",
11843              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11844     }
11845
11846   /* Get list of vxlan-tunnel interfaces */
11847   M (VXLAN_TUNNEL_DUMP, mp);
11848
11849   mp->sw_if_index = htonl (sw_if_index);
11850
11851   S (mp);
11852
11853   /* Use a control ping for synchronization */
11854   MPING (CONTROL_PING, mp_ping);
11855   S (mp_ping);
11856
11857   W (ret);
11858   return ret;
11859 }
11860
11861 static uword unformat_geneve_decap_next
11862   (unformat_input_t * input, va_list * args)
11863 {
11864   u32 *result = va_arg (*args, u32 *);
11865   u32 tmp;
11866
11867   if (unformat (input, "l2"))
11868     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11869   else if (unformat (input, "%d", &tmp))
11870     *result = tmp;
11871   else
11872     return 0;
11873   return 1;
11874 }
11875
11876 static int
11877 api_geneve_add_del_tunnel (vat_main_t * vam)
11878 {
11879   unformat_input_t *line_input = vam->input;
11880   vl_api_geneve_add_del_tunnel_t *mp;
11881   ip46_address_t src, dst;
11882   u8 is_add = 1;
11883   u8 ipv4_set = 0, ipv6_set = 0;
11884   u8 src_set = 0;
11885   u8 dst_set = 0;
11886   u8 grp_set = 0;
11887   u32 mcast_sw_if_index = ~0;
11888   u32 encap_vrf_id = 0;
11889   u32 decap_next_index = ~0;
11890   u32 vni = 0;
11891   int ret;
11892
11893   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11894   clib_memset (&src, 0, sizeof src);
11895   clib_memset (&dst, 0, sizeof dst);
11896
11897   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11898     {
11899       if (unformat (line_input, "del"))
11900         is_add = 0;
11901       else
11902         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11903         {
11904           ipv4_set = 1;
11905           src_set = 1;
11906         }
11907       else
11908         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11909         {
11910           ipv4_set = 1;
11911           dst_set = 1;
11912         }
11913       else
11914         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11915         {
11916           ipv6_set = 1;
11917           src_set = 1;
11918         }
11919       else
11920         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11921         {
11922           ipv6_set = 1;
11923           dst_set = 1;
11924         }
11925       else if (unformat (line_input, "group %U %U",
11926                          unformat_ip4_address, &dst.ip4,
11927                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11928         {
11929           grp_set = dst_set = 1;
11930           ipv4_set = 1;
11931         }
11932       else if (unformat (line_input, "group %U",
11933                          unformat_ip4_address, &dst.ip4))
11934         {
11935           grp_set = dst_set = 1;
11936           ipv4_set = 1;
11937         }
11938       else if (unformat (line_input, "group %U %U",
11939                          unformat_ip6_address, &dst.ip6,
11940                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11941         {
11942           grp_set = dst_set = 1;
11943           ipv6_set = 1;
11944         }
11945       else if (unformat (line_input, "group %U",
11946                          unformat_ip6_address, &dst.ip6))
11947         {
11948           grp_set = dst_set = 1;
11949           ipv6_set = 1;
11950         }
11951       else
11952         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11953         ;
11954       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11955         ;
11956       else if (unformat (line_input, "decap-next %U",
11957                          unformat_geneve_decap_next, &decap_next_index))
11958         ;
11959       else if (unformat (line_input, "vni %d", &vni))
11960         ;
11961       else
11962         {
11963           errmsg ("parse error '%U'", format_unformat_error, line_input);
11964           return -99;
11965         }
11966     }
11967
11968   if (src_set == 0)
11969     {
11970       errmsg ("tunnel src address not specified");
11971       return -99;
11972     }
11973   if (dst_set == 0)
11974     {
11975       errmsg ("tunnel dst address not specified");
11976       return -99;
11977     }
11978
11979   if (grp_set && !ip46_address_is_multicast (&dst))
11980     {
11981       errmsg ("tunnel group address not multicast");
11982       return -99;
11983     }
11984   if (grp_set && mcast_sw_if_index == ~0)
11985     {
11986       errmsg ("tunnel nonexistent multicast device");
11987       return -99;
11988     }
11989   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11990     {
11991       errmsg ("tunnel dst address must be unicast");
11992       return -99;
11993     }
11994
11995
11996   if (ipv4_set && ipv6_set)
11997     {
11998       errmsg ("both IPv4 and IPv6 addresses specified");
11999       return -99;
12000     }
12001
12002   if ((vni == 0) || (vni >> 24))
12003     {
12004       errmsg ("vni not specified or out of range");
12005       return -99;
12006     }
12007
12008   M (GENEVE_ADD_DEL_TUNNEL, mp);
12009
12010   if (ipv6_set)
12011     {
12012       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12013       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12014     }
12015   else
12016     {
12017       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12018       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12019     }
12020   mp->encap_vrf_id = ntohl (encap_vrf_id);
12021   mp->decap_next_index = ntohl (decap_next_index);
12022   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12023   mp->vni = ntohl (vni);
12024   mp->is_add = is_add;
12025
12026   S (mp);
12027   W (ret);
12028   return ret;
12029 }
12030
12031 static void vl_api_geneve_tunnel_details_t_handler
12032   (vl_api_geneve_tunnel_details_t * mp)
12033 {
12034   vat_main_t *vam = &vat_main;
12035   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12036   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12037
12038   if (mp->src_address.af == ADDRESS_IP6)
12039     {
12040       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12041       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12042     }
12043   else
12044     {
12045       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12046       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12047     }
12048
12049   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12050          ntohl (mp->sw_if_index),
12051          format_ip46_address, &src, IP46_TYPE_ANY,
12052          format_ip46_address, &dst, IP46_TYPE_ANY,
12053          ntohl (mp->encap_vrf_id),
12054          ntohl (mp->decap_next_index), ntohl (mp->vni),
12055          ntohl (mp->mcast_sw_if_index));
12056 }
12057
12058 static void vl_api_geneve_tunnel_details_t_handler_json
12059   (vl_api_geneve_tunnel_details_t * mp)
12060 {
12061   vat_main_t *vam = &vat_main;
12062   vat_json_node_t *node = NULL;
12063   bool is_ipv6;
12064
12065   if (VAT_JSON_ARRAY != vam->json_tree.type)
12066     {
12067       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12068       vat_json_init_array (&vam->json_tree);
12069     }
12070   node = vat_json_array_add (&vam->json_tree);
12071
12072   vat_json_init_object (node);
12073   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12074   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12075   if (is_ipv6)
12076     {
12077       struct in6_addr ip6;
12078
12079       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12080       vat_json_object_add_ip6 (node, "src_address", ip6);
12081       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12082       vat_json_object_add_ip6 (node, "dst_address", ip6);
12083     }
12084   else
12085     {
12086       struct in_addr ip4;
12087
12088       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12089       vat_json_object_add_ip4 (node, "src_address", ip4);
12090       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12091       vat_json_object_add_ip4 (node, "dst_address", ip4);
12092     }
12093   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12094   vat_json_object_add_uint (node, "decap_next_index",
12095                             ntohl (mp->decap_next_index));
12096   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12097   vat_json_object_add_uint (node, "mcast_sw_if_index",
12098                             ntohl (mp->mcast_sw_if_index));
12099 }
12100
12101 static int
12102 api_geneve_tunnel_dump (vat_main_t * vam)
12103 {
12104   unformat_input_t *i = vam->input;
12105   vl_api_geneve_tunnel_dump_t *mp;
12106   vl_api_control_ping_t *mp_ping;
12107   u32 sw_if_index;
12108   u8 sw_if_index_set = 0;
12109   int ret;
12110
12111   /* Parse args required to build the message */
12112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12113     {
12114       if (unformat (i, "sw_if_index %d", &sw_if_index))
12115         sw_if_index_set = 1;
12116       else
12117         break;
12118     }
12119
12120   if (sw_if_index_set == 0)
12121     {
12122       sw_if_index = ~0;
12123     }
12124
12125   if (!vam->json_output)
12126     {
12127       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12128              "sw_if_index", "local_address", "remote_address",
12129              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12130     }
12131
12132   /* Get list of geneve-tunnel interfaces */
12133   M (GENEVE_TUNNEL_DUMP, mp);
12134
12135   mp->sw_if_index = htonl (sw_if_index);
12136
12137   S (mp);
12138
12139   /* Use a control ping for synchronization */
12140   M (CONTROL_PING, mp_ping);
12141   S (mp_ping);
12142
12143   W (ret);
12144   return ret;
12145 }
12146
12147 static int
12148 api_gre_tunnel_add_del (vat_main_t * vam)
12149 {
12150   unformat_input_t *line_input = vam->input;
12151   vl_api_address_t src = { }, dst =
12152   {
12153   };
12154   vl_api_gre_tunnel_add_del_t *mp;
12155   vl_api_gre_tunnel_type_t t_type;
12156   u8 is_add = 1;
12157   u8 src_set = 0;
12158   u8 dst_set = 0;
12159   u32 outer_table_id = 0;
12160   u32 session_id = 0;
12161   u32 instance = ~0;
12162   int ret;
12163
12164   t_type = GRE_API_TUNNEL_TYPE_L3;
12165
12166   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12167     {
12168       if (unformat (line_input, "del"))
12169         is_add = 0;
12170       else if (unformat (line_input, "instance %d", &instance))
12171         ;
12172       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12173         {
12174           src_set = 1;
12175         }
12176       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12177         {
12178           dst_set = 1;
12179         }
12180       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12181         ;
12182       else if (unformat (line_input, "teb"))
12183         t_type = GRE_API_TUNNEL_TYPE_TEB;
12184       else if (unformat (line_input, "erspan %d", &session_id))
12185         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12186       else
12187         {
12188           errmsg ("parse error '%U'", format_unformat_error, line_input);
12189           return -99;
12190         }
12191     }
12192
12193   if (src_set == 0)
12194     {
12195       errmsg ("tunnel src address not specified");
12196       return -99;
12197     }
12198   if (dst_set == 0)
12199     {
12200       errmsg ("tunnel dst address not specified");
12201       return -99;
12202     }
12203
12204   M (GRE_TUNNEL_ADD_DEL, mp);
12205
12206   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12207   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12208
12209   mp->tunnel.instance = htonl (instance);
12210   mp->tunnel.outer_table_id = htonl (outer_table_id);
12211   mp->is_add = is_add;
12212   mp->tunnel.session_id = htons ((u16) session_id);
12213   mp->tunnel.type = htonl (t_type);
12214
12215   S (mp);
12216   W (ret);
12217   return ret;
12218 }
12219
12220 static void vl_api_gre_tunnel_details_t_handler
12221   (vl_api_gre_tunnel_details_t * mp)
12222 {
12223   vat_main_t *vam = &vat_main;
12224
12225   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12226          ntohl (mp->tunnel.sw_if_index),
12227          ntohl (mp->tunnel.instance),
12228          format_vl_api_address, &mp->tunnel.src,
12229          format_vl_api_address, &mp->tunnel.dst,
12230          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12231          ntohl (mp->tunnel.session_id));
12232 }
12233
12234 static void vl_api_gre_tunnel_details_t_handler_json
12235   (vl_api_gre_tunnel_details_t * mp)
12236 {
12237   vat_main_t *vam = &vat_main;
12238   vat_json_node_t *node = NULL;
12239
12240   if (VAT_JSON_ARRAY != vam->json_tree.type)
12241     {
12242       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12243       vat_json_init_array (&vam->json_tree);
12244     }
12245   node = vat_json_array_add (&vam->json_tree);
12246
12247   vat_json_init_object (node);
12248   vat_json_object_add_uint (node, "sw_if_index",
12249                             ntohl (mp->tunnel.sw_if_index));
12250   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12251
12252   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12253   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12254   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12255   vat_json_object_add_uint (node, "outer_table_id",
12256                             ntohl (mp->tunnel.outer_table_id));
12257   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12258 }
12259
12260 static int
12261 api_gre_tunnel_dump (vat_main_t * vam)
12262 {
12263   unformat_input_t *i = vam->input;
12264   vl_api_gre_tunnel_dump_t *mp;
12265   vl_api_control_ping_t *mp_ping;
12266   u32 sw_if_index;
12267   u8 sw_if_index_set = 0;
12268   int ret;
12269
12270   /* Parse args required to build the message */
12271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12272     {
12273       if (unformat (i, "sw_if_index %d", &sw_if_index))
12274         sw_if_index_set = 1;
12275       else
12276         break;
12277     }
12278
12279   if (sw_if_index_set == 0)
12280     {
12281       sw_if_index = ~0;
12282     }
12283
12284   if (!vam->json_output)
12285     {
12286       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12287              "sw_if_index", "instance", "src_address", "dst_address",
12288              "tunnel_type", "outer_fib_id", "session_id");
12289     }
12290
12291   /* Get list of gre-tunnel interfaces */
12292   M (GRE_TUNNEL_DUMP, mp);
12293
12294   mp->sw_if_index = htonl (sw_if_index);
12295
12296   S (mp);
12297
12298   /* Use a control ping for synchronization */
12299   MPING (CONTROL_PING, mp_ping);
12300   S (mp_ping);
12301
12302   W (ret);
12303   return ret;
12304 }
12305
12306 static int
12307 api_l2_fib_clear_table (vat_main_t * vam)
12308 {
12309 //  unformat_input_t * i = vam->input;
12310   vl_api_l2_fib_clear_table_t *mp;
12311   int ret;
12312
12313   M (L2_FIB_CLEAR_TABLE, mp);
12314
12315   S (mp);
12316   W (ret);
12317   return ret;
12318 }
12319
12320 static int
12321 api_l2_interface_efp_filter (vat_main_t * vam)
12322 {
12323   unformat_input_t *i = vam->input;
12324   vl_api_l2_interface_efp_filter_t *mp;
12325   u32 sw_if_index;
12326   u8 enable = 1;
12327   u8 sw_if_index_set = 0;
12328   int ret;
12329
12330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12333         sw_if_index_set = 1;
12334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12335         sw_if_index_set = 1;
12336       else if (unformat (i, "enable"))
12337         enable = 1;
12338       else if (unformat (i, "disable"))
12339         enable = 0;
12340       else
12341         {
12342           clib_warning ("parse error '%U'", format_unformat_error, i);
12343           return -99;
12344         }
12345     }
12346
12347   if (sw_if_index_set == 0)
12348     {
12349       errmsg ("missing sw_if_index");
12350       return -99;
12351     }
12352
12353   M (L2_INTERFACE_EFP_FILTER, mp);
12354
12355   mp->sw_if_index = ntohl (sw_if_index);
12356   mp->enable_disable = enable;
12357
12358   S (mp);
12359   W (ret);
12360   return ret;
12361 }
12362
12363 #define foreach_vtr_op                          \
12364 _("disable",  L2_VTR_DISABLED)                  \
12365 _("push-1",  L2_VTR_PUSH_1)                     \
12366 _("push-2",  L2_VTR_PUSH_2)                     \
12367 _("pop-1",  L2_VTR_POP_1)                       \
12368 _("pop-2",  L2_VTR_POP_2)                       \
12369 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12370 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12371 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12372 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12373
12374 static int
12375 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12376 {
12377   unformat_input_t *i = vam->input;
12378   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12379   u32 sw_if_index;
12380   u8 sw_if_index_set = 0;
12381   u8 vtr_op_set = 0;
12382   u32 vtr_op = 0;
12383   u32 push_dot1q = 1;
12384   u32 tag1 = ~0;
12385   u32 tag2 = ~0;
12386   int ret;
12387
12388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12389     {
12390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12391         sw_if_index_set = 1;
12392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12393         sw_if_index_set = 1;
12394       else if (unformat (i, "vtr_op %d", &vtr_op))
12395         vtr_op_set = 1;
12396 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12397       foreach_vtr_op
12398 #undef _
12399         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12400         ;
12401       else if (unformat (i, "tag1 %d", &tag1))
12402         ;
12403       else if (unformat (i, "tag2 %d", &tag2))
12404         ;
12405       else
12406         {
12407           clib_warning ("parse error '%U'", format_unformat_error, i);
12408           return -99;
12409         }
12410     }
12411
12412   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12413     {
12414       errmsg ("missing vtr operation or sw_if_index");
12415       return -99;
12416     }
12417
12418   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12419   mp->sw_if_index = ntohl (sw_if_index);
12420   mp->vtr_op = ntohl (vtr_op);
12421   mp->push_dot1q = ntohl (push_dot1q);
12422   mp->tag1 = ntohl (tag1);
12423   mp->tag2 = ntohl (tag2);
12424
12425   S (mp);
12426   W (ret);
12427   return ret;
12428 }
12429
12430 static int
12431 api_create_vhost_user_if (vat_main_t * vam)
12432 {
12433   unformat_input_t *i = vam->input;
12434   vl_api_create_vhost_user_if_t *mp;
12435   u8 *file_name;
12436   u8 is_server = 0;
12437   u8 file_name_set = 0;
12438   u32 custom_dev_instance = ~0;
12439   u8 hwaddr[6];
12440   u8 use_custom_mac = 0;
12441   u8 disable_mrg_rxbuf = 0;
12442   u8 disable_indirect_desc = 0;
12443   u8 *tag = 0;
12444   u8 enable_gso = 0;
12445   u8 enable_packed = 0;
12446   int ret;
12447
12448   /* Shut up coverity */
12449   clib_memset (hwaddr, 0, sizeof (hwaddr));
12450
12451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12452     {
12453       if (unformat (i, "socket %s", &file_name))
12454         {
12455           file_name_set = 1;
12456         }
12457       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12458         ;
12459       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12460         use_custom_mac = 1;
12461       else if (unformat (i, "server"))
12462         is_server = 1;
12463       else if (unformat (i, "disable_mrg_rxbuf"))
12464         disable_mrg_rxbuf = 1;
12465       else if (unformat (i, "disable_indirect_desc"))
12466         disable_indirect_desc = 1;
12467       else if (unformat (i, "gso"))
12468         enable_gso = 1;
12469       else if (unformat (i, "packed"))
12470         enable_packed = 1;
12471       else if (unformat (i, "tag %s", &tag))
12472         ;
12473       else
12474         break;
12475     }
12476
12477   if (file_name_set == 0)
12478     {
12479       errmsg ("missing socket file name");
12480       return -99;
12481     }
12482
12483   if (vec_len (file_name) > 255)
12484     {
12485       errmsg ("socket file name too long");
12486       return -99;
12487     }
12488   vec_add1 (file_name, 0);
12489
12490   M (CREATE_VHOST_USER_IF, mp);
12491
12492   mp->is_server = is_server;
12493   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12494   mp->disable_indirect_desc = disable_indirect_desc;
12495   mp->enable_gso = enable_gso;
12496   mp->enable_packed = enable_packed;
12497   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12498   vec_free (file_name);
12499   if (custom_dev_instance != ~0)
12500     {
12501       mp->renumber = 1;
12502       mp->custom_dev_instance = ntohl (custom_dev_instance);
12503     }
12504
12505   mp->use_custom_mac = use_custom_mac;
12506   clib_memcpy (mp->mac_address, hwaddr, 6);
12507   if (tag)
12508     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12509   vec_free (tag);
12510
12511   S (mp);
12512   W (ret);
12513   return ret;
12514 }
12515
12516 static int
12517 api_modify_vhost_user_if (vat_main_t * vam)
12518 {
12519   unformat_input_t *i = vam->input;
12520   vl_api_modify_vhost_user_if_t *mp;
12521   u8 *file_name;
12522   u8 is_server = 0;
12523   u8 file_name_set = 0;
12524   u32 custom_dev_instance = ~0;
12525   u8 sw_if_index_set = 0;
12526   u32 sw_if_index = (u32) ~ 0;
12527   u8 enable_gso = 0;
12528   u8 enable_packed = 0;
12529   int ret;
12530
12531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12532     {
12533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12534         sw_if_index_set = 1;
12535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12536         sw_if_index_set = 1;
12537       else if (unformat (i, "socket %s", &file_name))
12538         {
12539           file_name_set = 1;
12540         }
12541       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12542         ;
12543       else if (unformat (i, "server"))
12544         is_server = 1;
12545       else if (unformat (i, "gso"))
12546         enable_gso = 1;
12547       else if (unformat (i, "packed"))
12548         enable_packed = 1;
12549       else
12550         break;
12551     }
12552
12553   if (sw_if_index_set == 0)
12554     {
12555       errmsg ("missing sw_if_index or interface name");
12556       return -99;
12557     }
12558
12559   if (file_name_set == 0)
12560     {
12561       errmsg ("missing socket file name");
12562       return -99;
12563     }
12564
12565   if (vec_len (file_name) > 255)
12566     {
12567       errmsg ("socket file name too long");
12568       return -99;
12569     }
12570   vec_add1 (file_name, 0);
12571
12572   M (MODIFY_VHOST_USER_IF, mp);
12573
12574   mp->sw_if_index = ntohl (sw_if_index);
12575   mp->is_server = is_server;
12576   mp->enable_gso = enable_gso;
12577   mp->enable_packed = enable_packed;
12578   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12579   vec_free (file_name);
12580   if (custom_dev_instance != ~0)
12581     {
12582       mp->renumber = 1;
12583       mp->custom_dev_instance = ntohl (custom_dev_instance);
12584     }
12585
12586   S (mp);
12587   W (ret);
12588   return ret;
12589 }
12590
12591 static int
12592 api_delete_vhost_user_if (vat_main_t * vam)
12593 {
12594   unformat_input_t *i = vam->input;
12595   vl_api_delete_vhost_user_if_t *mp;
12596   u32 sw_if_index = ~0;
12597   u8 sw_if_index_set = 0;
12598   int ret;
12599
12600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12601     {
12602       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12603         sw_if_index_set = 1;
12604       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12605         sw_if_index_set = 1;
12606       else
12607         break;
12608     }
12609
12610   if (sw_if_index_set == 0)
12611     {
12612       errmsg ("missing sw_if_index or interface name");
12613       return -99;
12614     }
12615
12616
12617   M (DELETE_VHOST_USER_IF, mp);
12618
12619   mp->sw_if_index = ntohl (sw_if_index);
12620
12621   S (mp);
12622   W (ret);
12623   return ret;
12624 }
12625
12626 static void vl_api_sw_interface_vhost_user_details_t_handler
12627   (vl_api_sw_interface_vhost_user_details_t * mp)
12628 {
12629   vat_main_t *vam = &vat_main;
12630   u64 features;
12631
12632   features =
12633     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12634                                                     clib_net_to_host_u32
12635                                                     (mp->features_last_32) <<
12636                                                     32);
12637
12638   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12639          (char *) mp->interface_name,
12640          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12641          features, mp->is_server,
12642          ntohl (mp->num_regions), (char *) mp->sock_filename);
12643   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12644 }
12645
12646 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12647   (vl_api_sw_interface_vhost_user_details_t * mp)
12648 {
12649   vat_main_t *vam = &vat_main;
12650   vat_json_node_t *node = NULL;
12651
12652   if (VAT_JSON_ARRAY != vam->json_tree.type)
12653     {
12654       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12655       vat_json_init_array (&vam->json_tree);
12656     }
12657   node = vat_json_array_add (&vam->json_tree);
12658
12659   vat_json_init_object (node);
12660   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12661   vat_json_object_add_string_copy (node, "interface_name",
12662                                    mp->interface_name);
12663   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12664                             ntohl (mp->virtio_net_hdr_sz));
12665   vat_json_object_add_uint (node, "features_first_32",
12666                             clib_net_to_host_u32 (mp->features_first_32));
12667   vat_json_object_add_uint (node, "features_last_32",
12668                             clib_net_to_host_u32 (mp->features_last_32));
12669   vat_json_object_add_uint (node, "is_server", mp->is_server);
12670   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12671   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12672   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12673 }
12674
12675 static int
12676 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12677 {
12678   vl_api_sw_interface_vhost_user_dump_t *mp;
12679   vl_api_control_ping_t *mp_ping;
12680   int ret;
12681   print (vam->ofp,
12682          "Interface name            idx hdr_sz features server regions filename");
12683
12684   /* Get list of vhost-user interfaces */
12685   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12686   mp->sw_if_index = ntohl (~0);
12687   S (mp);
12688
12689   /* Use a control ping for synchronization */
12690   MPING (CONTROL_PING, mp_ping);
12691   S (mp_ping);
12692
12693   W (ret);
12694   return ret;
12695 }
12696
12697 static int
12698 api_show_version (vat_main_t * vam)
12699 {
12700   vl_api_show_version_t *mp;
12701   int ret;
12702
12703   M (SHOW_VERSION, mp);
12704
12705   S (mp);
12706   W (ret);
12707   return ret;
12708 }
12709
12710
12711 static int
12712 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12713 {
12714   unformat_input_t *line_input = vam->input;
12715   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12716   ip46_address_t local, remote;
12717   u8 is_add = 1;
12718   u8 local_set = 0;
12719   u8 remote_set = 0;
12720   u8 grp_set = 0;
12721   u32 mcast_sw_if_index = ~0;
12722   u32 encap_vrf_id = 0;
12723   u32 decap_vrf_id = 0;
12724   u8 protocol = ~0;
12725   u32 vni;
12726   u8 vni_set = 0;
12727   int ret;
12728
12729   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12730     {
12731       if (unformat (line_input, "del"))
12732         is_add = 0;
12733       else if (unformat (line_input, "local %U",
12734                          unformat_ip46_address, &local))
12735         {
12736           local_set = 1;
12737         }
12738       else if (unformat (line_input, "remote %U",
12739                          unformat_ip46_address, &remote))
12740         {
12741           remote_set = 1;
12742         }
12743       else if (unformat (line_input, "group %U %U",
12744                          unformat_ip46_address, &remote,
12745                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12746         {
12747           grp_set = remote_set = 1;
12748         }
12749       else if (unformat (line_input, "group %U",
12750                          unformat_ip46_address, &remote))
12751         {
12752           grp_set = remote_set = 1;
12753         }
12754       else
12755         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12756         ;
12757       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12758         ;
12759       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12760         ;
12761       else if (unformat (line_input, "vni %d", &vni))
12762         vni_set = 1;
12763       else if (unformat (line_input, "next-ip4"))
12764         protocol = 1;
12765       else if (unformat (line_input, "next-ip6"))
12766         protocol = 2;
12767       else if (unformat (line_input, "next-ethernet"))
12768         protocol = 3;
12769       else if (unformat (line_input, "next-nsh"))
12770         protocol = 4;
12771       else
12772         {
12773           errmsg ("parse error '%U'", format_unformat_error, line_input);
12774           return -99;
12775         }
12776     }
12777
12778   if (local_set == 0)
12779     {
12780       errmsg ("tunnel local address not specified");
12781       return -99;
12782     }
12783   if (remote_set == 0)
12784     {
12785       errmsg ("tunnel remote address not specified");
12786       return -99;
12787     }
12788   if (grp_set && mcast_sw_if_index == ~0)
12789     {
12790       errmsg ("tunnel nonexistent multicast device");
12791       return -99;
12792     }
12793   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12794     {
12795       errmsg ("both IPv4 and IPv6 addresses specified");
12796       return -99;
12797     }
12798
12799   if (vni_set == 0)
12800     {
12801       errmsg ("vni not specified");
12802       return -99;
12803     }
12804
12805   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12806
12807   ip_address_encode (&local,
12808                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12809                      IP46_TYPE_IP6, &mp->local);
12810   ip_address_encode (&remote,
12811                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12812                      IP46_TYPE_IP6, &mp->remote);
12813
12814   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12815   mp->encap_vrf_id = ntohl (encap_vrf_id);
12816   mp->decap_vrf_id = ntohl (decap_vrf_id);
12817   mp->protocol = protocol;
12818   mp->vni = ntohl (vni);
12819   mp->is_add = is_add;
12820
12821   S (mp);
12822   W (ret);
12823   return ret;
12824 }
12825
12826 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12827   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12828 {
12829   vat_main_t *vam = &vat_main;
12830   ip46_address_t local, remote;
12831
12832   ip_address_decode (&mp->local, &local);
12833   ip_address_decode (&mp->remote, &remote);
12834
12835   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12836          ntohl (mp->sw_if_index),
12837          format_ip46_address, &local, IP46_TYPE_ANY,
12838          format_ip46_address, &remote, IP46_TYPE_ANY,
12839          ntohl (mp->vni), mp->protocol,
12840          ntohl (mp->mcast_sw_if_index),
12841          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12842 }
12843
12844
12845 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12846   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12847 {
12848   vat_main_t *vam = &vat_main;
12849   vat_json_node_t *node = NULL;
12850   struct in_addr ip4;
12851   struct in6_addr ip6;
12852   ip46_address_t local, remote;
12853
12854   ip_address_decode (&mp->local, &local);
12855   ip_address_decode (&mp->remote, &remote);
12856
12857   if (VAT_JSON_ARRAY != vam->json_tree.type)
12858     {
12859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12860       vat_json_init_array (&vam->json_tree);
12861     }
12862   node = vat_json_array_add (&vam->json_tree);
12863
12864   vat_json_init_object (node);
12865   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12866   if (ip46_address_is_ip4 (&local))
12867     {
12868       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12869       vat_json_object_add_ip4 (node, "local", ip4);
12870       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12871       vat_json_object_add_ip4 (node, "remote", ip4);
12872     }
12873   else
12874     {
12875       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12876       vat_json_object_add_ip6 (node, "local", ip6);
12877       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12878       vat_json_object_add_ip6 (node, "remote", ip6);
12879     }
12880   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12881   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12882   vat_json_object_add_uint (node, "mcast_sw_if_index",
12883                             ntohl (mp->mcast_sw_if_index));
12884   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12885   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12886   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12887 }
12888
12889 static int
12890 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12891 {
12892   unformat_input_t *i = vam->input;
12893   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12894   vl_api_control_ping_t *mp_ping;
12895   u32 sw_if_index;
12896   u8 sw_if_index_set = 0;
12897   int ret;
12898
12899   /* Parse args required to build the message */
12900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12901     {
12902       if (unformat (i, "sw_if_index %d", &sw_if_index))
12903         sw_if_index_set = 1;
12904       else
12905         break;
12906     }
12907
12908   if (sw_if_index_set == 0)
12909     {
12910       sw_if_index = ~0;
12911     }
12912
12913   if (!vam->json_output)
12914     {
12915       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12916              "sw_if_index", "local", "remote", "vni",
12917              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12918     }
12919
12920   /* Get list of vxlan-tunnel interfaces */
12921   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12922
12923   mp->sw_if_index = htonl (sw_if_index);
12924
12925   S (mp);
12926
12927   /* Use a control ping for synchronization */
12928   MPING (CONTROL_PING, mp_ping);
12929   S (mp_ping);
12930
12931   W (ret);
12932   return ret;
12933 }
12934
12935 static void vl_api_l2_fib_table_details_t_handler
12936   (vl_api_l2_fib_table_details_t * mp)
12937 {
12938   vat_main_t *vam = &vat_main;
12939
12940   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12941          "       %d       %d     %d",
12942          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12943          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12944          mp->bvi_mac);
12945 }
12946
12947 static void vl_api_l2_fib_table_details_t_handler_json
12948   (vl_api_l2_fib_table_details_t * mp)
12949 {
12950   vat_main_t *vam = &vat_main;
12951   vat_json_node_t *node = NULL;
12952
12953   if (VAT_JSON_ARRAY != vam->json_tree.type)
12954     {
12955       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12956       vat_json_init_array (&vam->json_tree);
12957     }
12958   node = vat_json_array_add (&vam->json_tree);
12959
12960   vat_json_init_object (node);
12961   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12962   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12963   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12964   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12965   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12966   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12967 }
12968
12969 static int
12970 api_l2_fib_table_dump (vat_main_t * vam)
12971 {
12972   unformat_input_t *i = vam->input;
12973   vl_api_l2_fib_table_dump_t *mp;
12974   vl_api_control_ping_t *mp_ping;
12975   u32 bd_id;
12976   u8 bd_id_set = 0;
12977   int ret;
12978
12979   /* Parse args required to build the message */
12980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12981     {
12982       if (unformat (i, "bd_id %d", &bd_id))
12983         bd_id_set = 1;
12984       else
12985         break;
12986     }
12987
12988   if (bd_id_set == 0)
12989     {
12990       errmsg ("missing bridge domain");
12991       return -99;
12992     }
12993
12994   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12995
12996   /* Get list of l2 fib entries */
12997   M (L2_FIB_TABLE_DUMP, mp);
12998
12999   mp->bd_id = ntohl (bd_id);
13000   S (mp);
13001
13002   /* Use a control ping for synchronization */
13003   MPING (CONTROL_PING, mp_ping);
13004   S (mp_ping);
13005
13006   W (ret);
13007   return ret;
13008 }
13009
13010
13011 static int
13012 api_interface_name_renumber (vat_main_t * vam)
13013 {
13014   unformat_input_t *line_input = vam->input;
13015   vl_api_interface_name_renumber_t *mp;
13016   u32 sw_if_index = ~0;
13017   u32 new_show_dev_instance = ~0;
13018   int ret;
13019
13020   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13021     {
13022       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13023                     &sw_if_index))
13024         ;
13025       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13026         ;
13027       else if (unformat (line_input, "new_show_dev_instance %d",
13028                          &new_show_dev_instance))
13029         ;
13030       else
13031         break;
13032     }
13033
13034   if (sw_if_index == ~0)
13035     {
13036       errmsg ("missing interface name or sw_if_index");
13037       return -99;
13038     }
13039
13040   if (new_show_dev_instance == ~0)
13041     {
13042       errmsg ("missing new_show_dev_instance");
13043       return -99;
13044     }
13045
13046   M (INTERFACE_NAME_RENUMBER, mp);
13047
13048   mp->sw_if_index = ntohl (sw_if_index);
13049   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13050
13051   S (mp);
13052   W (ret);
13053   return ret;
13054 }
13055
13056 static int
13057 api_want_l2_macs_events (vat_main_t * vam)
13058 {
13059   unformat_input_t *line_input = vam->input;
13060   vl_api_want_l2_macs_events_t *mp;
13061   u8 enable_disable = 1;
13062   u32 scan_delay = 0;
13063   u32 max_macs_in_event = 0;
13064   u32 learn_limit = 0;
13065   int ret;
13066
13067   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13068     {
13069       if (unformat (line_input, "learn-limit %d", &learn_limit))
13070         ;
13071       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13072         ;
13073       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13074         ;
13075       else if (unformat (line_input, "disable"))
13076         enable_disable = 0;
13077       else
13078         break;
13079     }
13080
13081   M (WANT_L2_MACS_EVENTS, mp);
13082   mp->enable_disable = enable_disable;
13083   mp->pid = htonl (getpid ());
13084   mp->learn_limit = htonl (learn_limit);
13085   mp->scan_delay = (u8) scan_delay;
13086   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13087   S (mp);
13088   W (ret);
13089   return ret;
13090 }
13091
13092 static int
13093 api_input_acl_set_interface (vat_main_t * vam)
13094 {
13095   unformat_input_t *i = vam->input;
13096   vl_api_input_acl_set_interface_t *mp;
13097   u32 sw_if_index;
13098   int sw_if_index_set;
13099   u32 ip4_table_index = ~0;
13100   u32 ip6_table_index = ~0;
13101   u32 l2_table_index = ~0;
13102   u8 is_add = 1;
13103   int ret;
13104
13105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13106     {
13107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13108         sw_if_index_set = 1;
13109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13110         sw_if_index_set = 1;
13111       else if (unformat (i, "del"))
13112         is_add = 0;
13113       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13114         ;
13115       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13116         ;
13117       else if (unformat (i, "l2-table %d", &l2_table_index))
13118         ;
13119       else
13120         {
13121           clib_warning ("parse error '%U'", format_unformat_error, i);
13122           return -99;
13123         }
13124     }
13125
13126   if (sw_if_index_set == 0)
13127     {
13128       errmsg ("missing interface name or sw_if_index");
13129       return -99;
13130     }
13131
13132   M (INPUT_ACL_SET_INTERFACE, mp);
13133
13134   mp->sw_if_index = ntohl (sw_if_index);
13135   mp->ip4_table_index = ntohl (ip4_table_index);
13136   mp->ip6_table_index = ntohl (ip6_table_index);
13137   mp->l2_table_index = ntohl (l2_table_index);
13138   mp->is_add = is_add;
13139
13140   S (mp);
13141   W (ret);
13142   return ret;
13143 }
13144
13145 static int
13146 api_output_acl_set_interface (vat_main_t * vam)
13147 {
13148   unformat_input_t *i = vam->input;
13149   vl_api_output_acl_set_interface_t *mp;
13150   u32 sw_if_index;
13151   int sw_if_index_set;
13152   u32 ip4_table_index = ~0;
13153   u32 ip6_table_index = ~0;
13154   u32 l2_table_index = ~0;
13155   u8 is_add = 1;
13156   int ret;
13157
13158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13159     {
13160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13161         sw_if_index_set = 1;
13162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13163         sw_if_index_set = 1;
13164       else if (unformat (i, "del"))
13165         is_add = 0;
13166       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13167         ;
13168       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13169         ;
13170       else if (unformat (i, "l2-table %d", &l2_table_index))
13171         ;
13172       else
13173         {
13174           clib_warning ("parse error '%U'", format_unformat_error, i);
13175           return -99;
13176         }
13177     }
13178
13179   if (sw_if_index_set == 0)
13180     {
13181       errmsg ("missing interface name or sw_if_index");
13182       return -99;
13183     }
13184
13185   M (OUTPUT_ACL_SET_INTERFACE, mp);
13186
13187   mp->sw_if_index = ntohl (sw_if_index);
13188   mp->ip4_table_index = ntohl (ip4_table_index);
13189   mp->ip6_table_index = ntohl (ip6_table_index);
13190   mp->l2_table_index = ntohl (l2_table_index);
13191   mp->is_add = is_add;
13192
13193   S (mp);
13194   W (ret);
13195   return ret;
13196 }
13197
13198 static int
13199 api_ip_address_dump (vat_main_t * vam)
13200 {
13201   unformat_input_t *i = vam->input;
13202   vl_api_ip_address_dump_t *mp;
13203   vl_api_control_ping_t *mp_ping;
13204   u32 sw_if_index = ~0;
13205   u8 sw_if_index_set = 0;
13206   u8 ipv4_set = 0;
13207   u8 ipv6_set = 0;
13208   int ret;
13209
13210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13211     {
13212       if (unformat (i, "sw_if_index %d", &sw_if_index))
13213         sw_if_index_set = 1;
13214       else
13215         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13216         sw_if_index_set = 1;
13217       else if (unformat (i, "ipv4"))
13218         ipv4_set = 1;
13219       else if (unformat (i, "ipv6"))
13220         ipv6_set = 1;
13221       else
13222         break;
13223     }
13224
13225   if (ipv4_set && ipv6_set)
13226     {
13227       errmsg ("ipv4 and ipv6 flags cannot be both set");
13228       return -99;
13229     }
13230
13231   if ((!ipv4_set) && (!ipv6_set))
13232     {
13233       errmsg ("no ipv4 nor ipv6 flag set");
13234       return -99;
13235     }
13236
13237   if (sw_if_index_set == 0)
13238     {
13239       errmsg ("missing interface name or sw_if_index");
13240       return -99;
13241     }
13242
13243   vam->current_sw_if_index = sw_if_index;
13244   vam->is_ipv6 = ipv6_set;
13245
13246   M (IP_ADDRESS_DUMP, mp);
13247   mp->sw_if_index = ntohl (sw_if_index);
13248   mp->is_ipv6 = ipv6_set;
13249   S (mp);
13250
13251   /* Use a control ping for synchronization */
13252   MPING (CONTROL_PING, mp_ping);
13253   S (mp_ping);
13254
13255   W (ret);
13256   return ret;
13257 }
13258
13259 static int
13260 api_ip_dump (vat_main_t * vam)
13261 {
13262   vl_api_ip_dump_t *mp;
13263   vl_api_control_ping_t *mp_ping;
13264   unformat_input_t *in = vam->input;
13265   int ipv4_set = 0;
13266   int ipv6_set = 0;
13267   int is_ipv6;
13268   int i;
13269   int ret;
13270
13271   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13272     {
13273       if (unformat (in, "ipv4"))
13274         ipv4_set = 1;
13275       else if (unformat (in, "ipv6"))
13276         ipv6_set = 1;
13277       else
13278         break;
13279     }
13280
13281   if (ipv4_set && ipv6_set)
13282     {
13283       errmsg ("ipv4 and ipv6 flags cannot be both set");
13284       return -99;
13285     }
13286
13287   if ((!ipv4_set) && (!ipv6_set))
13288     {
13289       errmsg ("no ipv4 nor ipv6 flag set");
13290       return -99;
13291     }
13292
13293   is_ipv6 = ipv6_set;
13294   vam->is_ipv6 = is_ipv6;
13295
13296   /* free old data */
13297   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13298     {
13299       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13300     }
13301   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13302
13303   M (IP_DUMP, mp);
13304   mp->is_ipv6 = ipv6_set;
13305   S (mp);
13306
13307   /* Use a control ping for synchronization */
13308   MPING (CONTROL_PING, mp_ping);
13309   S (mp_ping);
13310
13311   W (ret);
13312   return ret;
13313 }
13314
13315 static int
13316 api_ipsec_spd_add_del (vat_main_t * vam)
13317 {
13318   unformat_input_t *i = vam->input;
13319   vl_api_ipsec_spd_add_del_t *mp;
13320   u32 spd_id = ~0;
13321   u8 is_add = 1;
13322   int ret;
13323
13324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13325     {
13326       if (unformat (i, "spd_id %d", &spd_id))
13327         ;
13328       else if (unformat (i, "del"))
13329         is_add = 0;
13330       else
13331         {
13332           clib_warning ("parse error '%U'", format_unformat_error, i);
13333           return -99;
13334         }
13335     }
13336   if (spd_id == ~0)
13337     {
13338       errmsg ("spd_id must be set");
13339       return -99;
13340     }
13341
13342   M (IPSEC_SPD_ADD_DEL, mp);
13343
13344   mp->spd_id = ntohl (spd_id);
13345   mp->is_add = is_add;
13346
13347   S (mp);
13348   W (ret);
13349   return ret;
13350 }
13351
13352 static int
13353 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13354 {
13355   unformat_input_t *i = vam->input;
13356   vl_api_ipsec_interface_add_del_spd_t *mp;
13357   u32 sw_if_index;
13358   u8 sw_if_index_set = 0;
13359   u32 spd_id = (u32) ~ 0;
13360   u8 is_add = 1;
13361   int ret;
13362
13363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13364     {
13365       if (unformat (i, "del"))
13366         is_add = 0;
13367       else if (unformat (i, "spd_id %d", &spd_id))
13368         ;
13369       else
13370         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13371         sw_if_index_set = 1;
13372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13373         sw_if_index_set = 1;
13374       else
13375         {
13376           clib_warning ("parse error '%U'", format_unformat_error, i);
13377           return -99;
13378         }
13379
13380     }
13381
13382   if (spd_id == (u32) ~ 0)
13383     {
13384       errmsg ("spd_id must be set");
13385       return -99;
13386     }
13387
13388   if (sw_if_index_set == 0)
13389     {
13390       errmsg ("missing interface name or sw_if_index");
13391       return -99;
13392     }
13393
13394   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13395
13396   mp->spd_id = ntohl (spd_id);
13397   mp->sw_if_index = ntohl (sw_if_index);
13398   mp->is_add = is_add;
13399
13400   S (mp);
13401   W (ret);
13402   return ret;
13403 }
13404
13405 static int
13406 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13407 {
13408   unformat_input_t *i = vam->input;
13409   vl_api_ipsec_spd_entry_add_del_t *mp;
13410   u8 is_add = 1, is_outbound = 0;
13411   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13412   i32 priority = 0;
13413   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13414   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13415   vl_api_address_t laddr_start = { }, laddr_stop =
13416   {
13417   }, raddr_start =
13418   {
13419   }, raddr_stop =
13420   {
13421   };
13422   int ret;
13423
13424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13425     {
13426       if (unformat (i, "del"))
13427         is_add = 0;
13428       if (unformat (i, "outbound"))
13429         is_outbound = 1;
13430       if (unformat (i, "inbound"))
13431         is_outbound = 0;
13432       else if (unformat (i, "spd_id %d", &spd_id))
13433         ;
13434       else if (unformat (i, "sa_id %d", &sa_id))
13435         ;
13436       else if (unformat (i, "priority %d", &priority))
13437         ;
13438       else if (unformat (i, "protocol %d", &protocol))
13439         ;
13440       else if (unformat (i, "lport_start %d", &lport_start))
13441         ;
13442       else if (unformat (i, "lport_stop %d", &lport_stop))
13443         ;
13444       else if (unformat (i, "rport_start %d", &rport_start))
13445         ;
13446       else if (unformat (i, "rport_stop %d", &rport_stop))
13447         ;
13448       else if (unformat (i, "laddr_start %U",
13449                          unformat_vl_api_address, &laddr_start))
13450         ;
13451       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13452                          &laddr_stop))
13453         ;
13454       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13455                          &raddr_start))
13456         ;
13457       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13458                          &raddr_stop))
13459         ;
13460       else
13461         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13462         {
13463           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13464             {
13465               clib_warning ("unsupported action: 'resolve'");
13466               return -99;
13467             }
13468         }
13469       else
13470         {
13471           clib_warning ("parse error '%U'", format_unformat_error, i);
13472           return -99;
13473         }
13474
13475     }
13476
13477   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13478
13479   mp->is_add = is_add;
13480
13481   mp->entry.spd_id = ntohl (spd_id);
13482   mp->entry.priority = ntohl (priority);
13483   mp->entry.is_outbound = is_outbound;
13484
13485   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13486                sizeof (vl_api_address_t));
13487   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13488                sizeof (vl_api_address_t));
13489   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13490                sizeof (vl_api_address_t));
13491   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13492                sizeof (vl_api_address_t));
13493
13494   mp->entry.protocol = (u8) protocol;
13495   mp->entry.local_port_start = ntohs ((u16) lport_start);
13496   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13497   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13498   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13499   mp->entry.policy = (u8) policy;
13500   mp->entry.sa_id = ntohl (sa_id);
13501
13502   S (mp);
13503   W (ret);
13504   return ret;
13505 }
13506
13507 static int
13508 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13509 {
13510   unformat_input_t *i = vam->input;
13511   vl_api_ipsec_sad_entry_add_del_t *mp;
13512   u32 sad_id = 0, spi = 0;
13513   u8 *ck = 0, *ik = 0;
13514   u8 is_add = 1;
13515
13516   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13517   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13518   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13519   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13520   vl_api_address_t tun_src, tun_dst;
13521   int ret;
13522
13523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13524     {
13525       if (unformat (i, "del"))
13526         is_add = 0;
13527       else if (unformat (i, "sad_id %d", &sad_id))
13528         ;
13529       else if (unformat (i, "spi %d", &spi))
13530         ;
13531       else if (unformat (i, "esp"))
13532         protocol = IPSEC_API_PROTO_ESP;
13533       else
13534         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13535         {
13536           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13537           if (ADDRESS_IP6 == tun_src.af)
13538             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13539         }
13540       else
13541         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13542         {
13543           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13544           if (ADDRESS_IP6 == tun_src.af)
13545             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13546         }
13547       else
13548         if (unformat (i, "crypto_alg %U",
13549                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13550         ;
13551       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13552         ;
13553       else if (unformat (i, "integ_alg %U",
13554                          unformat_ipsec_api_integ_alg, &integ_alg))
13555         ;
13556       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13557         ;
13558       else
13559         {
13560           clib_warning ("parse error '%U'", format_unformat_error, i);
13561           return -99;
13562         }
13563
13564     }
13565
13566   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13567
13568   mp->is_add = is_add;
13569   mp->entry.sad_id = ntohl (sad_id);
13570   mp->entry.protocol = protocol;
13571   mp->entry.spi = ntohl (spi);
13572   mp->entry.flags = flags;
13573
13574   mp->entry.crypto_algorithm = crypto_alg;
13575   mp->entry.integrity_algorithm = integ_alg;
13576   mp->entry.crypto_key.length = vec_len (ck);
13577   mp->entry.integrity_key.length = vec_len (ik);
13578
13579   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13580     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13581
13582   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13583     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13584
13585   if (ck)
13586     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13587   if (ik)
13588     clib_memcpy (mp->entry.integrity_key.data, ik,
13589                  mp->entry.integrity_key.length);
13590
13591   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13592     {
13593       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13594                    sizeof (mp->entry.tunnel_src));
13595       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13596                    sizeof (mp->entry.tunnel_dst));
13597     }
13598
13599   S (mp);
13600   W (ret);
13601   return ret;
13602 }
13603
13604 static int
13605 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13606 {
13607   unformat_input_t *i = vam->input;
13608   vl_api_ipsec_tunnel_if_add_del_t *mp;
13609   u32 local_spi = 0, remote_spi = 0;
13610   u32 crypto_alg = 0, integ_alg = 0;
13611   u8 *lck = NULL, *rck = NULL;
13612   u8 *lik = NULL, *rik = NULL;
13613   vl_api_address_t local_ip = { 0 };
13614   vl_api_address_t remote_ip = { 0 };
13615   f64 before = 0;
13616   u8 is_add = 1;
13617   u8 esn = 0;
13618   u8 anti_replay = 0;
13619   u8 renumber = 0;
13620   u32 instance = ~0;
13621   u32 count = 1, jj;
13622   int ret = -1;
13623
13624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13625     {
13626       if (unformat (i, "del"))
13627         is_add = 0;
13628       else if (unformat (i, "esn"))
13629         esn = 1;
13630       else if (unformat (i, "anti-replay"))
13631         anti_replay = 1;
13632       else if (unformat (i, "count %d", &count))
13633         ;
13634       else if (unformat (i, "local_spi %d", &local_spi))
13635         ;
13636       else if (unformat (i, "remote_spi %d", &remote_spi))
13637         ;
13638       else
13639         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13640         ;
13641       else
13642         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13643         ;
13644       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13645         ;
13646       else
13647         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13648         ;
13649       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13650         ;
13651       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13652         ;
13653       else
13654         if (unformat
13655             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13656         {
13657           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13658             {
13659               errmsg ("unsupported crypto-alg: '%U'\n",
13660                       format_ipsec_crypto_alg, crypto_alg);
13661               return -99;
13662             }
13663         }
13664       else
13665         if (unformat
13666             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13667         {
13668           if (integ_alg >= IPSEC_INTEG_N_ALG)
13669             {
13670               errmsg ("unsupported integ-alg: '%U'\n",
13671                       format_ipsec_integ_alg, integ_alg);
13672               return -99;
13673             }
13674         }
13675       else if (unformat (i, "instance %u", &instance))
13676         renumber = 1;
13677       else
13678         {
13679           errmsg ("parse error '%U'\n", format_unformat_error, i);
13680           return -99;
13681         }
13682     }
13683
13684   if (count > 1)
13685     {
13686       /* Turn on async mode */
13687       vam->async_mode = 1;
13688       vam->async_errors = 0;
13689       before = vat_time_now (vam);
13690     }
13691
13692   for (jj = 0; jj < count; jj++)
13693     {
13694       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13695
13696       mp->is_add = is_add;
13697       mp->esn = esn;
13698       mp->anti_replay = anti_replay;
13699
13700       if (jj > 0)
13701         increment_address (&remote_ip);
13702
13703       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13704       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13705
13706       mp->local_spi = htonl (local_spi + jj);
13707       mp->remote_spi = htonl (remote_spi + jj);
13708       mp->crypto_alg = (u8) crypto_alg;
13709
13710       mp->local_crypto_key_len = 0;
13711       if (lck)
13712         {
13713           mp->local_crypto_key_len = vec_len (lck);
13714           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13715             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13716           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13717         }
13718
13719       mp->remote_crypto_key_len = 0;
13720       if (rck)
13721         {
13722           mp->remote_crypto_key_len = vec_len (rck);
13723           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13724             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13725           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13726         }
13727
13728       mp->integ_alg = (u8) integ_alg;
13729
13730       mp->local_integ_key_len = 0;
13731       if (lik)
13732         {
13733           mp->local_integ_key_len = vec_len (lik);
13734           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13735             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13736           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13737         }
13738
13739       mp->remote_integ_key_len = 0;
13740       if (rik)
13741         {
13742           mp->remote_integ_key_len = vec_len (rik);
13743           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13744             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13745           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13746         }
13747
13748       if (renumber)
13749         {
13750           mp->renumber = renumber;
13751           mp->show_instance = ntohl (instance);
13752         }
13753       S (mp);
13754     }
13755
13756   /* When testing multiple add/del ops, use a control-ping to sync */
13757   if (count > 1)
13758     {
13759       vl_api_control_ping_t *mp_ping;
13760       f64 after;
13761       f64 timeout;
13762
13763       /* Shut off async mode */
13764       vam->async_mode = 0;
13765
13766       MPING (CONTROL_PING, mp_ping);
13767       S (mp_ping);
13768
13769       timeout = vat_time_now (vam) + 1.0;
13770       while (vat_time_now (vam) < timeout)
13771         if (vam->result_ready == 1)
13772           goto out;
13773       vam->retval = -99;
13774
13775     out:
13776       if (vam->retval == -99)
13777         errmsg ("timeout");
13778
13779       if (vam->async_errors > 0)
13780         {
13781           errmsg ("%d asynchronous errors", vam->async_errors);
13782           vam->retval = -98;
13783         }
13784       vam->async_errors = 0;
13785       after = vat_time_now (vam);
13786
13787       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13788       if (jj > 0)
13789         count = jj;
13790
13791       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13792              count, after - before, count / (after - before));
13793     }
13794   else
13795     {
13796       /* Wait for a reply... */
13797       W (ret);
13798       return ret;
13799     }
13800
13801   return ret;
13802 }
13803
13804 static void
13805 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13806 {
13807   vat_main_t *vam = &vat_main;
13808
13809   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13810          "crypto_key %U integ_alg %u integ_key %U flags %x "
13811          "tunnel_src_addr %U tunnel_dst_addr %U "
13812          "salt %u seq_outbound %lu last_seq_inbound %lu "
13813          "replay_window %lu stat_index %u\n",
13814          ntohl (mp->entry.sad_id),
13815          ntohl (mp->sw_if_index),
13816          ntohl (mp->entry.spi),
13817          ntohl (mp->entry.protocol),
13818          ntohl (mp->entry.crypto_algorithm),
13819          format_hex_bytes, mp->entry.crypto_key.data,
13820          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13821          format_hex_bytes, mp->entry.integrity_key.data,
13822          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13823          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13824          &mp->entry.tunnel_dst, ntohl (mp->salt),
13825          clib_net_to_host_u64 (mp->seq_outbound),
13826          clib_net_to_host_u64 (mp->last_seq_inbound),
13827          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13828 }
13829
13830 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13831 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13832
13833 static void vl_api_ipsec_sa_details_t_handler_json
13834   (vl_api_ipsec_sa_details_t * mp)
13835 {
13836   vat_main_t *vam = &vat_main;
13837   vat_json_node_t *node = NULL;
13838   vl_api_ipsec_sad_flags_t flags;
13839
13840   if (VAT_JSON_ARRAY != vam->json_tree.type)
13841     {
13842       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13843       vat_json_init_array (&vam->json_tree);
13844     }
13845   node = vat_json_array_add (&vam->json_tree);
13846
13847   vat_json_init_object (node);
13848   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13849   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13850   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13851   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13852   vat_json_object_add_uint (node, "crypto_alg",
13853                             ntohl (mp->entry.crypto_algorithm));
13854   vat_json_object_add_uint (node, "integ_alg",
13855                             ntohl (mp->entry.integrity_algorithm));
13856   flags = ntohl (mp->entry.flags);
13857   vat_json_object_add_uint (node, "use_esn",
13858                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13859   vat_json_object_add_uint (node, "use_anti_replay",
13860                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13861   vat_json_object_add_uint (node, "is_tunnel",
13862                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13863   vat_json_object_add_uint (node, "is_tunnel_ip6",
13864                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13865   vat_json_object_add_uint (node, "udp_encap",
13866                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13867   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13868                              mp->entry.crypto_key.length);
13869   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13870                              mp->entry.integrity_key.length);
13871   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13872   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13873   vat_json_object_add_uint (node, "replay_window",
13874                             clib_net_to_host_u64 (mp->replay_window));
13875   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13876 }
13877
13878 static int
13879 api_ipsec_sa_dump (vat_main_t * vam)
13880 {
13881   unformat_input_t *i = vam->input;
13882   vl_api_ipsec_sa_dump_t *mp;
13883   vl_api_control_ping_t *mp_ping;
13884   u32 sa_id = ~0;
13885   int ret;
13886
13887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13888     {
13889       if (unformat (i, "sa_id %d", &sa_id))
13890         ;
13891       else
13892         {
13893           clib_warning ("parse error '%U'", format_unformat_error, i);
13894           return -99;
13895         }
13896     }
13897
13898   M (IPSEC_SA_DUMP, mp);
13899
13900   mp->sa_id = ntohl (sa_id);
13901
13902   S (mp);
13903
13904   /* Use a control ping for synchronization */
13905   M (CONTROL_PING, mp_ping);
13906   S (mp_ping);
13907
13908   W (ret);
13909   return ret;
13910 }
13911
13912 static int
13913 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13914 {
13915   unformat_input_t *i = vam->input;
13916   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13917   u32 sw_if_index = ~0;
13918   u32 sa_id = ~0;
13919   u8 is_outbound = (u8) ~ 0;
13920   int ret;
13921
13922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13923     {
13924       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13925         ;
13926       else if (unformat (i, "sa_id %d", &sa_id))
13927         ;
13928       else if (unformat (i, "outbound"))
13929         is_outbound = 1;
13930       else if (unformat (i, "inbound"))
13931         is_outbound = 0;
13932       else
13933         {
13934           clib_warning ("parse error '%U'", format_unformat_error, i);
13935           return -99;
13936         }
13937     }
13938
13939   if (sw_if_index == ~0)
13940     {
13941       errmsg ("interface must be specified");
13942       return -99;
13943     }
13944
13945   if (sa_id == ~0)
13946     {
13947       errmsg ("SA ID must be specified");
13948       return -99;
13949     }
13950
13951   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13952
13953   mp->sw_if_index = htonl (sw_if_index);
13954   mp->sa_id = htonl (sa_id);
13955   mp->is_outbound = is_outbound;
13956
13957   S (mp);
13958   W (ret);
13959
13960   return ret;
13961 }
13962
13963 static int
13964 api_get_first_msg_id (vat_main_t * vam)
13965 {
13966   vl_api_get_first_msg_id_t *mp;
13967   unformat_input_t *i = vam->input;
13968   u8 *name;
13969   u8 name_set = 0;
13970   int ret;
13971
13972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13973     {
13974       if (unformat (i, "client %s", &name))
13975         name_set = 1;
13976       else
13977         break;
13978     }
13979
13980   if (name_set == 0)
13981     {
13982       errmsg ("missing client name");
13983       return -99;
13984     }
13985   vec_add1 (name, 0);
13986
13987   if (vec_len (name) > 63)
13988     {
13989       errmsg ("client name too long");
13990       return -99;
13991     }
13992
13993   M (GET_FIRST_MSG_ID, mp);
13994   clib_memcpy (mp->name, name, vec_len (name));
13995   S (mp);
13996   W (ret);
13997   return ret;
13998 }
13999
14000 static int
14001 api_cop_interface_enable_disable (vat_main_t * vam)
14002 {
14003   unformat_input_t *line_input = vam->input;
14004   vl_api_cop_interface_enable_disable_t *mp;
14005   u32 sw_if_index = ~0;
14006   u8 enable_disable = 1;
14007   int ret;
14008
14009   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14010     {
14011       if (unformat (line_input, "disable"))
14012         enable_disable = 0;
14013       if (unformat (line_input, "enable"))
14014         enable_disable = 1;
14015       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14016                          vam, &sw_if_index))
14017         ;
14018       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14019         ;
14020       else
14021         break;
14022     }
14023
14024   if (sw_if_index == ~0)
14025     {
14026       errmsg ("missing interface name or sw_if_index");
14027       return -99;
14028     }
14029
14030   /* Construct the API message */
14031   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14032   mp->sw_if_index = ntohl (sw_if_index);
14033   mp->enable_disable = enable_disable;
14034
14035   /* send it... */
14036   S (mp);
14037   /* Wait for the reply */
14038   W (ret);
14039   return ret;
14040 }
14041
14042 static int
14043 api_cop_whitelist_enable_disable (vat_main_t * vam)
14044 {
14045   unformat_input_t *line_input = vam->input;
14046   vl_api_cop_whitelist_enable_disable_t *mp;
14047   u32 sw_if_index = ~0;
14048   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14049   u32 fib_id = 0;
14050   int ret;
14051
14052   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14053     {
14054       if (unformat (line_input, "ip4"))
14055         ip4 = 1;
14056       else if (unformat (line_input, "ip6"))
14057         ip6 = 1;
14058       else if (unformat (line_input, "default"))
14059         default_cop = 1;
14060       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14061                          vam, &sw_if_index))
14062         ;
14063       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14064         ;
14065       else if (unformat (line_input, "fib-id %d", &fib_id))
14066         ;
14067       else
14068         break;
14069     }
14070
14071   if (sw_if_index == ~0)
14072     {
14073       errmsg ("missing interface name or sw_if_index");
14074       return -99;
14075     }
14076
14077   /* Construct the API message */
14078   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14079   mp->sw_if_index = ntohl (sw_if_index);
14080   mp->fib_id = ntohl (fib_id);
14081   mp->ip4 = ip4;
14082   mp->ip6 = ip6;
14083   mp->default_cop = default_cop;
14084
14085   /* send it... */
14086   S (mp);
14087   /* Wait for the reply */
14088   W (ret);
14089   return ret;
14090 }
14091
14092 static int
14093 api_get_node_graph (vat_main_t * vam)
14094 {
14095   vl_api_get_node_graph_t *mp;
14096   int ret;
14097
14098   M (GET_NODE_GRAPH, mp);
14099
14100   /* send it... */
14101   S (mp);
14102   /* Wait for the reply */
14103   W (ret);
14104   return ret;
14105 }
14106
14107 /* *INDENT-OFF* */
14108 /** Used for parsing LISP eids */
14109 typedef CLIB_PACKED(struct{
14110   union {
14111           ip46_address_t ip;
14112           mac_address_t mac;
14113           lisp_nsh_api_t nsh;
14114   } addr;
14115   u32 len;       /**< prefix length if IP */
14116   u8 type;      /**< type of eid */
14117 }) lisp_eid_vat_t;
14118 /* *INDENT-ON* */
14119
14120 static uword
14121 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14122 {
14123   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14124
14125   clib_memset (a, 0, sizeof (a[0]));
14126
14127   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14128     {
14129       a->type = 0;              /* ip prefix type */
14130     }
14131   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14132     {
14133       a->type = 1;              /* mac type */
14134     }
14135   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14136     {
14137       a->type = 2;              /* NSH type */
14138       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14139     }
14140   else
14141     {
14142       return 0;
14143     }
14144
14145   if (a->type == 0)
14146     {
14147       if (ip46_address_is_ip4 (&a->addr.ip))
14148         return a->len > 32 ? 1 : 0;
14149       else
14150         return a->len > 128 ? 1 : 0;
14151     }
14152
14153   return 1;
14154 }
14155
14156 static void
14157 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14158 {
14159   eid->type = vat_eid->type;
14160   switch (eid->type)
14161     {
14162     case EID_TYPE_API_PREFIX:
14163       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14164         {
14165           clib_memcpy (&eid->address.prefix.address.un.ip4,
14166                        &vat_eid->addr.ip.ip4, 4);
14167           eid->address.prefix.address.af = ADDRESS_IP4;
14168           eid->address.prefix.len = vat_eid->len;
14169         }
14170       else
14171         {
14172           clib_memcpy (&eid->address.prefix.address.un.ip6,
14173                        &vat_eid->addr.ip.ip6, 16);
14174           eid->address.prefix.address.af = ADDRESS_IP6;
14175           eid->address.prefix.len = vat_eid->len;
14176         }
14177       return;
14178     case EID_TYPE_API_MAC:
14179       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14180                    sizeof (eid->address.mac));
14181       return;
14182     case EID_TYPE_API_NSH:
14183       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14184                    sizeof (eid->address.nsh));
14185       return;
14186     default:
14187       ASSERT (0);
14188       return;
14189     }
14190 }
14191
14192 static int
14193 api_one_add_del_locator_set (vat_main_t * vam)
14194 {
14195   unformat_input_t *input = vam->input;
14196   vl_api_one_add_del_locator_set_t *mp;
14197   u8 is_add = 1;
14198   u8 *locator_set_name = NULL;
14199   u8 locator_set_name_set = 0;
14200   vl_api_local_locator_t locator, *locators = 0;
14201   u32 sw_if_index, priority, weight;
14202   u32 data_len = 0;
14203
14204   int ret;
14205   /* Parse args required to build the message */
14206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14207     {
14208       if (unformat (input, "del"))
14209         {
14210           is_add = 0;
14211         }
14212       else if (unformat (input, "locator-set %s", &locator_set_name))
14213         {
14214           locator_set_name_set = 1;
14215         }
14216       else if (unformat (input, "sw_if_index %u p %u w %u",
14217                          &sw_if_index, &priority, &weight))
14218         {
14219           locator.sw_if_index = htonl (sw_if_index);
14220           locator.priority = priority;
14221           locator.weight = weight;
14222           vec_add1 (locators, locator);
14223         }
14224       else
14225         if (unformat
14226             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14227              &sw_if_index, &priority, &weight))
14228         {
14229           locator.sw_if_index = htonl (sw_if_index);
14230           locator.priority = priority;
14231           locator.weight = weight;
14232           vec_add1 (locators, locator);
14233         }
14234       else
14235         break;
14236     }
14237
14238   if (locator_set_name_set == 0)
14239     {
14240       errmsg ("missing locator-set name");
14241       vec_free (locators);
14242       return -99;
14243     }
14244
14245   if (vec_len (locator_set_name) > 64)
14246     {
14247       errmsg ("locator-set name too long");
14248       vec_free (locator_set_name);
14249       vec_free (locators);
14250       return -99;
14251     }
14252   vec_add1 (locator_set_name, 0);
14253
14254   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14255
14256   /* Construct the API message */
14257   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14258
14259   mp->is_add = is_add;
14260   clib_memcpy (mp->locator_set_name, locator_set_name,
14261                vec_len (locator_set_name));
14262   vec_free (locator_set_name);
14263
14264   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14265   if (locators)
14266     clib_memcpy (mp->locators, locators, data_len);
14267   vec_free (locators);
14268
14269   /* send it... */
14270   S (mp);
14271
14272   /* Wait for a reply... */
14273   W (ret);
14274   return ret;
14275 }
14276
14277 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14278
14279 static int
14280 api_one_add_del_locator (vat_main_t * vam)
14281 {
14282   unformat_input_t *input = vam->input;
14283   vl_api_one_add_del_locator_t *mp;
14284   u32 tmp_if_index = ~0;
14285   u32 sw_if_index = ~0;
14286   u8 sw_if_index_set = 0;
14287   u8 sw_if_index_if_name_set = 0;
14288   u32 priority = ~0;
14289   u8 priority_set = 0;
14290   u32 weight = ~0;
14291   u8 weight_set = 0;
14292   u8 is_add = 1;
14293   u8 *locator_set_name = NULL;
14294   u8 locator_set_name_set = 0;
14295   int ret;
14296
14297   /* Parse args required to build the message */
14298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14299     {
14300       if (unformat (input, "del"))
14301         {
14302           is_add = 0;
14303         }
14304       else if (unformat (input, "locator-set %s", &locator_set_name))
14305         {
14306           locator_set_name_set = 1;
14307         }
14308       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14309                          &tmp_if_index))
14310         {
14311           sw_if_index_if_name_set = 1;
14312           sw_if_index = tmp_if_index;
14313         }
14314       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14315         {
14316           sw_if_index_set = 1;
14317           sw_if_index = tmp_if_index;
14318         }
14319       else if (unformat (input, "p %d", &priority))
14320         {
14321           priority_set = 1;
14322         }
14323       else if (unformat (input, "w %d", &weight))
14324         {
14325           weight_set = 1;
14326         }
14327       else
14328         break;
14329     }
14330
14331   if (locator_set_name_set == 0)
14332     {
14333       errmsg ("missing locator-set name");
14334       return -99;
14335     }
14336
14337   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14338     {
14339       errmsg ("missing sw_if_index");
14340       vec_free (locator_set_name);
14341       return -99;
14342     }
14343
14344   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14345     {
14346       errmsg ("cannot use both params interface name and sw_if_index");
14347       vec_free (locator_set_name);
14348       return -99;
14349     }
14350
14351   if (priority_set == 0)
14352     {
14353       errmsg ("missing locator-set priority");
14354       vec_free (locator_set_name);
14355       return -99;
14356     }
14357
14358   if (weight_set == 0)
14359     {
14360       errmsg ("missing locator-set weight");
14361       vec_free (locator_set_name);
14362       return -99;
14363     }
14364
14365   if (vec_len (locator_set_name) > 64)
14366     {
14367       errmsg ("locator-set name too long");
14368       vec_free (locator_set_name);
14369       return -99;
14370     }
14371   vec_add1 (locator_set_name, 0);
14372
14373   /* Construct the API message */
14374   M (ONE_ADD_DEL_LOCATOR, mp);
14375
14376   mp->is_add = is_add;
14377   mp->sw_if_index = ntohl (sw_if_index);
14378   mp->priority = priority;
14379   mp->weight = weight;
14380   clib_memcpy (mp->locator_set_name, locator_set_name,
14381                vec_len (locator_set_name));
14382   vec_free (locator_set_name);
14383
14384   /* send it... */
14385   S (mp);
14386
14387   /* Wait for a reply... */
14388   W (ret);
14389   return ret;
14390 }
14391
14392 #define api_lisp_add_del_locator api_one_add_del_locator
14393
14394 uword
14395 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14396 {
14397   u32 *key_id = va_arg (*args, u32 *);
14398   u8 *s = 0;
14399
14400   if (unformat (input, "%s", &s))
14401     {
14402       if (!strcmp ((char *) s, "sha1"))
14403         key_id[0] = HMAC_SHA_1_96;
14404       else if (!strcmp ((char *) s, "sha256"))
14405         key_id[0] = HMAC_SHA_256_128;
14406       else
14407         {
14408           clib_warning ("invalid key_id: '%s'", s);
14409           key_id[0] = HMAC_NO_KEY;
14410         }
14411     }
14412   else
14413     return 0;
14414
14415   vec_free (s);
14416   return 1;
14417 }
14418
14419 static int
14420 api_one_add_del_local_eid (vat_main_t * vam)
14421 {
14422   unformat_input_t *input = vam->input;
14423   vl_api_one_add_del_local_eid_t *mp;
14424   u8 is_add = 1;
14425   u8 eid_set = 0;
14426   lisp_eid_vat_t _eid, *eid = &_eid;
14427   u8 *locator_set_name = 0;
14428   u8 locator_set_name_set = 0;
14429   u32 vni = 0;
14430   u16 key_id = 0;
14431   u8 *key = 0;
14432   int ret;
14433
14434   /* Parse args required to build the message */
14435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14436     {
14437       if (unformat (input, "del"))
14438         {
14439           is_add = 0;
14440         }
14441       else if (unformat (input, "vni %d", &vni))
14442         {
14443           ;
14444         }
14445       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14446         {
14447           eid_set = 1;
14448         }
14449       else if (unformat (input, "locator-set %s", &locator_set_name))
14450         {
14451           locator_set_name_set = 1;
14452         }
14453       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14454         ;
14455       else if (unformat (input, "secret-key %_%v%_", &key))
14456         ;
14457       else
14458         break;
14459     }
14460
14461   if (locator_set_name_set == 0)
14462     {
14463       errmsg ("missing locator-set name");
14464       return -99;
14465     }
14466
14467   if (0 == eid_set)
14468     {
14469       errmsg ("EID address not set!");
14470       vec_free (locator_set_name);
14471       return -99;
14472     }
14473
14474   if (key && (0 == key_id))
14475     {
14476       errmsg ("invalid key_id!");
14477       return -99;
14478     }
14479
14480   if (vec_len (key) > 64)
14481     {
14482       errmsg ("key too long");
14483       vec_free (key);
14484       return -99;
14485     }
14486
14487   if (vec_len (locator_set_name) > 64)
14488     {
14489       errmsg ("locator-set name too long");
14490       vec_free (locator_set_name);
14491       return -99;
14492     }
14493   vec_add1 (locator_set_name, 0);
14494
14495   /* Construct the API message */
14496   M (ONE_ADD_DEL_LOCAL_EID, mp);
14497
14498   mp->is_add = is_add;
14499   lisp_eid_put_vat (&mp->eid, eid);
14500   mp->vni = clib_host_to_net_u32 (vni);
14501   mp->key.id = key_id;
14502   clib_memcpy (mp->locator_set_name, locator_set_name,
14503                vec_len (locator_set_name));
14504   clib_memcpy (mp->key.key, key, vec_len (key));
14505
14506   vec_free (locator_set_name);
14507   vec_free (key);
14508
14509   /* send it... */
14510   S (mp);
14511
14512   /* Wait for a reply... */
14513   W (ret);
14514   return ret;
14515 }
14516
14517 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14518
14519 static int
14520 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14521 {
14522   u32 dp_table = 0, vni = 0;;
14523   unformat_input_t *input = vam->input;
14524   vl_api_gpe_add_del_fwd_entry_t *mp;
14525   u8 is_add = 1;
14526   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14527   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14528   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14529   u32 action = ~0, w;
14530   ip4_address_t rmt_rloc4, lcl_rloc4;
14531   ip6_address_t rmt_rloc6, lcl_rloc6;
14532   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14533   int ret;
14534
14535   clib_memset (&rloc, 0, sizeof (rloc));
14536
14537   /* Parse args required to build the message */
14538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14539     {
14540       if (unformat (input, "del"))
14541         is_add = 0;
14542       else if (unformat (input, "add"))
14543         is_add = 1;
14544       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14545         {
14546           rmt_eid_set = 1;
14547         }
14548       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14549         {
14550           lcl_eid_set = 1;
14551         }
14552       else if (unformat (input, "vrf %d", &dp_table))
14553         ;
14554       else if (unformat (input, "bd %d", &dp_table))
14555         ;
14556       else if (unformat (input, "vni %d", &vni))
14557         ;
14558       else if (unformat (input, "w %d", &w))
14559         {
14560           if (!curr_rloc)
14561             {
14562               errmsg ("No RLOC configured for setting priority/weight!");
14563               return -99;
14564             }
14565           curr_rloc->weight = w;
14566         }
14567       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14568                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14569         {
14570           rloc.addr.af = 0;
14571           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14572           rloc.weight = 0;
14573           vec_add1 (lcl_locs, rloc);
14574
14575           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14576           vec_add1 (rmt_locs, rloc);
14577           /* weight saved in rmt loc */
14578           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14579         }
14580       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14581                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14582         {
14583           rloc.addr.af = 1;
14584           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14585           rloc.weight = 0;
14586           vec_add1 (lcl_locs, rloc);
14587
14588           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14589           vec_add1 (rmt_locs, rloc);
14590           /* weight saved in rmt loc */
14591           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14592         }
14593       else if (unformat (input, "action %d", &action))
14594         {
14595           ;
14596         }
14597       else
14598         {
14599           clib_warning ("parse error '%U'", format_unformat_error, input);
14600           return -99;
14601         }
14602     }
14603
14604   if (!rmt_eid_set)
14605     {
14606       errmsg ("remote eid addresses not set");
14607       return -99;
14608     }
14609
14610   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14611     {
14612       errmsg ("eid types don't match");
14613       return -99;
14614     }
14615
14616   if (0 == rmt_locs && (u32) ~ 0 == action)
14617     {
14618       errmsg ("action not set for negative mapping");
14619       return -99;
14620     }
14621
14622   /* Construct the API message */
14623   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14624       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14625
14626   mp->is_add = is_add;
14627   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14628   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14629   mp->dp_table = clib_host_to_net_u32 (dp_table);
14630   mp->vni = clib_host_to_net_u32 (vni);
14631   mp->action = action;
14632
14633   if (0 != rmt_locs && 0 != lcl_locs)
14634     {
14635       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14636       clib_memcpy (mp->locs, lcl_locs,
14637                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14638
14639       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14640       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14641                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14642     }
14643   vec_free (lcl_locs);
14644   vec_free (rmt_locs);
14645
14646   /* send it... */
14647   S (mp);
14648
14649   /* Wait for a reply... */
14650   W (ret);
14651   return ret;
14652 }
14653
14654 static int
14655 api_one_add_del_map_server (vat_main_t * vam)
14656 {
14657   unformat_input_t *input = vam->input;
14658   vl_api_one_add_del_map_server_t *mp;
14659   u8 is_add = 1;
14660   u8 ipv4_set = 0;
14661   u8 ipv6_set = 0;
14662   ip4_address_t ipv4;
14663   ip6_address_t ipv6;
14664   int ret;
14665
14666   /* Parse args required to build the message */
14667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14668     {
14669       if (unformat (input, "del"))
14670         {
14671           is_add = 0;
14672         }
14673       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14674         {
14675           ipv4_set = 1;
14676         }
14677       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14678         {
14679           ipv6_set = 1;
14680         }
14681       else
14682         break;
14683     }
14684
14685   if (ipv4_set && ipv6_set)
14686     {
14687       errmsg ("both eid v4 and v6 addresses set");
14688       return -99;
14689     }
14690
14691   if (!ipv4_set && !ipv6_set)
14692     {
14693       errmsg ("eid addresses not set");
14694       return -99;
14695     }
14696
14697   /* Construct the API message */
14698   M (ONE_ADD_DEL_MAP_SERVER, mp);
14699
14700   mp->is_add = is_add;
14701   if (ipv6_set)
14702     {
14703       mp->ip_address.af = 1;
14704       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14705     }
14706   else
14707     {
14708       mp->ip_address.af = 0;
14709       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14710     }
14711
14712   /* send it... */
14713   S (mp);
14714
14715   /* Wait for a reply... */
14716   W (ret);
14717   return ret;
14718 }
14719
14720 #define api_lisp_add_del_map_server api_one_add_del_map_server
14721
14722 static int
14723 api_one_add_del_map_resolver (vat_main_t * vam)
14724 {
14725   unformat_input_t *input = vam->input;
14726   vl_api_one_add_del_map_resolver_t *mp;
14727   u8 is_add = 1;
14728   u8 ipv4_set = 0;
14729   u8 ipv6_set = 0;
14730   ip4_address_t ipv4;
14731   ip6_address_t ipv6;
14732   int ret;
14733
14734   /* Parse args required to build the message */
14735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14736     {
14737       if (unformat (input, "del"))
14738         {
14739           is_add = 0;
14740         }
14741       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14742         {
14743           ipv4_set = 1;
14744         }
14745       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14746         {
14747           ipv6_set = 1;
14748         }
14749       else
14750         break;
14751     }
14752
14753   if (ipv4_set && ipv6_set)
14754     {
14755       errmsg ("both eid v4 and v6 addresses set");
14756       return -99;
14757     }
14758
14759   if (!ipv4_set && !ipv6_set)
14760     {
14761       errmsg ("eid addresses not set");
14762       return -99;
14763     }
14764
14765   /* Construct the API message */
14766   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14767
14768   mp->is_add = is_add;
14769   if (ipv6_set)
14770     {
14771       mp->ip_address.af = 1;
14772       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14773     }
14774   else
14775     {
14776       mp->ip_address.af = 0;
14777       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14778     }
14779
14780   /* send it... */
14781   S (mp);
14782
14783   /* Wait for a reply... */
14784   W (ret);
14785   return ret;
14786 }
14787
14788 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14789
14790 static int
14791 api_lisp_gpe_enable_disable (vat_main_t * vam)
14792 {
14793   unformat_input_t *input = vam->input;
14794   vl_api_gpe_enable_disable_t *mp;
14795   u8 is_set = 0;
14796   u8 is_enable = 1;
14797   int ret;
14798
14799   /* Parse args required to build the message */
14800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14801     {
14802       if (unformat (input, "enable"))
14803         {
14804           is_set = 1;
14805           is_enable = 1;
14806         }
14807       else if (unformat (input, "disable"))
14808         {
14809           is_set = 1;
14810           is_enable = 0;
14811         }
14812       else
14813         break;
14814     }
14815
14816   if (is_set == 0)
14817     {
14818       errmsg ("Value not set");
14819       return -99;
14820     }
14821
14822   /* Construct the API message */
14823   M (GPE_ENABLE_DISABLE, mp);
14824
14825   mp->is_enable = is_enable;
14826
14827   /* send it... */
14828   S (mp);
14829
14830   /* Wait for a reply... */
14831   W (ret);
14832   return ret;
14833 }
14834
14835 static int
14836 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14837 {
14838   unformat_input_t *input = vam->input;
14839   vl_api_one_rloc_probe_enable_disable_t *mp;
14840   u8 is_set = 0;
14841   u8 is_enable = 0;
14842   int ret;
14843
14844   /* Parse args required to build the message */
14845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14846     {
14847       if (unformat (input, "enable"))
14848         {
14849           is_set = 1;
14850           is_enable = 1;
14851         }
14852       else if (unformat (input, "disable"))
14853         is_set = 1;
14854       else
14855         break;
14856     }
14857
14858   if (!is_set)
14859     {
14860       errmsg ("Value not set");
14861       return -99;
14862     }
14863
14864   /* Construct the API message */
14865   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14866
14867   mp->is_enable = is_enable;
14868
14869   /* send it... */
14870   S (mp);
14871
14872   /* Wait for a reply... */
14873   W (ret);
14874   return ret;
14875 }
14876
14877 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14878
14879 static int
14880 api_one_map_register_enable_disable (vat_main_t * vam)
14881 {
14882   unformat_input_t *input = vam->input;
14883   vl_api_one_map_register_enable_disable_t *mp;
14884   u8 is_set = 0;
14885   u8 is_enable = 0;
14886   int ret;
14887
14888   /* Parse args required to build the message */
14889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14890     {
14891       if (unformat (input, "enable"))
14892         {
14893           is_set = 1;
14894           is_enable = 1;
14895         }
14896       else if (unformat (input, "disable"))
14897         is_set = 1;
14898       else
14899         break;
14900     }
14901
14902   if (!is_set)
14903     {
14904       errmsg ("Value not set");
14905       return -99;
14906     }
14907
14908   /* Construct the API message */
14909   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14910
14911   mp->is_enable = is_enable;
14912
14913   /* send it... */
14914   S (mp);
14915
14916   /* Wait for a reply... */
14917   W (ret);
14918   return ret;
14919 }
14920
14921 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14922
14923 static int
14924 api_one_enable_disable (vat_main_t * vam)
14925 {
14926   unformat_input_t *input = vam->input;
14927   vl_api_one_enable_disable_t *mp;
14928   u8 is_set = 0;
14929   u8 is_enable = 0;
14930   int ret;
14931
14932   /* Parse args required to build the message */
14933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14934     {
14935       if (unformat (input, "enable"))
14936         {
14937           is_set = 1;
14938           is_enable = 1;
14939         }
14940       else if (unformat (input, "disable"))
14941         {
14942           is_set = 1;
14943         }
14944       else
14945         break;
14946     }
14947
14948   if (!is_set)
14949     {
14950       errmsg ("Value not set");
14951       return -99;
14952     }
14953
14954   /* Construct the API message */
14955   M (ONE_ENABLE_DISABLE, mp);
14956
14957   mp->is_enable = is_enable;
14958
14959   /* send it... */
14960   S (mp);
14961
14962   /* Wait for a reply... */
14963   W (ret);
14964   return ret;
14965 }
14966
14967 #define api_lisp_enable_disable api_one_enable_disable
14968
14969 static int
14970 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14971 {
14972   unformat_input_t *input = vam->input;
14973   vl_api_one_enable_disable_xtr_mode_t *mp;
14974   u8 is_set = 0;
14975   u8 is_enable = 0;
14976   int ret;
14977
14978   /* Parse args required to build the message */
14979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14980     {
14981       if (unformat (input, "enable"))
14982         {
14983           is_set = 1;
14984           is_enable = 1;
14985         }
14986       else if (unformat (input, "disable"))
14987         {
14988           is_set = 1;
14989         }
14990       else
14991         break;
14992     }
14993
14994   if (!is_set)
14995     {
14996       errmsg ("Value not set");
14997       return -99;
14998     }
14999
15000   /* Construct the API message */
15001   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15002
15003   mp->is_enable = is_enable;
15004
15005   /* send it... */
15006   S (mp);
15007
15008   /* Wait for a reply... */
15009   W (ret);
15010   return ret;
15011 }
15012
15013 static int
15014 api_one_show_xtr_mode (vat_main_t * vam)
15015 {
15016   vl_api_one_show_xtr_mode_t *mp;
15017   int ret;
15018
15019   /* Construct the API message */
15020   M (ONE_SHOW_XTR_MODE, mp);
15021
15022   /* send it... */
15023   S (mp);
15024
15025   /* Wait for a reply... */
15026   W (ret);
15027   return ret;
15028 }
15029
15030 static int
15031 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15032 {
15033   unformat_input_t *input = vam->input;
15034   vl_api_one_enable_disable_pitr_mode_t *mp;
15035   u8 is_set = 0;
15036   u8 is_enable = 0;
15037   int ret;
15038
15039   /* Parse args required to build the message */
15040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15041     {
15042       if (unformat (input, "enable"))
15043         {
15044           is_set = 1;
15045           is_enable = 1;
15046         }
15047       else if (unformat (input, "disable"))
15048         {
15049           is_set = 1;
15050         }
15051       else
15052         break;
15053     }
15054
15055   if (!is_set)
15056     {
15057       errmsg ("Value not set");
15058       return -99;
15059     }
15060
15061   /* Construct the API message */
15062   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15063
15064   mp->is_enable = is_enable;
15065
15066   /* send it... */
15067   S (mp);
15068
15069   /* Wait for a reply... */
15070   W (ret);
15071   return ret;
15072 }
15073
15074 static int
15075 api_one_show_pitr_mode (vat_main_t * vam)
15076 {
15077   vl_api_one_show_pitr_mode_t *mp;
15078   int ret;
15079
15080   /* Construct the API message */
15081   M (ONE_SHOW_PITR_MODE, mp);
15082
15083   /* send it... */
15084   S (mp);
15085
15086   /* Wait for a reply... */
15087   W (ret);
15088   return ret;
15089 }
15090
15091 static int
15092 api_one_enable_disable_petr_mode (vat_main_t * vam)
15093 {
15094   unformat_input_t *input = vam->input;
15095   vl_api_one_enable_disable_petr_mode_t *mp;
15096   u8 is_set = 0;
15097   u8 is_enable = 0;
15098   int ret;
15099
15100   /* Parse args required to build the message */
15101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15102     {
15103       if (unformat (input, "enable"))
15104         {
15105           is_set = 1;
15106           is_enable = 1;
15107         }
15108       else if (unformat (input, "disable"))
15109         {
15110           is_set = 1;
15111         }
15112       else
15113         break;
15114     }
15115
15116   if (!is_set)
15117     {
15118       errmsg ("Value not set");
15119       return -99;
15120     }
15121
15122   /* Construct the API message */
15123   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15124
15125   mp->is_enable = is_enable;
15126
15127   /* send it... */
15128   S (mp);
15129
15130   /* Wait for a reply... */
15131   W (ret);
15132   return ret;
15133 }
15134
15135 static int
15136 api_one_show_petr_mode (vat_main_t * vam)
15137 {
15138   vl_api_one_show_petr_mode_t *mp;
15139   int ret;
15140
15141   /* Construct the API message */
15142   M (ONE_SHOW_PETR_MODE, mp);
15143
15144   /* send it... */
15145   S (mp);
15146
15147   /* Wait for a reply... */
15148   W (ret);
15149   return ret;
15150 }
15151
15152 static int
15153 api_show_one_map_register_state (vat_main_t * vam)
15154 {
15155   vl_api_show_one_map_register_state_t *mp;
15156   int ret;
15157
15158   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15159
15160   /* send */
15161   S (mp);
15162
15163   /* wait for reply */
15164   W (ret);
15165   return ret;
15166 }
15167
15168 #define api_show_lisp_map_register_state api_show_one_map_register_state
15169
15170 static int
15171 api_show_one_rloc_probe_state (vat_main_t * vam)
15172 {
15173   vl_api_show_one_rloc_probe_state_t *mp;
15174   int ret;
15175
15176   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15177
15178   /* send */
15179   S (mp);
15180
15181   /* wait for reply */
15182   W (ret);
15183   return ret;
15184 }
15185
15186 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15187
15188 static int
15189 api_one_add_del_ndp_entry (vat_main_t * vam)
15190 {
15191   vl_api_one_add_del_ndp_entry_t *mp;
15192   unformat_input_t *input = vam->input;
15193   u8 is_add = 1;
15194   u8 mac_set = 0;
15195   u8 bd_set = 0;
15196   u8 ip_set = 0;
15197   u8 mac[6] = { 0, };
15198   u8 ip6[16] = { 0, };
15199   u32 bd = ~0;
15200   int ret;
15201
15202   /* Parse args required to build the message */
15203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15204     {
15205       if (unformat (input, "del"))
15206         is_add = 0;
15207       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15208         mac_set = 1;
15209       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15210         ip_set = 1;
15211       else if (unformat (input, "bd %d", &bd))
15212         bd_set = 1;
15213       else
15214         {
15215           errmsg ("parse error '%U'", format_unformat_error, input);
15216           return -99;
15217         }
15218     }
15219
15220   if (!bd_set || !ip_set || (!mac_set && is_add))
15221     {
15222       errmsg ("Missing BD, IP or MAC!");
15223       return -99;
15224     }
15225
15226   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15227   mp->is_add = is_add;
15228   clib_memcpy (&mp->entry.mac, mac, 6);
15229   mp->bd = clib_host_to_net_u32 (bd);
15230   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15231
15232   /* send */
15233   S (mp);
15234
15235   /* wait for reply */
15236   W (ret);
15237   return ret;
15238 }
15239
15240 static int
15241 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15242 {
15243   vl_api_one_add_del_l2_arp_entry_t *mp;
15244   unformat_input_t *input = vam->input;
15245   u8 is_add = 1;
15246   u8 mac_set = 0;
15247   u8 bd_set = 0;
15248   u8 ip_set = 0;
15249   u8 mac[6] = { 0, };
15250   u32 ip4 = 0, bd = ~0;
15251   int ret;
15252
15253   /* Parse args required to build the message */
15254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15255     {
15256       if (unformat (input, "del"))
15257         is_add = 0;
15258       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15259         mac_set = 1;
15260       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15261         ip_set = 1;
15262       else if (unformat (input, "bd %d", &bd))
15263         bd_set = 1;
15264       else
15265         {
15266           errmsg ("parse error '%U'", format_unformat_error, input);
15267           return -99;
15268         }
15269     }
15270
15271   if (!bd_set || !ip_set || (!mac_set && is_add))
15272     {
15273       errmsg ("Missing BD, IP or MAC!");
15274       return -99;
15275     }
15276
15277   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15278   mp->is_add = is_add;
15279   clib_memcpy (&mp->entry.mac, mac, 6);
15280   mp->bd = clib_host_to_net_u32 (bd);
15281   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15282
15283   /* send */
15284   S (mp);
15285
15286   /* wait for reply */
15287   W (ret);
15288   return ret;
15289 }
15290
15291 static int
15292 api_one_ndp_bd_get (vat_main_t * vam)
15293 {
15294   vl_api_one_ndp_bd_get_t *mp;
15295   int ret;
15296
15297   M (ONE_NDP_BD_GET, mp);
15298
15299   /* send */
15300   S (mp);
15301
15302   /* wait for reply */
15303   W (ret);
15304   return ret;
15305 }
15306
15307 static int
15308 api_one_ndp_entries_get (vat_main_t * vam)
15309 {
15310   vl_api_one_ndp_entries_get_t *mp;
15311   unformat_input_t *input = vam->input;
15312   u8 bd_set = 0;
15313   u32 bd = ~0;
15314   int ret;
15315
15316   /* Parse args required to build the message */
15317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15318     {
15319       if (unformat (input, "bd %d", &bd))
15320         bd_set = 1;
15321       else
15322         {
15323           errmsg ("parse error '%U'", format_unformat_error, input);
15324           return -99;
15325         }
15326     }
15327
15328   if (!bd_set)
15329     {
15330       errmsg ("Expected bridge domain!");
15331       return -99;
15332     }
15333
15334   M (ONE_NDP_ENTRIES_GET, mp);
15335   mp->bd = clib_host_to_net_u32 (bd);
15336
15337   /* send */
15338   S (mp);
15339
15340   /* wait for reply */
15341   W (ret);
15342   return ret;
15343 }
15344
15345 static int
15346 api_one_l2_arp_bd_get (vat_main_t * vam)
15347 {
15348   vl_api_one_l2_arp_bd_get_t *mp;
15349   int ret;
15350
15351   M (ONE_L2_ARP_BD_GET, mp);
15352
15353   /* send */
15354   S (mp);
15355
15356   /* wait for reply */
15357   W (ret);
15358   return ret;
15359 }
15360
15361 static int
15362 api_one_l2_arp_entries_get (vat_main_t * vam)
15363 {
15364   vl_api_one_l2_arp_entries_get_t *mp;
15365   unformat_input_t *input = vam->input;
15366   u8 bd_set = 0;
15367   u32 bd = ~0;
15368   int ret;
15369
15370   /* Parse args required to build the message */
15371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15372     {
15373       if (unformat (input, "bd %d", &bd))
15374         bd_set = 1;
15375       else
15376         {
15377           errmsg ("parse error '%U'", format_unformat_error, input);
15378           return -99;
15379         }
15380     }
15381
15382   if (!bd_set)
15383     {
15384       errmsg ("Expected bridge domain!");
15385       return -99;
15386     }
15387
15388   M (ONE_L2_ARP_ENTRIES_GET, mp);
15389   mp->bd = clib_host_to_net_u32 (bd);
15390
15391   /* send */
15392   S (mp);
15393
15394   /* wait for reply */
15395   W (ret);
15396   return ret;
15397 }
15398
15399 static int
15400 api_one_stats_enable_disable (vat_main_t * vam)
15401 {
15402   vl_api_one_stats_enable_disable_t *mp;
15403   unformat_input_t *input = vam->input;
15404   u8 is_set = 0;
15405   u8 is_enable = 0;
15406   int ret;
15407
15408   /* Parse args required to build the message */
15409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15410     {
15411       if (unformat (input, "enable"))
15412         {
15413           is_set = 1;
15414           is_enable = 1;
15415         }
15416       else if (unformat (input, "disable"))
15417         {
15418           is_set = 1;
15419         }
15420       else
15421         break;
15422     }
15423
15424   if (!is_set)
15425     {
15426       errmsg ("Value not set");
15427       return -99;
15428     }
15429
15430   M (ONE_STATS_ENABLE_DISABLE, mp);
15431   mp->is_enable = is_enable;
15432
15433   /* send */
15434   S (mp);
15435
15436   /* wait for reply */
15437   W (ret);
15438   return ret;
15439 }
15440
15441 static int
15442 api_show_one_stats_enable_disable (vat_main_t * vam)
15443 {
15444   vl_api_show_one_stats_enable_disable_t *mp;
15445   int ret;
15446
15447   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15448
15449   /* send */
15450   S (mp);
15451
15452   /* wait for reply */
15453   W (ret);
15454   return ret;
15455 }
15456
15457 static int
15458 api_show_one_map_request_mode (vat_main_t * vam)
15459 {
15460   vl_api_show_one_map_request_mode_t *mp;
15461   int ret;
15462
15463   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15464
15465   /* send */
15466   S (mp);
15467
15468   /* wait for reply */
15469   W (ret);
15470   return ret;
15471 }
15472
15473 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15474
15475 static int
15476 api_one_map_request_mode (vat_main_t * vam)
15477 {
15478   unformat_input_t *input = vam->input;
15479   vl_api_one_map_request_mode_t *mp;
15480   u8 mode = 0;
15481   int ret;
15482
15483   /* Parse args required to build the message */
15484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15485     {
15486       if (unformat (input, "dst-only"))
15487         mode = 0;
15488       else if (unformat (input, "src-dst"))
15489         mode = 1;
15490       else
15491         {
15492           errmsg ("parse error '%U'", format_unformat_error, input);
15493           return -99;
15494         }
15495     }
15496
15497   M (ONE_MAP_REQUEST_MODE, mp);
15498
15499   mp->mode = mode;
15500
15501   /* send */
15502   S (mp);
15503
15504   /* wait for reply */
15505   W (ret);
15506   return ret;
15507 }
15508
15509 #define api_lisp_map_request_mode api_one_map_request_mode
15510
15511 /**
15512  * Enable/disable ONE proxy ITR.
15513  *
15514  * @param vam vpp API test context
15515  * @return return code
15516  */
15517 static int
15518 api_one_pitr_set_locator_set (vat_main_t * vam)
15519 {
15520   u8 ls_name_set = 0;
15521   unformat_input_t *input = vam->input;
15522   vl_api_one_pitr_set_locator_set_t *mp;
15523   u8 is_add = 1;
15524   u8 *ls_name = 0;
15525   int ret;
15526
15527   /* Parse args required to build the message */
15528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15529     {
15530       if (unformat (input, "del"))
15531         is_add = 0;
15532       else if (unformat (input, "locator-set %s", &ls_name))
15533         ls_name_set = 1;
15534       else
15535         {
15536           errmsg ("parse error '%U'", format_unformat_error, input);
15537           return -99;
15538         }
15539     }
15540
15541   if (!ls_name_set)
15542     {
15543       errmsg ("locator-set name not set!");
15544       return -99;
15545     }
15546
15547   M (ONE_PITR_SET_LOCATOR_SET, mp);
15548
15549   mp->is_add = is_add;
15550   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15551   vec_free (ls_name);
15552
15553   /* send */
15554   S (mp);
15555
15556   /* wait for reply */
15557   W (ret);
15558   return ret;
15559 }
15560
15561 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15562
15563 static int
15564 api_one_nsh_set_locator_set (vat_main_t * vam)
15565 {
15566   u8 ls_name_set = 0;
15567   unformat_input_t *input = vam->input;
15568   vl_api_one_nsh_set_locator_set_t *mp;
15569   u8 is_add = 1;
15570   u8 *ls_name = 0;
15571   int ret;
15572
15573   /* Parse args required to build the message */
15574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15575     {
15576       if (unformat (input, "del"))
15577         is_add = 0;
15578       else if (unformat (input, "ls %s", &ls_name))
15579         ls_name_set = 1;
15580       else
15581         {
15582           errmsg ("parse error '%U'", format_unformat_error, input);
15583           return -99;
15584         }
15585     }
15586
15587   if (!ls_name_set && is_add)
15588     {
15589       errmsg ("locator-set name not set!");
15590       return -99;
15591     }
15592
15593   M (ONE_NSH_SET_LOCATOR_SET, mp);
15594
15595   mp->is_add = is_add;
15596   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15597   vec_free (ls_name);
15598
15599   /* send */
15600   S (mp);
15601
15602   /* wait for reply */
15603   W (ret);
15604   return ret;
15605 }
15606
15607 static int
15608 api_show_one_pitr (vat_main_t * vam)
15609 {
15610   vl_api_show_one_pitr_t *mp;
15611   int ret;
15612
15613   if (!vam->json_output)
15614     {
15615       print (vam->ofp, "%=20s", "lisp status:");
15616     }
15617
15618   M (SHOW_ONE_PITR, mp);
15619   /* send it... */
15620   S (mp);
15621
15622   /* Wait for a reply... */
15623   W (ret);
15624   return ret;
15625 }
15626
15627 #define api_show_lisp_pitr api_show_one_pitr
15628
15629 static int
15630 api_one_use_petr (vat_main_t * vam)
15631 {
15632   unformat_input_t *input = vam->input;
15633   vl_api_one_use_petr_t *mp;
15634   u8 is_add = 0;
15635   ip_address_t ip;
15636   int ret;
15637
15638   clib_memset (&ip, 0, sizeof (ip));
15639
15640   /* Parse args required to build the message */
15641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15642     {
15643       if (unformat (input, "disable"))
15644         is_add = 0;
15645       else
15646         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15647         {
15648           is_add = 1;
15649           ip_addr_version (&ip) = AF_IP4;
15650         }
15651       else
15652         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15653         {
15654           is_add = 1;
15655           ip_addr_version (&ip) = AF_IP6;
15656         }
15657       else
15658         {
15659           errmsg ("parse error '%U'", format_unformat_error, input);
15660           return -99;
15661         }
15662     }
15663
15664   M (ONE_USE_PETR, mp);
15665
15666   mp->is_add = is_add;
15667   if (is_add)
15668     {
15669       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15670       if (mp->ip_address.af)
15671         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15672       else
15673         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15674     }
15675
15676   /* send */
15677   S (mp);
15678
15679   /* wait for reply */
15680   W (ret);
15681   return ret;
15682 }
15683
15684 #define api_lisp_use_petr api_one_use_petr
15685
15686 static int
15687 api_show_one_nsh_mapping (vat_main_t * vam)
15688 {
15689   vl_api_show_one_use_petr_t *mp;
15690   int ret;
15691
15692   if (!vam->json_output)
15693     {
15694       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15695     }
15696
15697   M (SHOW_ONE_NSH_MAPPING, mp);
15698   /* send it... */
15699   S (mp);
15700
15701   /* Wait for a reply... */
15702   W (ret);
15703   return ret;
15704 }
15705
15706 static int
15707 api_show_one_use_petr (vat_main_t * vam)
15708 {
15709   vl_api_show_one_use_petr_t *mp;
15710   int ret;
15711
15712   if (!vam->json_output)
15713     {
15714       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15715     }
15716
15717   M (SHOW_ONE_USE_PETR, mp);
15718   /* send it... */
15719   S (mp);
15720
15721   /* Wait for a reply... */
15722   W (ret);
15723   return ret;
15724 }
15725
15726 #define api_show_lisp_use_petr api_show_one_use_petr
15727
15728 /**
15729  * Add/delete mapping between vni and vrf
15730  */
15731 static int
15732 api_one_eid_table_add_del_map (vat_main_t * vam)
15733 {
15734   unformat_input_t *input = vam->input;
15735   vl_api_one_eid_table_add_del_map_t *mp;
15736   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15737   u32 vni, vrf, bd_index;
15738   int ret;
15739
15740   /* Parse args required to build the message */
15741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15742     {
15743       if (unformat (input, "del"))
15744         is_add = 0;
15745       else if (unformat (input, "vrf %d", &vrf))
15746         vrf_set = 1;
15747       else if (unformat (input, "bd_index %d", &bd_index))
15748         bd_index_set = 1;
15749       else if (unformat (input, "vni %d", &vni))
15750         vni_set = 1;
15751       else
15752         break;
15753     }
15754
15755   if (!vni_set || (!vrf_set && !bd_index_set))
15756     {
15757       errmsg ("missing arguments!");
15758       return -99;
15759     }
15760
15761   if (vrf_set && bd_index_set)
15762     {
15763       errmsg ("error: both vrf and bd entered!");
15764       return -99;
15765     }
15766
15767   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15768
15769   mp->is_add = is_add;
15770   mp->vni = htonl (vni);
15771   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15772   mp->is_l2 = bd_index_set;
15773
15774   /* send */
15775   S (mp);
15776
15777   /* wait for reply */
15778   W (ret);
15779   return ret;
15780 }
15781
15782 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15783
15784 uword
15785 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15786 {
15787   u32 *action = va_arg (*args, u32 *);
15788   u8 *s = 0;
15789
15790   if (unformat (input, "%s", &s))
15791     {
15792       if (!strcmp ((char *) s, "no-action"))
15793         action[0] = 0;
15794       else if (!strcmp ((char *) s, "natively-forward"))
15795         action[0] = 1;
15796       else if (!strcmp ((char *) s, "send-map-request"))
15797         action[0] = 2;
15798       else if (!strcmp ((char *) s, "drop"))
15799         action[0] = 3;
15800       else
15801         {
15802           clib_warning ("invalid action: '%s'", s);
15803           action[0] = 3;
15804         }
15805     }
15806   else
15807     return 0;
15808
15809   vec_free (s);
15810   return 1;
15811 }
15812
15813 /**
15814  * Add/del remote mapping to/from ONE control plane
15815  *
15816  * @param vam vpp API test context
15817  * @return return code
15818  */
15819 static int
15820 api_one_add_del_remote_mapping (vat_main_t * vam)
15821 {
15822   unformat_input_t *input = vam->input;
15823   vl_api_one_add_del_remote_mapping_t *mp;
15824   u32 vni = 0;
15825   lisp_eid_vat_t _eid, *eid = &_eid;
15826   lisp_eid_vat_t _seid, *seid = &_seid;
15827   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15828   u32 action = ~0, p, w, data_len;
15829   ip4_address_t rloc4;
15830   ip6_address_t rloc6;
15831   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15832   int ret;
15833
15834   clib_memset (&rloc, 0, sizeof (rloc));
15835
15836   /* Parse args required to build the message */
15837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15838     {
15839       if (unformat (input, "del-all"))
15840         {
15841           del_all = 1;
15842         }
15843       else if (unformat (input, "del"))
15844         {
15845           is_add = 0;
15846         }
15847       else if (unformat (input, "add"))
15848         {
15849           is_add = 1;
15850         }
15851       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15852         {
15853           eid_set = 1;
15854         }
15855       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15856         {
15857           seid_set = 1;
15858         }
15859       else if (unformat (input, "vni %d", &vni))
15860         {
15861           ;
15862         }
15863       else if (unformat (input, "p %d w %d", &p, &w))
15864         {
15865           if (!curr_rloc)
15866             {
15867               errmsg ("No RLOC configured for setting priority/weight!");
15868               return -99;
15869             }
15870           curr_rloc->priority = p;
15871           curr_rloc->weight = w;
15872         }
15873       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15874         {
15875           rloc.ip_address.af = 0;
15876           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15877           vec_add1 (rlocs, rloc);
15878           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15879         }
15880       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15881         {
15882           rloc.ip_address.af = 1;
15883           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15884           vec_add1 (rlocs, rloc);
15885           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15886         }
15887       else if (unformat (input, "action %U",
15888                          unformat_negative_mapping_action, &action))
15889         {
15890           ;
15891         }
15892       else
15893         {
15894           clib_warning ("parse error '%U'", format_unformat_error, input);
15895           return -99;
15896         }
15897     }
15898
15899   if (0 == eid_set)
15900     {
15901       errmsg ("missing params!");
15902       return -99;
15903     }
15904
15905   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15906     {
15907       errmsg ("no action set for negative map-reply!");
15908       return -99;
15909     }
15910
15911   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15912
15913   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15914   mp->is_add = is_add;
15915   mp->vni = htonl (vni);
15916   mp->action = (u8) action;
15917   mp->is_src_dst = seid_set;
15918   mp->del_all = del_all;
15919   lisp_eid_put_vat (&mp->deid, eid);
15920   lisp_eid_put_vat (&mp->seid, seid);
15921
15922   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15923   clib_memcpy (mp->rlocs, rlocs, data_len);
15924   vec_free (rlocs);
15925
15926   /* send it... */
15927   S (mp);
15928
15929   /* Wait for a reply... */
15930   W (ret);
15931   return ret;
15932 }
15933
15934 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15935
15936 /**
15937  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15938  * forwarding entries in data-plane accordingly.
15939  *
15940  * @param vam vpp API test context
15941  * @return return code
15942  */
15943 static int
15944 api_one_add_del_adjacency (vat_main_t * vam)
15945 {
15946   unformat_input_t *input = vam->input;
15947   vl_api_one_add_del_adjacency_t *mp;
15948   u32 vni = 0;
15949   u8 is_add = 1;
15950   int ret;
15951   lisp_eid_vat_t leid, reid;
15952
15953   leid.type = reid.type = (u8) ~ 0;
15954
15955   /* Parse args required to build the message */
15956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15957     {
15958       if (unformat (input, "del"))
15959         {
15960           is_add = 0;
15961         }
15962       else if (unformat (input, "add"))
15963         {
15964           is_add = 1;
15965         }
15966       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15967                          &reid.addr.ip, &reid.len))
15968         {
15969           reid.type = 0;        /* ipv4 */
15970         }
15971       else if (unformat (input, "reid %U", unformat_ethernet_address,
15972                          &reid.addr.mac))
15973         {
15974           reid.type = 1;        /* mac */
15975         }
15976       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
15977                          &leid.addr.ip, &leid.len))
15978         {
15979           leid.type = 0;        /* ipv4 */
15980         }
15981       else if (unformat (input, "leid %U", unformat_ethernet_address,
15982                          &leid.addr.mac))
15983         {
15984           leid.type = 1;        /* mac */
15985         }
15986       else if (unformat (input, "vni %d", &vni))
15987         {
15988           ;
15989         }
15990       else
15991         {
15992           errmsg ("parse error '%U'", format_unformat_error, input);
15993           return -99;
15994         }
15995     }
15996
15997   if ((u8) ~ 0 == reid.type)
15998     {
15999       errmsg ("missing params!");
16000       return -99;
16001     }
16002
16003   if (leid.type != reid.type)
16004     {
16005       errmsg ("remote and local EIDs are of different types!");
16006       return -99;
16007     }
16008
16009   M (ONE_ADD_DEL_ADJACENCY, mp);
16010   mp->is_add = is_add;
16011   mp->vni = htonl (vni);
16012   lisp_eid_put_vat (&mp->leid, &leid);
16013   lisp_eid_put_vat (&mp->reid, &reid);
16014
16015   /* send it... */
16016   S (mp);
16017
16018   /* Wait for a reply... */
16019   W (ret);
16020   return ret;
16021 }
16022
16023 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16024
16025 uword
16026 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16027 {
16028   u32 *mode = va_arg (*args, u32 *);
16029
16030   if (unformat (input, "lisp"))
16031     *mode = 0;
16032   else if (unformat (input, "vxlan"))
16033     *mode = 1;
16034   else
16035     return 0;
16036
16037   return 1;
16038 }
16039
16040 static int
16041 api_gpe_get_encap_mode (vat_main_t * vam)
16042 {
16043   vl_api_gpe_get_encap_mode_t *mp;
16044   int ret;
16045
16046   /* Construct the API message */
16047   M (GPE_GET_ENCAP_MODE, mp);
16048
16049   /* send it... */
16050   S (mp);
16051
16052   /* Wait for a reply... */
16053   W (ret);
16054   return ret;
16055 }
16056
16057 static int
16058 api_gpe_set_encap_mode (vat_main_t * vam)
16059 {
16060   unformat_input_t *input = vam->input;
16061   vl_api_gpe_set_encap_mode_t *mp;
16062   int ret;
16063   u32 mode = 0;
16064
16065   /* Parse args required to build the message */
16066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16067     {
16068       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16069         ;
16070       else
16071         break;
16072     }
16073
16074   /* Construct the API message */
16075   M (GPE_SET_ENCAP_MODE, mp);
16076
16077   mp->is_vxlan = mode;
16078
16079   /* send it... */
16080   S (mp);
16081
16082   /* Wait for a reply... */
16083   W (ret);
16084   return ret;
16085 }
16086
16087 static int
16088 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16089 {
16090   unformat_input_t *input = vam->input;
16091   vl_api_gpe_add_del_iface_t *mp;
16092   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16093   u32 dp_table = 0, vni = 0;
16094   int ret;
16095
16096   /* Parse args required to build the message */
16097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16098     {
16099       if (unformat (input, "up"))
16100         {
16101           action_set = 1;
16102           is_add = 1;
16103         }
16104       else if (unformat (input, "down"))
16105         {
16106           action_set = 1;
16107           is_add = 0;
16108         }
16109       else if (unformat (input, "table_id %d", &dp_table))
16110         {
16111           dp_table_set = 1;
16112         }
16113       else if (unformat (input, "bd_id %d", &dp_table))
16114         {
16115           dp_table_set = 1;
16116           is_l2 = 1;
16117         }
16118       else if (unformat (input, "vni %d", &vni))
16119         {
16120           vni_set = 1;
16121         }
16122       else
16123         break;
16124     }
16125
16126   if (action_set == 0)
16127     {
16128       errmsg ("Action not set");
16129       return -99;
16130     }
16131   if (dp_table_set == 0 || vni_set == 0)
16132     {
16133       errmsg ("vni and dp_table must be set");
16134       return -99;
16135     }
16136
16137   /* Construct the API message */
16138   M (GPE_ADD_DEL_IFACE, mp);
16139
16140   mp->is_add = is_add;
16141   mp->dp_table = clib_host_to_net_u32 (dp_table);
16142   mp->is_l2 = is_l2;
16143   mp->vni = clib_host_to_net_u32 (vni);
16144
16145   /* send it... */
16146   S (mp);
16147
16148   /* Wait for a reply... */
16149   W (ret);
16150   return ret;
16151 }
16152
16153 static int
16154 api_one_map_register_fallback_threshold (vat_main_t * vam)
16155 {
16156   unformat_input_t *input = vam->input;
16157   vl_api_one_map_register_fallback_threshold_t *mp;
16158   u32 value = 0;
16159   u8 is_set = 0;
16160   int ret;
16161
16162   /* Parse args required to build the message */
16163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16164     {
16165       if (unformat (input, "%u", &value))
16166         is_set = 1;
16167       else
16168         {
16169           clib_warning ("parse error '%U'", format_unformat_error, input);
16170           return -99;
16171         }
16172     }
16173
16174   if (!is_set)
16175     {
16176       errmsg ("fallback threshold value is missing!");
16177       return -99;
16178     }
16179
16180   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16181   mp->value = clib_host_to_net_u32 (value);
16182
16183   /* send it... */
16184   S (mp);
16185
16186   /* Wait for a reply... */
16187   W (ret);
16188   return ret;
16189 }
16190
16191 static int
16192 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16193 {
16194   vl_api_show_one_map_register_fallback_threshold_t *mp;
16195   int ret;
16196
16197   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16198
16199   /* send it... */
16200   S (mp);
16201
16202   /* Wait for a reply... */
16203   W (ret);
16204   return ret;
16205 }
16206
16207 uword
16208 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16209 {
16210   u32 *proto = va_arg (*args, u32 *);
16211
16212   if (unformat (input, "udp"))
16213     *proto = 1;
16214   else if (unformat (input, "api"))
16215     *proto = 2;
16216   else
16217     return 0;
16218
16219   return 1;
16220 }
16221
16222 static int
16223 api_one_set_transport_protocol (vat_main_t * vam)
16224 {
16225   unformat_input_t *input = vam->input;
16226   vl_api_one_set_transport_protocol_t *mp;
16227   u8 is_set = 0;
16228   u32 protocol = 0;
16229   int ret;
16230
16231   /* Parse args required to build the message */
16232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16233     {
16234       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16235         is_set = 1;
16236       else
16237         {
16238           clib_warning ("parse error '%U'", format_unformat_error, input);
16239           return -99;
16240         }
16241     }
16242
16243   if (!is_set)
16244     {
16245       errmsg ("Transport protocol missing!");
16246       return -99;
16247     }
16248
16249   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16250   mp->protocol = (u8) protocol;
16251
16252   /* send it... */
16253   S (mp);
16254
16255   /* Wait for a reply... */
16256   W (ret);
16257   return ret;
16258 }
16259
16260 static int
16261 api_one_get_transport_protocol (vat_main_t * vam)
16262 {
16263   vl_api_one_get_transport_protocol_t *mp;
16264   int ret;
16265
16266   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16267
16268   /* send it... */
16269   S (mp);
16270
16271   /* Wait for a reply... */
16272   W (ret);
16273   return ret;
16274 }
16275
16276 static int
16277 api_one_map_register_set_ttl (vat_main_t * vam)
16278 {
16279   unformat_input_t *input = vam->input;
16280   vl_api_one_map_register_set_ttl_t *mp;
16281   u32 ttl = 0;
16282   u8 is_set = 0;
16283   int ret;
16284
16285   /* Parse args required to build the message */
16286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16287     {
16288       if (unformat (input, "%u", &ttl))
16289         is_set = 1;
16290       else
16291         {
16292           clib_warning ("parse error '%U'", format_unformat_error, input);
16293           return -99;
16294         }
16295     }
16296
16297   if (!is_set)
16298     {
16299       errmsg ("TTL value missing!");
16300       return -99;
16301     }
16302
16303   M (ONE_MAP_REGISTER_SET_TTL, mp);
16304   mp->ttl = clib_host_to_net_u32 (ttl);
16305
16306   /* send it... */
16307   S (mp);
16308
16309   /* Wait for a reply... */
16310   W (ret);
16311   return ret;
16312 }
16313
16314 static int
16315 api_show_one_map_register_ttl (vat_main_t * vam)
16316 {
16317   vl_api_show_one_map_register_ttl_t *mp;
16318   int ret;
16319
16320   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16321
16322   /* send it... */
16323   S (mp);
16324
16325   /* Wait for a reply... */
16326   W (ret);
16327   return ret;
16328 }
16329
16330 /**
16331  * Add/del map request itr rlocs from ONE control plane and updates
16332  *
16333  * @param vam vpp API test context
16334  * @return return code
16335  */
16336 static int
16337 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16338 {
16339   unformat_input_t *input = vam->input;
16340   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16341   u8 *locator_set_name = 0;
16342   u8 locator_set_name_set = 0;
16343   u8 is_add = 1;
16344   int ret;
16345
16346   /* Parse args required to build the message */
16347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16348     {
16349       if (unformat (input, "del"))
16350         {
16351           is_add = 0;
16352         }
16353       else if (unformat (input, "%_%v%_", &locator_set_name))
16354         {
16355           locator_set_name_set = 1;
16356         }
16357       else
16358         {
16359           clib_warning ("parse error '%U'", format_unformat_error, input);
16360           return -99;
16361         }
16362     }
16363
16364   if (is_add && !locator_set_name_set)
16365     {
16366       errmsg ("itr-rloc is not set!");
16367       return -99;
16368     }
16369
16370   if (is_add && vec_len (locator_set_name) > 64)
16371     {
16372       errmsg ("itr-rloc locator-set name too long");
16373       vec_free (locator_set_name);
16374       return -99;
16375     }
16376
16377   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16378   mp->is_add = is_add;
16379   if (is_add)
16380     {
16381       clib_memcpy (mp->locator_set_name, locator_set_name,
16382                    vec_len (locator_set_name));
16383     }
16384   else
16385     {
16386       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16387     }
16388   vec_free (locator_set_name);
16389
16390   /* send it... */
16391   S (mp);
16392
16393   /* Wait for a reply... */
16394   W (ret);
16395   return ret;
16396 }
16397
16398 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16399
16400 static int
16401 api_one_locator_dump (vat_main_t * vam)
16402 {
16403   unformat_input_t *input = vam->input;
16404   vl_api_one_locator_dump_t *mp;
16405   vl_api_control_ping_t *mp_ping;
16406   u8 is_index_set = 0, is_name_set = 0;
16407   u8 *ls_name = 0;
16408   u32 ls_index = ~0;
16409   int ret;
16410
16411   /* Parse args required to build the message */
16412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16413     {
16414       if (unformat (input, "ls_name %_%v%_", &ls_name))
16415         {
16416           is_name_set = 1;
16417         }
16418       else if (unformat (input, "ls_index %d", &ls_index))
16419         {
16420           is_index_set = 1;
16421         }
16422       else
16423         {
16424           errmsg ("parse error '%U'", format_unformat_error, input);
16425           return -99;
16426         }
16427     }
16428
16429   if (!is_index_set && !is_name_set)
16430     {
16431       errmsg ("error: expected one of index or name!");
16432       return -99;
16433     }
16434
16435   if (is_index_set && is_name_set)
16436     {
16437       errmsg ("error: only one param expected!");
16438       return -99;
16439     }
16440
16441   if (vec_len (ls_name) > 62)
16442     {
16443       errmsg ("error: locator set name too long!");
16444       return -99;
16445     }
16446
16447   if (!vam->json_output)
16448     {
16449       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16450     }
16451
16452   M (ONE_LOCATOR_DUMP, mp);
16453   mp->is_index_set = is_index_set;
16454
16455   if (is_index_set)
16456     mp->ls_index = clib_host_to_net_u32 (ls_index);
16457   else
16458     {
16459       vec_add1 (ls_name, 0);
16460       strncpy ((char *) mp->ls_name, (char *) ls_name,
16461                sizeof (mp->ls_name) - 1);
16462     }
16463
16464   /* send it... */
16465   S (mp);
16466
16467   /* Use a control ping for synchronization */
16468   MPING (CONTROL_PING, mp_ping);
16469   S (mp_ping);
16470
16471   /* Wait for a reply... */
16472   W (ret);
16473   return ret;
16474 }
16475
16476 #define api_lisp_locator_dump api_one_locator_dump
16477
16478 static int
16479 api_one_locator_set_dump (vat_main_t * vam)
16480 {
16481   vl_api_one_locator_set_dump_t *mp;
16482   vl_api_control_ping_t *mp_ping;
16483   unformat_input_t *input = vam->input;
16484   u8 filter = 0;
16485   int ret;
16486
16487   /* Parse args required to build the message */
16488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16489     {
16490       if (unformat (input, "local"))
16491         {
16492           filter = 1;
16493         }
16494       else if (unformat (input, "remote"))
16495         {
16496           filter = 2;
16497         }
16498       else
16499         {
16500           errmsg ("parse error '%U'", format_unformat_error, input);
16501           return -99;
16502         }
16503     }
16504
16505   if (!vam->json_output)
16506     {
16507       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16508     }
16509
16510   M (ONE_LOCATOR_SET_DUMP, mp);
16511
16512   mp->filter = filter;
16513
16514   /* send it... */
16515   S (mp);
16516
16517   /* Use a control ping for synchronization */
16518   MPING (CONTROL_PING, mp_ping);
16519   S (mp_ping);
16520
16521   /* Wait for a reply... */
16522   W (ret);
16523   return ret;
16524 }
16525
16526 #define api_lisp_locator_set_dump api_one_locator_set_dump
16527
16528 static int
16529 api_one_eid_table_map_dump (vat_main_t * vam)
16530 {
16531   u8 is_l2 = 0;
16532   u8 mode_set = 0;
16533   unformat_input_t *input = vam->input;
16534   vl_api_one_eid_table_map_dump_t *mp;
16535   vl_api_control_ping_t *mp_ping;
16536   int ret;
16537
16538   /* Parse args required to build the message */
16539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16540     {
16541       if (unformat (input, "l2"))
16542         {
16543           is_l2 = 1;
16544           mode_set = 1;
16545         }
16546       else if (unformat (input, "l3"))
16547         {
16548           is_l2 = 0;
16549           mode_set = 1;
16550         }
16551       else
16552         {
16553           errmsg ("parse error '%U'", format_unformat_error, input);
16554           return -99;
16555         }
16556     }
16557
16558   if (!mode_set)
16559     {
16560       errmsg ("expected one of 'l2' or 'l3' parameter!");
16561       return -99;
16562     }
16563
16564   if (!vam->json_output)
16565     {
16566       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16567     }
16568
16569   M (ONE_EID_TABLE_MAP_DUMP, mp);
16570   mp->is_l2 = is_l2;
16571
16572   /* send it... */
16573   S (mp);
16574
16575   /* Use a control ping for synchronization */
16576   MPING (CONTROL_PING, mp_ping);
16577   S (mp_ping);
16578
16579   /* Wait for a reply... */
16580   W (ret);
16581   return ret;
16582 }
16583
16584 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16585
16586 static int
16587 api_one_eid_table_vni_dump (vat_main_t * vam)
16588 {
16589   vl_api_one_eid_table_vni_dump_t *mp;
16590   vl_api_control_ping_t *mp_ping;
16591   int ret;
16592
16593   if (!vam->json_output)
16594     {
16595       print (vam->ofp, "VNI");
16596     }
16597
16598   M (ONE_EID_TABLE_VNI_DUMP, mp);
16599
16600   /* send it... */
16601   S (mp);
16602
16603   /* Use a control ping for synchronization */
16604   MPING (CONTROL_PING, mp_ping);
16605   S (mp_ping);
16606
16607   /* Wait for a reply... */
16608   W (ret);
16609   return ret;
16610 }
16611
16612 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16613
16614 static int
16615 api_one_eid_table_dump (vat_main_t * vam)
16616 {
16617   unformat_input_t *i = vam->input;
16618   vl_api_one_eid_table_dump_t *mp;
16619   vl_api_control_ping_t *mp_ping;
16620   u8 filter = 0;
16621   int ret;
16622   u32 vni, t = 0;
16623   lisp_eid_vat_t eid;
16624   u8 eid_set = 0;
16625
16626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16627     {
16628       if (unformat
16629           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16630         {
16631           eid_set = 1;
16632           eid.type = 0;
16633         }
16634       else
16635         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16636         {
16637           eid_set = 1;
16638           eid.type = 1;
16639         }
16640       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16641         {
16642           eid_set = 1;
16643           eid.type = 2;
16644         }
16645       else if (unformat (i, "vni %d", &t))
16646         {
16647           vni = t;
16648         }
16649       else if (unformat (i, "local"))
16650         {
16651           filter = 1;
16652         }
16653       else if (unformat (i, "remote"))
16654         {
16655           filter = 2;
16656         }
16657       else
16658         {
16659           errmsg ("parse error '%U'", format_unformat_error, i);
16660           return -99;
16661         }
16662     }
16663
16664   if (!vam->json_output)
16665     {
16666       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16667              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16668     }
16669
16670   M (ONE_EID_TABLE_DUMP, mp);
16671
16672   mp->filter = filter;
16673   if (eid_set)
16674     {
16675       mp->eid_set = 1;
16676       mp->vni = htonl (vni);
16677       lisp_eid_put_vat (&mp->eid, &eid);
16678     }
16679
16680   /* send it... */
16681   S (mp);
16682
16683   /* Use a control ping for synchronization */
16684   MPING (CONTROL_PING, mp_ping);
16685   S (mp_ping);
16686
16687   /* Wait for a reply... */
16688   W (ret);
16689   return ret;
16690 }
16691
16692 #define api_lisp_eid_table_dump api_one_eid_table_dump
16693
16694 static int
16695 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16696 {
16697   unformat_input_t *i = vam->input;
16698   vl_api_gpe_fwd_entries_get_t *mp;
16699   u8 vni_set = 0;
16700   u32 vni = ~0;
16701   int ret;
16702
16703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16704     {
16705       if (unformat (i, "vni %d", &vni))
16706         {
16707           vni_set = 1;
16708         }
16709       else
16710         {
16711           errmsg ("parse error '%U'", format_unformat_error, i);
16712           return -99;
16713         }
16714     }
16715
16716   if (!vni_set)
16717     {
16718       errmsg ("vni not set!");
16719       return -99;
16720     }
16721
16722   if (!vam->json_output)
16723     {
16724       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16725              "leid", "reid");
16726     }
16727
16728   M (GPE_FWD_ENTRIES_GET, mp);
16729   mp->vni = clib_host_to_net_u32 (vni);
16730
16731   /* send it... */
16732   S (mp);
16733
16734   /* Wait for a reply... */
16735   W (ret);
16736   return ret;
16737 }
16738
16739 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16740 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16741 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16742 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16743 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16744 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16745 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16746 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16747
16748 static int
16749 api_one_adjacencies_get (vat_main_t * vam)
16750 {
16751   unformat_input_t *i = vam->input;
16752   vl_api_one_adjacencies_get_t *mp;
16753   u8 vni_set = 0;
16754   u32 vni = ~0;
16755   int ret;
16756
16757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16758     {
16759       if (unformat (i, "vni %d", &vni))
16760         {
16761           vni_set = 1;
16762         }
16763       else
16764         {
16765           errmsg ("parse error '%U'", format_unformat_error, i);
16766           return -99;
16767         }
16768     }
16769
16770   if (!vni_set)
16771     {
16772       errmsg ("vni not set!");
16773       return -99;
16774     }
16775
16776   if (!vam->json_output)
16777     {
16778       print (vam->ofp, "%s %40s", "leid", "reid");
16779     }
16780
16781   M (ONE_ADJACENCIES_GET, mp);
16782   mp->vni = clib_host_to_net_u32 (vni);
16783
16784   /* send it... */
16785   S (mp);
16786
16787   /* Wait for a reply... */
16788   W (ret);
16789   return ret;
16790 }
16791
16792 #define api_lisp_adjacencies_get api_one_adjacencies_get
16793
16794 static int
16795 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16796 {
16797   unformat_input_t *i = vam->input;
16798   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16799   int ret;
16800   u8 ip_family_set = 0, is_ip4 = 1;
16801
16802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16803     {
16804       if (unformat (i, "ip4"))
16805         {
16806           ip_family_set = 1;
16807           is_ip4 = 1;
16808         }
16809       else if (unformat (i, "ip6"))
16810         {
16811           ip_family_set = 1;
16812           is_ip4 = 0;
16813         }
16814       else
16815         {
16816           errmsg ("parse error '%U'", format_unformat_error, i);
16817           return -99;
16818         }
16819     }
16820
16821   if (!ip_family_set)
16822     {
16823       errmsg ("ip family not set!");
16824       return -99;
16825     }
16826
16827   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16828   mp->is_ip4 = is_ip4;
16829
16830   /* send it... */
16831   S (mp);
16832
16833   /* Wait for a reply... */
16834   W (ret);
16835   return ret;
16836 }
16837
16838 static int
16839 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16840 {
16841   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16842   int ret;
16843
16844   if (!vam->json_output)
16845     {
16846       print (vam->ofp, "VNIs");
16847     }
16848
16849   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16850
16851   /* send it... */
16852   S (mp);
16853
16854   /* Wait for a reply... */
16855   W (ret);
16856   return ret;
16857 }
16858
16859 static int
16860 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16861 {
16862   unformat_input_t *i = vam->input;
16863   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16864   int ret = 0;
16865   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16866   struct in_addr ip4;
16867   struct in6_addr ip6;
16868   u32 table_id = 0, nh_sw_if_index = ~0;
16869
16870   clib_memset (&ip4, 0, sizeof (ip4));
16871   clib_memset (&ip6, 0, sizeof (ip6));
16872
16873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16874     {
16875       if (unformat (i, "del"))
16876         is_add = 0;
16877       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16878                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16879         {
16880           ip_set = 1;
16881           is_ip4 = 1;
16882         }
16883       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16884                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16885         {
16886           ip_set = 1;
16887           is_ip4 = 0;
16888         }
16889       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16890         {
16891           ip_set = 1;
16892           is_ip4 = 1;
16893           nh_sw_if_index = ~0;
16894         }
16895       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16896         {
16897           ip_set = 1;
16898           is_ip4 = 0;
16899           nh_sw_if_index = ~0;
16900         }
16901       else if (unformat (i, "table %d", &table_id))
16902         ;
16903       else
16904         {
16905           errmsg ("parse error '%U'", format_unformat_error, i);
16906           return -99;
16907         }
16908     }
16909
16910   if (!ip_set)
16911     {
16912       errmsg ("nh addr not set!");
16913       return -99;
16914     }
16915
16916   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16917   mp->is_add = is_add;
16918   mp->table_id = clib_host_to_net_u32 (table_id);
16919   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16920   mp->nh_addr.af = is_ip4 ? 0 : 1;
16921   if (is_ip4)
16922     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16923   else
16924     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16925
16926   /* send it... */
16927   S (mp);
16928
16929   /* Wait for a reply... */
16930   W (ret);
16931   return ret;
16932 }
16933
16934 static int
16935 api_one_map_server_dump (vat_main_t * vam)
16936 {
16937   vl_api_one_map_server_dump_t *mp;
16938   vl_api_control_ping_t *mp_ping;
16939   int ret;
16940
16941   if (!vam->json_output)
16942     {
16943       print (vam->ofp, "%=20s", "Map server");
16944     }
16945
16946   M (ONE_MAP_SERVER_DUMP, mp);
16947   /* send it... */
16948   S (mp);
16949
16950   /* Use a control ping for synchronization */
16951   MPING (CONTROL_PING, mp_ping);
16952   S (mp_ping);
16953
16954   /* Wait for a reply... */
16955   W (ret);
16956   return ret;
16957 }
16958
16959 #define api_lisp_map_server_dump api_one_map_server_dump
16960
16961 static int
16962 api_one_map_resolver_dump (vat_main_t * vam)
16963 {
16964   vl_api_one_map_resolver_dump_t *mp;
16965   vl_api_control_ping_t *mp_ping;
16966   int ret;
16967
16968   if (!vam->json_output)
16969     {
16970       print (vam->ofp, "%=20s", "Map resolver");
16971     }
16972
16973   M (ONE_MAP_RESOLVER_DUMP, mp);
16974   /* send it... */
16975   S (mp);
16976
16977   /* Use a control ping for synchronization */
16978   MPING (CONTROL_PING, mp_ping);
16979   S (mp_ping);
16980
16981   /* Wait for a reply... */
16982   W (ret);
16983   return ret;
16984 }
16985
16986 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16987
16988 static int
16989 api_one_stats_flush (vat_main_t * vam)
16990 {
16991   vl_api_one_stats_flush_t *mp;
16992   int ret = 0;
16993
16994   M (ONE_STATS_FLUSH, mp);
16995   S (mp);
16996   W (ret);
16997   return ret;
16998 }
16999
17000 static int
17001 api_one_stats_dump (vat_main_t * vam)
17002 {
17003   vl_api_one_stats_dump_t *mp;
17004   vl_api_control_ping_t *mp_ping;
17005   int ret;
17006
17007   M (ONE_STATS_DUMP, mp);
17008   /* send it... */
17009   S (mp);
17010
17011   /* Use a control ping for synchronization */
17012   MPING (CONTROL_PING, mp_ping);
17013   S (mp_ping);
17014
17015   /* Wait for a reply... */
17016   W (ret);
17017   return ret;
17018 }
17019
17020 static int
17021 api_show_one_status (vat_main_t * vam)
17022 {
17023   vl_api_show_one_status_t *mp;
17024   int ret;
17025
17026   if (!vam->json_output)
17027     {
17028       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17029     }
17030
17031   M (SHOW_ONE_STATUS, mp);
17032   /* send it... */
17033   S (mp);
17034   /* Wait for a reply... */
17035   W (ret);
17036   return ret;
17037 }
17038
17039 #define api_show_lisp_status api_show_one_status
17040
17041 static int
17042 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17043 {
17044   vl_api_gpe_fwd_entry_path_dump_t *mp;
17045   vl_api_control_ping_t *mp_ping;
17046   unformat_input_t *i = vam->input;
17047   u32 fwd_entry_index = ~0;
17048   int ret;
17049
17050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17051     {
17052       if (unformat (i, "index %d", &fwd_entry_index))
17053         ;
17054       else
17055         break;
17056     }
17057
17058   if (~0 == fwd_entry_index)
17059     {
17060       errmsg ("no index specified!");
17061       return -99;
17062     }
17063
17064   if (!vam->json_output)
17065     {
17066       print (vam->ofp, "first line");
17067     }
17068
17069   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17070
17071   /* send it... */
17072   S (mp);
17073   /* Use a control ping for synchronization */
17074   MPING (CONTROL_PING, mp_ping);
17075   S (mp_ping);
17076
17077   /* Wait for a reply... */
17078   W (ret);
17079   return ret;
17080 }
17081
17082 static int
17083 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17084 {
17085   vl_api_one_get_map_request_itr_rlocs_t *mp;
17086   int ret;
17087
17088   if (!vam->json_output)
17089     {
17090       print (vam->ofp, "%=20s", "itr-rlocs:");
17091     }
17092
17093   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17094   /* send it... */
17095   S (mp);
17096   /* Wait for a reply... */
17097   W (ret);
17098   return ret;
17099 }
17100
17101 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17102
17103 static int
17104 api_af_packet_create (vat_main_t * vam)
17105 {
17106   unformat_input_t *i = vam->input;
17107   vl_api_af_packet_create_t *mp;
17108   u8 *host_if_name = 0;
17109   u8 hw_addr[6];
17110   u8 random_hw_addr = 1;
17111   int ret;
17112
17113   clib_memset (hw_addr, 0, sizeof (hw_addr));
17114
17115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17116     {
17117       if (unformat (i, "name %s", &host_if_name))
17118         vec_add1 (host_if_name, 0);
17119       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17120         random_hw_addr = 0;
17121       else
17122         break;
17123     }
17124
17125   if (!vec_len (host_if_name))
17126     {
17127       errmsg ("host-interface name must be specified");
17128       return -99;
17129     }
17130
17131   if (vec_len (host_if_name) > 64)
17132     {
17133       errmsg ("host-interface name too long");
17134       return -99;
17135     }
17136
17137   M (AF_PACKET_CREATE, mp);
17138
17139   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17140   clib_memcpy (mp->hw_addr, hw_addr, 6);
17141   mp->use_random_hw_addr = random_hw_addr;
17142   vec_free (host_if_name);
17143
17144   S (mp);
17145
17146   /* *INDENT-OFF* */
17147   W2 (ret,
17148       ({
17149         if (ret == 0)
17150           fprintf (vam->ofp ? vam->ofp : stderr,
17151                    " new sw_if_index = %d\n", vam->sw_if_index);
17152       }));
17153   /* *INDENT-ON* */
17154   return ret;
17155 }
17156
17157 static int
17158 api_af_packet_delete (vat_main_t * vam)
17159 {
17160   unformat_input_t *i = vam->input;
17161   vl_api_af_packet_delete_t *mp;
17162   u8 *host_if_name = 0;
17163   int ret;
17164
17165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17166     {
17167       if (unformat (i, "name %s", &host_if_name))
17168         vec_add1 (host_if_name, 0);
17169       else
17170         break;
17171     }
17172
17173   if (!vec_len (host_if_name))
17174     {
17175       errmsg ("host-interface name must be specified");
17176       return -99;
17177     }
17178
17179   if (vec_len (host_if_name) > 64)
17180     {
17181       errmsg ("host-interface name too long");
17182       return -99;
17183     }
17184
17185   M (AF_PACKET_DELETE, mp);
17186
17187   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17188   vec_free (host_if_name);
17189
17190   S (mp);
17191   W (ret);
17192   return ret;
17193 }
17194
17195 static void vl_api_af_packet_details_t_handler
17196   (vl_api_af_packet_details_t * mp)
17197 {
17198   vat_main_t *vam = &vat_main;
17199
17200   print (vam->ofp, "%-16s %d",
17201          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17202 }
17203
17204 static void vl_api_af_packet_details_t_handler_json
17205   (vl_api_af_packet_details_t * mp)
17206 {
17207   vat_main_t *vam = &vat_main;
17208   vat_json_node_t *node = NULL;
17209
17210   if (VAT_JSON_ARRAY != vam->json_tree.type)
17211     {
17212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17213       vat_json_init_array (&vam->json_tree);
17214     }
17215   node = vat_json_array_add (&vam->json_tree);
17216
17217   vat_json_init_object (node);
17218   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17219   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17220 }
17221
17222 static int
17223 api_af_packet_dump (vat_main_t * vam)
17224 {
17225   vl_api_af_packet_dump_t *mp;
17226   vl_api_control_ping_t *mp_ping;
17227   int ret;
17228
17229   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17230   /* Get list of tap interfaces */
17231   M (AF_PACKET_DUMP, mp);
17232   S (mp);
17233
17234   /* Use a control ping for synchronization */
17235   MPING (CONTROL_PING, mp_ping);
17236   S (mp_ping);
17237
17238   W (ret);
17239   return ret;
17240 }
17241
17242 static int
17243 api_policer_add_del (vat_main_t * vam)
17244 {
17245   unformat_input_t *i = vam->input;
17246   vl_api_policer_add_del_t *mp;
17247   u8 is_add = 1;
17248   u8 *name = 0;
17249   u32 cir = 0;
17250   u32 eir = 0;
17251   u64 cb = 0;
17252   u64 eb = 0;
17253   u8 rate_type = 0;
17254   u8 round_type = 0;
17255   u8 type = 0;
17256   u8 color_aware = 0;
17257   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17258   int ret;
17259
17260   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17261   conform_action.dscp = 0;
17262   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17263   exceed_action.dscp = 0;
17264   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17265   violate_action.dscp = 0;
17266
17267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17268     {
17269       if (unformat (i, "del"))
17270         is_add = 0;
17271       else if (unformat (i, "name %s", &name))
17272         vec_add1 (name, 0);
17273       else if (unformat (i, "cir %u", &cir))
17274         ;
17275       else if (unformat (i, "eir %u", &eir))
17276         ;
17277       else if (unformat (i, "cb %u", &cb))
17278         ;
17279       else if (unformat (i, "eb %u", &eb))
17280         ;
17281       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17282                          &rate_type))
17283         ;
17284       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17285                          &round_type))
17286         ;
17287       else if (unformat (i, "type %U", unformat_policer_type, &type))
17288         ;
17289       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17290                          &conform_action))
17291         ;
17292       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17293                          &exceed_action))
17294         ;
17295       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17296                          &violate_action))
17297         ;
17298       else if (unformat (i, "color-aware"))
17299         color_aware = 1;
17300       else
17301         break;
17302     }
17303
17304   if (!vec_len (name))
17305     {
17306       errmsg ("policer name must be specified");
17307       return -99;
17308     }
17309
17310   if (vec_len (name) > 64)
17311     {
17312       errmsg ("policer name too long");
17313       return -99;
17314     }
17315
17316   M (POLICER_ADD_DEL, mp);
17317
17318   clib_memcpy (mp->name, name, vec_len (name));
17319   vec_free (name);
17320   mp->is_add = is_add;
17321   mp->cir = ntohl (cir);
17322   mp->eir = ntohl (eir);
17323   mp->cb = clib_net_to_host_u64 (cb);
17324   mp->eb = clib_net_to_host_u64 (eb);
17325   mp->rate_type = rate_type;
17326   mp->round_type = round_type;
17327   mp->type = type;
17328   mp->conform_action.type = conform_action.action_type;
17329   mp->conform_action.dscp = conform_action.dscp;
17330   mp->exceed_action.type = exceed_action.action_type;
17331   mp->exceed_action.dscp = exceed_action.dscp;
17332   mp->violate_action.type = violate_action.action_type;
17333   mp->violate_action.dscp = violate_action.dscp;
17334   mp->color_aware = color_aware;
17335
17336   S (mp);
17337   W (ret);
17338   return ret;
17339 }
17340
17341 static int
17342 api_policer_dump (vat_main_t * vam)
17343 {
17344   unformat_input_t *i = vam->input;
17345   vl_api_policer_dump_t *mp;
17346   vl_api_control_ping_t *mp_ping;
17347   u8 *match_name = 0;
17348   u8 match_name_valid = 0;
17349   int ret;
17350
17351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17352     {
17353       if (unformat (i, "name %s", &match_name))
17354         {
17355           vec_add1 (match_name, 0);
17356           match_name_valid = 1;
17357         }
17358       else
17359         break;
17360     }
17361
17362   M (POLICER_DUMP, mp);
17363   mp->match_name_valid = match_name_valid;
17364   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17365   vec_free (match_name);
17366   /* send it... */
17367   S (mp);
17368
17369   /* Use a control ping for synchronization */
17370   MPING (CONTROL_PING, mp_ping);
17371   S (mp_ping);
17372
17373   /* Wait for a reply... */
17374   W (ret);
17375   return ret;
17376 }
17377
17378 static int
17379 api_policer_classify_set_interface (vat_main_t * vam)
17380 {
17381   unformat_input_t *i = vam->input;
17382   vl_api_policer_classify_set_interface_t *mp;
17383   u32 sw_if_index;
17384   int sw_if_index_set;
17385   u32 ip4_table_index = ~0;
17386   u32 ip6_table_index = ~0;
17387   u32 l2_table_index = ~0;
17388   u8 is_add = 1;
17389   int ret;
17390
17391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17392     {
17393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17394         sw_if_index_set = 1;
17395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17396         sw_if_index_set = 1;
17397       else if (unformat (i, "del"))
17398         is_add = 0;
17399       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17400         ;
17401       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17402         ;
17403       else if (unformat (i, "l2-table %d", &l2_table_index))
17404         ;
17405       else
17406         {
17407           clib_warning ("parse error '%U'", format_unformat_error, i);
17408           return -99;
17409         }
17410     }
17411
17412   if (sw_if_index_set == 0)
17413     {
17414       errmsg ("missing interface name or sw_if_index");
17415       return -99;
17416     }
17417
17418   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17419
17420   mp->sw_if_index = ntohl (sw_if_index);
17421   mp->ip4_table_index = ntohl (ip4_table_index);
17422   mp->ip6_table_index = ntohl (ip6_table_index);
17423   mp->l2_table_index = ntohl (l2_table_index);
17424   mp->is_add = is_add;
17425
17426   S (mp);
17427   W (ret);
17428   return ret;
17429 }
17430
17431 static int
17432 api_policer_classify_dump (vat_main_t * vam)
17433 {
17434   unformat_input_t *i = vam->input;
17435   vl_api_policer_classify_dump_t *mp;
17436   vl_api_control_ping_t *mp_ping;
17437   u8 type = POLICER_CLASSIFY_N_TABLES;
17438   int ret;
17439
17440   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17441     ;
17442   else
17443     {
17444       errmsg ("classify table type must be specified");
17445       return -99;
17446     }
17447
17448   if (!vam->json_output)
17449     {
17450       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17451     }
17452
17453   M (POLICER_CLASSIFY_DUMP, mp);
17454   mp->type = type;
17455   /* send it... */
17456   S (mp);
17457
17458   /* Use a control ping for synchronization */
17459   MPING (CONTROL_PING, mp_ping);
17460   S (mp_ping);
17461
17462   /* Wait for a reply... */
17463   W (ret);
17464   return ret;
17465 }
17466
17467 static u8 *
17468 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17469 {
17470   vl_api_fib_path_nh_proto_t proto =
17471     va_arg (*args, vl_api_fib_path_nh_proto_t);
17472
17473   switch (proto)
17474     {
17475     case FIB_API_PATH_NH_PROTO_IP4:
17476       s = format (s, "ip4");
17477       break;
17478     case FIB_API_PATH_NH_PROTO_IP6:
17479       s = format (s, "ip6");
17480       break;
17481     case FIB_API_PATH_NH_PROTO_MPLS:
17482       s = format (s, "mpls");
17483       break;
17484     case FIB_API_PATH_NH_PROTO_BIER:
17485       s = format (s, "bier");
17486       break;
17487     case FIB_API_PATH_NH_PROTO_ETHERNET:
17488       s = format (s, "ethernet");
17489       break;
17490     }
17491
17492   return (s);
17493 }
17494
17495 static u8 *
17496 format_vl_api_ip_address_union (u8 * s, va_list * args)
17497 {
17498   vl_api_address_family_t af = va_arg (*args, int);
17499   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17500
17501   switch (af)
17502     {
17503     case ADDRESS_IP4:
17504       s = format (s, "%U", format_ip4_address, u->ip4);
17505       break;
17506     case ADDRESS_IP6:
17507       s = format (s, "%U", format_ip6_address, u->ip6);
17508       break;
17509     }
17510   return (s);
17511 }
17512
17513 static u8 *
17514 format_vl_api_fib_path_type (u8 * s, va_list * args)
17515 {
17516   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17517
17518   switch (t)
17519     {
17520     case FIB_API_PATH_TYPE_NORMAL:
17521       s = format (s, "normal");
17522       break;
17523     case FIB_API_PATH_TYPE_LOCAL:
17524       s = format (s, "local");
17525       break;
17526     case FIB_API_PATH_TYPE_DROP:
17527       s = format (s, "drop");
17528       break;
17529     case FIB_API_PATH_TYPE_UDP_ENCAP:
17530       s = format (s, "udp-encap");
17531       break;
17532     case FIB_API_PATH_TYPE_BIER_IMP:
17533       s = format (s, "bier-imp");
17534       break;
17535     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17536       s = format (s, "unreach");
17537       break;
17538     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17539       s = format (s, "prohibit");
17540       break;
17541     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17542       s = format (s, "src-lookup");
17543       break;
17544     case FIB_API_PATH_TYPE_DVR:
17545       s = format (s, "dvr");
17546       break;
17547     case FIB_API_PATH_TYPE_INTERFACE_RX:
17548       s = format (s, "interface-rx");
17549       break;
17550     case FIB_API_PATH_TYPE_CLASSIFY:
17551       s = format (s, "classify");
17552       break;
17553     }
17554
17555   return (s);
17556 }
17557
17558 static void
17559 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17560 {
17561   print (vam->ofp,
17562          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17563          ntohl (fp->weight), ntohl (fp->sw_if_index),
17564          format_vl_api_fib_path_type, fp->type,
17565          format_fib_api_path_nh_proto, fp->proto,
17566          format_vl_api_ip_address_union, &fp->nh.address);
17567 }
17568
17569 static void
17570 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17571                                  vl_api_fib_path_t * fp)
17572 {
17573   struct in_addr ip4;
17574   struct in6_addr ip6;
17575
17576   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17577   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17578   vat_json_object_add_uint (node, "type", fp->type);
17579   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17580   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17581     {
17582       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17583       vat_json_object_add_ip4 (node, "next_hop", ip4);
17584     }
17585   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17586     {
17587       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17588       vat_json_object_add_ip6 (node, "next_hop", ip6);
17589     }
17590 }
17591
17592 static void
17593 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17594 {
17595   vat_main_t *vam = &vat_main;
17596   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17597   vl_api_fib_path_t *fp;
17598   i32 i;
17599
17600   print (vam->ofp, "sw_if_index %d via:",
17601          ntohl (mp->mt_tunnel.mt_sw_if_index));
17602   fp = mp->mt_tunnel.mt_paths;
17603   for (i = 0; i < count; i++)
17604     {
17605       vl_api_fib_path_print (vam, fp);
17606       fp++;
17607     }
17608
17609   print (vam->ofp, "");
17610 }
17611
17612 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17613 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17614
17615 static void
17616 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17617 {
17618   vat_main_t *vam = &vat_main;
17619   vat_json_node_t *node = NULL;
17620   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17621   vl_api_fib_path_t *fp;
17622   i32 i;
17623
17624   if (VAT_JSON_ARRAY != vam->json_tree.type)
17625     {
17626       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17627       vat_json_init_array (&vam->json_tree);
17628     }
17629   node = vat_json_array_add (&vam->json_tree);
17630
17631   vat_json_init_object (node);
17632   vat_json_object_add_uint (node, "sw_if_index",
17633                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17634
17635   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17636
17637   fp = mp->mt_tunnel.mt_paths;
17638   for (i = 0; i < count; i++)
17639     {
17640       vl_api_mpls_fib_path_json_print (node, fp);
17641       fp++;
17642     }
17643 }
17644
17645 static int
17646 api_mpls_tunnel_dump (vat_main_t * vam)
17647 {
17648   vl_api_mpls_tunnel_dump_t *mp;
17649   vl_api_control_ping_t *mp_ping;
17650   int ret;
17651
17652   M (MPLS_TUNNEL_DUMP, mp);
17653
17654   S (mp);
17655
17656   /* Use a control ping for synchronization */
17657   MPING (CONTROL_PING, mp_ping);
17658   S (mp_ping);
17659
17660   W (ret);
17661   return ret;
17662 }
17663
17664 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17665 #define vl_api_mpls_table_details_t_print vl_noop_handler
17666
17667
17668 static void
17669 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17670 {
17671   vat_main_t *vam = &vat_main;
17672
17673   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17674 }
17675
17676 static void vl_api_mpls_table_details_t_handler_json
17677   (vl_api_mpls_table_details_t * mp)
17678 {
17679   vat_main_t *vam = &vat_main;
17680   vat_json_node_t *node = NULL;
17681
17682   if (VAT_JSON_ARRAY != vam->json_tree.type)
17683     {
17684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17685       vat_json_init_array (&vam->json_tree);
17686     }
17687   node = vat_json_array_add (&vam->json_tree);
17688
17689   vat_json_init_object (node);
17690   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17691 }
17692
17693 static int
17694 api_mpls_table_dump (vat_main_t * vam)
17695 {
17696   vl_api_mpls_table_dump_t *mp;
17697   vl_api_control_ping_t *mp_ping;
17698   int ret;
17699
17700   M (MPLS_TABLE_DUMP, mp);
17701   S (mp);
17702
17703   /* Use a control ping for synchronization */
17704   MPING (CONTROL_PING, mp_ping);
17705   S (mp_ping);
17706
17707   W (ret);
17708   return ret;
17709 }
17710
17711 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17712 #define vl_api_mpls_route_details_t_print vl_noop_handler
17713
17714 static void
17715 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17716 {
17717   vat_main_t *vam = &vat_main;
17718   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17719   vl_api_fib_path_t *fp;
17720   int i;
17721
17722   print (vam->ofp,
17723          "table-id %d, label %u, ess_bit %u",
17724          ntohl (mp->mr_route.mr_table_id),
17725          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17726   fp = mp->mr_route.mr_paths;
17727   for (i = 0; i < count; i++)
17728     {
17729       vl_api_fib_path_print (vam, fp);
17730       fp++;
17731     }
17732 }
17733
17734 static void vl_api_mpls_route_details_t_handler_json
17735   (vl_api_mpls_route_details_t * mp)
17736 {
17737   vat_main_t *vam = &vat_main;
17738   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17739   vat_json_node_t *node = NULL;
17740   vl_api_fib_path_t *fp;
17741   int i;
17742
17743   if (VAT_JSON_ARRAY != vam->json_tree.type)
17744     {
17745       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17746       vat_json_init_array (&vam->json_tree);
17747     }
17748   node = vat_json_array_add (&vam->json_tree);
17749
17750   vat_json_init_object (node);
17751   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17752   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17753   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17754   vat_json_object_add_uint (node, "path_count", count);
17755   fp = mp->mr_route.mr_paths;
17756   for (i = 0; i < count; i++)
17757     {
17758       vl_api_mpls_fib_path_json_print (node, fp);
17759       fp++;
17760     }
17761 }
17762
17763 static int
17764 api_mpls_route_dump (vat_main_t * vam)
17765 {
17766   unformat_input_t *input = vam->input;
17767   vl_api_mpls_route_dump_t *mp;
17768   vl_api_control_ping_t *mp_ping;
17769   u32 table_id;
17770   int ret;
17771
17772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17773     {
17774       if (unformat (input, "table_id %d", &table_id))
17775         ;
17776       else
17777         break;
17778     }
17779   if (table_id == ~0)
17780     {
17781       errmsg ("missing table id");
17782       return -99;
17783     }
17784
17785   M (MPLS_ROUTE_DUMP, mp);
17786
17787   mp->table.mt_table_id = ntohl (table_id);
17788   S (mp);
17789
17790   /* Use a control ping for synchronization */
17791   MPING (CONTROL_PING, mp_ping);
17792   S (mp_ping);
17793
17794   W (ret);
17795   return ret;
17796 }
17797
17798 #define vl_api_ip_table_details_t_endian vl_noop_handler
17799 #define vl_api_ip_table_details_t_print vl_noop_handler
17800
17801 static void
17802 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17803 {
17804   vat_main_t *vam = &vat_main;
17805
17806   print (vam->ofp,
17807          "%s; table-id %d, prefix %U/%d",
17808          mp->table.name, ntohl (mp->table.table_id));
17809 }
17810
17811
17812 static void vl_api_ip_table_details_t_handler_json
17813   (vl_api_ip_table_details_t * mp)
17814 {
17815   vat_main_t *vam = &vat_main;
17816   vat_json_node_t *node = NULL;
17817
17818   if (VAT_JSON_ARRAY != vam->json_tree.type)
17819     {
17820       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17821       vat_json_init_array (&vam->json_tree);
17822     }
17823   node = vat_json_array_add (&vam->json_tree);
17824
17825   vat_json_init_object (node);
17826   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17827 }
17828
17829 static int
17830 api_ip_table_dump (vat_main_t * vam)
17831 {
17832   vl_api_ip_table_dump_t *mp;
17833   vl_api_control_ping_t *mp_ping;
17834   int ret;
17835
17836   M (IP_TABLE_DUMP, mp);
17837   S (mp);
17838
17839   /* Use a control ping for synchronization */
17840   MPING (CONTROL_PING, mp_ping);
17841   S (mp_ping);
17842
17843   W (ret);
17844   return ret;
17845 }
17846
17847 static int
17848 api_ip_mtable_dump (vat_main_t * vam)
17849 {
17850   vl_api_ip_mtable_dump_t *mp;
17851   vl_api_control_ping_t *mp_ping;
17852   int ret;
17853
17854   M (IP_MTABLE_DUMP, mp);
17855   S (mp);
17856
17857   /* Use a control ping for synchronization */
17858   MPING (CONTROL_PING, mp_ping);
17859   S (mp_ping);
17860
17861   W (ret);
17862   return ret;
17863 }
17864
17865 static int
17866 api_ip_mroute_dump (vat_main_t * vam)
17867 {
17868   unformat_input_t *input = vam->input;
17869   vl_api_control_ping_t *mp_ping;
17870   vl_api_ip_mroute_dump_t *mp;
17871   int ret, is_ip6;
17872   u32 table_id;
17873
17874   is_ip6 = 0;
17875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17876     {
17877       if (unformat (input, "table_id %d", &table_id))
17878         ;
17879       else if (unformat (input, "ip6"))
17880         is_ip6 = 1;
17881       else if (unformat (input, "ip4"))
17882         is_ip6 = 0;
17883       else
17884         break;
17885     }
17886   if (table_id == ~0)
17887     {
17888       errmsg ("missing table id");
17889       return -99;
17890     }
17891
17892   M (IP_MROUTE_DUMP, mp);
17893   mp->table.table_id = table_id;
17894   mp->table.is_ip6 = is_ip6;
17895   S (mp);
17896
17897   /* Use a control ping for synchronization */
17898   MPING (CONTROL_PING, mp_ping);
17899   S (mp_ping);
17900
17901   W (ret);
17902   return ret;
17903 }
17904
17905 #define vl_api_ip_route_details_t_endian vl_noop_handler
17906 #define vl_api_ip_route_details_t_print vl_noop_handler
17907
17908 static void
17909 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17910 {
17911   vat_main_t *vam = &vat_main;
17912   u8 count = mp->route.n_paths;
17913   vl_api_fib_path_t *fp;
17914   int i;
17915
17916   print (vam->ofp,
17917          "table-id %d, prefix %U/%d",
17918          ntohl (mp->route.table_id),
17919          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17920   for (i = 0; i < count; i++)
17921     {
17922       fp = &mp->route.paths[i];
17923
17924       vl_api_fib_path_print (vam, fp);
17925       fp++;
17926     }
17927 }
17928
17929 static void vl_api_ip_route_details_t_handler_json
17930   (vl_api_ip_route_details_t * mp)
17931 {
17932   vat_main_t *vam = &vat_main;
17933   u8 count = mp->route.n_paths;
17934   vat_json_node_t *node = NULL;
17935   struct in_addr ip4;
17936   struct in6_addr ip6;
17937   vl_api_fib_path_t *fp;
17938   int i;
17939
17940   if (VAT_JSON_ARRAY != vam->json_tree.type)
17941     {
17942       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17943       vat_json_init_array (&vam->json_tree);
17944     }
17945   node = vat_json_array_add (&vam->json_tree);
17946
17947   vat_json_init_object (node);
17948   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17949   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17950     {
17951       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17952       vat_json_object_add_ip6 (node, "prefix", ip6);
17953     }
17954   else
17955     {
17956       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17957       vat_json_object_add_ip4 (node, "prefix", ip4);
17958     }
17959   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17960   vat_json_object_add_uint (node, "path_count", count);
17961   for (i = 0; i < count; i++)
17962     {
17963       fp = &mp->route.paths[i];
17964       vl_api_mpls_fib_path_json_print (node, fp);
17965     }
17966 }
17967
17968 static int
17969 api_ip_route_dump (vat_main_t * vam)
17970 {
17971   unformat_input_t *input = vam->input;
17972   vl_api_ip_route_dump_t *mp;
17973   vl_api_control_ping_t *mp_ping;
17974   u32 table_id;
17975   u8 is_ip6;
17976   int ret;
17977
17978   is_ip6 = 0;
17979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17980     {
17981       if (unformat (input, "table_id %d", &table_id))
17982         ;
17983       else if (unformat (input, "ip6"))
17984         is_ip6 = 1;
17985       else if (unformat (input, "ip4"))
17986         is_ip6 = 0;
17987       else
17988         break;
17989     }
17990   if (table_id == ~0)
17991     {
17992       errmsg ("missing table id");
17993       return -99;
17994     }
17995
17996   M (IP_ROUTE_DUMP, mp);
17997
17998   mp->table.table_id = table_id;
17999   mp->table.is_ip6 = is_ip6;
18000
18001   S (mp);
18002
18003   /* Use a control ping for synchronization */
18004   MPING (CONTROL_PING, mp_ping);
18005   S (mp_ping);
18006
18007   W (ret);
18008   return ret;
18009 }
18010
18011 int
18012 api_classify_table_ids (vat_main_t * vam)
18013 {
18014   vl_api_classify_table_ids_t *mp;
18015   int ret;
18016
18017   /* Construct the API message */
18018   M (CLASSIFY_TABLE_IDS, mp);
18019   mp->context = 0;
18020
18021   S (mp);
18022   W (ret);
18023   return ret;
18024 }
18025
18026 int
18027 api_classify_table_by_interface (vat_main_t * vam)
18028 {
18029   unformat_input_t *input = vam->input;
18030   vl_api_classify_table_by_interface_t *mp;
18031
18032   u32 sw_if_index = ~0;
18033   int ret;
18034   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18035     {
18036       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18037         ;
18038       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18039         ;
18040       else
18041         break;
18042     }
18043   if (sw_if_index == ~0)
18044     {
18045       errmsg ("missing interface name or sw_if_index");
18046       return -99;
18047     }
18048
18049   /* Construct the API message */
18050   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18051   mp->context = 0;
18052   mp->sw_if_index = ntohl (sw_if_index);
18053
18054   S (mp);
18055   W (ret);
18056   return ret;
18057 }
18058
18059 int
18060 api_classify_table_info (vat_main_t * vam)
18061 {
18062   unformat_input_t *input = vam->input;
18063   vl_api_classify_table_info_t *mp;
18064
18065   u32 table_id = ~0;
18066   int ret;
18067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18068     {
18069       if (unformat (input, "table_id %d", &table_id))
18070         ;
18071       else
18072         break;
18073     }
18074   if (table_id == ~0)
18075     {
18076       errmsg ("missing table id");
18077       return -99;
18078     }
18079
18080   /* Construct the API message */
18081   M (CLASSIFY_TABLE_INFO, mp);
18082   mp->context = 0;
18083   mp->table_id = ntohl (table_id);
18084
18085   S (mp);
18086   W (ret);
18087   return ret;
18088 }
18089
18090 int
18091 api_classify_session_dump (vat_main_t * vam)
18092 {
18093   unformat_input_t *input = vam->input;
18094   vl_api_classify_session_dump_t *mp;
18095   vl_api_control_ping_t *mp_ping;
18096
18097   u32 table_id = ~0;
18098   int ret;
18099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18100     {
18101       if (unformat (input, "table_id %d", &table_id))
18102         ;
18103       else
18104         break;
18105     }
18106   if (table_id == ~0)
18107     {
18108       errmsg ("missing table id");
18109       return -99;
18110     }
18111
18112   /* Construct the API message */
18113   M (CLASSIFY_SESSION_DUMP, mp);
18114   mp->context = 0;
18115   mp->table_id = ntohl (table_id);
18116   S (mp);
18117
18118   /* Use a control ping for synchronization */
18119   MPING (CONTROL_PING, mp_ping);
18120   S (mp_ping);
18121
18122   W (ret);
18123   return ret;
18124 }
18125
18126 static void
18127 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18128 {
18129   vat_main_t *vam = &vat_main;
18130
18131   print (vam->ofp, "collector_address %U, collector_port %d, "
18132          "src_address %U, vrf_id %d, path_mtu %u, "
18133          "template_interval %u, udp_checksum %d",
18134          format_ip4_address, mp->collector_address,
18135          ntohs (mp->collector_port),
18136          format_ip4_address, mp->src_address,
18137          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18138          ntohl (mp->template_interval), mp->udp_checksum);
18139
18140   vam->retval = 0;
18141   vam->result_ready = 1;
18142 }
18143
18144 static void
18145   vl_api_ipfix_exporter_details_t_handler_json
18146   (vl_api_ipfix_exporter_details_t * mp)
18147 {
18148   vat_main_t *vam = &vat_main;
18149   vat_json_node_t node;
18150   struct in_addr collector_address;
18151   struct in_addr src_address;
18152
18153   vat_json_init_object (&node);
18154   clib_memcpy (&collector_address, &mp->collector_address,
18155                sizeof (collector_address));
18156   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18157   vat_json_object_add_uint (&node, "collector_port",
18158                             ntohs (mp->collector_port));
18159   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18160   vat_json_object_add_ip4 (&node, "src_address", src_address);
18161   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18162   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18163   vat_json_object_add_uint (&node, "template_interval",
18164                             ntohl (mp->template_interval));
18165   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18166
18167   vat_json_print (vam->ofp, &node);
18168   vat_json_free (&node);
18169   vam->retval = 0;
18170   vam->result_ready = 1;
18171 }
18172
18173 int
18174 api_ipfix_exporter_dump (vat_main_t * vam)
18175 {
18176   vl_api_ipfix_exporter_dump_t *mp;
18177   int ret;
18178
18179   /* Construct the API message */
18180   M (IPFIX_EXPORTER_DUMP, mp);
18181   mp->context = 0;
18182
18183   S (mp);
18184   W (ret);
18185   return ret;
18186 }
18187
18188 static int
18189 api_ipfix_classify_stream_dump (vat_main_t * vam)
18190 {
18191   vl_api_ipfix_classify_stream_dump_t *mp;
18192   int ret;
18193
18194   /* Construct the API message */
18195   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18196   mp->context = 0;
18197
18198   S (mp);
18199   W (ret);
18200   return ret;
18201   /* NOTREACHED */
18202   return 0;
18203 }
18204
18205 static void
18206   vl_api_ipfix_classify_stream_details_t_handler
18207   (vl_api_ipfix_classify_stream_details_t * mp)
18208 {
18209   vat_main_t *vam = &vat_main;
18210   print (vam->ofp, "domain_id %d, src_port %d",
18211          ntohl (mp->domain_id), ntohs (mp->src_port));
18212   vam->retval = 0;
18213   vam->result_ready = 1;
18214 }
18215
18216 static void
18217   vl_api_ipfix_classify_stream_details_t_handler_json
18218   (vl_api_ipfix_classify_stream_details_t * mp)
18219 {
18220   vat_main_t *vam = &vat_main;
18221   vat_json_node_t node;
18222
18223   vat_json_init_object (&node);
18224   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18225   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18226
18227   vat_json_print (vam->ofp, &node);
18228   vat_json_free (&node);
18229   vam->retval = 0;
18230   vam->result_ready = 1;
18231 }
18232
18233 static int
18234 api_ipfix_classify_table_dump (vat_main_t * vam)
18235 {
18236   vl_api_ipfix_classify_table_dump_t *mp;
18237   vl_api_control_ping_t *mp_ping;
18238   int ret;
18239
18240   if (!vam->json_output)
18241     {
18242       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18243              "transport_protocol");
18244     }
18245
18246   /* Construct the API message */
18247   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18248
18249   /* send it... */
18250   S (mp);
18251
18252   /* Use a control ping for synchronization */
18253   MPING (CONTROL_PING, mp_ping);
18254   S (mp_ping);
18255
18256   W (ret);
18257   return ret;
18258 }
18259
18260 static void
18261   vl_api_ipfix_classify_table_details_t_handler
18262   (vl_api_ipfix_classify_table_details_t * mp)
18263 {
18264   vat_main_t *vam = &vat_main;
18265   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18266          mp->transport_protocol);
18267 }
18268
18269 static void
18270   vl_api_ipfix_classify_table_details_t_handler_json
18271   (vl_api_ipfix_classify_table_details_t * mp)
18272 {
18273   vat_json_node_t *node = NULL;
18274   vat_main_t *vam = &vat_main;
18275
18276   if (VAT_JSON_ARRAY != vam->json_tree.type)
18277     {
18278       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18279       vat_json_init_array (&vam->json_tree);
18280     }
18281
18282   node = vat_json_array_add (&vam->json_tree);
18283   vat_json_init_object (node);
18284
18285   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18286   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18287   vat_json_object_add_uint (node, "transport_protocol",
18288                             mp->transport_protocol);
18289 }
18290
18291 static int
18292 api_sw_interface_span_enable_disable (vat_main_t * vam)
18293 {
18294   unformat_input_t *i = vam->input;
18295   vl_api_sw_interface_span_enable_disable_t *mp;
18296   u32 src_sw_if_index = ~0;
18297   u32 dst_sw_if_index = ~0;
18298   u8 state = 3;
18299   int ret;
18300   u8 is_l2 = 0;
18301
18302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18303     {
18304       if (unformat
18305           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18306         ;
18307       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18308         ;
18309       else
18310         if (unformat
18311             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18312         ;
18313       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18314         ;
18315       else if (unformat (i, "disable"))
18316         state = 0;
18317       else if (unformat (i, "rx"))
18318         state = 1;
18319       else if (unformat (i, "tx"))
18320         state = 2;
18321       else if (unformat (i, "both"))
18322         state = 3;
18323       else if (unformat (i, "l2"))
18324         is_l2 = 1;
18325       else
18326         break;
18327     }
18328
18329   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18330
18331   mp->sw_if_index_from = htonl (src_sw_if_index);
18332   mp->sw_if_index_to = htonl (dst_sw_if_index);
18333   mp->state = state;
18334   mp->is_l2 = is_l2;
18335
18336   S (mp);
18337   W (ret);
18338   return ret;
18339 }
18340
18341 static void
18342 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18343                                             * mp)
18344 {
18345   vat_main_t *vam = &vat_main;
18346   u8 *sw_if_from_name = 0;
18347   u8 *sw_if_to_name = 0;
18348   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18349   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18350   char *states[] = { "none", "rx", "tx", "both" };
18351   hash_pair_t *p;
18352
18353   /* *INDENT-OFF* */
18354   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18355   ({
18356     if ((u32) p->value[0] == sw_if_index_from)
18357       {
18358         sw_if_from_name = (u8 *)(p->key);
18359         if (sw_if_to_name)
18360           break;
18361       }
18362     if ((u32) p->value[0] == sw_if_index_to)
18363       {
18364         sw_if_to_name = (u8 *)(p->key);
18365         if (sw_if_from_name)
18366           break;
18367       }
18368   }));
18369   /* *INDENT-ON* */
18370   print (vam->ofp, "%20s => %20s (%s) %s",
18371          sw_if_from_name, sw_if_to_name, states[mp->state],
18372          mp->is_l2 ? "l2" : "device");
18373 }
18374
18375 static void
18376   vl_api_sw_interface_span_details_t_handler_json
18377   (vl_api_sw_interface_span_details_t * mp)
18378 {
18379   vat_main_t *vam = &vat_main;
18380   vat_json_node_t *node = NULL;
18381   u8 *sw_if_from_name = 0;
18382   u8 *sw_if_to_name = 0;
18383   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18384   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18385   hash_pair_t *p;
18386
18387   /* *INDENT-OFF* */
18388   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18389   ({
18390     if ((u32) p->value[0] == sw_if_index_from)
18391       {
18392         sw_if_from_name = (u8 *)(p->key);
18393         if (sw_if_to_name)
18394           break;
18395       }
18396     if ((u32) p->value[0] == sw_if_index_to)
18397       {
18398         sw_if_to_name = (u8 *)(p->key);
18399         if (sw_if_from_name)
18400           break;
18401       }
18402   }));
18403   /* *INDENT-ON* */
18404
18405   if (VAT_JSON_ARRAY != vam->json_tree.type)
18406     {
18407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18408       vat_json_init_array (&vam->json_tree);
18409     }
18410   node = vat_json_array_add (&vam->json_tree);
18411
18412   vat_json_init_object (node);
18413   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18414   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18415   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18416   if (0 != sw_if_to_name)
18417     {
18418       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18419     }
18420   vat_json_object_add_uint (node, "state", mp->state);
18421   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18422 }
18423
18424 static int
18425 api_sw_interface_span_dump (vat_main_t * vam)
18426 {
18427   unformat_input_t *input = vam->input;
18428   vl_api_sw_interface_span_dump_t *mp;
18429   vl_api_control_ping_t *mp_ping;
18430   u8 is_l2 = 0;
18431   int ret;
18432
18433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18434     {
18435       if (unformat (input, "l2"))
18436         is_l2 = 1;
18437       else
18438         break;
18439     }
18440
18441   M (SW_INTERFACE_SPAN_DUMP, mp);
18442   mp->is_l2 = is_l2;
18443   S (mp);
18444
18445   /* Use a control ping for synchronization */
18446   MPING (CONTROL_PING, mp_ping);
18447   S (mp_ping);
18448
18449   W (ret);
18450   return ret;
18451 }
18452
18453 int
18454 api_pg_create_interface (vat_main_t * vam)
18455 {
18456   unformat_input_t *input = vam->input;
18457   vl_api_pg_create_interface_t *mp;
18458
18459   u32 if_id = ~0, gso_size = 0;
18460   u8 gso_enabled = 0;
18461   int ret;
18462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18463     {
18464       if (unformat (input, "if_id %d", &if_id))
18465         ;
18466       else if (unformat (input, "gso-enabled"))
18467         {
18468           gso_enabled = 1;
18469           if (unformat (input, "gso-size %u", &gso_size))
18470             ;
18471           else
18472             {
18473               errmsg ("missing gso-size");
18474               return -99;
18475             }
18476         }
18477       else
18478         break;
18479     }
18480   if (if_id == ~0)
18481     {
18482       errmsg ("missing pg interface index");
18483       return -99;
18484     }
18485
18486   /* Construct the API message */
18487   M (PG_CREATE_INTERFACE, mp);
18488   mp->context = 0;
18489   mp->interface_id = ntohl (if_id);
18490   mp->gso_enabled = gso_enabled;
18491
18492   S (mp);
18493   W (ret);
18494   return ret;
18495 }
18496
18497 int
18498 api_pg_capture (vat_main_t * vam)
18499 {
18500   unformat_input_t *input = vam->input;
18501   vl_api_pg_capture_t *mp;
18502
18503   u32 if_id = ~0;
18504   u8 enable = 1;
18505   u32 count = 1;
18506   u8 pcap_file_set = 0;
18507   u8 *pcap_file = 0;
18508   int ret;
18509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18510     {
18511       if (unformat (input, "if_id %d", &if_id))
18512         ;
18513       else if (unformat (input, "pcap %s", &pcap_file))
18514         pcap_file_set = 1;
18515       else if (unformat (input, "count %d", &count))
18516         ;
18517       else if (unformat (input, "disable"))
18518         enable = 0;
18519       else
18520         break;
18521     }
18522   if (if_id == ~0)
18523     {
18524       errmsg ("missing pg interface index");
18525       return -99;
18526     }
18527   if (pcap_file_set > 0)
18528     {
18529       if (vec_len (pcap_file) > 255)
18530         {
18531           errmsg ("pcap file name is too long");
18532           return -99;
18533         }
18534     }
18535
18536   /* Construct the API message */
18537   M (PG_CAPTURE, mp);
18538   mp->context = 0;
18539   mp->interface_id = ntohl (if_id);
18540   mp->is_enabled = enable;
18541   mp->count = ntohl (count);
18542   if (pcap_file_set != 0)
18543     {
18544       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18545     }
18546   vec_free (pcap_file);
18547
18548   S (mp);
18549   W (ret);
18550   return ret;
18551 }
18552
18553 int
18554 api_pg_enable_disable (vat_main_t * vam)
18555 {
18556   unformat_input_t *input = vam->input;
18557   vl_api_pg_enable_disable_t *mp;
18558
18559   u8 enable = 1;
18560   u8 stream_name_set = 0;
18561   u8 *stream_name = 0;
18562   int ret;
18563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18564     {
18565       if (unformat (input, "stream %s", &stream_name))
18566         stream_name_set = 1;
18567       else if (unformat (input, "disable"))
18568         enable = 0;
18569       else
18570         break;
18571     }
18572
18573   if (stream_name_set > 0)
18574     {
18575       if (vec_len (stream_name) > 255)
18576         {
18577           errmsg ("stream name too long");
18578           return -99;
18579         }
18580     }
18581
18582   /* Construct the API message */
18583   M (PG_ENABLE_DISABLE, mp);
18584   mp->context = 0;
18585   mp->is_enabled = enable;
18586   if (stream_name_set != 0)
18587     {
18588       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18589     }
18590   vec_free (stream_name);
18591
18592   S (mp);
18593   W (ret);
18594   return ret;
18595 }
18596
18597 int
18598 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18599 {
18600   unformat_input_t *input = vam->input;
18601   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18602
18603   u16 *low_ports = 0;
18604   u16 *high_ports = 0;
18605   u16 this_low;
18606   u16 this_hi;
18607   vl_api_prefix_t prefix;
18608   u32 tmp, tmp2;
18609   u8 prefix_set = 0;
18610   u32 vrf_id = ~0;
18611   u8 is_add = 1;
18612   int ret;
18613
18614   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18615     {
18616       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18617         prefix_set = 1;
18618       else if (unformat (input, "vrf %d", &vrf_id))
18619         ;
18620       else if (unformat (input, "del"))
18621         is_add = 0;
18622       else if (unformat (input, "port %d", &tmp))
18623         {
18624           if (tmp == 0 || tmp > 65535)
18625             {
18626               errmsg ("port %d out of range", tmp);
18627               return -99;
18628             }
18629           this_low = tmp;
18630           this_hi = this_low + 1;
18631           vec_add1 (low_ports, this_low);
18632           vec_add1 (high_ports, this_hi);
18633         }
18634       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18635         {
18636           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18637             {
18638               errmsg ("incorrect range parameters");
18639               return -99;
18640             }
18641           this_low = tmp;
18642           /* Note: in debug CLI +1 is added to high before
18643              passing to real fn that does "the work"
18644              (ip_source_and_port_range_check_add_del).
18645              This fn is a wrapper around the binary API fn a
18646              control plane will call, which expects this increment
18647              to have occurred. Hence letting the binary API control
18648              plane fn do the increment for consistency between VAT
18649              and other control planes.
18650            */
18651           this_hi = tmp2;
18652           vec_add1 (low_ports, this_low);
18653           vec_add1 (high_ports, this_hi);
18654         }
18655       else
18656         break;
18657     }
18658
18659   if (prefix_set == 0)
18660     {
18661       errmsg ("<address>/<mask> not specified");
18662       return -99;
18663     }
18664
18665   if (vrf_id == ~0)
18666     {
18667       errmsg ("VRF ID required, not specified");
18668       return -99;
18669     }
18670
18671   if (vrf_id == 0)
18672     {
18673       errmsg
18674         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18675       return -99;
18676     }
18677
18678   if (vec_len (low_ports) == 0)
18679     {
18680       errmsg ("At least one port or port range required");
18681       return -99;
18682     }
18683
18684   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18685
18686   mp->is_add = is_add;
18687
18688   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18689
18690   mp->number_of_ranges = vec_len (low_ports);
18691
18692   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18693   vec_free (low_ports);
18694
18695   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18696   vec_free (high_ports);
18697
18698   mp->vrf_id = ntohl (vrf_id);
18699
18700   S (mp);
18701   W (ret);
18702   return ret;
18703 }
18704
18705 int
18706 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18707 {
18708   unformat_input_t *input = vam->input;
18709   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18710   u32 sw_if_index = ~0;
18711   int vrf_set = 0;
18712   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18713   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18714   u8 is_add = 1;
18715   int ret;
18716
18717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18718     {
18719       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18720         ;
18721       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18722         ;
18723       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18724         vrf_set = 1;
18725       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18726         vrf_set = 1;
18727       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18728         vrf_set = 1;
18729       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18730         vrf_set = 1;
18731       else if (unformat (input, "del"))
18732         is_add = 0;
18733       else
18734         break;
18735     }
18736
18737   if (sw_if_index == ~0)
18738     {
18739       errmsg ("Interface required but not specified");
18740       return -99;
18741     }
18742
18743   if (vrf_set == 0)
18744     {
18745       errmsg ("VRF ID required but not specified");
18746       return -99;
18747     }
18748
18749   if (tcp_out_vrf_id == 0
18750       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18751     {
18752       errmsg
18753         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18754       return -99;
18755     }
18756
18757   /* Construct the API message */
18758   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18759
18760   mp->sw_if_index = ntohl (sw_if_index);
18761   mp->is_add = is_add;
18762   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18763   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18764   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18765   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18766
18767   /* send it... */
18768   S (mp);
18769
18770   /* Wait for a reply... */
18771   W (ret);
18772   return ret;
18773 }
18774
18775 static int
18776 api_set_punt (vat_main_t * vam)
18777 {
18778   unformat_input_t *i = vam->input;
18779   vl_api_address_family_t af;
18780   vl_api_set_punt_t *mp;
18781   u32 protocol = ~0;
18782   u32 port = ~0;
18783   int is_add = 1;
18784   int ret;
18785
18786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18787     {
18788       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18789         ;
18790       else if (unformat (i, "protocol %d", &protocol))
18791         ;
18792       else if (unformat (i, "port %d", &port))
18793         ;
18794       else if (unformat (i, "del"))
18795         is_add = 0;
18796       else
18797         {
18798           clib_warning ("parse error '%U'", format_unformat_error, i);
18799           return -99;
18800         }
18801     }
18802
18803   M (SET_PUNT, mp);
18804
18805   mp->is_add = (u8) is_add;
18806   mp->punt.type = PUNT_API_TYPE_L4;
18807   mp->punt.punt.l4.af = af;
18808   mp->punt.punt.l4.protocol = (u8) protocol;
18809   mp->punt.punt.l4.port = htons ((u16) port);
18810
18811   S (mp);
18812   W (ret);
18813   return ret;
18814 }
18815
18816 static int
18817 api_delete_subif (vat_main_t * vam)
18818 {
18819   unformat_input_t *i = vam->input;
18820   vl_api_delete_subif_t *mp;
18821   u32 sw_if_index = ~0;
18822   int ret;
18823
18824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18825     {
18826       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18827         ;
18828       if (unformat (i, "sw_if_index %d", &sw_if_index))
18829         ;
18830       else
18831         break;
18832     }
18833
18834   if (sw_if_index == ~0)
18835     {
18836       errmsg ("missing sw_if_index");
18837       return -99;
18838     }
18839
18840   /* Construct the API message */
18841   M (DELETE_SUBIF, mp);
18842   mp->sw_if_index = ntohl (sw_if_index);
18843
18844   S (mp);
18845   W (ret);
18846   return ret;
18847 }
18848
18849 #define foreach_pbb_vtr_op      \
18850 _("disable",  L2_VTR_DISABLED)  \
18851 _("pop",  L2_VTR_POP_2)         \
18852 _("push",  L2_VTR_PUSH_2)
18853
18854 static int
18855 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18856 {
18857   unformat_input_t *i = vam->input;
18858   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18859   u32 sw_if_index = ~0, vtr_op = ~0;
18860   u16 outer_tag = ~0;
18861   u8 dmac[6], smac[6];
18862   u8 dmac_set = 0, smac_set = 0;
18863   u16 vlanid = 0;
18864   u32 sid = ~0;
18865   u32 tmp;
18866   int ret;
18867
18868   /* Shut up coverity */
18869   clib_memset (dmac, 0, sizeof (dmac));
18870   clib_memset (smac, 0, sizeof (smac));
18871
18872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18873     {
18874       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18875         ;
18876       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18877         ;
18878       else if (unformat (i, "vtr_op %d", &vtr_op))
18879         ;
18880 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18881       foreach_pbb_vtr_op
18882 #undef _
18883         else if (unformat (i, "translate_pbb_stag"))
18884         {
18885           if (unformat (i, "%d", &tmp))
18886             {
18887               vtr_op = L2_VTR_TRANSLATE_2_1;
18888               outer_tag = tmp;
18889             }
18890           else
18891             {
18892               errmsg
18893                 ("translate_pbb_stag operation requires outer tag definition");
18894               return -99;
18895             }
18896         }
18897       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18898         dmac_set++;
18899       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18900         smac_set++;
18901       else if (unformat (i, "sid %d", &sid))
18902         ;
18903       else if (unformat (i, "vlanid %d", &tmp))
18904         vlanid = tmp;
18905       else
18906         {
18907           clib_warning ("parse error '%U'", format_unformat_error, i);
18908           return -99;
18909         }
18910     }
18911
18912   if ((sw_if_index == ~0) || (vtr_op == ~0))
18913     {
18914       errmsg ("missing sw_if_index or vtr operation");
18915       return -99;
18916     }
18917   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18918       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18919     {
18920       errmsg
18921         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18922       return -99;
18923     }
18924
18925   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18926   mp->sw_if_index = ntohl (sw_if_index);
18927   mp->vtr_op = ntohl (vtr_op);
18928   mp->outer_tag = ntohs (outer_tag);
18929   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18930   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18931   mp->b_vlanid = ntohs (vlanid);
18932   mp->i_sid = ntohl (sid);
18933
18934   S (mp);
18935   W (ret);
18936   return ret;
18937 }
18938
18939 static int
18940 api_flow_classify_set_interface (vat_main_t * vam)
18941 {
18942   unformat_input_t *i = vam->input;
18943   vl_api_flow_classify_set_interface_t *mp;
18944   u32 sw_if_index;
18945   int sw_if_index_set;
18946   u32 ip4_table_index = ~0;
18947   u32 ip6_table_index = ~0;
18948   u8 is_add = 1;
18949   int ret;
18950
18951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18952     {
18953       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18954         sw_if_index_set = 1;
18955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18956         sw_if_index_set = 1;
18957       else if (unformat (i, "del"))
18958         is_add = 0;
18959       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18960         ;
18961       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18962         ;
18963       else
18964         {
18965           clib_warning ("parse error '%U'", format_unformat_error, i);
18966           return -99;
18967         }
18968     }
18969
18970   if (sw_if_index_set == 0)
18971     {
18972       errmsg ("missing interface name or sw_if_index");
18973       return -99;
18974     }
18975
18976   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18977
18978   mp->sw_if_index = ntohl (sw_if_index);
18979   mp->ip4_table_index = ntohl (ip4_table_index);
18980   mp->ip6_table_index = ntohl (ip6_table_index);
18981   mp->is_add = is_add;
18982
18983   S (mp);
18984   W (ret);
18985   return ret;
18986 }
18987
18988 static int
18989 api_flow_classify_dump (vat_main_t * vam)
18990 {
18991   unformat_input_t *i = vam->input;
18992   vl_api_flow_classify_dump_t *mp;
18993   vl_api_control_ping_t *mp_ping;
18994   u8 type = FLOW_CLASSIFY_N_TABLES;
18995   int ret;
18996
18997   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18998     ;
18999   else
19000     {
19001       errmsg ("classify table type must be specified");
19002       return -99;
19003     }
19004
19005   if (!vam->json_output)
19006     {
19007       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19008     }
19009
19010   M (FLOW_CLASSIFY_DUMP, mp);
19011   mp->type = type;
19012   /* send it... */
19013   S (mp);
19014
19015   /* Use a control ping for synchronization */
19016   MPING (CONTROL_PING, mp_ping);
19017   S (mp_ping);
19018
19019   /* Wait for a reply... */
19020   W (ret);
19021   return ret;
19022 }
19023
19024 static int
19025 api_feature_enable_disable (vat_main_t * vam)
19026 {
19027   unformat_input_t *i = vam->input;
19028   vl_api_feature_enable_disable_t *mp;
19029   u8 *arc_name = 0;
19030   u8 *feature_name = 0;
19031   u32 sw_if_index = ~0;
19032   u8 enable = 1;
19033   int ret;
19034
19035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19036     {
19037       if (unformat (i, "arc_name %s", &arc_name))
19038         ;
19039       else if (unformat (i, "feature_name %s", &feature_name))
19040         ;
19041       else
19042         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19043         ;
19044       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19045         ;
19046       else if (unformat (i, "disable"))
19047         enable = 0;
19048       else
19049         break;
19050     }
19051
19052   if (arc_name == 0)
19053     {
19054       errmsg ("missing arc name");
19055       return -99;
19056     }
19057   if (vec_len (arc_name) > 63)
19058     {
19059       errmsg ("arc name too long");
19060     }
19061
19062   if (feature_name == 0)
19063     {
19064       errmsg ("missing feature name");
19065       return -99;
19066     }
19067   if (vec_len (feature_name) > 63)
19068     {
19069       errmsg ("feature name too long");
19070     }
19071
19072   if (sw_if_index == ~0)
19073     {
19074       errmsg ("missing interface name or sw_if_index");
19075       return -99;
19076     }
19077
19078   /* Construct the API message */
19079   M (FEATURE_ENABLE_DISABLE, mp);
19080   mp->sw_if_index = ntohl (sw_if_index);
19081   mp->enable = enable;
19082   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19083   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19084   vec_free (arc_name);
19085   vec_free (feature_name);
19086
19087   S (mp);
19088   W (ret);
19089   return ret;
19090 }
19091
19092 static int
19093 api_feature_gso_enable_disable (vat_main_t * vam)
19094 {
19095   unformat_input_t *i = vam->input;
19096   vl_api_feature_gso_enable_disable_t *mp;
19097   u32 sw_if_index = ~0;
19098   u8 enable = 1;
19099   int ret;
19100
19101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19102     {
19103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19104         ;
19105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19106         ;
19107       else if (unformat (i, "enable"))
19108         enable = 1;
19109       else if (unformat (i, "disable"))
19110         enable = 0;
19111       else
19112         break;
19113     }
19114
19115   if (sw_if_index == ~0)
19116     {
19117       errmsg ("missing interface name or sw_if_index");
19118       return -99;
19119     }
19120
19121   /* Construct the API message */
19122   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19123   mp->sw_if_index = ntohl (sw_if_index);
19124   mp->enable_disable = enable;
19125
19126   S (mp);
19127   W (ret);
19128   return ret;
19129 }
19130
19131 static int
19132 api_sw_interface_tag_add_del (vat_main_t * vam)
19133 {
19134   unformat_input_t *i = vam->input;
19135   vl_api_sw_interface_tag_add_del_t *mp;
19136   u32 sw_if_index = ~0;
19137   u8 *tag = 0;
19138   u8 enable = 1;
19139   int ret;
19140
19141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19142     {
19143       if (unformat (i, "tag %s", &tag))
19144         ;
19145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19146         ;
19147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19148         ;
19149       else if (unformat (i, "del"))
19150         enable = 0;
19151       else
19152         break;
19153     }
19154
19155   if (sw_if_index == ~0)
19156     {
19157       errmsg ("missing interface name or sw_if_index");
19158       return -99;
19159     }
19160
19161   if (enable && (tag == 0))
19162     {
19163       errmsg ("no tag specified");
19164       return -99;
19165     }
19166
19167   /* Construct the API message */
19168   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19169   mp->sw_if_index = ntohl (sw_if_index);
19170   mp->is_add = enable;
19171   if (enable)
19172     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19173   vec_free (tag);
19174
19175   S (mp);
19176   W (ret);
19177   return ret;
19178 }
19179
19180 static int
19181 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19182 {
19183   unformat_input_t *i = vam->input;
19184   vl_api_mac_address_t mac = { 0 };
19185   vl_api_sw_interface_add_del_mac_address_t *mp;
19186   u32 sw_if_index = ~0;
19187   u8 is_add = 1;
19188   u8 mac_set = 0;
19189   int ret;
19190
19191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19192     {
19193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19194         ;
19195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19196         ;
19197       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19198         mac_set++;
19199       else if (unformat (i, "del"))
19200         is_add = 0;
19201       else
19202         break;
19203     }
19204
19205   if (sw_if_index == ~0)
19206     {
19207       errmsg ("missing interface name or sw_if_index");
19208       return -99;
19209     }
19210
19211   if (!mac_set)
19212     {
19213       errmsg ("missing MAC address");
19214       return -99;
19215     }
19216
19217   /* Construct the API message */
19218   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19219   mp->sw_if_index = ntohl (sw_if_index);
19220   mp->is_add = is_add;
19221   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19222
19223   S (mp);
19224   W (ret);
19225   return ret;
19226 }
19227
19228 static void vl_api_l2_xconnect_details_t_handler
19229   (vl_api_l2_xconnect_details_t * mp)
19230 {
19231   vat_main_t *vam = &vat_main;
19232
19233   print (vam->ofp, "%15d%15d",
19234          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19235 }
19236
19237 static void vl_api_l2_xconnect_details_t_handler_json
19238   (vl_api_l2_xconnect_details_t * mp)
19239 {
19240   vat_main_t *vam = &vat_main;
19241   vat_json_node_t *node = NULL;
19242
19243   if (VAT_JSON_ARRAY != vam->json_tree.type)
19244     {
19245       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19246       vat_json_init_array (&vam->json_tree);
19247     }
19248   node = vat_json_array_add (&vam->json_tree);
19249
19250   vat_json_init_object (node);
19251   vat_json_object_add_uint (node, "rx_sw_if_index",
19252                             ntohl (mp->rx_sw_if_index));
19253   vat_json_object_add_uint (node, "tx_sw_if_index",
19254                             ntohl (mp->tx_sw_if_index));
19255 }
19256
19257 static int
19258 api_l2_xconnect_dump (vat_main_t * vam)
19259 {
19260   vl_api_l2_xconnect_dump_t *mp;
19261   vl_api_control_ping_t *mp_ping;
19262   int ret;
19263
19264   if (!vam->json_output)
19265     {
19266       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19267     }
19268
19269   M (L2_XCONNECT_DUMP, mp);
19270
19271   S (mp);
19272
19273   /* Use a control ping for synchronization */
19274   MPING (CONTROL_PING, mp_ping);
19275   S (mp_ping);
19276
19277   W (ret);
19278   return ret;
19279 }
19280
19281 static int
19282 api_hw_interface_set_mtu (vat_main_t * vam)
19283 {
19284   unformat_input_t *i = vam->input;
19285   vl_api_hw_interface_set_mtu_t *mp;
19286   u32 sw_if_index = ~0;
19287   u32 mtu = 0;
19288   int ret;
19289
19290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19291     {
19292       if (unformat (i, "mtu %d", &mtu))
19293         ;
19294       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19295         ;
19296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19297         ;
19298       else
19299         break;
19300     }
19301
19302   if (sw_if_index == ~0)
19303     {
19304       errmsg ("missing interface name or sw_if_index");
19305       return -99;
19306     }
19307
19308   if (mtu == 0)
19309     {
19310       errmsg ("no mtu specified");
19311       return -99;
19312     }
19313
19314   /* Construct the API message */
19315   M (HW_INTERFACE_SET_MTU, mp);
19316   mp->sw_if_index = ntohl (sw_if_index);
19317   mp->mtu = ntohs ((u16) mtu);
19318
19319   S (mp);
19320   W (ret);
19321   return ret;
19322 }
19323
19324 static int
19325 api_p2p_ethernet_add (vat_main_t * vam)
19326 {
19327   unformat_input_t *i = vam->input;
19328   vl_api_p2p_ethernet_add_t *mp;
19329   u32 parent_if_index = ~0;
19330   u32 sub_id = ~0;
19331   u8 remote_mac[6];
19332   u8 mac_set = 0;
19333   int ret;
19334
19335   clib_memset (remote_mac, 0, sizeof (remote_mac));
19336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19337     {
19338       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19339         ;
19340       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19341         ;
19342       else
19343         if (unformat
19344             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19345         mac_set++;
19346       else if (unformat (i, "sub_id %d", &sub_id))
19347         ;
19348       else
19349         {
19350           clib_warning ("parse error '%U'", format_unformat_error, i);
19351           return -99;
19352         }
19353     }
19354
19355   if (parent_if_index == ~0)
19356     {
19357       errmsg ("missing interface name or sw_if_index");
19358       return -99;
19359     }
19360   if (mac_set == 0)
19361     {
19362       errmsg ("missing remote mac address");
19363       return -99;
19364     }
19365   if (sub_id == ~0)
19366     {
19367       errmsg ("missing sub-interface id");
19368       return -99;
19369     }
19370
19371   M (P2P_ETHERNET_ADD, mp);
19372   mp->parent_if_index = ntohl (parent_if_index);
19373   mp->subif_id = ntohl (sub_id);
19374   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19375
19376   S (mp);
19377   W (ret);
19378   return ret;
19379 }
19380
19381 static int
19382 api_p2p_ethernet_del (vat_main_t * vam)
19383 {
19384   unformat_input_t *i = vam->input;
19385   vl_api_p2p_ethernet_del_t *mp;
19386   u32 parent_if_index = ~0;
19387   u8 remote_mac[6];
19388   u8 mac_set = 0;
19389   int ret;
19390
19391   clib_memset (remote_mac, 0, sizeof (remote_mac));
19392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19393     {
19394       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19395         ;
19396       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19397         ;
19398       else
19399         if (unformat
19400             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19401         mac_set++;
19402       else
19403         {
19404           clib_warning ("parse error '%U'", format_unformat_error, i);
19405           return -99;
19406         }
19407     }
19408
19409   if (parent_if_index == ~0)
19410     {
19411       errmsg ("missing interface name or sw_if_index");
19412       return -99;
19413     }
19414   if (mac_set == 0)
19415     {
19416       errmsg ("missing remote mac address");
19417       return -99;
19418     }
19419
19420   M (P2P_ETHERNET_DEL, mp);
19421   mp->parent_if_index = ntohl (parent_if_index);
19422   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19423
19424   S (mp);
19425   W (ret);
19426   return ret;
19427 }
19428
19429 static int
19430 api_lldp_config (vat_main_t * vam)
19431 {
19432   unformat_input_t *i = vam->input;
19433   vl_api_lldp_config_t *mp;
19434   int tx_hold = 0;
19435   int tx_interval = 0;
19436   u8 *sys_name = NULL;
19437   int ret;
19438
19439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19440     {
19441       if (unformat (i, "system-name %s", &sys_name))
19442         ;
19443       else if (unformat (i, "tx-hold %d", &tx_hold))
19444         ;
19445       else if (unformat (i, "tx-interval %d", &tx_interval))
19446         ;
19447       else
19448         {
19449           clib_warning ("parse error '%U'", format_unformat_error, i);
19450           return -99;
19451         }
19452     }
19453
19454   vec_add1 (sys_name, 0);
19455
19456   M (LLDP_CONFIG, mp);
19457   mp->tx_hold = htonl (tx_hold);
19458   mp->tx_interval = htonl (tx_interval);
19459   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19460   vec_free (sys_name);
19461
19462   S (mp);
19463   W (ret);
19464   return ret;
19465 }
19466
19467 static int
19468 api_sw_interface_set_lldp (vat_main_t * vam)
19469 {
19470   unformat_input_t *i = vam->input;
19471   vl_api_sw_interface_set_lldp_t *mp;
19472   u32 sw_if_index = ~0;
19473   u32 enable = 1;
19474   u8 *port_desc = NULL, *mgmt_oid = NULL;
19475   ip4_address_t ip4_addr;
19476   ip6_address_t ip6_addr;
19477   int ret;
19478
19479   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19480   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19481
19482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19483     {
19484       if (unformat (i, "disable"))
19485         enable = 0;
19486       else
19487         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19488         ;
19489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19490         ;
19491       else if (unformat (i, "port-desc %s", &port_desc))
19492         ;
19493       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19494         ;
19495       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19496         ;
19497       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19498         ;
19499       else
19500         break;
19501     }
19502
19503   if (sw_if_index == ~0)
19504     {
19505       errmsg ("missing interface name or sw_if_index");
19506       return -99;
19507     }
19508
19509   /* Construct the API message */
19510   vec_add1 (port_desc, 0);
19511   vec_add1 (mgmt_oid, 0);
19512   M (SW_INTERFACE_SET_LLDP, mp);
19513   mp->sw_if_index = ntohl (sw_if_index);
19514   mp->enable = enable;
19515   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19516   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19517   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19518   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19519   vec_free (port_desc);
19520   vec_free (mgmt_oid);
19521
19522   S (mp);
19523   W (ret);
19524   return ret;
19525 }
19526
19527 static int
19528 api_tcp_configure_src_addresses (vat_main_t * vam)
19529 {
19530   vl_api_tcp_configure_src_addresses_t *mp;
19531   unformat_input_t *i = vam->input;
19532   vl_api_address_t first, last;
19533   u8 range_set = 0;
19534   u32 vrf_id = 0;
19535   int ret;
19536
19537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19538     {
19539       if (unformat (i, "%U - %U",
19540                     unformat_vl_api_address, &first,
19541                     unformat_vl_api_address, &last))
19542         {
19543           if (range_set)
19544             {
19545               errmsg ("one range per message (range already set)");
19546               return -99;
19547             }
19548           range_set = 1;
19549         }
19550       else if (unformat (i, "vrf %d", &vrf_id))
19551         ;
19552       else
19553         break;
19554     }
19555
19556   if (range_set == 0)
19557     {
19558       errmsg ("address range not set");
19559       return -99;
19560     }
19561
19562   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19563
19564   mp->vrf_id = ntohl (vrf_id);
19565   clib_memcpy (&mp->first_address, &first, sizeof (first));
19566   clib_memcpy (&mp->last_address, &last, sizeof (last));
19567
19568   S (mp);
19569   W (ret);
19570   return ret;
19571 }
19572
19573 static void vl_api_app_namespace_add_del_reply_t_handler
19574   (vl_api_app_namespace_add_del_reply_t * mp)
19575 {
19576   vat_main_t *vam = &vat_main;
19577   i32 retval = ntohl (mp->retval);
19578   if (vam->async_mode)
19579     {
19580       vam->async_errors += (retval < 0);
19581     }
19582   else
19583     {
19584       vam->retval = retval;
19585       if (retval == 0)
19586         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19587       vam->result_ready = 1;
19588     }
19589 }
19590
19591 static void vl_api_app_namespace_add_del_reply_t_handler_json
19592   (vl_api_app_namespace_add_del_reply_t * mp)
19593 {
19594   vat_main_t *vam = &vat_main;
19595   vat_json_node_t node;
19596
19597   vat_json_init_object (&node);
19598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19599   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19600
19601   vat_json_print (vam->ofp, &node);
19602   vat_json_free (&node);
19603
19604   vam->retval = ntohl (mp->retval);
19605   vam->result_ready = 1;
19606 }
19607
19608 static int
19609 api_app_namespace_add_del (vat_main_t * vam)
19610 {
19611   vl_api_app_namespace_add_del_t *mp;
19612   unformat_input_t *i = vam->input;
19613   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19614   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19615   u64 secret;
19616   int ret;
19617
19618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19619     {
19620       if (unformat (i, "id %_%v%_", &ns_id))
19621         ;
19622       else if (unformat (i, "secret %lu", &secret))
19623         secret_set = 1;
19624       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19625         sw_if_index_set = 1;
19626       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19627         ;
19628       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19629         ;
19630       else
19631         break;
19632     }
19633   if (!ns_id || !secret_set || !sw_if_index_set)
19634     {
19635       errmsg ("namespace id, secret and sw_if_index must be set");
19636       return -99;
19637     }
19638   if (vec_len (ns_id) > 64)
19639     {
19640       errmsg ("namespace id too long");
19641       return -99;
19642     }
19643   M (APP_NAMESPACE_ADD_DEL, mp);
19644
19645   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19646   mp->secret = clib_host_to_net_u64 (secret);
19647   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19648   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19649   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19650   vec_free (ns_id);
19651   S (mp);
19652   W (ret);
19653   return ret;
19654 }
19655
19656 static int
19657 api_sock_init_shm (vat_main_t * vam)
19658 {
19659 #if VPP_API_TEST_BUILTIN == 0
19660   unformat_input_t *i = vam->input;
19661   vl_api_shm_elem_config_t *config = 0;
19662   u64 size = 64 << 20;
19663   int rv;
19664
19665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19666     {
19667       if (unformat (i, "size %U", unformat_memory_size, &size))
19668         ;
19669       else
19670         break;
19671     }
19672
19673   /*
19674    * Canned custom ring allocator config.
19675    * Should probably parse all of this
19676    */
19677   vec_validate (config, 6);
19678   config[0].type = VL_API_VLIB_RING;
19679   config[0].size = 256;
19680   config[0].count = 32;
19681
19682   config[1].type = VL_API_VLIB_RING;
19683   config[1].size = 1024;
19684   config[1].count = 16;
19685
19686   config[2].type = VL_API_VLIB_RING;
19687   config[2].size = 4096;
19688   config[2].count = 2;
19689
19690   config[3].type = VL_API_CLIENT_RING;
19691   config[3].size = 256;
19692   config[3].count = 32;
19693
19694   config[4].type = VL_API_CLIENT_RING;
19695   config[4].size = 1024;
19696   config[4].count = 16;
19697
19698   config[5].type = VL_API_CLIENT_RING;
19699   config[5].size = 4096;
19700   config[5].count = 2;
19701
19702   config[6].type = VL_API_QUEUE;
19703   config[6].count = 128;
19704   config[6].size = sizeof (uword);
19705
19706   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19707   if (!rv)
19708     vam->client_index_invalid = 1;
19709   return rv;
19710 #else
19711   return -99;
19712 #endif
19713 }
19714
19715 static void
19716 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19717 {
19718   vat_main_t *vam = &vat_main;
19719   fib_prefix_t lcl, rmt;
19720
19721   ip_prefix_decode (&mp->lcl, &lcl);
19722   ip_prefix_decode (&mp->rmt, &rmt);
19723
19724   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19725     {
19726       print (vam->ofp,
19727              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19728              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19729              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19730              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19731              &rmt.fp_addr.ip4, rmt.fp_len,
19732              clib_net_to_host_u16 (mp->rmt_port),
19733              clib_net_to_host_u32 (mp->action_index), mp->tag);
19734     }
19735   else
19736     {
19737       print (vam->ofp,
19738              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19739              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19740              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19741              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19742              &rmt.fp_addr.ip6, rmt.fp_len,
19743              clib_net_to_host_u16 (mp->rmt_port),
19744              clib_net_to_host_u32 (mp->action_index), mp->tag);
19745     }
19746 }
19747
19748 static void
19749 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19750                                              mp)
19751 {
19752   vat_main_t *vam = &vat_main;
19753   vat_json_node_t *node = NULL;
19754   struct in6_addr ip6;
19755   struct in_addr ip4;
19756
19757   fib_prefix_t lcl, rmt;
19758
19759   ip_prefix_decode (&mp->lcl, &lcl);
19760   ip_prefix_decode (&mp->rmt, &rmt);
19761
19762   if (VAT_JSON_ARRAY != vam->json_tree.type)
19763     {
19764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19765       vat_json_init_array (&vam->json_tree);
19766     }
19767   node = vat_json_array_add (&vam->json_tree);
19768   vat_json_init_object (node);
19769
19770   vat_json_object_add_uint (node, "appns_index",
19771                             clib_net_to_host_u32 (mp->appns_index));
19772   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19773   vat_json_object_add_uint (node, "scope", mp->scope);
19774   vat_json_object_add_uint (node, "action_index",
19775                             clib_net_to_host_u32 (mp->action_index));
19776   vat_json_object_add_uint (node, "lcl_port",
19777                             clib_net_to_host_u16 (mp->lcl_port));
19778   vat_json_object_add_uint (node, "rmt_port",
19779                             clib_net_to_host_u16 (mp->rmt_port));
19780   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19781   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19782   vat_json_object_add_string_copy (node, "tag", mp->tag);
19783   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19784     {
19785       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19786       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19787       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19788       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19789     }
19790   else
19791     {
19792       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19793       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19794       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19795       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19796     }
19797 }
19798
19799 static int
19800 api_session_rule_add_del (vat_main_t * vam)
19801 {
19802   vl_api_session_rule_add_del_t *mp;
19803   unformat_input_t *i = vam->input;
19804   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19805   u32 appns_index = 0, scope = 0;
19806   ip4_address_t lcl_ip4, rmt_ip4;
19807   ip6_address_t lcl_ip6, rmt_ip6;
19808   u8 is_ip4 = 1, conn_set = 0;
19809   u8 is_add = 1, *tag = 0;
19810   int ret;
19811   fib_prefix_t lcl, rmt;
19812
19813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19814     {
19815       if (unformat (i, "del"))
19816         is_add = 0;
19817       else if (unformat (i, "add"))
19818         ;
19819       else if (unformat (i, "proto tcp"))
19820         proto = 0;
19821       else if (unformat (i, "proto udp"))
19822         proto = 1;
19823       else if (unformat (i, "appns %d", &appns_index))
19824         ;
19825       else if (unformat (i, "scope %d", &scope))
19826         ;
19827       else if (unformat (i, "tag %_%v%_", &tag))
19828         ;
19829       else
19830         if (unformat
19831             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19832              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19833              &rmt_port))
19834         {
19835           is_ip4 = 1;
19836           conn_set = 1;
19837         }
19838       else
19839         if (unformat
19840             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19841              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19842              &rmt_port))
19843         {
19844           is_ip4 = 0;
19845           conn_set = 1;
19846         }
19847       else if (unformat (i, "action %d", &action))
19848         ;
19849       else
19850         break;
19851     }
19852   if (proto == ~0 || !conn_set || action == ~0)
19853     {
19854       errmsg ("transport proto, connection and action must be set");
19855       return -99;
19856     }
19857
19858   if (scope > 3)
19859     {
19860       errmsg ("scope should be 0-3");
19861       return -99;
19862     }
19863
19864   M (SESSION_RULE_ADD_DEL, mp);
19865
19866   clib_memset (&lcl, 0, sizeof (lcl));
19867   clib_memset (&rmt, 0, sizeof (rmt));
19868   if (is_ip4)
19869     {
19870       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19871       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19872       lcl.fp_len = lcl_plen;
19873       rmt.fp_len = rmt_plen;
19874     }
19875   else
19876     {
19877       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19878       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19879       lcl.fp_len = lcl_plen;
19880       rmt.fp_len = rmt_plen;
19881     }
19882
19883
19884   ip_prefix_encode (&lcl, &mp->lcl);
19885   ip_prefix_encode (&rmt, &mp->rmt);
19886   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19887   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19888   mp->transport_proto =
19889     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19890   mp->action_index = clib_host_to_net_u32 (action);
19891   mp->appns_index = clib_host_to_net_u32 (appns_index);
19892   mp->scope = scope;
19893   mp->is_add = is_add;
19894   if (tag)
19895     {
19896       clib_memcpy (mp->tag, tag, vec_len (tag));
19897       vec_free (tag);
19898     }
19899
19900   S (mp);
19901   W (ret);
19902   return ret;
19903 }
19904
19905 static int
19906 api_session_rules_dump (vat_main_t * vam)
19907 {
19908   vl_api_session_rules_dump_t *mp;
19909   vl_api_control_ping_t *mp_ping;
19910   int ret;
19911
19912   if (!vam->json_output)
19913     {
19914       print (vam->ofp, "%=20s", "Session Rules");
19915     }
19916
19917   M (SESSION_RULES_DUMP, mp);
19918   /* send it... */
19919   S (mp);
19920
19921   /* Use a control ping for synchronization */
19922   MPING (CONTROL_PING, mp_ping);
19923   S (mp_ping);
19924
19925   /* Wait for a reply... */
19926   W (ret);
19927   return ret;
19928 }
19929
19930 static int
19931 api_ip_container_proxy_add_del (vat_main_t * vam)
19932 {
19933   vl_api_ip_container_proxy_add_del_t *mp;
19934   unformat_input_t *i = vam->input;
19935   u32 sw_if_index = ~0;
19936   vl_api_prefix_t pfx = { };
19937   u8 is_add = 1;
19938   int ret;
19939
19940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19941     {
19942       if (unformat (i, "del"))
19943         is_add = 0;
19944       else if (unformat (i, "add"))
19945         ;
19946       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19947         ;
19948       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19949         ;
19950       else
19951         break;
19952     }
19953   if (sw_if_index == ~0 || pfx.len == 0)
19954     {
19955       errmsg ("address and sw_if_index must be set");
19956       return -99;
19957     }
19958
19959   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19960
19961   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19962   mp->is_add = is_add;
19963   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19964
19965   S (mp);
19966   W (ret);
19967   return ret;
19968 }
19969
19970 static int
19971 api_qos_record_enable_disable (vat_main_t * vam)
19972 {
19973   unformat_input_t *i = vam->input;
19974   vl_api_qos_record_enable_disable_t *mp;
19975   u32 sw_if_index, qs = 0xff;
19976   u8 sw_if_index_set = 0;
19977   u8 enable = 1;
19978   int ret;
19979
19980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19981     {
19982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19983         sw_if_index_set = 1;
19984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19985         sw_if_index_set = 1;
19986       else if (unformat (i, "%U", unformat_qos_source, &qs))
19987         ;
19988       else if (unformat (i, "disable"))
19989         enable = 0;
19990       else
19991         {
19992           clib_warning ("parse error '%U'", format_unformat_error, i);
19993           return -99;
19994         }
19995     }
19996
19997   if (sw_if_index_set == 0)
19998     {
19999       errmsg ("missing interface name or sw_if_index");
20000       return -99;
20001     }
20002   if (qs == 0xff)
20003     {
20004       errmsg ("input location must be specified");
20005       return -99;
20006     }
20007
20008   M (QOS_RECORD_ENABLE_DISABLE, mp);
20009
20010   mp->record.sw_if_index = ntohl (sw_if_index);
20011   mp->record.input_source = qs;
20012   mp->enable = enable;
20013
20014   S (mp);
20015   W (ret);
20016   return ret;
20017 }
20018
20019
20020 static int
20021 q_or_quit (vat_main_t * vam)
20022 {
20023 #if VPP_API_TEST_BUILTIN == 0
20024   longjmp (vam->jump_buf, 1);
20025 #endif
20026   return 0;                     /* not so much */
20027 }
20028
20029 static int
20030 q (vat_main_t * vam)
20031 {
20032   return q_or_quit (vam);
20033 }
20034
20035 static int
20036 quit (vat_main_t * vam)
20037 {
20038   return q_or_quit (vam);
20039 }
20040
20041 static int
20042 comment (vat_main_t * vam)
20043 {
20044   return 0;
20045 }
20046
20047 static int
20048 elog_save (vat_main_t * vam)
20049 {
20050 #if VPP_API_TEST_BUILTIN == 0
20051   elog_main_t *em = &vam->elog_main;
20052   unformat_input_t *i = vam->input;
20053   char *file, *chroot_file;
20054   clib_error_t *error;
20055
20056   if (!unformat (i, "%s", &file))
20057     {
20058       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20059       return 0;
20060     }
20061
20062   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20063   if (strstr (file, "..") || index (file, '/'))
20064     {
20065       errmsg ("illegal characters in filename '%s'", file);
20066       return 0;
20067     }
20068
20069   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20070
20071   vec_free (file);
20072
20073   errmsg ("Saving %wd of %wd events to %s",
20074           elog_n_events_in_buffer (em),
20075           elog_buffer_capacity (em), chroot_file);
20076
20077   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20078   vec_free (chroot_file);
20079
20080   if (error)
20081     clib_error_report (error);
20082 #else
20083   errmsg ("Use the vpp event loger...");
20084 #endif
20085
20086   return 0;
20087 }
20088
20089 static int
20090 elog_setup (vat_main_t * vam)
20091 {
20092 #if VPP_API_TEST_BUILTIN == 0
20093   elog_main_t *em = &vam->elog_main;
20094   unformat_input_t *i = vam->input;
20095   u32 nevents = 128 << 10;
20096
20097   (void) unformat (i, "nevents %d", &nevents);
20098
20099   elog_init (em, nevents);
20100   vl_api_set_elog_main (em);
20101   vl_api_set_elog_trace_api_messages (1);
20102   errmsg ("Event logger initialized with %u events", nevents);
20103 #else
20104   errmsg ("Use the vpp event loger...");
20105 #endif
20106   return 0;
20107 }
20108
20109 static int
20110 elog_enable (vat_main_t * vam)
20111 {
20112 #if VPP_API_TEST_BUILTIN == 0
20113   elog_main_t *em = &vam->elog_main;
20114
20115   elog_enable_disable (em, 1 /* enable */ );
20116   vl_api_set_elog_trace_api_messages (1);
20117   errmsg ("Event logger enabled...");
20118 #else
20119   errmsg ("Use the vpp event loger...");
20120 #endif
20121   return 0;
20122 }
20123
20124 static int
20125 elog_disable (vat_main_t * vam)
20126 {
20127 #if VPP_API_TEST_BUILTIN == 0
20128   elog_main_t *em = &vam->elog_main;
20129
20130   elog_enable_disable (em, 0 /* enable */ );
20131   vl_api_set_elog_trace_api_messages (1);
20132   errmsg ("Event logger disabled...");
20133 #else
20134   errmsg ("Use the vpp event loger...");
20135 #endif
20136   return 0;
20137 }
20138
20139 static int
20140 statseg (vat_main_t * vam)
20141 {
20142   ssvm_private_t *ssvmp = &vam->stat_segment;
20143   ssvm_shared_header_t *shared_header = ssvmp->sh;
20144   vlib_counter_t **counters;
20145   u64 thread0_index1_packets;
20146   u64 thread0_index1_bytes;
20147   f64 vector_rate, input_rate;
20148   uword *p;
20149
20150   uword *counter_vector_by_name;
20151   if (vam->stat_segment_lockp == 0)
20152     {
20153       errmsg ("Stat segment not mapped...");
20154       return -99;
20155     }
20156
20157   /* look up "/if/rx for sw_if_index 1 as a test */
20158
20159   clib_spinlock_lock (vam->stat_segment_lockp);
20160
20161   counter_vector_by_name = (uword *) shared_header->opaque[1];
20162
20163   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20164   if (p == 0)
20165     {
20166       clib_spinlock_unlock (vam->stat_segment_lockp);
20167       errmsg ("/if/tx not found?");
20168       return -99;
20169     }
20170
20171   /* Fish per-thread vector of combined counters from shared memory */
20172   counters = (vlib_counter_t **) p[0];
20173
20174   if (vec_len (counters[0]) < 2)
20175     {
20176       clib_spinlock_unlock (vam->stat_segment_lockp);
20177       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20178       return -99;
20179     }
20180
20181   /* Read thread 0 sw_if_index 1 counter */
20182   thread0_index1_packets = counters[0][1].packets;
20183   thread0_index1_bytes = counters[0][1].bytes;
20184
20185   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20186   if (p == 0)
20187     {
20188       clib_spinlock_unlock (vam->stat_segment_lockp);
20189       errmsg ("vector_rate not found?");
20190       return -99;
20191     }
20192
20193   vector_rate = *(f64 *) (p[0]);
20194   p = hash_get_mem (counter_vector_by_name, "input_rate");
20195   if (p == 0)
20196     {
20197       clib_spinlock_unlock (vam->stat_segment_lockp);
20198       errmsg ("input_rate not found?");
20199       return -99;
20200     }
20201   input_rate = *(f64 *) (p[0]);
20202
20203   clib_spinlock_unlock (vam->stat_segment_lockp);
20204
20205   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20206          vector_rate, input_rate);
20207   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20208          thread0_index1_packets, thread0_index1_bytes);
20209
20210   return 0;
20211 }
20212
20213 static int
20214 cmd_cmp (void *a1, void *a2)
20215 {
20216   u8 **c1 = a1;
20217   u8 **c2 = a2;
20218
20219   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20220 }
20221
20222 static int
20223 help (vat_main_t * vam)
20224 {
20225   u8 **cmds = 0;
20226   u8 *name = 0;
20227   hash_pair_t *p;
20228   unformat_input_t *i = vam->input;
20229   int j;
20230
20231   if (unformat (i, "%s", &name))
20232     {
20233       uword *hs;
20234
20235       vec_add1 (name, 0);
20236
20237       hs = hash_get_mem (vam->help_by_name, name);
20238       if (hs)
20239         print (vam->ofp, "usage: %s %s", name, hs[0]);
20240       else
20241         print (vam->ofp, "No such msg / command '%s'", name);
20242       vec_free (name);
20243       return 0;
20244     }
20245
20246   print (vam->ofp, "Help is available for the following:");
20247
20248     /* *INDENT-OFF* */
20249     hash_foreach_pair (p, vam->function_by_name,
20250     ({
20251       vec_add1 (cmds, (u8 *)(p->key));
20252     }));
20253     /* *INDENT-ON* */
20254
20255   vec_sort_with_function (cmds, cmd_cmp);
20256
20257   for (j = 0; j < vec_len (cmds); j++)
20258     print (vam->ofp, "%s", cmds[j]);
20259
20260   vec_free (cmds);
20261   return 0;
20262 }
20263
20264 static int
20265 set (vat_main_t * vam)
20266 {
20267   u8 *name = 0, *value = 0;
20268   unformat_input_t *i = vam->input;
20269
20270   if (unformat (i, "%s", &name))
20271     {
20272       /* The input buffer is a vector, not a string. */
20273       value = vec_dup (i->buffer);
20274       vec_delete (value, i->index, 0);
20275       /* Almost certainly has a trailing newline */
20276       if (value[vec_len (value) - 1] == '\n')
20277         value[vec_len (value) - 1] = 0;
20278       /* Make sure it's a proper string, one way or the other */
20279       vec_add1 (value, 0);
20280       (void) clib_macro_set_value (&vam->macro_main,
20281                                    (char *) name, (char *) value);
20282     }
20283   else
20284     errmsg ("usage: set <name> <value>");
20285
20286   vec_free (name);
20287   vec_free (value);
20288   return 0;
20289 }
20290
20291 static int
20292 unset (vat_main_t * vam)
20293 {
20294   u8 *name = 0;
20295
20296   if (unformat (vam->input, "%s", &name))
20297     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20298       errmsg ("unset: %s wasn't set", name);
20299   vec_free (name);
20300   return 0;
20301 }
20302
20303 typedef struct
20304 {
20305   u8 *name;
20306   u8 *value;
20307 } macro_sort_t;
20308
20309
20310 static int
20311 macro_sort_cmp (void *a1, void *a2)
20312 {
20313   macro_sort_t *s1 = a1;
20314   macro_sort_t *s2 = a2;
20315
20316   return strcmp ((char *) (s1->name), (char *) (s2->name));
20317 }
20318
20319 static int
20320 dump_macro_table (vat_main_t * vam)
20321 {
20322   macro_sort_t *sort_me = 0, *sm;
20323   int i;
20324   hash_pair_t *p;
20325
20326     /* *INDENT-OFF* */
20327     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20328     ({
20329       vec_add2 (sort_me, sm, 1);
20330       sm->name = (u8 *)(p->key);
20331       sm->value = (u8 *) (p->value[0]);
20332     }));
20333     /* *INDENT-ON* */
20334
20335   vec_sort_with_function (sort_me, macro_sort_cmp);
20336
20337   if (vec_len (sort_me))
20338     print (vam->ofp, "%-15s%s", "Name", "Value");
20339   else
20340     print (vam->ofp, "The macro table is empty...");
20341
20342   for (i = 0; i < vec_len (sort_me); i++)
20343     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20344   return 0;
20345 }
20346
20347 static int
20348 dump_node_table (vat_main_t * vam)
20349 {
20350   int i, j;
20351   vlib_node_t *node, *next_node;
20352
20353   if (vec_len (vam->graph_nodes) == 0)
20354     {
20355       print (vam->ofp, "Node table empty, issue get_node_graph...");
20356       return 0;
20357     }
20358
20359   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20360     {
20361       node = vam->graph_nodes[0][i];
20362       print (vam->ofp, "[%d] %s", i, node->name);
20363       for (j = 0; j < vec_len (node->next_nodes); j++)
20364         {
20365           if (node->next_nodes[j] != ~0)
20366             {
20367               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20368               print (vam->ofp, "  [%d] %s", j, next_node->name);
20369             }
20370         }
20371     }
20372   return 0;
20373 }
20374
20375 static int
20376 value_sort_cmp (void *a1, void *a2)
20377 {
20378   name_sort_t *n1 = a1;
20379   name_sort_t *n2 = a2;
20380
20381   if (n1->value < n2->value)
20382     return -1;
20383   if (n1->value > n2->value)
20384     return 1;
20385   return 0;
20386 }
20387
20388
20389 static int
20390 dump_msg_api_table (vat_main_t * vam)
20391 {
20392   api_main_t *am = vlibapi_get_main ();
20393   name_sort_t *nses = 0, *ns;
20394   hash_pair_t *hp;
20395   int i;
20396
20397   /* *INDENT-OFF* */
20398   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20399   ({
20400     vec_add2 (nses, ns, 1);
20401     ns->name = (u8 *)(hp->key);
20402     ns->value = (u32) hp->value[0];
20403   }));
20404   /* *INDENT-ON* */
20405
20406   vec_sort_with_function (nses, value_sort_cmp);
20407
20408   for (i = 0; i < vec_len (nses); i++)
20409     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20410   vec_free (nses);
20411   return 0;
20412 }
20413
20414 static int
20415 get_msg_id (vat_main_t * vam)
20416 {
20417   u8 *name_and_crc;
20418   u32 message_index;
20419
20420   if (unformat (vam->input, "%s", &name_and_crc))
20421     {
20422       message_index = vl_msg_api_get_msg_index (name_and_crc);
20423       if (message_index == ~0)
20424         {
20425           print (vam->ofp, " '%s' not found", name_and_crc);
20426           return 0;
20427         }
20428       print (vam->ofp, " '%s' has message index %d",
20429              name_and_crc, message_index);
20430       return 0;
20431     }
20432   errmsg ("name_and_crc required...");
20433   return 0;
20434 }
20435
20436 static int
20437 search_node_table (vat_main_t * vam)
20438 {
20439   unformat_input_t *line_input = vam->input;
20440   u8 *node_to_find;
20441   int j;
20442   vlib_node_t *node, *next_node;
20443   uword *p;
20444
20445   if (vam->graph_node_index_by_name == 0)
20446     {
20447       print (vam->ofp, "Node table empty, issue get_node_graph...");
20448       return 0;
20449     }
20450
20451   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20452     {
20453       if (unformat (line_input, "%s", &node_to_find))
20454         {
20455           vec_add1 (node_to_find, 0);
20456           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20457           if (p == 0)
20458             {
20459               print (vam->ofp, "%s not found...", node_to_find);
20460               goto out;
20461             }
20462           node = vam->graph_nodes[0][p[0]];
20463           print (vam->ofp, "[%d] %s", p[0], node->name);
20464           for (j = 0; j < vec_len (node->next_nodes); j++)
20465             {
20466               if (node->next_nodes[j] != ~0)
20467                 {
20468                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20469                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20470                 }
20471             }
20472         }
20473
20474       else
20475         {
20476           clib_warning ("parse error '%U'", format_unformat_error,
20477                         line_input);
20478           return -99;
20479         }
20480
20481     out:
20482       vec_free (node_to_find);
20483
20484     }
20485
20486   return 0;
20487 }
20488
20489
20490 static int
20491 script (vat_main_t * vam)
20492 {
20493 #if (VPP_API_TEST_BUILTIN==0)
20494   u8 *s = 0;
20495   char *save_current_file;
20496   unformat_input_t save_input;
20497   jmp_buf save_jump_buf;
20498   u32 save_line_number;
20499
20500   FILE *new_fp, *save_ifp;
20501
20502   if (unformat (vam->input, "%s", &s))
20503     {
20504       new_fp = fopen ((char *) s, "r");
20505       if (new_fp == 0)
20506         {
20507           errmsg ("Couldn't open script file %s", s);
20508           vec_free (s);
20509           return -99;
20510         }
20511     }
20512   else
20513     {
20514       errmsg ("Missing script name");
20515       return -99;
20516     }
20517
20518   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20519   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20520   save_ifp = vam->ifp;
20521   save_line_number = vam->input_line_number;
20522   save_current_file = (char *) vam->current_file;
20523
20524   vam->input_line_number = 0;
20525   vam->ifp = new_fp;
20526   vam->current_file = s;
20527   do_one_file (vam);
20528
20529   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20530   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20531   vam->ifp = save_ifp;
20532   vam->input_line_number = save_line_number;
20533   vam->current_file = (u8 *) save_current_file;
20534   vec_free (s);
20535
20536   return 0;
20537 #else
20538   clib_warning ("use the exec command...");
20539   return -99;
20540 #endif
20541 }
20542
20543 static int
20544 echo (vat_main_t * vam)
20545 {
20546   print (vam->ofp, "%v", vam->input->buffer);
20547   return 0;
20548 }
20549
20550 /* List of API message constructors, CLI names map to api_xxx */
20551 #define foreach_vpe_api_msg                                             \
20552 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20553 _(sw_interface_dump,"")                                                 \
20554 _(sw_interface_set_flags,                                               \
20555   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20556 _(sw_interface_add_del_address,                                         \
20557   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20558 _(sw_interface_set_rx_mode,                                             \
20559   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20560 _(sw_interface_set_rx_placement,                                        \
20561   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20562 _(sw_interface_rx_placement_dump,                                       \
20563   "[<intfc> | sw_if_index <id>]")                                         \
20564 _(sw_interface_set_table,                                               \
20565   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20566 _(sw_interface_set_mpls_enable,                                         \
20567   "<intfc> | sw_if_index [disable | dis]")                              \
20568 _(sw_interface_set_vpath,                                               \
20569   "<intfc> | sw_if_index <id> enable | disable")                        \
20570 _(sw_interface_set_vxlan_bypass,                                        \
20571   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20572 _(sw_interface_set_geneve_bypass,                                       \
20573   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20574 _(sw_interface_set_l2_xconnect,                                         \
20575   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20576   "enable | disable")                                                   \
20577 _(sw_interface_set_l2_bridge,                                           \
20578   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20579   "[shg <split-horizon-group>] [bvi]\n"                                 \
20580   "enable | disable")                                                   \
20581 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20582 _(bridge_domain_add_del,                                                \
20583   "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") \
20584 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20585 _(l2fib_add_del,                                                        \
20586   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20587 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20588 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20589 _(l2_flags,                                                             \
20590   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20591 _(bridge_flags,                                                         \
20592   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20593 _(tap_create_v2,                                                        \
20594   "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload | gro-coalesce] [persist] [attach] [tun]") \
20595 _(tap_delete_v2,                                                        \
20596   "<vpp-if-name> | sw_if_index <id>")                                   \
20597 _(sw_interface_tap_v2_dump, "")                                         \
20598 _(virtio_pci_create,                                                    \
20599   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20600 _(virtio_pci_delete,                                                    \
20601   "<vpp-if-name> | sw_if_index <id>")                                   \
20602 _(sw_interface_virtio_pci_dump, "")                                     \
20603 _(bond_create,                                                          \
20604   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20605   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20606   "[id <if-id>]")                                                       \
20607 _(bond_delete,                                                          \
20608   "<vpp-if-name> | sw_if_index <id>")                                   \
20609 _(bond_enslave,                                                         \
20610   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20611 _(bond_detach_slave,                                                    \
20612   "sw_if_index <n>")                                                    \
20613  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20614 _(sw_interface_bond_dump, "")                                           \
20615 _(sw_interface_slave_dump,                                              \
20616   "<vpp-if-name> | sw_if_index <id>")                                   \
20617 _(ip_table_add_del,                                                     \
20618   "table <n> [ipv6] [add | del]\n")                                     \
20619 _(ip_route_add_del,                                                     \
20620   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20621   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20622   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20623   "[multipath] [count <n>] [del]")                                      \
20624 _(ip_mroute_add_del,                                                    \
20625   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20626   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20627 _(mpls_table_add_del,                                                   \
20628   "table <n> [add | del]\n")                                            \
20629 _(mpls_route_add_del,                                                   \
20630   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20631   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20632   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20633   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20634   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20635   "[count <n>] [del]")                                                  \
20636 _(mpls_ip_bind_unbind,                                                  \
20637   "<label> <addr/len>")                                                 \
20638 _(mpls_tunnel_add_del,                                                  \
20639   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20640   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20641   "[l2-only]  [out-label <n>]")                                         \
20642 _(sr_mpls_policy_add,                                                   \
20643   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20644 _(sr_mpls_policy_del,                                                   \
20645   "bsid <id>")                                                          \
20646 _(bier_table_add_del,                                                   \
20647   "<label> <sub-domain> <set> <bsl> [del]")                             \
20648 _(bier_route_add_del,                                                   \
20649   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20650   "[<intfc> | sw_if_index <id>]"                                        \
20651   "[weight <n>] [del] [multipath]")                                     \
20652 _(sw_interface_set_unnumbered,                                          \
20653   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20654 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20655 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20656   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20657   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20658   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20659 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20660 _(ip_table_flush, "table <n> [ipv6]")                                   \
20661 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20662 _(set_ip_flow_hash,                                                     \
20663   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20664 _(sw_interface_ip6_enable_disable,                                      \
20665   "<intfc> | sw_if_index <id> enable | disable")                        \
20666 _(l2_patch_add_del,                                                     \
20667   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20668   "enable | disable")                                                   \
20669 _(sr_localsid_add_del,                                                  \
20670   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20671   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20672 _(classify_add_del_table,                                               \
20673   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20674   " [del] [del-chain] mask <mask-value>\n"                              \
20675   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20676   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20677 _(classify_add_del_session,                                             \
20678   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20679   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20680   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20681   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20682 _(classify_set_interface_ip_table,                                      \
20683   "<intfc> | sw_if_index <nn> table <nn>")                              \
20684 _(classify_set_interface_l2_tables,                                     \
20685   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20686   "  [other-table <nn>]")                                               \
20687 _(get_node_index, "node <node-name")                                    \
20688 _(add_node_next, "node <node-name> next <next-node-name>")              \
20689 _(l2tpv3_create_tunnel,                                                 \
20690   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20691   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20692   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20693 _(l2tpv3_set_tunnel_cookies,                                            \
20694   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20695   "[new_remote_cookie <nn>]\n")                                         \
20696 _(l2tpv3_interface_enable_disable,                                      \
20697   "<intfc> | sw_if_index <nn> enable | disable")                        \
20698 _(l2tpv3_set_lookup_key,                                                \
20699   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20700 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20701 _(vxlan_offload_rx,                                                     \
20702   "hw { <interface name> | hw_if_index <nn>} "                          \
20703   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20704 _(vxlan_add_del_tunnel,                                                 \
20705   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20706   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20707   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20708 _(geneve_add_del_tunnel,                                                \
20709   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20710   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20711   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20712 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20713 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20714 _(gre_tunnel_add_del,                                                   \
20715   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20716   "[teb | erspan <session-id>] [del]")                                  \
20717 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20718 _(l2_fib_clear_table, "")                                               \
20719 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20720 _(l2_interface_vlan_tag_rewrite,                                        \
20721   "<intfc> | sw_if_index <nn> \n"                                       \
20722   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20723   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20724 _(create_vhost_user_if,                                                 \
20725         "socket <filename> [server] [renumber <dev_instance>] "         \
20726         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20727         "[mac <mac_address>] [packed]")                                 \
20728 _(modify_vhost_user_if,                                                 \
20729         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20730         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20731 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20732 _(sw_interface_vhost_user_dump, "")                                     \
20733 _(show_version, "")                                                     \
20734 _(show_threads, "")                                                     \
20735 _(vxlan_gpe_add_del_tunnel,                                             \
20736   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20737   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20738   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20739   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20740 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20741 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20742 _(interface_name_renumber,                                              \
20743   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20744 _(input_acl_set_interface,                                              \
20745   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20746   "  [l2-table <nn>] [del]")                                            \
20747 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20748 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20749 _(ip_dump, "ipv4 | ipv6")                                               \
20750 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20751 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20752   "  spid_id <n> ")                                                     \
20753 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20754   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20755   "  integ_alg <alg> integ_key <hex>")                                  \
20756 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20757   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20758   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20759   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20760 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20761   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20762   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20763   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20764   "  [instance <n>]")     \
20765 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20766 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20767 _(delete_loopback,"sw_if_index <nn>")                                   \
20768 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20769 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20770 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20771 _(want_interface_events,  "enable|disable")                             \
20772 _(get_first_msg_id, "client <name>")                                    \
20773 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20774 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20775   "fib-id <nn> [ip4][ip6][default]")                                    \
20776 _(get_node_graph, " ")                                                  \
20777 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20778 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20779 _(ioam_disable, "")                                                     \
20780 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20781                             " sw_if_index <sw_if_index> p <priority> "  \
20782                             "w <weight>] [del]")                        \
20783 _(one_add_del_locator, "locator-set <locator_name> "                    \
20784                         "iface <intf> | sw_if_index <sw_if_index> "     \
20785                         "p <priority> w <weight> [del]")                \
20786 _(one_add_del_local_eid,"vni <vni> eid "                                \
20787                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20788                          "locator-set <locator_name> [del]"             \
20789                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20790 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20791 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20792 _(one_enable_disable, "enable|disable")                                 \
20793 _(one_map_register_enable_disable, "enable|disable")                    \
20794 _(one_map_register_fallback_threshold, "<value>")                       \
20795 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20796 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20797                                "[seid <seid>] "                         \
20798                                "rloc <locator> p <prio> "               \
20799                                "w <weight> [rloc <loc> ... ] "          \
20800                                "action <action> [del-all]")             \
20801 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20802                           "<local-eid>")                                \
20803 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20804 _(one_use_petr, "ip-address> | disable")                                \
20805 _(one_map_request_mode, "src-dst|dst-only")                             \
20806 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20807 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20808 _(one_locator_set_dump, "[local | remote]")                             \
20809 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20810 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20811                        "[local] | [remote]")                            \
20812 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20813 _(one_ndp_bd_get, "")                                                   \
20814 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20815 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20816 _(one_l2_arp_bd_get, "")                                                \
20817 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20818 _(one_stats_enable_disable, "enable|disable")                           \
20819 _(show_one_stats_enable_disable, "")                                    \
20820 _(one_eid_table_vni_dump, "")                                           \
20821 _(one_eid_table_map_dump, "l2|l3")                                      \
20822 _(one_map_resolver_dump, "")                                            \
20823 _(one_map_server_dump, "")                                              \
20824 _(one_adjacencies_get, "vni <vni>")                                     \
20825 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20826 _(show_one_rloc_probe_state, "")                                        \
20827 _(show_one_map_register_state, "")                                      \
20828 _(show_one_status, "")                                                  \
20829 _(one_stats_dump, "")                                                   \
20830 _(one_stats_flush, "")                                                  \
20831 _(one_get_map_request_itr_rlocs, "")                                    \
20832 _(one_map_register_set_ttl, "<ttl>")                                    \
20833 _(one_set_transport_protocol, "udp|api")                                \
20834 _(one_get_transport_protocol, "")                                       \
20835 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20836 _(one_show_xtr_mode, "")                                                \
20837 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20838 _(one_show_pitr_mode, "")                                               \
20839 _(one_enable_disable_petr_mode, "enable|disable")                       \
20840 _(one_show_petr_mode, "")                                               \
20841 _(show_one_nsh_mapping, "")                                             \
20842 _(show_one_pitr, "")                                                    \
20843 _(show_one_use_petr, "")                                                \
20844 _(show_one_map_request_mode, "")                                        \
20845 _(show_one_map_register_ttl, "")                                        \
20846 _(show_one_map_register_fallback_threshold, "")                         \
20847 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20848                             " sw_if_index <sw_if_index> p <priority> "  \
20849                             "w <weight>] [del]")                        \
20850 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20851                         "iface <intf> | sw_if_index <sw_if_index> "     \
20852                         "p <priority> w <weight> [del]")                \
20853 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20854                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20855                          "locator-set <locator_name> [del]"             \
20856                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20857 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20858 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20859 _(lisp_enable_disable, "enable|disable")                                \
20860 _(lisp_map_register_enable_disable, "enable|disable")                   \
20861 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20862 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20863                                "[seid <seid>] "                         \
20864                                "rloc <locator> p <prio> "               \
20865                                "w <weight> [rloc <loc> ... ] "          \
20866                                "action <action> [del-all]")             \
20867 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20868                           "<local-eid>")                                \
20869 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20870 _(lisp_use_petr, "<ip-address> | disable")                              \
20871 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20872 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20873 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20874 _(lisp_locator_set_dump, "[local | remote]")                            \
20875 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20876 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20877                        "[local] | [remote]")                            \
20878 _(lisp_eid_table_vni_dump, "")                                          \
20879 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20880 _(lisp_map_resolver_dump, "")                                           \
20881 _(lisp_map_server_dump, "")                                             \
20882 _(lisp_adjacencies_get, "vni <vni>")                                    \
20883 _(gpe_fwd_entry_vnis_get, "")                                           \
20884 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20885 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20886                                 "[table <table-id>]")                   \
20887 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20888 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20889 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20890 _(gpe_get_encap_mode, "")                                               \
20891 _(lisp_gpe_add_del_iface, "up|down")                                    \
20892 _(lisp_gpe_enable_disable, "enable|disable")                            \
20893 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20894   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20895 _(show_lisp_rloc_probe_state, "")                                       \
20896 _(show_lisp_map_register_state, "")                                     \
20897 _(show_lisp_status, "")                                                 \
20898 _(lisp_get_map_request_itr_rlocs, "")                                   \
20899 _(show_lisp_pitr, "")                                                   \
20900 _(show_lisp_use_petr, "")                                               \
20901 _(show_lisp_map_request_mode, "")                                       \
20902 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20903 _(af_packet_delete, "name <host interface name>")                       \
20904 _(af_packet_dump, "")                                                   \
20905 _(policer_add_del, "name <policer name> <params> [del]")                \
20906 _(policer_dump, "[name <policer name>]")                                \
20907 _(policer_classify_set_interface,                                       \
20908   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20909   "  [l2-table <nn>] [del]")                                            \
20910 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20911 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20912 _(mpls_table_dump, "")                                                  \
20913 _(mpls_route_dump, "table-id <ID>")                                     \
20914 _(classify_table_ids, "")                                               \
20915 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20916 _(classify_table_info, "table_id <nn>")                                 \
20917 _(classify_session_dump, "table_id <nn>")                               \
20918 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20919     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20920     "[template_interval <nn>] [udp_checksum]")                          \
20921 _(ipfix_exporter_dump, "")                                              \
20922 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20923 _(ipfix_classify_stream_dump, "")                                       \
20924 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20925 _(ipfix_classify_table_dump, "")                                        \
20926 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20927 _(sw_interface_span_dump, "[l2]")                                           \
20928 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20929 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20930 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20931 _(pg_enable_disable, "[stream <id>] disable")                           \
20932 _(ip_source_and_port_range_check_add_del,                               \
20933   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20934 _(ip_source_and_port_range_check_interface_add_del,                     \
20935   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20936   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20937 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20938 _(l2_interface_pbb_tag_rewrite,                                         \
20939   "<intfc> | sw_if_index <nn> \n"                                       \
20940   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20941   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20942 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20943 _(flow_classify_set_interface,                                          \
20944   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20945 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20946 _(ip_table_dump, "")                                                    \
20947 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20948 _(ip_mtable_dump, "")                                                   \
20949 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20950 _(feature_enable_disable, "arc_name <arc_name> "                        \
20951   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20952 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20953   "[enable | disable] ")                                                \
20954 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20955 "[disable]")                                                            \
20956 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20957   "mac <mac-address> [del]")                                            \
20958 _(l2_xconnect_dump, "")                                                 \
20959 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20960 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20961 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20962 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20963 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20964 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
20965   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
20966 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
20967 _(sock_init_shm, "size <nnn>")                                          \
20968 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
20969 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
20970   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
20971 _(session_rules_dump, "")                                               \
20972 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
20973 _(output_acl_set_interface,                                             \
20974   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20975   "  [l2-table <nn>] [del]")                                            \
20976 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
20977
20978 /* List of command functions, CLI names map directly to functions */
20979 #define foreach_cli_function                                    \
20980 _(comment, "usage: comment <ignore-rest-of-line>")              \
20981 _(dump_interface_table, "usage: dump_interface_table")          \
20982 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20983 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20984 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20985 _(dump_macro_table, "usage: dump_macro_table ")                 \
20986 _(dump_node_table, "usage: dump_node_table")                    \
20987 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20988 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
20989 _(elog_disable, "usage: elog_disable")                          \
20990 _(elog_enable, "usage: elog_enable")                            \
20991 _(elog_save, "usage: elog_save <filename>")                     \
20992 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20993 _(echo, "usage: echo <message>")                                \
20994 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20995 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20996 _(help, "usage: help")                                          \
20997 _(q, "usage: quit")                                             \
20998 _(quit, "usage: quit")                                          \
20999 _(search_node_table, "usage: search_node_table <name>...")      \
21000 _(set, "usage: set <variable-name> <value>")                    \
21001 _(script, "usage: script <file-name>")                          \
21002 _(statseg, "usage: statseg")                                    \
21003 _(unset, "usage: unset <variable-name>")
21004
21005 #define _(N,n)                                  \
21006     static void vl_api_##n##_t_handler_uni      \
21007     (vl_api_##n##_t * mp)                       \
21008     {                                           \
21009         vat_main_t * vam = &vat_main;           \
21010         if (vam->json_output) {                 \
21011             vl_api_##n##_t_handler_json(mp);    \
21012         } else {                                \
21013             vl_api_##n##_t_handler(mp);         \
21014         }                                       \
21015     }
21016 foreach_vpe_api_reply_msg;
21017 #if VPP_API_TEST_BUILTIN == 0
21018 foreach_standalone_reply_msg;
21019 #endif
21020 #undef _
21021
21022 void
21023 vat_api_hookup (vat_main_t * vam)
21024 {
21025 #define _(N,n)                                                  \
21026     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21027                            vl_api_##n##_t_handler_uni,          \
21028                            vl_noop_handler,                     \
21029                            vl_api_##n##_t_endian,               \
21030                            vl_api_##n##_t_print,                \
21031                            sizeof(vl_api_##n##_t), 1);
21032   foreach_vpe_api_reply_msg;
21033 #if VPP_API_TEST_BUILTIN == 0
21034   foreach_standalone_reply_msg;
21035 #endif
21036 #undef _
21037
21038 #if (VPP_API_TEST_BUILTIN==0)
21039   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21040
21041   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21042
21043   vam->function_by_name = hash_create_string (0, sizeof (uword));
21044
21045   vam->help_by_name = hash_create_string (0, sizeof (uword));
21046 #endif
21047
21048   /* API messages we can send */
21049 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21050   foreach_vpe_api_msg;
21051 #undef _
21052
21053   /* Help strings */
21054 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21055   foreach_vpe_api_msg;
21056 #undef _
21057
21058   /* CLI functions */
21059 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21060   foreach_cli_function;
21061 #undef _
21062
21063   /* Help strings */
21064 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21065   foreach_cli_function;
21066 #undef _
21067 }
21068
21069 #if VPP_API_TEST_BUILTIN
21070 static clib_error_t *
21071 vat_api_hookup_shim (vlib_main_t * vm)
21072 {
21073   vat_api_hookup (&vat_main);
21074   return 0;
21075 }
21076
21077 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21078 #endif
21079
21080 /*
21081  * fd.io coding-style-patch-verification: ON
21082  *
21083  * Local Variables:
21084  * eval: (c-set-style "gnu")
21085  * End:
21086  */