gso: packet coalesce library
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2020 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/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
55 #include <vnet/ethernet/ethernet_types_api.h>
56 #include <vnet/ip/ip_types_api.h>
57 #include "vat/json_format.h"
58 #include <vnet/ip/ip_types_api.h>
59 #include <vnet/ethernet/ethernet_types_api.h>
60
61 #include <inttypes.h>
62 #include <sys/stat.h>
63
64 #define vl_typedefs             /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_typedefs
67
68 /* declare message handlers for each api */
69
70 #define vl_endianfun            /* define message structures */
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_endianfun
73
74 /* instantiate all the print functions we know about */
75 #if VPP_API_TEST_BUILTIN == 0
76 #define vl_print(handle, ...)
77 #else
78 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
79 #endif
80 #define vl_printfun
81 #include <vpp/api/vpe_all_api_h.h>
82 #undef vl_printfun
83
84 #define __plugin_msg_base 0
85 #include <vlibapi/vat_helper_macros.h>
86
87 #include <vnet/format_fns.h>
88
89 void vl_api_set_elog_main (elog_main_t * m);
90 int vl_api_set_elog_trace_api_messages (int enable);
91
92 #if VPP_API_TEST_BUILTIN == 0
93 #include <netdb.h>
94
95 u32
96 vl (void *p)
97 {
98   return vec_len (p);
99 }
100
101 int
102 vat_socket_connect (vat_main_t * vam)
103 {
104   int rv;
105   api_main_t *am = vlibapi_get_main ();
106   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111
112   /* vpp expects the client index in network order */
113   vam->my_client_index = htonl (socket_client_main.client_index);
114   am->my_client_index = vam->my_client_index;
115   return 0;
116 }
117 #else /* vpp built-in case, we don't do sockets... */
118 int
119 vat_socket_connect (vat_main_t * vam)
120 {
121   return 0;
122 }
123
124 int
125 vl_socket_client_read (int wait)
126 {
127   return -1;
128 };
129
130 int
131 vl_socket_client_write ()
132 {
133   return -1;
134 };
135
136 void *
137 vl_socket_client_msg_alloc (int nbytes)
138 {
139   return 0;
140 }
141 #endif
142
143
144 f64
145 vat_time_now (vat_main_t * vam)
146 {
147 #if VPP_API_TEST_BUILTIN
148   return vlib_time_now (vam->vlib_main);
149 #else
150   return clib_time_now (&vam->clib_time);
151 #endif
152 }
153
154 void
155 errmsg (char *fmt, ...)
156 {
157   vat_main_t *vam = &vat_main;
158   va_list va;
159   u8 *s;
160
161   va_start (va, fmt);
162   s = va_format (0, fmt, &va);
163   va_end (va);
164
165   vec_add1 (s, 0);
166
167 #if VPP_API_TEST_BUILTIN
168   vlib_cli_output (vam->vlib_main, (char *) s);
169 #else
170   {
171     if (vam->ifp != stdin)
172       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
173                vam->input_line_number);
174     else
175       fformat (vam->ofp, "%s\n", (char *) s);
176     fflush (vam->ofp);
177   }
178 #endif
179
180   vec_free (s);
181 }
182
183 #if VPP_API_TEST_BUILTIN == 0
184 static uword
185 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
186 {
187   vat_main_t *vam = va_arg (*args, vat_main_t *);
188   u32 *result = va_arg (*args, u32 *);
189   u8 *if_name;
190   uword *p;
191
192   if (!unformat (input, "%s", &if_name))
193     return 0;
194
195   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
196   if (p == 0)
197     return 0;
198   *result = p[0];
199   return 1;
200 }
201
202 static uword
203 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
204 {
205   return 0;
206 }
207
208 /* Parse an IP4 address %d.%d.%d.%d. */
209 uword
210 unformat_ip4_address (unformat_input_t * input, va_list * args)
211 {
212   u8 *result = va_arg (*args, u8 *);
213   unsigned a[4];
214
215   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
216     return 0;
217
218   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
219     return 0;
220
221   result[0] = a[0];
222   result[1] = a[1];
223   result[2] = a[2];
224   result[3] = a[3];
225
226   return 1;
227 }
228
229 uword
230 unformat_ethernet_address (unformat_input_t * input, va_list * args)
231 {
232   u8 *result = va_arg (*args, u8 *);
233   u32 i, a[6];
234
235   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
236                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
237     return 0;
238
239   /* Check range. */
240   for (i = 0; i < 6; i++)
241     if (a[i] >= (1 << 8))
242       return 0;
243
244   for (i = 0; i < 6; i++)
245     result[i] = a[i];
246
247   return 1;
248 }
249
250 /* Returns ethernet type as an int in host byte order. */
251 uword
252 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
253                                         va_list * args)
254 {
255   u16 *result = va_arg (*args, u16 *);
256   int type;
257
258   /* Numeric type. */
259   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
260     {
261       if (type >= (1 << 16))
262         return 0;
263       *result = type;
264       return 1;
265     }
266   return 0;
267 }
268
269 /* Parse an IP46 address. */
270 uword
271 unformat_ip46_address (unformat_input_t * input, va_list * args)
272 {
273   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
274   ip46_type_t type = va_arg (*args, ip46_type_t);
275   if ((type != IP46_TYPE_IP6) &&
276       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
277     {
278       ip46_address_mask_ip4 (ip46);
279       return 1;
280     }
281   else if ((type != IP46_TYPE_IP4) &&
282            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
283     {
284       return 1;
285     }
286   return 0;
287 }
288
289 /* Parse an IP6 address. */
290 uword
291 unformat_ip6_address (unformat_input_t * input, va_list * args)
292 {
293   ip6_address_t *result = va_arg (*args, ip6_address_t *);
294   u16 hex_quads[8];
295   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
296   uword c, n_colon, double_colon_index;
297
298   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
299   double_colon_index = ARRAY_LEN (hex_quads);
300   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
301     {
302       hex_digit = 16;
303       if (c >= '0' && c <= '9')
304         hex_digit = c - '0';
305       else if (c >= 'a' && c <= 'f')
306         hex_digit = c + 10 - 'a';
307       else if (c >= 'A' && c <= 'F')
308         hex_digit = c + 10 - 'A';
309       else if (c == ':' && n_colon < 2)
310         n_colon++;
311       else
312         {
313           unformat_put_input (input);
314           break;
315         }
316
317       /* Too many hex quads. */
318       if (n_hex_quads >= ARRAY_LEN (hex_quads))
319         return 0;
320
321       if (hex_digit < 16)
322         {
323           hex_quad = (hex_quad << 4) | hex_digit;
324
325           /* Hex quad must fit in 16 bits. */
326           if (n_hex_digits >= 4)
327             return 0;
328
329           n_colon = 0;
330           n_hex_digits++;
331         }
332
333       /* Save position of :: */
334       if (n_colon == 2)
335         {
336           /* More than one :: ? */
337           if (double_colon_index < ARRAY_LEN (hex_quads))
338             return 0;
339           double_colon_index = n_hex_quads;
340         }
341
342       if (n_colon > 0 && n_hex_digits > 0)
343         {
344           hex_quads[n_hex_quads++] = hex_quad;
345           hex_quad = 0;
346           n_hex_digits = 0;
347         }
348     }
349
350   if (n_hex_digits > 0)
351     hex_quads[n_hex_quads++] = hex_quad;
352
353   {
354     word i;
355
356     /* Expand :: to appropriate number of zero hex quads. */
357     if (double_colon_index < ARRAY_LEN (hex_quads))
358       {
359         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
360
361         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
362           hex_quads[n_zero + i] = hex_quads[i];
363
364         for (i = 0; i < n_zero; i++)
365           hex_quads[double_colon_index + i] = 0;
366
367         n_hex_quads = ARRAY_LEN (hex_quads);
368       }
369
370     /* Too few hex quads given. */
371     if (n_hex_quads < ARRAY_LEN (hex_quads))
372       return 0;
373
374     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
375       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
376
377     return 1;
378   }
379 }
380
381 uword
382 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
383 {
384   u32 *r = va_arg (*args, u32 *);
385
386   if (0);
387 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
388   foreach_ipsec_policy_action
389 #undef _
390     else
391     return 0;
392   return 1;
393 }
394
395 u8 *
396 format_ipsec_crypto_alg (u8 * s, va_list * args)
397 {
398   u32 i = va_arg (*args, u32);
399   u8 *t = 0;
400
401   switch (i)
402     {
403 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
404       foreach_ipsec_crypto_alg
405 #undef _
406     default:
407       return format (s, "unknown");
408     }
409   return format (s, "%s", t);
410 }
411
412 u8 *
413 format_ipsec_integ_alg (u8 * s, va_list * args)
414 {
415   u32 i = va_arg (*args, u32);
416   u8 *t = 0;
417
418   switch (i)
419     {
420 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
421       foreach_ipsec_integ_alg
422 #undef _
423     default:
424       return format (s, "unknown");
425     }
426   return format (s, "%s", t);
427 }
428
429 #else /* VPP_API_TEST_BUILTIN == 1 */
430 static uword
431 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
432 {
433   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
434   vnet_main_t *vnm = vnet_get_main ();
435   u32 *result = va_arg (*args, u32 *);
436
437   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
438 }
439
440 static uword
441 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
442 {
443   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
444   vnet_main_t *vnm = vnet_get_main ();
445   u32 *result = va_arg (*args, u32 *);
446
447   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
448 }
449
450 #endif /* VPP_API_TEST_BUILTIN */
451
452 uword
453 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
454 {
455   u32 *r = va_arg (*args, u32 *);
456
457   if (0);
458 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
459   foreach_ipsec_crypto_alg
460 #undef _
461     else
462     return 0;
463   return 1;
464 }
465
466 uword
467 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
468 {
469   u32 *r = va_arg (*args, u32 *);
470
471   if (0);
472 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
473   foreach_ipsec_integ_alg
474 #undef _
475     else
476     return 0;
477   return 1;
478 }
479
480 static uword
481 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
482 {
483   u8 *r = va_arg (*args, u8 *);
484
485   if (unformat (input, "kbps"))
486     *r = SSE2_QOS_RATE_KBPS;
487   else if (unformat (input, "pps"))
488     *r = SSE2_QOS_RATE_PPS;
489   else
490     return 0;
491   return 1;
492 }
493
494 static uword
495 unformat_policer_round_type (unformat_input_t * input, va_list * args)
496 {
497   u8 *r = va_arg (*args, u8 *);
498
499   if (unformat (input, "closest"))
500     *r = SSE2_QOS_ROUND_TO_CLOSEST;
501   else if (unformat (input, "up"))
502     *r = SSE2_QOS_ROUND_TO_UP;
503   else if (unformat (input, "down"))
504     *r = SSE2_QOS_ROUND_TO_DOWN;
505   else
506     return 0;
507   return 1;
508 }
509
510 static uword
511 unformat_policer_type (unformat_input_t * input, va_list * args)
512 {
513   u8 *r = va_arg (*args, u8 *);
514
515   if (unformat (input, "1r2c"))
516     *r = SSE2_QOS_POLICER_TYPE_1R2C;
517   else if (unformat (input, "1r3c"))
518     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
519   else if (unformat (input, "2r3c-2698"))
520     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
521   else if (unformat (input, "2r3c-4115"))
522     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
523   else if (unformat (input, "2r3c-mef5cf1"))
524     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
525   else
526     return 0;
527   return 1;
528 }
529
530 static uword
531 unformat_dscp (unformat_input_t * input, va_list * va)
532 {
533   u8 *r = va_arg (*va, u8 *);
534
535   if (0);
536 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
537   foreach_vnet_dscp
538 #undef _
539     else
540     return 0;
541   return 1;
542 }
543
544 static uword
545 unformat_policer_action_type (unformat_input_t * input, va_list * va)
546 {
547   sse2_qos_pol_action_params_st *a
548     = va_arg (*va, sse2_qos_pol_action_params_st *);
549
550   if (unformat (input, "drop"))
551     a->action_type = SSE2_QOS_ACTION_DROP;
552   else if (unformat (input, "transmit"))
553     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
554   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
555     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
556   else
557     return 0;
558   return 1;
559 }
560
561 static uword
562 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
563 {
564   u32 *r = va_arg (*va, u32 *);
565   u32 tid;
566
567   if (unformat (input, "ip4"))
568     tid = POLICER_CLASSIFY_TABLE_IP4;
569   else if (unformat (input, "ip6"))
570     tid = POLICER_CLASSIFY_TABLE_IP6;
571   else if (unformat (input, "l2"))
572     tid = POLICER_CLASSIFY_TABLE_L2;
573   else
574     return 0;
575
576   *r = tid;
577   return 1;
578 }
579
580 static uword
581 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
582 {
583   u32 *r = va_arg (*va, u32 *);
584   u32 tid;
585
586   if (unformat (input, "ip4"))
587     tid = FLOW_CLASSIFY_TABLE_IP4;
588   else if (unformat (input, "ip6"))
589     tid = FLOW_CLASSIFY_TABLE_IP6;
590   else
591     return 0;
592
593   *r = tid;
594   return 1;
595 }
596
597 #if (VPP_API_TEST_BUILTIN==0)
598
599 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
600 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
601 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
602 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
603
604 uword
605 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
606 {
607   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
608   mfib_itf_attribute_t attr;
609
610   old = *iflags;
611   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
612   {
613     if (unformat (input, mfib_itf_flag_long_names[attr]))
614       *iflags |= (1 << attr);
615   }
616   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
617   {
618     if (unformat (input, mfib_itf_flag_names[attr]))
619       *iflags |= (1 << attr);
620   }
621
622   return (old == *iflags ? 0 : 1);
623 }
624
625 uword
626 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
627 {
628   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
629   mfib_entry_attribute_t attr;
630
631   old = *eflags;
632   FOR_EACH_MFIB_ATTRIBUTE (attr)
633   {
634     if (unformat (input, mfib_flag_long_names[attr]))
635       *eflags |= (1 << attr);
636   }
637   FOR_EACH_MFIB_ATTRIBUTE (attr)
638   {
639     if (unformat (input, mfib_flag_names[attr]))
640       *eflags |= (1 << attr);
641   }
642
643   return (old == *eflags ? 0 : 1);
644 }
645
646 u8 *
647 format_ip4_address (u8 * s, va_list * args)
648 {
649   u8 *a = va_arg (*args, u8 *);
650   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
651 }
652
653 u8 *
654 format_ip6_address (u8 * s, va_list * args)
655 {
656   ip6_address_t *a = va_arg (*args, ip6_address_t *);
657   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
658
659   i_max_n_zero = ARRAY_LEN (a->as_u16);
660   max_n_zeros = 0;
661   i_first_zero = i_max_n_zero;
662   n_zeros = 0;
663   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
664     {
665       u32 is_zero = a->as_u16[i] == 0;
666       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
667         {
668           i_first_zero = i;
669           n_zeros = 0;
670         }
671       n_zeros += is_zero;
672       if ((!is_zero && n_zeros > max_n_zeros)
673           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
674         {
675           i_max_n_zero = i_first_zero;
676           max_n_zeros = n_zeros;
677           i_first_zero = ARRAY_LEN (a->as_u16);
678           n_zeros = 0;
679         }
680     }
681
682   last_double_colon = 0;
683   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
684     {
685       if (i == i_max_n_zero && max_n_zeros > 1)
686         {
687           s = format (s, "::");
688           i += max_n_zeros - 1;
689           last_double_colon = 1;
690         }
691       else
692         {
693           s = format (s, "%s%x",
694                       (last_double_colon || i == 0) ? "" : ":",
695                       clib_net_to_host_u16 (a->as_u16[i]));
696           last_double_colon = 0;
697         }
698     }
699
700   return s;
701 }
702
703 /* Format an IP46 address. */
704 u8 *
705 format_ip46_address (u8 * s, va_list * args)
706 {
707   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
708   ip46_type_t type = va_arg (*args, ip46_type_t);
709   int is_ip4 = 1;
710
711   switch (type)
712     {
713     case IP46_TYPE_ANY:
714       is_ip4 = ip46_address_is_ip4 (ip46);
715       break;
716     case IP46_TYPE_IP4:
717       is_ip4 = 1;
718       break;
719     case IP46_TYPE_IP6:
720       is_ip4 = 0;
721       break;
722     }
723
724   return is_ip4 ?
725     format (s, "%U", format_ip4_address, &ip46->ip4) :
726     format (s, "%U", format_ip6_address, &ip46->ip6);
727 }
728
729 u8 *
730 format_ethernet_address (u8 * s, va_list * args)
731 {
732   u8 *a = va_arg (*args, u8 *);
733
734   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
735                  a[0], a[1], a[2], a[3], a[4], a[5]);
736 }
737 #endif
738
739 static void
740 increment_v4_address (vl_api_ip4_address_t * i)
741 {
742   ip4_address_t *a = (ip4_address_t *) i;
743   u32 v;
744
745   v = ntohl (a->as_u32) + 1;
746   a->as_u32 = ntohl (v);
747 }
748
749 static void
750 increment_v6_address (vl_api_ip6_address_t * i)
751 {
752   ip6_address_t *a = (ip6_address_t *) i;
753   u64 v0, v1;
754
755   v0 = clib_net_to_host_u64 (a->as_u64[0]);
756   v1 = clib_net_to_host_u64 (a->as_u64[1]);
757
758   v1 += 1;
759   if (v1 == 0)
760     v0 += 1;
761   a->as_u64[0] = clib_net_to_host_u64 (v0);
762   a->as_u64[1] = clib_net_to_host_u64 (v1);
763 }
764
765 static void
766 increment_address (vl_api_address_t * a)
767 {
768   if (a->af == ADDRESS_IP4)
769     increment_v4_address (&a->un.ip4);
770   else if (a->af == ADDRESS_IP6)
771     increment_v6_address (&a->un.ip6);
772 }
773
774 static void
775 set_ip4_address (vl_api_address_t * a, u32 v)
776 {
777   if (a->af == ADDRESS_IP4)
778     {
779       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
780       i->as_u32 = v;
781     }
782 }
783
784 void
785 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
786 {
787   if (is_ip4)
788     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
789   else
790     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
791                       sizeof (ip6_address_t));
792 }
793
794 static void
795 increment_mac_address (u8 * mac)
796 {
797   u64 tmp = *((u64 *) mac);
798   tmp = clib_net_to_host_u64 (tmp);
799   tmp += 1 << 16;               /* skip unused (least significant) octets */
800   tmp = clib_host_to_net_u64 (tmp);
801
802   clib_memcpy (mac, &tmp, 6);
803 }
804
805 static void
806 vat_json_object_add_address (vat_json_node_t * node,
807                              const char *str, const vl_api_address_t * addr)
808 {
809   if (ADDRESS_IP6 == addr->af)
810     {
811       struct in6_addr ip6;
812
813       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
814       vat_json_object_add_ip6 (node, str, ip6);
815     }
816   else
817     {
818       struct in_addr ip4;
819
820       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
821       vat_json_object_add_ip4 (node, str, ip4);
822     }
823 }
824
825 static void
826 vat_json_object_add_prefix (vat_json_node_t * node,
827                             const vl_api_prefix_t * prefix)
828 {
829   vat_json_object_add_uint (node, "len", prefix->len);
830   vat_json_object_add_address (node, "address", &prefix->address);
831 }
832
833 static void vl_api_create_loopback_reply_t_handler
834   (vl_api_create_loopback_reply_t * mp)
835 {
836   vat_main_t *vam = &vat_main;
837   i32 retval = ntohl (mp->retval);
838
839   vam->retval = retval;
840   vam->regenerate_interface_table = 1;
841   vam->sw_if_index = ntohl (mp->sw_if_index);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_loopback_reply_t_handler_json
846   (vl_api_create_loopback_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   vat_json_node_t node;
850
851   vat_json_init_object (&node);
852   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
853   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
854
855   vat_json_print (vam->ofp, &node);
856   vat_json_free (&node);
857   vam->retval = ntohl (mp->retval);
858   vam->result_ready = 1;
859 }
860
861 static void vl_api_create_loopback_instance_reply_t_handler
862   (vl_api_create_loopback_instance_reply_t * mp)
863 {
864   vat_main_t *vam = &vat_main;
865   i32 retval = ntohl (mp->retval);
866
867   vam->retval = retval;
868   vam->regenerate_interface_table = 1;
869   vam->sw_if_index = ntohl (mp->sw_if_index);
870   vam->result_ready = 1;
871 }
872
873 static void vl_api_create_loopback_instance_reply_t_handler_json
874   (vl_api_create_loopback_instance_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   vat_json_node_t node;
878
879   vat_json_init_object (&node);
880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
881   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
882
883   vat_json_print (vam->ofp, &node);
884   vat_json_free (&node);
885   vam->retval = ntohl (mp->retval);
886   vam->result_ready = 1;
887 }
888
889 static void vl_api_af_packet_create_reply_t_handler
890   (vl_api_af_packet_create_reply_t * mp)
891 {
892   vat_main_t *vam = &vat_main;
893   i32 retval = ntohl (mp->retval);
894
895   vam->retval = retval;
896   vam->regenerate_interface_table = 1;
897   vam->sw_if_index = ntohl (mp->sw_if_index);
898   vam->result_ready = 1;
899 }
900
901 static void vl_api_af_packet_create_reply_t_handler_json
902   (vl_api_af_packet_create_reply_t * mp)
903 {
904   vat_main_t *vam = &vat_main;
905   vat_json_node_t node;
906
907   vat_json_init_object (&node);
908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
909   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
910
911   vat_json_print (vam->ofp, &node);
912   vat_json_free (&node);
913
914   vam->retval = ntohl (mp->retval);
915   vam->result_ready = 1;
916 }
917
918 static void vl_api_create_vlan_subif_reply_t_handler
919   (vl_api_create_vlan_subif_reply_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   i32 retval = ntohl (mp->retval);
923
924   vam->retval = retval;
925   vam->regenerate_interface_table = 1;
926   vam->sw_if_index = ntohl (mp->sw_if_index);
927   vam->result_ready = 1;
928 }
929
930 static void vl_api_create_vlan_subif_reply_t_handler_json
931   (vl_api_create_vlan_subif_reply_t * mp)
932 {
933   vat_main_t *vam = &vat_main;
934   vat_json_node_t node;
935
936   vat_json_init_object (&node);
937   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
938   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
939
940   vat_json_print (vam->ofp, &node);
941   vat_json_free (&node);
942
943   vam->retval = ntohl (mp->retval);
944   vam->result_ready = 1;
945 }
946
947 static void vl_api_create_subif_reply_t_handler
948   (vl_api_create_subif_reply_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   i32 retval = ntohl (mp->retval);
952
953   vam->retval = retval;
954   vam->regenerate_interface_table = 1;
955   vam->sw_if_index = ntohl (mp->sw_if_index);
956   vam->result_ready = 1;
957 }
958
959 static void vl_api_create_subif_reply_t_handler_json
960   (vl_api_create_subif_reply_t * mp)
961 {
962   vat_main_t *vam = &vat_main;
963   vat_json_node_t node;
964
965   vat_json_init_object (&node);
966   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
967   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
968
969   vat_json_print (vam->ofp, &node);
970   vat_json_free (&node);
971
972   vam->retval = ntohl (mp->retval);
973   vam->result_ready = 1;
974 }
975
976 static void vl_api_interface_name_renumber_reply_t_handler
977   (vl_api_interface_name_renumber_reply_t * mp)
978 {
979   vat_main_t *vam = &vat_main;
980   i32 retval = ntohl (mp->retval);
981
982   vam->retval = retval;
983   vam->regenerate_interface_table = 1;
984   vam->result_ready = 1;
985 }
986
987 static void vl_api_interface_name_renumber_reply_t_handler_json
988   (vl_api_interface_name_renumber_reply_t * mp)
989 {
990   vat_main_t *vam = &vat_main;
991   vat_json_node_t node;
992
993   vat_json_init_object (&node);
994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
995
996   vat_json_print (vam->ofp, &node);
997   vat_json_free (&node);
998
999   vam->retval = ntohl (mp->retval);
1000   vam->result_ready = 1;
1001 }
1002
1003 /*
1004  * Special-case: build the interface table, maintain
1005  * the next loopback sw_if_index vbl.
1006  */
1007 static void vl_api_sw_interface_details_t_handler
1008   (vl_api_sw_interface_details_t * mp)
1009 {
1010   vat_main_t *vam = &vat_main;
1011   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1012
1013   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1014                 ntohl (mp->sw_if_index));
1015
1016   /* In sub interface case, fill the sub interface table entry */
1017   if (mp->sw_if_index != mp->sup_sw_if_index)
1018     {
1019       sw_interface_subif_t *sub = NULL;
1020
1021       vec_add2 (vam->sw_if_subif_table, sub, 1);
1022
1023       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1024       strncpy ((char *) sub->interface_name, (char *) s,
1025                vec_len (sub->interface_name));
1026       sub->sw_if_index = ntohl (mp->sw_if_index);
1027       sub->sub_id = ntohl (mp->sub_id);
1028
1029       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1030
1031       sub->sub_number_of_tags = mp->sub_number_of_tags;
1032       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1033       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1034
1035       /* vlan tag rewrite */
1036       sub->vtr_op = ntohl (mp->vtr_op);
1037       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1038       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1039       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1040     }
1041 }
1042
1043 static void vl_api_sw_interface_details_t_handler_json
1044   (vl_api_sw_interface_details_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   vat_json_node_t *node = NULL;
1048
1049   if (VAT_JSON_ARRAY != vam->json_tree.type)
1050     {
1051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1052       vat_json_init_array (&vam->json_tree);
1053     }
1054   node = vat_json_array_add (&vam->json_tree);
1055
1056   vat_json_init_object (node);
1057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1058   vat_json_object_add_uint (node, "sup_sw_if_index",
1059                             ntohl (mp->sup_sw_if_index));
1060   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1061                              sizeof (mp->l2_address));
1062   vat_json_object_add_string_copy (node, "interface_name",
1063                                    mp->interface_name);
1064   vat_json_object_add_string_copy (node, "interface_dev_type",
1065                                    mp->interface_dev_type);
1066   vat_json_object_add_uint (node, "flags", mp->flags);
1067   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1068   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1069   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1070   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1071   vat_json_object_add_uint (node, "sub_number_of_tags",
1072                             mp->sub_number_of_tags);
1073   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1074                             ntohs (mp->sub_outer_vlan_id));
1075   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1076                             ntohs (mp->sub_inner_vlan_id));
1077   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1078   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1079   vat_json_object_add_uint (node, "vtr_push_dot1q",
1080                             ntohl (mp->vtr_push_dot1q));
1081   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1082   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1083   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1084     {
1085       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1086                                        format (0, "%U",
1087                                                format_ethernet_address,
1088                                                &mp->b_dmac));
1089       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1090                                        format (0, "%U",
1091                                                format_ethernet_address,
1092                                                &mp->b_smac));
1093       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1094       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1095     }
1096 }
1097
1098 #if VPP_API_TEST_BUILTIN == 0
1099 static void vl_api_sw_interface_event_t_handler
1100   (vl_api_sw_interface_event_t * mp)
1101 {
1102   vat_main_t *vam = &vat_main;
1103   if (vam->interface_event_display)
1104     errmsg ("interface flags: sw_if_index %d %s %s",
1105             ntohl (mp->sw_if_index),
1106             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1107             "admin-up" : "admin-down",
1108             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1109             "link-up" : "link-down");
1110 }
1111 #endif
1112
1113 __clib_unused static void
1114 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1115 {
1116   /* JSON output not supported */
1117 }
1118
1119 static void
1120 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1121 {
1122   vat_main_t *vam = &vat_main;
1123   i32 retval = ntohl (mp->retval);
1124
1125   vam->retval = retval;
1126   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void
1131 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   vat_json_node_t node;
1135   void *oldheap;
1136   u8 *reply;
1137
1138   vat_json_init_object (&node);
1139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1140   vat_json_object_add_uint (&node, "reply_in_shmem",
1141                             ntohl (mp->reply_in_shmem));
1142   /* Toss the shared-memory original... */
1143   oldheap = vl_msg_push_heap ();
1144
1145   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1146   vec_free (reply);
1147
1148   vl_msg_pop_heap (oldheap);
1149
1150   vat_json_print (vam->ofp, &node);
1151   vat_json_free (&node);
1152
1153   vam->retval = ntohl (mp->retval);
1154   vam->result_ready = 1;
1155 }
1156
1157 static void
1158 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1159 {
1160   vat_main_t *vam = &vat_main;
1161   i32 retval = ntohl (mp->retval);
1162
1163   vec_reset_length (vam->cmd_reply);
1164
1165   vam->retval = retval;
1166   if (retval == 0)
1167     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1168   vam->result_ready = 1;
1169 }
1170
1171 static void
1172 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   vat_json_node_t node;
1176   u8 *reply = 0;                /* reply vector */
1177
1178   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1179   vec_reset_length (vam->cmd_reply);
1180
1181   vat_json_init_object (&node);
1182   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1183   vat_json_object_add_string_copy (&node, "reply", reply);
1184
1185   vat_json_print (vam->ofp, &node);
1186   vat_json_free (&node);
1187   vec_free (reply);
1188
1189   vam->retval = ntohl (mp->retval);
1190   vam->result_ready = 1;
1191 }
1192
1193 static void vl_api_classify_add_del_table_reply_t_handler
1194   (vl_api_classify_add_del_table_reply_t * mp)
1195 {
1196   vat_main_t *vam = &vat_main;
1197   i32 retval = ntohl (mp->retval);
1198   if (vam->async_mode)
1199     {
1200       vam->async_errors += (retval < 0);
1201     }
1202   else
1203     {
1204       vam->retval = retval;
1205       if (retval == 0 &&
1206           ((mp->new_table_index != 0xFFFFFFFF) ||
1207            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1208            (mp->match_n_vectors != 0xFFFFFFFF)))
1209         /*
1210          * Note: this is just barely thread-safe, depends on
1211          * the main thread spinning waiting for an answer...
1212          */
1213         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1214                 ntohl (mp->new_table_index),
1215                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1216       vam->result_ready = 1;
1217     }
1218 }
1219
1220 static void vl_api_classify_add_del_table_reply_t_handler_json
1221   (vl_api_classify_add_del_table_reply_t * mp)
1222 {
1223   vat_main_t *vam = &vat_main;
1224   vat_json_node_t node;
1225
1226   vat_json_init_object (&node);
1227   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1228   vat_json_object_add_uint (&node, "new_table_index",
1229                             ntohl (mp->new_table_index));
1230   vat_json_object_add_uint (&node, "skip_n_vectors",
1231                             ntohl (mp->skip_n_vectors));
1232   vat_json_object_add_uint (&node, "match_n_vectors",
1233                             ntohl (mp->match_n_vectors));
1234
1235   vat_json_print (vam->ofp, &node);
1236   vat_json_free (&node);
1237
1238   vam->retval = ntohl (mp->retval);
1239   vam->result_ready = 1;
1240 }
1241
1242 static void vl_api_get_node_index_reply_t_handler
1243   (vl_api_get_node_index_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   i32 retval = ntohl (mp->retval);
1247   if (vam->async_mode)
1248     {
1249       vam->async_errors += (retval < 0);
1250     }
1251   else
1252     {
1253       vam->retval = retval;
1254       if (retval == 0)
1255         errmsg ("node index %d", ntohl (mp->node_index));
1256       vam->result_ready = 1;
1257     }
1258 }
1259
1260 static void vl_api_get_node_index_reply_t_handler_json
1261   (vl_api_get_node_index_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   vat_json_node_t node;
1265
1266   vat_json_init_object (&node);
1267   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1268   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1269
1270   vat_json_print (vam->ofp, &node);
1271   vat_json_free (&node);
1272
1273   vam->retval = ntohl (mp->retval);
1274   vam->result_ready = 1;
1275 }
1276
1277 static void vl_api_get_next_index_reply_t_handler
1278   (vl_api_get_next_index_reply_t * mp)
1279 {
1280   vat_main_t *vam = &vat_main;
1281   i32 retval = ntohl (mp->retval);
1282   if (vam->async_mode)
1283     {
1284       vam->async_errors += (retval < 0);
1285     }
1286   else
1287     {
1288       vam->retval = retval;
1289       if (retval == 0)
1290         errmsg ("next node index %d", ntohl (mp->next_index));
1291       vam->result_ready = 1;
1292     }
1293 }
1294
1295 static void vl_api_get_next_index_reply_t_handler_json
1296   (vl_api_get_next_index_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   vat_json_node_t node;
1300
1301   vat_json_init_object (&node);
1302   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1303   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1304
1305   vat_json_print (vam->ofp, &node);
1306   vat_json_free (&node);
1307
1308   vam->retval = ntohl (mp->retval);
1309   vam->result_ready = 1;
1310 }
1311
1312 static void vl_api_add_node_next_reply_t_handler
1313   (vl_api_add_node_next_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   i32 retval = ntohl (mp->retval);
1317   if (vam->async_mode)
1318     {
1319       vam->async_errors += (retval < 0);
1320     }
1321   else
1322     {
1323       vam->retval = retval;
1324       if (retval == 0)
1325         errmsg ("next index %d", ntohl (mp->next_index));
1326       vam->result_ready = 1;
1327     }
1328 }
1329
1330 static void vl_api_add_node_next_reply_t_handler_json
1331   (vl_api_add_node_next_reply_t * mp)
1332 {
1333   vat_main_t *vam = &vat_main;
1334   vat_json_node_t node;
1335
1336   vat_json_init_object (&node);
1337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1338   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1339
1340   vat_json_print (vam->ofp, &node);
1341   vat_json_free (&node);
1342
1343   vam->retval = ntohl (mp->retval);
1344   vam->result_ready = 1;
1345 }
1346
1347 static void vl_api_show_version_reply_t_handler
1348   (vl_api_show_version_reply_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   i32 retval = ntohl (mp->retval);
1352
1353   if (retval >= 0)
1354     {
1355       errmsg ("        program: %s", mp->program);
1356       errmsg ("        version: %s", mp->version);
1357       errmsg ("     build date: %s", mp->build_date);
1358       errmsg ("build directory: %s", mp->build_directory);
1359     }
1360   vam->retval = retval;
1361   vam->result_ready = 1;
1362 }
1363
1364 static void vl_api_show_version_reply_t_handler_json
1365   (vl_api_show_version_reply_t * mp)
1366 {
1367   vat_main_t *vam = &vat_main;
1368   vat_json_node_t node;
1369
1370   vat_json_init_object (&node);
1371   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1372   vat_json_object_add_string_copy (&node, "program", mp->program);
1373   vat_json_object_add_string_copy (&node, "version", mp->version);
1374   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1375   vat_json_object_add_string_copy (&node, "build_directory",
1376                                    mp->build_directory);
1377
1378   vat_json_print (vam->ofp, &node);
1379   vat_json_free (&node);
1380
1381   vam->retval = ntohl (mp->retval);
1382   vam->result_ready = 1;
1383 }
1384
1385 static void vl_api_show_threads_reply_t_handler
1386   (vl_api_show_threads_reply_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   i32 retval = ntohl (mp->retval);
1390   int i, count = 0;
1391
1392   if (retval >= 0)
1393     count = ntohl (mp->count);
1394
1395   for (i = 0; i < count; i++)
1396     print (vam->ofp,
1397            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1398            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1399            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1400            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1401            ntohl (mp->thread_data[i].cpu_socket));
1402
1403   vam->retval = retval;
1404   vam->result_ready = 1;
1405 }
1406
1407 static void vl_api_show_threads_reply_t_handler_json
1408   (vl_api_show_threads_reply_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   vat_json_node_t node;
1412   vl_api_thread_data_t *td;
1413   i32 retval = ntohl (mp->retval);
1414   int i, count = 0;
1415
1416   if (retval >= 0)
1417     count = ntohl (mp->count);
1418
1419   vat_json_init_object (&node);
1420   vat_json_object_add_int (&node, "retval", retval);
1421   vat_json_object_add_uint (&node, "count", count);
1422
1423   for (i = 0; i < count; i++)
1424     {
1425       td = &mp->thread_data[i];
1426       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1427       vat_json_object_add_string_copy (&node, "name", td->name);
1428       vat_json_object_add_string_copy (&node, "type", td->type);
1429       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1430       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1431       vat_json_object_add_int (&node, "core", ntohl (td->id));
1432       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1433     }
1434
1435   vat_json_print (vam->ofp, &node);
1436   vat_json_free (&node);
1437
1438   vam->retval = retval;
1439   vam->result_ready = 1;
1440 }
1441
1442 static int
1443 api_show_threads (vat_main_t * vam)
1444 {
1445   vl_api_show_threads_t *mp;
1446   int ret;
1447
1448   print (vam->ofp,
1449          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1450          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1451
1452   M (SHOW_THREADS, mp);
1453
1454   S (mp);
1455   W (ret);
1456   return ret;
1457 }
1458
1459 static void
1460 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1461 {
1462   u32 n_macs = ntohl (mp->n_macs);
1463   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1464           ntohl (mp->pid), mp->client_index, n_macs);
1465   int i;
1466   for (i = 0; i < n_macs; i++)
1467     {
1468       vl_api_mac_entry_t *mac = &mp->mac[i];
1469       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1470               i + 1, ntohl (mac->sw_if_index),
1471               format_ethernet_address, mac->mac_addr, mac->action);
1472       if (i == 1000)
1473         break;
1474     }
1475 }
1476
1477 static void
1478 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1479 {
1480   /* JSON output not supported */
1481 }
1482
1483 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1484 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1485
1486 /*
1487  * Special-case: build the bridge domain table, maintain
1488  * the next bd id vbl.
1489  */
1490 static void vl_api_bridge_domain_details_t_handler
1491   (vl_api_bridge_domain_details_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1495   int i;
1496
1497   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1498          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1499
1500   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1501          ntohl (mp->bd_id), mp->learn, mp->forward,
1502          mp->flood, ntohl (mp->bvi_sw_if_index),
1503          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1504
1505   if (n_sw_ifs)
1506     {
1507       vl_api_bridge_domain_sw_if_t *sw_ifs;
1508       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1509              "Interface Name");
1510
1511       sw_ifs = mp->sw_if_details;
1512       for (i = 0; i < n_sw_ifs; i++)
1513         {
1514           u8 *sw_if_name = 0;
1515           u32 sw_if_index;
1516           hash_pair_t *p;
1517
1518           sw_if_index = ntohl (sw_ifs->sw_if_index);
1519
1520           /* *INDENT-OFF* */
1521           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1522                              ({
1523                                if ((u32) p->value[0] == sw_if_index)
1524                                  {
1525                                    sw_if_name = (u8 *)(p->key);
1526                                    break;
1527                                  }
1528                              }));
1529           /* *INDENT-ON* */
1530           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1531                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1532                  "sw_if_index not found!");
1533
1534           sw_ifs++;
1535         }
1536     }
1537 }
1538
1539 static void vl_api_bridge_domain_details_t_handler_json
1540   (vl_api_bridge_domain_details_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   vat_json_node_t *node, *array = NULL;
1544   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1545
1546   if (VAT_JSON_ARRAY != vam->json_tree.type)
1547     {
1548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1549       vat_json_init_array (&vam->json_tree);
1550     }
1551   node = vat_json_array_add (&vam->json_tree);
1552
1553   vat_json_init_object (node);
1554   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1555   vat_json_object_add_uint (node, "flood", mp->flood);
1556   vat_json_object_add_uint (node, "forward", mp->forward);
1557   vat_json_object_add_uint (node, "learn", mp->learn);
1558   vat_json_object_add_uint (node, "bvi_sw_if_index",
1559                             ntohl (mp->bvi_sw_if_index));
1560   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1561   array = vat_json_object_add (node, "sw_if");
1562   vat_json_init_array (array);
1563
1564
1565
1566   if (n_sw_ifs)
1567     {
1568       vl_api_bridge_domain_sw_if_t *sw_ifs;
1569       int i;
1570
1571       sw_ifs = mp->sw_if_details;
1572       for (i = 0; i < n_sw_ifs; i++)
1573         {
1574           node = vat_json_array_add (array);
1575           vat_json_init_object (node);
1576           vat_json_object_add_uint (node, "sw_if_index",
1577                                     ntohl (sw_ifs->sw_if_index));
1578           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1579           sw_ifs++;
1580         }
1581     }
1582 }
1583
1584 static void vl_api_control_ping_reply_t_handler
1585   (vl_api_control_ping_reply_t * mp)
1586 {
1587   vat_main_t *vam = &vat_main;
1588   i32 retval = ntohl (mp->retval);
1589   if (vam->async_mode)
1590     {
1591       vam->async_errors += (retval < 0);
1592     }
1593   else
1594     {
1595       vam->retval = retval;
1596       vam->result_ready = 1;
1597     }
1598   if (vam->socket_client_main)
1599     vam->socket_client_main->control_pings_outstanding--;
1600 }
1601
1602 static void vl_api_control_ping_reply_t_handler_json
1603   (vl_api_control_ping_reply_t * mp)
1604 {
1605   vat_main_t *vam = &vat_main;
1606   i32 retval = ntohl (mp->retval);
1607
1608   if (VAT_JSON_NONE != vam->json_tree.type)
1609     {
1610       vat_json_print (vam->ofp, &vam->json_tree);
1611       vat_json_free (&vam->json_tree);
1612       vam->json_tree.type = VAT_JSON_NONE;
1613     }
1614   else
1615     {
1616       /* just print [] */
1617       vat_json_init_array (&vam->json_tree);
1618       vat_json_print (vam->ofp, &vam->json_tree);
1619       vam->json_tree.type = VAT_JSON_NONE;
1620     }
1621
1622   vam->retval = retval;
1623   vam->result_ready = 1;
1624 }
1625
1626 static void
1627   vl_api_bridge_domain_set_mac_age_reply_t_handler
1628   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1629 {
1630   vat_main_t *vam = &vat_main;
1631   i32 retval = ntohl (mp->retval);
1632   if (vam->async_mode)
1633     {
1634       vam->async_errors += (retval < 0);
1635     }
1636   else
1637     {
1638       vam->retval = retval;
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1644   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651
1652   vat_json_print (vam->ofp, &node);
1653   vat_json_free (&node);
1654
1655   vam->retval = ntohl (mp->retval);
1656   vam->result_ready = 1;
1657 }
1658
1659 static void
1660 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   i32 retval = ntohl (mp->retval);
1664   if (vam->async_mode)
1665     {
1666       vam->async_errors += (retval < 0);
1667     }
1668   else
1669     {
1670       vam->retval = retval;
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_l2_flags_reply_t_handler_json
1676   (vl_api_l2_flags_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1684                             ntohl (mp->resulting_feature_bitmap));
1685
1686   vat_json_print (vam->ofp, &node);
1687   vat_json_free (&node);
1688
1689   vam->retval = ntohl (mp->retval);
1690   vam->result_ready = 1;
1691 }
1692
1693 static void vl_api_bridge_flags_reply_t_handler
1694   (vl_api_bridge_flags_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   i32 retval = ntohl (mp->retval);
1698   if (vam->async_mode)
1699     {
1700       vam->async_errors += (retval < 0);
1701     }
1702   else
1703     {
1704       vam->retval = retval;
1705       vam->result_ready = 1;
1706     }
1707 }
1708
1709 static void vl_api_bridge_flags_reply_t_handler_json
1710   (vl_api_bridge_flags_reply_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t node;
1714
1715   vat_json_init_object (&node);
1716   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1717   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1718                             ntohl (mp->resulting_feature_bitmap));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725 }
1726
1727 static void
1728 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   i32 retval = ntohl (mp->retval);
1732   if (vam->async_mode)
1733     {
1734       vam->async_errors += (retval < 0);
1735     }
1736   else
1737     {
1738       vam->retval = retval;
1739       vam->sw_if_index = ntohl (mp->sw_if_index);
1740       vam->result_ready = 1;
1741     }
1742
1743 }
1744
1745 static void vl_api_tap_create_v2_reply_t_handler_json
1746   (vl_api_tap_create_v2_reply_t * mp)
1747 {
1748   vat_main_t *vam = &vat_main;
1749   vat_json_node_t node;
1750
1751   vat_json_init_object (&node);
1752   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1753   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1754
1755   vat_json_print (vam->ofp, &node);
1756   vat_json_free (&node);
1757
1758   vam->retval = ntohl (mp->retval);
1759   vam->result_ready = 1;
1760
1761 }
1762
1763 static void
1764 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1765 {
1766   vat_main_t *vam = &vat_main;
1767   i32 retval = ntohl (mp->retval);
1768   if (vam->async_mode)
1769     {
1770       vam->async_errors += (retval < 0);
1771     }
1772   else
1773     {
1774       vam->retval = retval;
1775       vam->result_ready = 1;
1776     }
1777 }
1778
1779 static void vl_api_tap_delete_v2_reply_t_handler_json
1780   (vl_api_tap_delete_v2_reply_t * mp)
1781 {
1782   vat_main_t *vam = &vat_main;
1783   vat_json_node_t node;
1784
1785   vat_json_init_object (&node);
1786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1787
1788   vat_json_print (vam->ofp, &node);
1789   vat_json_free (&node);
1790
1791   vam->retval = ntohl (mp->retval);
1792   vam->result_ready = 1;
1793 }
1794
1795 static void
1796 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1797                                           mp)
1798 {
1799   vat_main_t *vam = &vat_main;
1800   i32 retval = ntohl (mp->retval);
1801   if (vam->async_mode)
1802     {
1803       vam->async_errors += (retval < 0);
1804     }
1805   else
1806     {
1807       vam->retval = retval;
1808       vam->sw_if_index = ntohl (mp->sw_if_index);
1809       vam->result_ready = 1;
1810     }
1811 }
1812
1813 static void vl_api_virtio_pci_create_reply_t_handler_json
1814   (vl_api_virtio_pci_create_reply_t * mp)
1815 {
1816   vat_main_t *vam = &vat_main;
1817   vat_json_node_t node;
1818
1819   vat_json_init_object (&node);
1820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1822
1823   vat_json_print (vam->ofp, &node);
1824   vat_json_free (&node);
1825
1826   vam->retval = ntohl (mp->retval);
1827   vam->result_ready = 1;
1828
1829 }
1830
1831 static void
1832 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1833                                           mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->result_ready = 1;
1845     }
1846 }
1847
1848 static void vl_api_virtio_pci_delete_reply_t_handler_json
1849   (vl_api_virtio_pci_delete_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   vat_json_node_t node;
1853
1854   vat_json_init_object (&node);
1855   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1856
1857   vat_json_print (vam->ofp, &node);
1858   vat_json_free (&node);
1859
1860   vam->retval = ntohl (mp->retval);
1861   vam->result_ready = 1;
1862 }
1863
1864 static void
1865 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   i32 retval = ntohl (mp->retval);
1869
1870   if (vam->async_mode)
1871     {
1872       vam->async_errors += (retval < 0);
1873     }
1874   else
1875     {
1876       vam->retval = retval;
1877       vam->sw_if_index = ntohl (mp->sw_if_index);
1878       vam->result_ready = 1;
1879     }
1880 }
1881
1882 static void vl_api_bond_create_reply_t_handler_json
1883   (vl_api_bond_create_reply_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   vat_json_node_t node;
1887
1888   vat_json_init_object (&node);
1889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1890   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1891
1892   vat_json_print (vam->ofp, &node);
1893   vat_json_free (&node);
1894
1895   vam->retval = ntohl (mp->retval);
1896   vam->result_ready = 1;
1897 }
1898
1899 static void
1900 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   i32 retval = ntohl (mp->retval);
1904
1905   if (vam->async_mode)
1906     {
1907       vam->async_errors += (retval < 0);
1908     }
1909   else
1910     {
1911       vam->retval = retval;
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_bond_delete_reply_t_handler_json
1917   (vl_api_bond_delete_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921
1922   vat_json_init_object (&node);
1923   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1924
1925   vat_json_print (vam->ofp, &node);
1926   vat_json_free (&node);
1927
1928   vam->retval = ntohl (mp->retval);
1929   vam->result_ready = 1;
1930 }
1931
1932 static void
1933 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
1934 {
1935   vat_main_t *vam = &vat_main;
1936   i32 retval = ntohl (mp->retval);
1937
1938   if (vam->async_mode)
1939     {
1940       vam->async_errors += (retval < 0);
1941     }
1942   else
1943     {
1944       vam->retval = retval;
1945       vam->result_ready = 1;
1946     }
1947 }
1948
1949 static void vl_api_bond_add_member_reply_t_handler_json
1950   (vl_api_bond_add_member_reply_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953   vat_json_node_t node;
1954
1955   vat_json_init_object (&node);
1956   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1957
1958   vat_json_print (vam->ofp, &node);
1959   vat_json_free (&node);
1960
1961   vam->retval = ntohl (mp->retval);
1962   vam->result_ready = 1;
1963 }
1964
1965 static void
1966 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
1967                                            mp)
1968 {
1969   vat_main_t *vam = &vat_main;
1970   i32 retval = ntohl (mp->retval);
1971
1972   if (vam->async_mode)
1973     {
1974       vam->async_errors += (retval < 0);
1975     }
1976   else
1977     {
1978       vam->retval = retval;
1979       vam->result_ready = 1;
1980     }
1981 }
1982
1983 static void vl_api_bond_detach_member_reply_t_handler_json
1984   (vl_api_bond_detach_member_reply_t * mp)
1985 {
1986   vat_main_t *vam = &vat_main;
1987   vat_json_node_t node;
1988
1989   vat_json_init_object (&node);
1990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1991
1992   vat_json_print (vam->ofp, &node);
1993   vat_json_free (&node);
1994
1995   vam->retval = ntohl (mp->retval);
1996   vam->result_ready = 1;
1997 }
1998
1999 static int
2000 api_sw_interface_set_bond_weight (vat_main_t * vam)
2001 {
2002   unformat_input_t *i = vam->input;
2003   vl_api_sw_interface_set_bond_weight_t *mp;
2004   u32 sw_if_index = ~0;
2005   u32 weight = 0;
2006   u8 weight_enter = 0;
2007   int ret;
2008
2009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2010     {
2011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2012         ;
2013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2014         ;
2015       else if (unformat (i, "weight %u", &weight))
2016         weight_enter = 1;
2017       else
2018         break;
2019     }
2020
2021   if (sw_if_index == ~0)
2022     {
2023       errmsg ("missing interface name or sw_if_index");
2024       return -99;
2025     }
2026   if (weight_enter == 0)
2027     {
2028       errmsg ("missing valid weight");
2029       return -99;
2030     }
2031
2032   /* Construct the API message */
2033   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2034   mp->sw_if_index = ntohl (sw_if_index);
2035   mp->weight = ntohl (weight);
2036
2037   S (mp);
2038   W (ret);
2039   return ret;
2040 }
2041
2042 static void vl_api_sw_bond_interface_details_t_handler
2043   (vl_api_sw_bond_interface_details_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046
2047   print (vam->ofp,
2048          "%-16s %-12d %-12U %-13U %-14u %-14u",
2049          mp->interface_name, ntohl (mp->sw_if_index),
2050          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2051          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2052 }
2053
2054 static void vl_api_sw_bond_interface_details_t_handler_json
2055   (vl_api_sw_bond_interface_details_t * mp)
2056 {
2057   vat_main_t *vam = &vat_main;
2058   vat_json_node_t *node = NULL;
2059
2060   if (VAT_JSON_ARRAY != vam->json_tree.type)
2061     {
2062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2063       vat_json_init_array (&vam->json_tree);
2064     }
2065   node = vat_json_array_add (&vam->json_tree);
2066
2067   vat_json_init_object (node);
2068   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2069   vat_json_object_add_string_copy (node, "interface_name",
2070                                    mp->interface_name);
2071   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2072   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2073   vat_json_object_add_uint (node, "active_members",
2074                             ntohl (mp->active_members));
2075   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2076 }
2077
2078 static int
2079 api_sw_bond_interface_dump (vat_main_t * vam)
2080 {
2081   unformat_input_t *i = vam->input;
2082   vl_api_sw_bond_interface_dump_t *mp;
2083   vl_api_control_ping_t *mp_ping;
2084   int ret;
2085   u32 sw_if_index = ~0;
2086
2087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2088     {
2089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2090         ;
2091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2092         ;
2093       else
2094         break;
2095     }
2096
2097   print (vam->ofp,
2098          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2099          "interface name", "sw_if_index", "mode", "load balance",
2100          "active members", "members");
2101
2102   /* Get list of bond interfaces */
2103   M (SW_BOND_INTERFACE_DUMP, mp);
2104   mp->sw_if_index = ntohl (sw_if_index);
2105   S (mp);
2106
2107   /* Use a control ping for synchronization */
2108   MPING (CONTROL_PING, mp_ping);
2109   S (mp_ping);
2110
2111   W (ret);
2112   return ret;
2113 }
2114
2115 static void vl_api_sw_member_interface_details_t_handler
2116   (vl_api_sw_member_interface_details_t * mp)
2117 {
2118   vat_main_t *vam = &vat_main;
2119
2120   print (vam->ofp,
2121          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2122          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2123          ntohl (mp->weight), mp->is_local_numa);
2124 }
2125
2126 static void vl_api_sw_member_interface_details_t_handler_json
2127   (vl_api_sw_member_interface_details_t * mp)
2128 {
2129   vat_main_t *vam = &vat_main;
2130   vat_json_node_t *node = NULL;
2131
2132   if (VAT_JSON_ARRAY != vam->json_tree.type)
2133     {
2134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2135       vat_json_init_array (&vam->json_tree);
2136     }
2137   node = vat_json_array_add (&vam->json_tree);
2138
2139   vat_json_init_object (node);
2140   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2141   vat_json_object_add_string_copy (node, "interface_name",
2142                                    mp->interface_name);
2143   vat_json_object_add_uint (node, "passive", mp->is_passive);
2144   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2145   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2146   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2147 }
2148
2149 static int
2150 api_sw_member_interface_dump (vat_main_t * vam)
2151 {
2152   unformat_input_t *i = vam->input;
2153   vl_api_sw_member_interface_dump_t *mp;
2154   vl_api_control_ping_t *mp_ping;
2155   u32 sw_if_index = ~0;
2156   u8 sw_if_index_set = 0;
2157   int ret;
2158
2159   /* Parse args required to build the message */
2160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2161     {
2162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2163         sw_if_index_set = 1;
2164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2165         sw_if_index_set = 1;
2166       else
2167         break;
2168     }
2169
2170   if (sw_if_index_set == 0)
2171     {
2172       errmsg ("missing vpp interface name. ");
2173       return -99;
2174     }
2175
2176   print (vam->ofp,
2177          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2178          "member interface name", "sw_if_index", "passive", "long_timeout",
2179          "weight", "local numa");
2180
2181   /* Get list of bond interfaces */
2182   M (SW_MEMBER_INTERFACE_DUMP, mp);
2183   mp->sw_if_index = ntohl (sw_if_index);
2184   S (mp);
2185
2186   /* Use a control ping for synchronization */
2187   MPING (CONTROL_PING, mp_ping);
2188   S (mp_ping);
2189
2190   W (ret);
2191   return ret;
2192 }
2193
2194 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2195   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2196 {
2197   vat_main_t *vam = &vat_main;
2198   i32 retval = ntohl (mp->retval);
2199   if (vam->async_mode)
2200     {
2201       vam->async_errors += (retval < 0);
2202     }
2203   else
2204     {
2205       vam->retval = retval;
2206       vam->sw_if_index = ntohl (mp->sw_if_index);
2207       vam->result_ready = 1;
2208     }
2209   vam->regenerate_interface_table = 1;
2210 }
2211
2212 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2213   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2214 {
2215   vat_main_t *vam = &vat_main;
2216   vat_json_node_t node;
2217
2218   vat_json_init_object (&node);
2219   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2220   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2221                             ntohl (mp->sw_if_index));
2222
2223   vat_json_print (vam->ofp, &node);
2224   vat_json_free (&node);
2225
2226   vam->retval = ntohl (mp->retval);
2227   vam->result_ready = 1;
2228 }
2229
2230 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2231   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   i32 retval = ntohl (mp->retval);
2235   if (vam->async_mode)
2236     {
2237       vam->async_errors += (retval < 0);
2238     }
2239   else
2240     {
2241       vam->retval = retval;
2242       vam->sw_if_index = ntohl (mp->sw_if_index);
2243       vam->result_ready = 1;
2244     }
2245 }
2246
2247 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2248   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   vat_json_node_t node;
2252
2253   vat_json_init_object (&node);
2254   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2255   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2256
2257   vat_json_print (vam->ofp, &node);
2258   vat_json_free (&node);
2259
2260   vam->retval = ntohl (mp->retval);
2261   vam->result_ready = 1;
2262 }
2263
2264 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2265   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   i32 retval = ntohl (mp->retval);
2269   if (vam->async_mode)
2270     {
2271       vam->async_errors += (retval < 0);
2272     }
2273   else
2274     {
2275       vam->retval = retval;
2276       vam->result_ready = 1;
2277     }
2278 }
2279
2280 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2281   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2282 {
2283   vat_main_t *vam = &vat_main;
2284   vat_json_node_t node;
2285
2286   vat_json_init_object (&node);
2287   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2288   vat_json_object_add_uint (&node, "fwd_entry_index",
2289                             clib_net_to_host_u32 (mp->fwd_entry_index));
2290
2291   vat_json_print (vam->ofp, &node);
2292   vat_json_free (&node);
2293
2294   vam->retval = ntohl (mp->retval);
2295   vam->result_ready = 1;
2296 }
2297
2298 u8 *
2299 format_lisp_transport_protocol (u8 * s, va_list * args)
2300 {
2301   u32 proto = va_arg (*args, u32);
2302
2303   switch (proto)
2304     {
2305     case 1:
2306       return format (s, "udp");
2307     case 2:
2308       return format (s, "api");
2309     default:
2310       return 0;
2311     }
2312   return 0;
2313 }
2314
2315 static void vl_api_one_get_transport_protocol_reply_t_handler
2316   (vl_api_one_get_transport_protocol_reply_t * mp)
2317 {
2318   vat_main_t *vam = &vat_main;
2319   i32 retval = ntohl (mp->retval);
2320   if (vam->async_mode)
2321     {
2322       vam->async_errors += (retval < 0);
2323     }
2324   else
2325     {
2326       u32 proto = mp->protocol;
2327       print (vam->ofp, "Transport protocol: %U",
2328              format_lisp_transport_protocol, proto);
2329       vam->retval = retval;
2330       vam->result_ready = 1;
2331     }
2332 }
2333
2334 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2335   (vl_api_one_get_transport_protocol_reply_t * mp)
2336 {
2337   vat_main_t *vam = &vat_main;
2338   vat_json_node_t node;
2339   u8 *s;
2340
2341   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2342   vec_add1 (s, 0);
2343
2344   vat_json_init_object (&node);
2345   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2346   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2347
2348   vec_free (s);
2349   vat_json_print (vam->ofp, &node);
2350   vat_json_free (&node);
2351
2352   vam->retval = ntohl (mp->retval);
2353   vam->result_ready = 1;
2354 }
2355
2356 static void vl_api_one_add_del_locator_set_reply_t_handler
2357   (vl_api_one_add_del_locator_set_reply_t * mp)
2358 {
2359   vat_main_t *vam = &vat_main;
2360   i32 retval = ntohl (mp->retval);
2361   if (vam->async_mode)
2362     {
2363       vam->async_errors += (retval < 0);
2364     }
2365   else
2366     {
2367       vam->retval = retval;
2368       vam->result_ready = 1;
2369     }
2370 }
2371
2372 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2373   (vl_api_one_add_del_locator_set_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2390   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404   vam->regenerate_interface_table = 1;
2405 }
2406
2407 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2408   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   vat_json_node_t node;
2412
2413   vat_json_init_object (&node);
2414   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2415   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2416
2417   vat_json_print (vam->ofp, &node);
2418   vat_json_free (&node);
2419
2420   vam->retval = ntohl (mp->retval);
2421   vam->result_ready = 1;
2422 }
2423
2424 static void vl_api_vxlan_offload_rx_reply_t_handler
2425   (vl_api_vxlan_offload_rx_reply_t * mp)
2426 {
2427   vat_main_t *vam = &vat_main;
2428   i32 retval = ntohl (mp->retval);
2429   if (vam->async_mode)
2430     {
2431       vam->async_errors += (retval < 0);
2432     }
2433   else
2434     {
2435       vam->retval = retval;
2436       vam->result_ready = 1;
2437     }
2438 }
2439
2440 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2441   (vl_api_vxlan_offload_rx_reply_t * mp)
2442 {
2443   vat_main_t *vam = &vat_main;
2444   vat_json_node_t node;
2445
2446   vat_json_init_object (&node);
2447   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2448
2449   vat_json_print (vam->ofp, &node);
2450   vat_json_free (&node);
2451
2452   vam->retval = ntohl (mp->retval);
2453   vam->result_ready = 1;
2454 }
2455
2456 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2457   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   i32 retval = ntohl (mp->retval);
2461   if (vam->async_mode)
2462     {
2463       vam->async_errors += (retval < 0);
2464     }
2465   else
2466     {
2467       vam->retval = retval;
2468       vam->sw_if_index = ntohl (mp->sw_if_index);
2469       vam->result_ready = 1;
2470     }
2471 }
2472
2473 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2474   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477   vat_json_node_t node;
2478
2479   vat_json_init_object (&node);
2480   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2481   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2482
2483   vat_json_print (vam->ofp, &node);
2484   vat_json_free (&node);
2485
2486   vam->retval = ntohl (mp->retval);
2487   vam->result_ready = 1;
2488 }
2489
2490 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2491   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2492 {
2493   vat_main_t *vam = &vat_main;
2494   i32 retval = ntohl (mp->retval);
2495   if (vam->async_mode)
2496     {
2497       vam->async_errors += (retval < 0);
2498     }
2499   else
2500     {
2501       vam->retval = retval;
2502       vam->sw_if_index = ntohl (mp->sw_if_index);
2503       vam->result_ready = 1;
2504     }
2505   vam->regenerate_interface_table = 1;
2506 }
2507
2508 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2509   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   vat_json_node_t node;
2513
2514   vat_json_init_object (&node);
2515   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2516   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2517
2518   vat_json_print (vam->ofp, &node);
2519   vat_json_free (&node);
2520
2521   vam->retval = ntohl (mp->retval);
2522   vam->result_ready = 1;
2523 }
2524
2525 static void vl_api_gre_tunnel_add_del_reply_t_handler
2526   (vl_api_gre_tunnel_add_del_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   i32 retval = ntohl (mp->retval);
2530   if (vam->async_mode)
2531     {
2532       vam->async_errors += (retval < 0);
2533     }
2534   else
2535     {
2536       vam->retval = retval;
2537       vam->sw_if_index = ntohl (mp->sw_if_index);
2538       vam->result_ready = 1;
2539     }
2540 }
2541
2542 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2543   (vl_api_gre_tunnel_add_del_reply_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   vat_json_node_t node;
2547
2548   vat_json_init_object (&node);
2549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2551
2552   vat_json_print (vam->ofp, &node);
2553   vat_json_free (&node);
2554
2555   vam->retval = ntohl (mp->retval);
2556   vam->result_ready = 1;
2557 }
2558
2559 static void vl_api_create_vhost_user_if_reply_t_handler
2560   (vl_api_create_vhost_user_if_reply_t * mp)
2561 {
2562   vat_main_t *vam = &vat_main;
2563   i32 retval = ntohl (mp->retval);
2564   if (vam->async_mode)
2565     {
2566       vam->async_errors += (retval < 0);
2567     }
2568   else
2569     {
2570       vam->retval = retval;
2571       vam->sw_if_index = ntohl (mp->sw_if_index);
2572       vam->result_ready = 1;
2573     }
2574   vam->regenerate_interface_table = 1;
2575 }
2576
2577 static void vl_api_create_vhost_user_if_reply_t_handler_json
2578   (vl_api_create_vhost_user_if_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   vat_json_node_t node;
2582
2583   vat_json_init_object (&node);
2584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2585   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2586
2587   vat_json_print (vam->ofp, &node);
2588   vat_json_free (&node);
2589
2590   vam->retval = ntohl (mp->retval);
2591   vam->result_ready = 1;
2592 }
2593
2594 static void vl_api_ip_address_details_t_handler
2595   (vl_api_ip_address_details_t * mp)
2596 {
2597   vat_main_t *vam = &vat_main;
2598   static ip_address_details_t empty_ip_address_details = { {0} };
2599   ip_address_details_t *address = NULL;
2600   ip_details_t *current_ip_details = NULL;
2601   ip_details_t *details = NULL;
2602
2603   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2604
2605   if (!details || vam->current_sw_if_index >= vec_len (details)
2606       || !details[vam->current_sw_if_index].present)
2607     {
2608       errmsg ("ip address details arrived but not stored");
2609       errmsg ("ip_dump should be called first");
2610       return;
2611     }
2612
2613   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2614
2615 #define addresses (current_ip_details->addr)
2616
2617   vec_validate_init_empty (addresses, vec_len (addresses),
2618                            empty_ip_address_details);
2619
2620   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2621
2622   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2623   address->prefix_length = mp->prefix.len;
2624 #undef addresses
2625 }
2626
2627 static void vl_api_ip_address_details_t_handler_json
2628   (vl_api_ip_address_details_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vat_json_node_t *node = NULL;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639
2640   vat_json_init_object (node);
2641   vat_json_object_add_prefix (node, &mp->prefix);
2642 }
2643
2644 static void
2645 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   static ip_details_t empty_ip_details = { 0 };
2649   ip_details_t *ip = NULL;
2650   u32 sw_if_index = ~0;
2651
2652   sw_if_index = ntohl (mp->sw_if_index);
2653
2654   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2655                            sw_if_index, empty_ip_details);
2656
2657   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2658                          sw_if_index);
2659
2660   ip->present = 1;
2661 }
2662
2663 static void
2664 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2665 {
2666   vat_main_t *vam = &vat_main;
2667
2668   if (VAT_JSON_ARRAY != vam->json_tree.type)
2669     {
2670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2671       vat_json_init_array (&vam->json_tree);
2672     }
2673   vat_json_array_add_uint (&vam->json_tree,
2674                            clib_net_to_host_u32 (mp->sw_if_index));
2675 }
2676
2677 static void vl_api_get_first_msg_id_reply_t_handler
2678   (vl_api_get_first_msg_id_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   i32 retval = ntohl (mp->retval);
2682
2683   if (vam->async_mode)
2684     {
2685       vam->async_errors += (retval < 0);
2686     }
2687   else
2688     {
2689       vam->retval = retval;
2690       vam->result_ready = 1;
2691     }
2692   if (retval >= 0)
2693     {
2694       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2695     }
2696 }
2697
2698 static void vl_api_get_first_msg_id_reply_t_handler_json
2699   (vl_api_get_first_msg_id_reply_t * mp)
2700 {
2701   vat_main_t *vam = &vat_main;
2702   vat_json_node_t node;
2703
2704   vat_json_init_object (&node);
2705   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2706   vat_json_object_add_uint (&node, "first_msg_id",
2707                             (uint) ntohs (mp->first_msg_id));
2708
2709   vat_json_print (vam->ofp, &node);
2710   vat_json_free (&node);
2711
2712   vam->retval = ntohl (mp->retval);
2713   vam->result_ready = 1;
2714 }
2715
2716 static void vl_api_get_node_graph_reply_t_handler
2717   (vl_api_get_node_graph_reply_t * mp)
2718 {
2719   vat_main_t *vam = &vat_main;
2720   i32 retval = ntohl (mp->retval);
2721   u8 *pvt_copy, *reply;
2722   void *oldheap;
2723   vlib_node_t *node;
2724   int i;
2725
2726   if (vam->async_mode)
2727     {
2728       vam->async_errors += (retval < 0);
2729     }
2730   else
2731     {
2732       vam->retval = retval;
2733       vam->result_ready = 1;
2734     }
2735
2736   /* "Should never happen..." */
2737   if (retval != 0)
2738     return;
2739
2740   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2741   pvt_copy = vec_dup (reply);
2742
2743   /* Toss the shared-memory original... */
2744   oldheap = vl_msg_push_heap ();
2745
2746   vec_free (reply);
2747
2748   vl_msg_pop_heap (oldheap);
2749
2750   if (vam->graph_nodes)
2751     {
2752       hash_free (vam->graph_node_index_by_name);
2753
2754       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2755         {
2756           node = vam->graph_nodes[0][i];
2757           vec_free (node->name);
2758           vec_free (node->next_nodes);
2759           vec_free (node);
2760         }
2761       vec_free (vam->graph_nodes[0]);
2762       vec_free (vam->graph_nodes);
2763     }
2764
2765   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2766   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2767   vec_free (pvt_copy);
2768
2769   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2770     {
2771       node = vam->graph_nodes[0][i];
2772       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2773     }
2774 }
2775
2776 static void vl_api_get_node_graph_reply_t_handler_json
2777   (vl_api_get_node_graph_reply_t * mp)
2778 {
2779   vat_main_t *vam = &vat_main;
2780   void *oldheap;
2781   vat_json_node_t node;
2782   u8 *reply;
2783
2784   /* $$$$ make this real? */
2785   vat_json_init_object (&node);
2786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2787   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2788
2789   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2790
2791   /* Toss the shared-memory original... */
2792   oldheap = vl_msg_push_heap ();
2793
2794   vec_free (reply);
2795
2796   vl_msg_pop_heap (oldheap);
2797
2798   vat_json_print (vam->ofp, &node);
2799   vat_json_free (&node);
2800
2801   vam->retval = ntohl (mp->retval);
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   u8 *s = 0;
2810
2811   if (mp->local)
2812     {
2813       s = format (s, "%=16d%=16d%=16d",
2814                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2815     }
2816   else
2817     {
2818       s = format (s, "%=16U%=16d%=16d",
2819                   format_ip46_address,
2820                   mp->ip_address, mp->priority, mp->weight);
2821     }
2822
2823   print (vam->ofp, "%v", s);
2824   vec_free (s);
2825 }
2826
2827 static void
2828 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   vat_json_node_t *node = NULL;
2832   struct in6_addr ip6;
2833   struct in_addr ip4;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842
2843   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2844   vat_json_object_add_uint (node, "priority", mp->priority);
2845   vat_json_object_add_uint (node, "weight", mp->weight);
2846
2847   if (mp->local)
2848     vat_json_object_add_uint (node, "sw_if_index",
2849                               clib_net_to_host_u32 (mp->sw_if_index));
2850   else
2851     {
2852       if (mp->ip_address.af)
2853         {
2854           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2855           vat_json_object_add_ip6 (node, "address", ip6);
2856         }
2857       else
2858         {
2859           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2860           vat_json_object_add_ip4 (node, "address", ip4);
2861         }
2862     }
2863 }
2864
2865 static void
2866 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2867                                           mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *ls_name = 0;
2871
2872   ls_name = format (0, "%s", mp->ls_name);
2873
2874   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2875          ls_name);
2876   vec_free (ls_name);
2877 }
2878
2879 static void
2880   vl_api_one_locator_set_details_t_handler_json
2881   (vl_api_one_locator_set_details_t * mp)
2882 {
2883   vat_main_t *vam = &vat_main;
2884   vat_json_node_t *node = 0;
2885   u8 *ls_name = 0;
2886
2887   ls_name = format (0, "%s", mp->ls_name);
2888   vec_add1 (ls_name, 0);
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896
2897   vat_json_init_object (node);
2898   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2899   vat_json_object_add_uint (node, "ls_index",
2900                             clib_net_to_host_u32 (mp->ls_index));
2901   vec_free (ls_name);
2902 }
2903
2904 typedef struct
2905 {
2906   u32 spi;
2907   u8 si;
2908 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2909
2910 uword
2911 unformat_nsh_address (unformat_input_t * input, va_list * args)
2912 {
2913   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2914   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2915 }
2916
2917 static u8 *
2918 format_nsh_address_vat (u8 * s, va_list * args)
2919 {
2920   nsh_t *a = va_arg (*args, nsh_t *);
2921   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2922 }
2923
2924 static u8 *
2925 format_lisp_flat_eid (u8 * s, va_list * args)
2926 {
2927   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2928
2929   switch (eid->type)
2930     {
2931     case EID_TYPE_API_PREFIX:
2932       if (eid->address.prefix.address.af)
2933         return format (s, "%U/%d", format_ip6_address,
2934                        eid->address.prefix.address.un.ip6,
2935                        eid->address.prefix.len);
2936       return format (s, "%U/%d", format_ip4_address,
2937                      eid->address.prefix.address.un.ip4,
2938                      eid->address.prefix.len);
2939     case EID_TYPE_API_MAC:
2940       return format (s, "%U", format_ethernet_address, eid->address.mac);
2941     case EID_TYPE_API_NSH:
2942       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2943     }
2944   return 0;
2945 }
2946
2947 static u8 *
2948 format_lisp_eid_vat (u8 * s, va_list * args)
2949 {
2950   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2951   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2952   u8 is_src_dst = (u8) va_arg (*args, int);
2953
2954   if (is_src_dst)
2955     s = format (s, "%U|", format_lisp_flat_eid, seid);
2956
2957   s = format (s, "%U", format_lisp_flat_eid, deid);
2958
2959   return s;
2960 }
2961
2962 static void
2963 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   u8 *s = 0, *eid = 0;
2967
2968   if (~0 == mp->locator_set_index)
2969     s = format (0, "action: %d", mp->action);
2970   else
2971     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   eid = format (0, "%U", format_lisp_eid_vat,
2974                 &mp->deid, &mp->seid, mp->is_src_dst);
2975   vec_add1 (eid, 0);
2976
2977   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2978          clib_net_to_host_u32 (mp->vni),
2979          eid,
2980          mp->is_local ? "local" : "remote",
2981          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2982          clib_net_to_host_u16 (mp->key.id), mp->key.key);
2983
2984   vec_free (s);
2985   vec_free (eid);
2986 }
2987
2988 static void
2989 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2990                                              * mp)
2991 {
2992   vat_main_t *vam = &vat_main;
2993   vat_json_node_t *node = 0;
2994   u8 *eid = 0;
2995
2996   if (VAT_JSON_ARRAY != vam->json_tree.type)
2997     {
2998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2999       vat_json_init_array (&vam->json_tree);
3000     }
3001   node = vat_json_array_add (&vam->json_tree);
3002
3003   vat_json_init_object (node);
3004   if (~0 == mp->locator_set_index)
3005     vat_json_object_add_uint (node, "action", mp->action);
3006   else
3007     vat_json_object_add_uint (node, "locator_set_index",
3008                               clib_net_to_host_u32 (mp->locator_set_index));
3009
3010   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3011   if (mp->deid.type == 3)
3012     {
3013       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3014       vat_json_init_object (nsh_json);
3015       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3016       vat_json_object_add_uint (nsh_json, "spi",
3017                                 clib_net_to_host_u32 (nsh->spi));
3018       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3019     }
3020   else
3021     {
3022       eid = format (0, "%U", format_lisp_eid_vat,
3023                     &mp->deid, &mp->seid, mp->is_src_dst);
3024       vec_add1 (eid, 0);
3025       vat_json_object_add_string_copy (node, "eid", eid);
3026       vec_free (eid);
3027     }
3028   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3029   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3030   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3031
3032   if (mp->key.id)
3033     {
3034       vat_json_object_add_uint (node, "key_id",
3035                                 clib_net_to_host_u16 (mp->key.id));
3036       vat_json_object_add_string_copy (node, "key", mp->key.key);
3037     }
3038 }
3039
3040 static void
3041 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3042 {
3043   vat_main_t *vam = &vat_main;
3044   u8 *seid = 0, *deid = 0;
3045   ip46_address_t lloc, rloc;
3046
3047   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3048
3049   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3050
3051   vec_add1 (deid, 0);
3052   vec_add1 (seid, 0);
3053
3054   if (mp->lloc.af)
3055     {
3056       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3057       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3058     }
3059   else
3060     {
3061       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3062       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3063     }
3064
3065
3066   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3067          clib_net_to_host_u32 (mp->vni),
3068          seid, deid,
3069          format_ip46_address, lloc,
3070          format_ip46_address, rloc,
3071          clib_net_to_host_u32 (mp->pkt_count),
3072          clib_net_to_host_u32 (mp->bytes));
3073
3074   vec_free (deid);
3075   vec_free (seid);
3076 }
3077
3078 static void
3079 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3080 {
3081   struct in6_addr ip6;
3082   struct in_addr ip4;
3083   vat_main_t *vam = &vat_main;
3084   vat_json_node_t *node = 0;
3085   u8 *deid = 0, *seid = 0;
3086
3087   if (VAT_JSON_ARRAY != vam->json_tree.type)
3088     {
3089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3090       vat_json_init_array (&vam->json_tree);
3091     }
3092   node = vat_json_array_add (&vam->json_tree);
3093
3094   vat_json_init_object (node);
3095   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3096
3097   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3098
3099   vec_add1 (deid, 0);
3100   vec_add1 (seid, 0);
3101
3102   vat_json_object_add_string_copy (node, "seid", seid);
3103   vat_json_object_add_string_copy (node, "deid", deid);
3104   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3105
3106   if (mp->lloc.af)
3107     {
3108       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3109       vat_json_object_add_ip6 (node, "lloc", ip6);
3110       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3111       vat_json_object_add_ip6 (node, "rloc", ip6);
3112
3113     }
3114   else
3115     {
3116       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3117       vat_json_object_add_ip4 (node, "lloc", ip4);
3118       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3119       vat_json_object_add_ip4 (node, "rloc", ip4);
3120     }
3121   vat_json_object_add_uint (node, "pkt_count",
3122                             clib_net_to_host_u32 (mp->pkt_count));
3123   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3124
3125   vec_free (deid);
3126   vec_free (seid);
3127 }
3128
3129 static void
3130   vl_api_one_eid_table_map_details_t_handler
3131   (vl_api_one_eid_table_map_details_t * mp)
3132 {
3133   vat_main_t *vam = &vat_main;
3134
3135   u8 *line = format (0, "%=10d%=10d",
3136                      clib_net_to_host_u32 (mp->vni),
3137                      clib_net_to_host_u32 (mp->dp_table));
3138   print (vam->ofp, "%v", line);
3139   vec_free (line);
3140 }
3141
3142 static void
3143   vl_api_one_eid_table_map_details_t_handler_json
3144   (vl_api_one_eid_table_map_details_t * mp)
3145 {
3146   vat_main_t *vam = &vat_main;
3147   vat_json_node_t *node = NULL;
3148
3149   if (VAT_JSON_ARRAY != vam->json_tree.type)
3150     {
3151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3152       vat_json_init_array (&vam->json_tree);
3153     }
3154   node = vat_json_array_add (&vam->json_tree);
3155   vat_json_init_object (node);
3156   vat_json_object_add_uint (node, "dp_table",
3157                             clib_net_to_host_u32 (mp->dp_table));
3158   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3159 }
3160
3161 static void
3162   vl_api_one_eid_table_vni_details_t_handler
3163   (vl_api_one_eid_table_vni_details_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166
3167   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3168   print (vam->ofp, "%v", line);
3169   vec_free (line);
3170 }
3171
3172 static void
3173   vl_api_one_eid_table_vni_details_t_handler_json
3174   (vl_api_one_eid_table_vni_details_t * mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *node = NULL;
3178
3179   if (VAT_JSON_ARRAY != vam->json_tree.type)
3180     {
3181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3182       vat_json_init_array (&vam->json_tree);
3183     }
3184   node = vat_json_array_add (&vam->json_tree);
3185   vat_json_init_object (node);
3186   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3187 }
3188
3189 static void
3190   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3191   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194   int retval = clib_net_to_host_u32 (mp->retval);
3195
3196   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3197   print (vam->ofp, "fallback threshold value: %d", mp->value);
3198
3199   vam->retval = retval;
3200   vam->result_ready = 1;
3201 }
3202
3203 static void
3204   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3205   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t _node, *node = &_node;
3209   int retval = clib_net_to_host_u32 (mp->retval);
3210
3211   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3212   vat_json_init_object (node);
3213   vat_json_object_add_uint (node, "value", mp->value);
3214
3215   vat_json_print (vam->ofp, node);
3216   vat_json_free (node);
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
3224   (vl_api_show_one_map_register_state_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   int retval = clib_net_to_host_u32 (mp->retval);
3228
3229   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3230
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_map_register_state_reply_t_handler_json
3237   (vl_api_show_one_map_register_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t _node, *node = &_node;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242
3243   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3244
3245   vat_json_init_object (node);
3246   vat_json_object_add_string_copy (node, "state", s);
3247
3248   vat_json_print (vam->ofp, node);
3249   vat_json_free (node);
3250
3251   vam->retval = retval;
3252   vam->result_ready = 1;
3253   vec_free (s);
3254 }
3255
3256 static void
3257   vl_api_show_one_rloc_probe_state_reply_t_handler
3258   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3259 {
3260   vat_main_t *vam = &vat_main;
3261   int retval = clib_net_to_host_u32 (mp->retval);
3262
3263   if (retval)
3264     goto end;
3265
3266   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3267 end:
3268   vam->retval = retval;
3269   vam->result_ready = 1;
3270 }
3271
3272 static void
3273   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3274   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3275 {
3276   vat_main_t *vam = &vat_main;
3277   vat_json_node_t _node, *node = &_node;
3278   int retval = clib_net_to_host_u32 (mp->retval);
3279
3280   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3281   vat_json_init_object (node);
3282   vat_json_object_add_string_copy (node, "state", s);
3283
3284   vat_json_print (vam->ofp, node);
3285   vat_json_free (node);
3286
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289   vec_free (s);
3290 }
3291
3292 static void
3293   vl_api_show_one_stats_enable_disable_reply_t_handler
3294   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3303 end:
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306 }
3307
3308 static void
3309   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3310   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   vat_json_node_t _node, *node = &_node;
3314   int retval = clib_net_to_host_u32 (mp->retval);
3315
3316   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3317   vat_json_init_object (node);
3318   vat_json_object_add_string_copy (node, "state", s);
3319
3320   vat_json_print (vam->ofp, node);
3321   vat_json_free (node);
3322
3323   vam->retval = retval;
3324   vam->result_ready = 1;
3325   vec_free (s);
3326 }
3327
3328 static void
3329 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3330 {
3331   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3332   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3333   e->vni = clib_net_to_host_u32 (e->vni);
3334 }
3335
3336 static void
3337   gpe_fwd_entries_get_reply_t_net_to_host
3338   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3339 {
3340   u32 i;
3341
3342   mp->count = clib_net_to_host_u32 (mp->count);
3343   for (i = 0; i < mp->count; i++)
3344     {
3345       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3346     }
3347 }
3348
3349 static u8 *
3350 format_gpe_encap_mode (u8 * s, va_list * args)
3351 {
3352   u32 mode = va_arg (*args, u32);
3353
3354   switch (mode)
3355     {
3356     case 0:
3357       return format (s, "lisp");
3358     case 1:
3359       return format (s, "vxlan");
3360     }
3361   return 0;
3362 }
3363
3364 static void
3365   vl_api_gpe_get_encap_mode_reply_t_handler
3366   (vl_api_gpe_get_encap_mode_reply_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369
3370   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3371   vam->retval = ntohl (mp->retval);
3372   vam->result_ready = 1;
3373 }
3374
3375 static void
3376   vl_api_gpe_get_encap_mode_reply_t_handler_json
3377   (vl_api_gpe_get_encap_mode_reply_t * mp)
3378 {
3379   vat_main_t *vam = &vat_main;
3380   vat_json_node_t node;
3381
3382   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3383   vec_add1 (encap_mode, 0);
3384
3385   vat_json_init_object (&node);
3386   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3387
3388   vec_free (encap_mode);
3389   vat_json_print (vam->ofp, &node);
3390   vat_json_free (&node);
3391
3392   vam->retval = ntohl (mp->retval);
3393   vam->result_ready = 1;
3394 }
3395
3396 static void
3397   vl_api_gpe_fwd_entry_path_details_t_handler
3398   (vl_api_gpe_fwd_entry_path_details_t * mp)
3399 {
3400   vat_main_t *vam = &vat_main;
3401   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3402
3403   if (mp->lcl_loc.addr.af)
3404     format_ip_address_fcn = format_ip6_address;
3405   else
3406     format_ip_address_fcn = format_ip4_address;
3407
3408   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3409          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3410          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3411 }
3412
3413 static void
3414 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3415 {
3416   struct in6_addr ip6;
3417   struct in_addr ip4;
3418
3419   if (loc->addr.af)
3420     {
3421       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3422       vat_json_object_add_ip6 (n, "address", ip6);
3423     }
3424   else
3425     {
3426       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3427       vat_json_object_add_ip4 (n, "address", ip4);
3428     }
3429   vat_json_object_add_uint (n, "weight", loc->weight);
3430 }
3431
3432 static void
3433   vl_api_gpe_fwd_entry_path_details_t_handler_json
3434   (vl_api_gpe_fwd_entry_path_details_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   vat_json_node_t *node = NULL;
3438   vat_json_node_t *loc_node;
3439
3440   if (VAT_JSON_ARRAY != vam->json_tree.type)
3441     {
3442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3443       vat_json_init_array (&vam->json_tree);
3444     }
3445   node = vat_json_array_add (&vam->json_tree);
3446   vat_json_init_object (node);
3447
3448   loc_node = vat_json_object_add (node, "local_locator");
3449   vat_json_init_object (loc_node);
3450   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3451
3452   loc_node = vat_json_object_add (node, "remote_locator");
3453   vat_json_init_object (loc_node);
3454   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3455 }
3456
3457 static void
3458   vl_api_gpe_fwd_entries_get_reply_t_handler
3459   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   u32 i;
3463   int retval = clib_net_to_host_u32 (mp->retval);
3464   vl_api_gpe_fwd_entry_t *e;
3465
3466   if (retval)
3467     goto end;
3468
3469   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3470
3471   for (i = 0; i < mp->count; i++)
3472     {
3473       e = &mp->entries[i];
3474       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3475              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3476     }
3477
3478 end:
3479   vam->retval = retval;
3480   vam->result_ready = 1;
3481 }
3482
3483 static void
3484   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3485   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3486 {
3487   u8 *s = 0;
3488   vat_main_t *vam = &vat_main;
3489   vat_json_node_t *e = 0, root;
3490   u32 i;
3491   int retval = clib_net_to_host_u32 (mp->retval);
3492   vl_api_gpe_fwd_entry_t *fwd;
3493
3494   if (retval)
3495     goto end;
3496
3497   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3498   vat_json_init_array (&root);
3499
3500   for (i = 0; i < mp->count; i++)
3501     {
3502       e = vat_json_array_add (&root);
3503       fwd = &mp->entries[i];
3504
3505       vat_json_init_object (e);
3506       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3507       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3508       vat_json_object_add_int (e, "vni", fwd->vni);
3509       vat_json_object_add_int (e, "action", fwd->action);
3510
3511       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3512       vec_add1 (s, 0);
3513       vat_json_object_add_string_copy (e, "leid", s);
3514       vec_free (s);
3515
3516       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3517       vec_add1 (s, 0);
3518       vat_json_object_add_string_copy (e, "reid", s);
3519       vec_free (s);
3520     }
3521
3522   vat_json_print (vam->ofp, &root);
3523   vat_json_free (&root);
3524
3525 end:
3526   vam->retval = retval;
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3532   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u32 i, n;
3536   int retval = clib_net_to_host_u32 (mp->retval);
3537   vl_api_gpe_native_fwd_rpath_t *r;
3538
3539   if (retval)
3540     goto end;
3541
3542   n = clib_net_to_host_u32 (mp->count);
3543
3544   for (i = 0; i < n; i++)
3545     {
3546       r = &mp->entries[i];
3547       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3548              clib_net_to_host_u32 (r->fib_index),
3549              clib_net_to_host_u32 (r->nh_sw_if_index),
3550              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3551              r->nh_addr.un);
3552     }
3553
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3561   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t root, *e;
3565   u32 i, n;
3566   int retval = clib_net_to_host_u32 (mp->retval);
3567   vl_api_gpe_native_fwd_rpath_t *r;
3568   u8 *s;
3569
3570   if (retval)
3571     goto end;
3572
3573   n = clib_net_to_host_u32 (mp->count);
3574   vat_json_init_array (&root);
3575
3576   for (i = 0; i < n; i++)
3577     {
3578       e = vat_json_array_add (&root);
3579       vat_json_init_object (e);
3580       r = &mp->entries[i];
3581       s =
3582         format (0, "%U",
3583                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3584                 r->nh_addr.un);
3585       vec_add1 (s, 0);
3586       vat_json_object_add_string_copy (e, "ip4", s);
3587       vec_free (s);
3588
3589       vat_json_object_add_uint (e, "fib_index",
3590                                 clib_net_to_host_u32 (r->fib_index));
3591       vat_json_object_add_uint (e, "nh_sw_if_index",
3592                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3593     }
3594
3595   vat_json_print (vam->ofp, &root);
3596   vat_json_free (&root);
3597
3598 end:
3599   vam->retval = retval;
3600   vam->result_ready = 1;
3601 }
3602
3603 static void
3604   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3605   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3606 {
3607   vat_main_t *vam = &vat_main;
3608   u32 i, n;
3609   int retval = clib_net_to_host_u32 (mp->retval);
3610
3611   if (retval)
3612     goto end;
3613
3614   n = clib_net_to_host_u32 (mp->count);
3615
3616   for (i = 0; i < n; i++)
3617     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3618
3619 end:
3620   vam->retval = retval;
3621   vam->result_ready = 1;
3622 }
3623
3624 static void
3625   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3626   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3627 {
3628   vat_main_t *vam = &vat_main;
3629   vat_json_node_t root;
3630   u32 i, n;
3631   int retval = clib_net_to_host_u32 (mp->retval);
3632
3633   if (retval)
3634     goto end;
3635
3636   n = clib_net_to_host_u32 (mp->count);
3637   vat_json_init_array (&root);
3638
3639   for (i = 0; i < n; i++)
3640     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3641
3642   vat_json_print (vam->ofp, &root);
3643   vat_json_free (&root);
3644
3645 end:
3646   vam->retval = retval;
3647   vam->result_ready = 1;
3648 }
3649
3650 static void
3651   vl_api_one_ndp_entries_get_reply_t_handler
3652   (vl_api_one_ndp_entries_get_reply_t * mp)
3653 {
3654   vat_main_t *vam = &vat_main;
3655   u32 i, n;
3656   int retval = clib_net_to_host_u32 (mp->retval);
3657
3658   if (retval)
3659     goto end;
3660
3661   n = clib_net_to_host_u32 (mp->count);
3662
3663   for (i = 0; i < n; i++)
3664     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3665            format_ethernet_address, mp->entries[i].mac);
3666
3667 end:
3668   vam->retval = retval;
3669   vam->result_ready = 1;
3670 }
3671
3672 static void
3673   vl_api_one_ndp_entries_get_reply_t_handler_json
3674   (vl_api_one_ndp_entries_get_reply_t * mp)
3675 {
3676   u8 *s = 0;
3677   vat_main_t *vam = &vat_main;
3678   vat_json_node_t *e = 0, root;
3679   u32 i, n;
3680   int retval = clib_net_to_host_u32 (mp->retval);
3681   vl_api_one_ndp_entry_t *arp_entry;
3682
3683   if (retval)
3684     goto end;
3685
3686   n = clib_net_to_host_u32 (mp->count);
3687   vat_json_init_array (&root);
3688
3689   for (i = 0; i < n; i++)
3690     {
3691       e = vat_json_array_add (&root);
3692       arp_entry = &mp->entries[i];
3693
3694       vat_json_init_object (e);
3695       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3696       vec_add1 (s, 0);
3697
3698       vat_json_object_add_string_copy (e, "mac", s);
3699       vec_free (s);
3700
3701       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3702       vec_add1 (s, 0);
3703       vat_json_object_add_string_copy (e, "ip6", s);
3704       vec_free (s);
3705     }
3706
3707   vat_json_print (vam->ofp, &root);
3708   vat_json_free (&root);
3709
3710 end:
3711   vam->retval = retval;
3712   vam->result_ready = 1;
3713 }
3714
3715 static void
3716   vl_api_one_l2_arp_entries_get_reply_t_handler
3717   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3718 {
3719   vat_main_t *vam = &vat_main;
3720   u32 i, n;
3721   int retval = clib_net_to_host_u32 (mp->retval);
3722
3723   if (retval)
3724     goto end;
3725
3726   n = clib_net_to_host_u32 (mp->count);
3727
3728   for (i = 0; i < n; i++)
3729     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3730            format_ethernet_address, mp->entries[i].mac);
3731
3732 end:
3733   vam->retval = retval;
3734   vam->result_ready = 1;
3735 }
3736
3737 static void
3738   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3739   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3740 {
3741   u8 *s = 0;
3742   vat_main_t *vam = &vat_main;
3743   vat_json_node_t *e = 0, root;
3744   u32 i, n;
3745   int retval = clib_net_to_host_u32 (mp->retval);
3746   vl_api_one_l2_arp_entry_t *arp_entry;
3747
3748   if (retval)
3749     goto end;
3750
3751   n = clib_net_to_host_u32 (mp->count);
3752   vat_json_init_array (&root);
3753
3754   for (i = 0; i < n; i++)
3755     {
3756       e = vat_json_array_add (&root);
3757       arp_entry = &mp->entries[i];
3758
3759       vat_json_init_object (e);
3760       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3761       vec_add1 (s, 0);
3762
3763       vat_json_object_add_string_copy (e, "mac", s);
3764       vec_free (s);
3765
3766       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3767       vec_add1 (s, 0);
3768       vat_json_object_add_string_copy (e, "ip4", s);
3769       vec_free (s);
3770     }
3771
3772   vat_json_print (vam->ofp, &root);
3773   vat_json_free (&root);
3774
3775 end:
3776   vam->retval = retval;
3777   vam->result_ready = 1;
3778 }
3779
3780 static void
3781 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3782 {
3783   vat_main_t *vam = &vat_main;
3784   u32 i, n;
3785   int retval = clib_net_to_host_u32 (mp->retval);
3786
3787   if (retval)
3788     goto end;
3789
3790   n = clib_net_to_host_u32 (mp->count);
3791
3792   for (i = 0; i < n; i++)
3793     {
3794       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3795     }
3796
3797 end:
3798   vam->retval = retval;
3799   vam->result_ready = 1;
3800 }
3801
3802 static void
3803   vl_api_one_ndp_bd_get_reply_t_handler_json
3804   (vl_api_one_ndp_bd_get_reply_t * mp)
3805 {
3806   vat_main_t *vam = &vat_main;
3807   vat_json_node_t root;
3808   u32 i, n;
3809   int retval = clib_net_to_host_u32 (mp->retval);
3810
3811   if (retval)
3812     goto end;
3813
3814   n = clib_net_to_host_u32 (mp->count);
3815   vat_json_init_array (&root);
3816
3817   for (i = 0; i < n; i++)
3818     {
3819       vat_json_array_add_uint (&root,
3820                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3821     }
3822
3823   vat_json_print (vam->ofp, &root);
3824   vat_json_free (&root);
3825
3826 end:
3827   vam->retval = retval;
3828   vam->result_ready = 1;
3829 }
3830
3831 static void
3832   vl_api_one_l2_arp_bd_get_reply_t_handler
3833   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3834 {
3835   vat_main_t *vam = &vat_main;
3836   u32 i, n;
3837   int retval = clib_net_to_host_u32 (mp->retval);
3838
3839   if (retval)
3840     goto end;
3841
3842   n = clib_net_to_host_u32 (mp->count);
3843
3844   for (i = 0; i < n; i++)
3845     {
3846       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3847     }
3848
3849 end:
3850   vam->retval = retval;
3851   vam->result_ready = 1;
3852 }
3853
3854 static void
3855   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3856   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3857 {
3858   vat_main_t *vam = &vat_main;
3859   vat_json_node_t root;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867   vat_json_init_array (&root);
3868
3869   for (i = 0; i < n; i++)
3870     {
3871       vat_json_array_add_uint (&root,
3872                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3873     }
3874
3875   vat_json_print (vam->ofp, &root);
3876   vat_json_free (&root);
3877
3878 end:
3879   vam->retval = retval;
3880   vam->result_ready = 1;
3881 }
3882
3883 static void
3884   vl_api_one_adjacencies_get_reply_t_handler
3885   (vl_api_one_adjacencies_get_reply_t * mp)
3886 {
3887   vat_main_t *vam = &vat_main;
3888   u32 i, n;
3889   int retval = clib_net_to_host_u32 (mp->retval);
3890   vl_api_one_adjacency_t *a;
3891
3892   if (retval)
3893     goto end;
3894
3895   n = clib_net_to_host_u32 (mp->count);
3896
3897   for (i = 0; i < n; i++)
3898     {
3899       a = &mp->adjacencies[i];
3900       print (vam->ofp, "%U %40U",
3901              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3902     }
3903
3904 end:
3905   vam->retval = retval;
3906   vam->result_ready = 1;
3907 }
3908
3909 static void
3910   vl_api_one_adjacencies_get_reply_t_handler_json
3911   (vl_api_one_adjacencies_get_reply_t * mp)
3912 {
3913   u8 *s = 0;
3914   vat_main_t *vam = &vat_main;
3915   vat_json_node_t *e = 0, root;
3916   u32 i, n;
3917   int retval = clib_net_to_host_u32 (mp->retval);
3918   vl_api_one_adjacency_t *a;
3919
3920   if (retval)
3921     goto end;
3922
3923   n = clib_net_to_host_u32 (mp->count);
3924   vat_json_init_array (&root);
3925
3926   for (i = 0; i < n; i++)
3927     {
3928       e = vat_json_array_add (&root);
3929       a = &mp->adjacencies[i];
3930
3931       vat_json_init_object (e);
3932       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3933       vec_add1 (s, 0);
3934       vat_json_object_add_string_copy (e, "leid", s);
3935       vec_free (s);
3936
3937       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3938       vec_add1 (s, 0);
3939       vat_json_object_add_string_copy (e, "reid", s);
3940       vec_free (s);
3941     }
3942
3943   vat_json_print (vam->ofp, &root);
3944   vat_json_free (&root);
3945
3946 end:
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
3955
3956   print (vam->ofp, "%=20U",
3957          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3958          mp->ip_address.un);
3959 }
3960
3961 static void
3962   vl_api_one_map_server_details_t_handler_json
3963   (vl_api_one_map_server_details_t * mp)
3964 {
3965   vat_main_t *vam = &vat_main;
3966   vat_json_node_t *node = NULL;
3967   struct in6_addr ip6;
3968   struct in_addr ip4;
3969
3970   if (VAT_JSON_ARRAY != vam->json_tree.type)
3971     {
3972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3973       vat_json_init_array (&vam->json_tree);
3974     }
3975   node = vat_json_array_add (&vam->json_tree);
3976
3977   vat_json_init_object (node);
3978   if (mp->ip_address.af)
3979     {
3980       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3981       vat_json_object_add_ip6 (node, "map-server", ip6);
3982     }
3983   else
3984     {
3985       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3986       vat_json_object_add_ip4 (node, "map-server", ip4);
3987     }
3988 }
3989
3990 static void
3991 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3992                                            * mp)
3993 {
3994   vat_main_t *vam = &vat_main;
3995
3996   print (vam->ofp, "%=20U",
3997          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3998          mp->ip_address.un);
3999 }
4000
4001 static void
4002   vl_api_one_map_resolver_details_t_handler_json
4003   (vl_api_one_map_resolver_details_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   vat_json_node_t *node = NULL;
4007   struct in6_addr ip6;
4008   struct in_addr ip4;
4009
4010   if (VAT_JSON_ARRAY != vam->json_tree.type)
4011     {
4012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4013       vat_json_init_array (&vam->json_tree);
4014     }
4015   node = vat_json_array_add (&vam->json_tree);
4016
4017   vat_json_init_object (node);
4018   if (mp->ip_address.af)
4019     {
4020       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4021       vat_json_object_add_ip6 (node, "map resolver", ip6);
4022     }
4023   else
4024     {
4025       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4026       vat_json_object_add_ip4 (node, "map resolver", ip4);
4027     }
4028 }
4029
4030 static void
4031 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4032 {
4033   vat_main_t *vam = &vat_main;
4034   i32 retval = ntohl (mp->retval);
4035
4036   if (0 <= retval)
4037     {
4038       print (vam->ofp, "feature: %s\ngpe: %s",
4039              mp->feature_status ? "enabled" : "disabled",
4040              mp->gpe_status ? "enabled" : "disabled");
4041     }
4042
4043   vam->retval = retval;
4044   vam->result_ready = 1;
4045 }
4046
4047 static void
4048   vl_api_show_one_status_reply_t_handler_json
4049   (vl_api_show_one_status_reply_t * mp)
4050 {
4051   vat_main_t *vam = &vat_main;
4052   vat_json_node_t node;
4053   u8 *gpe_status = NULL;
4054   u8 *feature_status = NULL;
4055
4056   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4057   feature_status = format (0, "%s",
4058                            mp->feature_status ? "enabled" : "disabled");
4059   vec_add1 (gpe_status, 0);
4060   vec_add1 (feature_status, 0);
4061
4062   vat_json_init_object (&node);
4063   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4064   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4065
4066   vec_free (gpe_status);
4067   vec_free (feature_status);
4068
4069   vat_json_print (vam->ofp, &node);
4070   vat_json_free (&node);
4071
4072   vam->retval = ntohl (mp->retval);
4073   vam->result_ready = 1;
4074 }
4075
4076 static void
4077   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4078   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081   i32 retval = ntohl (mp->retval);
4082
4083   if (retval >= 0)
4084     {
4085       print (vam->ofp, "%=20s", mp->locator_set_name);
4086     }
4087
4088   vam->retval = retval;
4089   vam->result_ready = 1;
4090 }
4091
4092 static void
4093   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4094   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4095 {
4096   vat_main_t *vam = &vat_main;
4097   vat_json_node_t *node = NULL;
4098
4099   if (VAT_JSON_ARRAY != vam->json_tree.type)
4100     {
4101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4102       vat_json_init_array (&vam->json_tree);
4103     }
4104   node = vat_json_array_add (&vam->json_tree);
4105
4106   vat_json_init_object (node);
4107   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4108
4109   vat_json_print (vam->ofp, node);
4110   vat_json_free (node);
4111
4112   vam->retval = ntohl (mp->retval);
4113   vam->result_ready = 1;
4114 }
4115
4116 static u8 *
4117 format_lisp_map_request_mode (u8 * s, va_list * args)
4118 {
4119   u32 mode = va_arg (*args, u32);
4120
4121   switch (mode)
4122     {
4123     case 0:
4124       return format (0, "dst-only");
4125     case 1:
4126       return format (0, "src-dst");
4127     }
4128   return 0;
4129 }
4130
4131 static void
4132   vl_api_show_one_map_request_mode_reply_t_handler
4133   (vl_api_show_one_map_request_mode_reply_t * mp)
4134 {
4135   vat_main_t *vam = &vat_main;
4136   i32 retval = ntohl (mp->retval);
4137
4138   if (0 <= retval)
4139     {
4140       u32 mode = mp->mode;
4141       print (vam->ofp, "map_request_mode: %U",
4142              format_lisp_map_request_mode, mode);
4143     }
4144
4145   vam->retval = retval;
4146   vam->result_ready = 1;
4147 }
4148
4149 static void
4150   vl_api_show_one_map_request_mode_reply_t_handler_json
4151   (vl_api_show_one_map_request_mode_reply_t * mp)
4152 {
4153   vat_main_t *vam = &vat_main;
4154   vat_json_node_t node;
4155   u8 *s = 0;
4156   u32 mode;
4157
4158   mode = mp->mode;
4159   s = format (0, "%U", format_lisp_map_request_mode, mode);
4160   vec_add1 (s, 0);
4161
4162   vat_json_init_object (&node);
4163   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4164   vat_json_print (vam->ofp, &node);
4165   vat_json_free (&node);
4166
4167   vec_free (s);
4168   vam->retval = ntohl (mp->retval);
4169   vam->result_ready = 1;
4170 }
4171
4172 static void
4173   vl_api_one_show_xtr_mode_reply_t_handler
4174   (vl_api_one_show_xtr_mode_reply_t * mp)
4175 {
4176   vat_main_t *vam = &vat_main;
4177   i32 retval = ntohl (mp->retval);
4178
4179   if (0 <= retval)
4180     {
4181       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4182     }
4183
4184   vam->retval = retval;
4185   vam->result_ready = 1;
4186 }
4187
4188 static void
4189   vl_api_one_show_xtr_mode_reply_t_handler_json
4190   (vl_api_one_show_xtr_mode_reply_t * mp)
4191 {
4192   vat_main_t *vam = &vat_main;
4193   vat_json_node_t node;
4194   u8 *status = 0;
4195
4196   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4197   vec_add1 (status, 0);
4198
4199   vat_json_init_object (&node);
4200   vat_json_object_add_string_copy (&node, "status", status);
4201
4202   vec_free (status);
4203
4204   vat_json_print (vam->ofp, &node);
4205   vat_json_free (&node);
4206
4207   vam->retval = ntohl (mp->retval);
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_one_show_pitr_mode_reply_t_handler
4213   (vl_api_one_show_pitr_mode_reply_t * mp)
4214 {
4215   vat_main_t *vam = &vat_main;
4216   i32 retval = ntohl (mp->retval);
4217
4218   if (0 <= retval)
4219     {
4220       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4221     }
4222
4223   vam->retval = retval;
4224   vam->result_ready = 1;
4225 }
4226
4227 static void
4228   vl_api_one_show_pitr_mode_reply_t_handler_json
4229   (vl_api_one_show_pitr_mode_reply_t * mp)
4230 {
4231   vat_main_t *vam = &vat_main;
4232   vat_json_node_t node;
4233   u8 *status = 0;
4234
4235   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4236   vec_add1 (status, 0);
4237
4238   vat_json_init_object (&node);
4239   vat_json_object_add_string_copy (&node, "status", status);
4240
4241   vec_free (status);
4242
4243   vat_json_print (vam->ofp, &node);
4244   vat_json_free (&node);
4245
4246   vam->retval = ntohl (mp->retval);
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_show_petr_mode_reply_t_handler
4252   (vl_api_one_show_petr_mode_reply_t * mp)
4253 {
4254   vat_main_t *vam = &vat_main;
4255   i32 retval = ntohl (mp->retval);
4256
4257   if (0 <= retval)
4258     {
4259       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4260     }
4261
4262   vam->retval = retval;
4263   vam->result_ready = 1;
4264 }
4265
4266 static void
4267   vl_api_one_show_petr_mode_reply_t_handler_json
4268   (vl_api_one_show_petr_mode_reply_t * mp)
4269 {
4270   vat_main_t *vam = &vat_main;
4271   vat_json_node_t node;
4272   u8 *status = 0;
4273
4274   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4275   vec_add1 (status, 0);
4276
4277   vat_json_init_object (&node);
4278   vat_json_object_add_string_copy (&node, "status", status);
4279
4280   vec_free (status);
4281
4282   vat_json_print (vam->ofp, &node);
4283   vat_json_free (&node);
4284
4285   vam->retval = ntohl (mp->retval);
4286   vam->result_ready = 1;
4287 }
4288
4289 static void
4290   vl_api_show_one_use_petr_reply_t_handler
4291   (vl_api_show_one_use_petr_reply_t * mp)
4292 {
4293   vat_main_t *vam = &vat_main;
4294   i32 retval = ntohl (mp->retval);
4295
4296   if (0 <= retval)
4297     {
4298       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4299       if (mp->status)
4300         {
4301           print (vam->ofp, "Proxy-ETR address; %U",
4302                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4303                  mp->ip_address.un);
4304         }
4305     }
4306
4307   vam->retval = retval;
4308   vam->result_ready = 1;
4309 }
4310
4311 static void
4312   vl_api_show_one_use_petr_reply_t_handler_json
4313   (vl_api_show_one_use_petr_reply_t * mp)
4314 {
4315   vat_main_t *vam = &vat_main;
4316   vat_json_node_t node;
4317   u8 *status = 0;
4318   struct in_addr ip4;
4319   struct in6_addr ip6;
4320
4321   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4322   vec_add1 (status, 0);
4323
4324   vat_json_init_object (&node);
4325   vat_json_object_add_string_copy (&node, "status", status);
4326   if (mp->status)
4327     {
4328       if (mp->ip_address.af)
4329         {
4330           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4331           vat_json_object_add_ip6 (&node, "address", ip6);
4332         }
4333       else
4334         {
4335           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4336           vat_json_object_add_ip4 (&node, "address", ip4);
4337         }
4338     }
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_show_one_nsh_mapping_reply_t_handler
4351   (vl_api_show_one_nsh_mapping_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%-20s%-16s",
4359              mp->is_set ? "set" : "not-set",
4360              mp->is_set ? (char *) mp->locator_set_name : "");
4361     }
4362
4363   vam->retval = retval;
4364   vam->result_ready = 1;
4365 }
4366
4367 static void
4368   vl_api_show_one_nsh_mapping_reply_t_handler_json
4369   (vl_api_show_one_nsh_mapping_reply_t * mp)
4370 {
4371   vat_main_t *vam = &vat_main;
4372   vat_json_node_t node;
4373   u8 *status = 0;
4374
4375   status = format (0, "%s", mp->is_set ? "yes" : "no");
4376   vec_add1 (status, 0);
4377
4378   vat_json_init_object (&node);
4379   vat_json_object_add_string_copy (&node, "is_set", status);
4380   if (mp->is_set)
4381     {
4382       vat_json_object_add_string_copy (&node, "locator_set",
4383                                        mp->locator_set_name);
4384     }
4385
4386   vec_free (status);
4387
4388   vat_json_print (vam->ofp, &node);
4389   vat_json_free (&node);
4390
4391   vam->retval = ntohl (mp->retval);
4392   vam->result_ready = 1;
4393 }
4394
4395 static void
4396   vl_api_show_one_map_register_ttl_reply_t_handler
4397   (vl_api_show_one_map_register_ttl_reply_t * mp)
4398 {
4399   vat_main_t *vam = &vat_main;
4400   i32 retval = ntohl (mp->retval);
4401
4402   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4403
4404   if (0 <= retval)
4405     {
4406       print (vam->ofp, "ttl: %u", mp->ttl);
4407     }
4408
4409   vam->retval = retval;
4410   vam->result_ready = 1;
4411 }
4412
4413 static void
4414   vl_api_show_one_map_register_ttl_reply_t_handler_json
4415   (vl_api_show_one_map_register_ttl_reply_t * mp)
4416 {
4417   vat_main_t *vam = &vat_main;
4418   vat_json_node_t node;
4419
4420   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4421   vat_json_init_object (&node);
4422   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4423
4424   vat_json_print (vam->ofp, &node);
4425   vat_json_free (&node);
4426
4427   vam->retval = ntohl (mp->retval);
4428   vam->result_ready = 1;
4429 }
4430
4431 static void
4432 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   i32 retval = ntohl (mp->retval);
4436
4437   if (0 <= retval)
4438     {
4439       print (vam->ofp, "%-20s%-16s",
4440              mp->status ? "enabled" : "disabled",
4441              mp->status ? (char *) mp->locator_set_name : "");
4442     }
4443
4444   vam->retval = retval;
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4450 {
4451   vat_main_t *vam = &vat_main;
4452   vat_json_node_t node;
4453   u8 *status = 0;
4454
4455   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4456   vec_add1 (status, 0);
4457
4458   vat_json_init_object (&node);
4459   vat_json_object_add_string_copy (&node, "status", status);
4460   if (mp->status)
4461     {
4462       vat_json_object_add_string_copy (&node, "locator_set",
4463                                        mp->locator_set_name);
4464     }
4465
4466   vec_free (status);
4467
4468   vat_json_print (vam->ofp, &node);
4469   vat_json_free (&node);
4470
4471   vam->retval = ntohl (mp->retval);
4472   vam->result_ready = 1;
4473 }
4474
4475 static u8 *
4476 format_policer_type (u8 * s, va_list * va)
4477 {
4478   u32 i = va_arg (*va, u32);
4479
4480   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4481     s = format (s, "1r2c");
4482   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4483     s = format (s, "1r3c");
4484   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4485     s = format (s, "2r3c-2698");
4486   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4487     s = format (s, "2r3c-4115");
4488   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4489     s = format (s, "2r3c-mef5cf1");
4490   else
4491     s = format (s, "ILLEGAL");
4492   return s;
4493 }
4494
4495 static u8 *
4496 format_policer_rate_type (u8 * s, va_list * va)
4497 {
4498   u32 i = va_arg (*va, u32);
4499
4500   if (i == SSE2_QOS_RATE_KBPS)
4501     s = format (s, "kbps");
4502   else if (i == SSE2_QOS_RATE_PPS)
4503     s = format (s, "pps");
4504   else
4505     s = format (s, "ILLEGAL");
4506   return s;
4507 }
4508
4509 static u8 *
4510 format_policer_round_type (u8 * s, va_list * va)
4511 {
4512   u32 i = va_arg (*va, u32);
4513
4514   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4515     s = format (s, "closest");
4516   else if (i == SSE2_QOS_ROUND_TO_UP)
4517     s = format (s, "up");
4518   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4519     s = format (s, "down");
4520   else
4521     s = format (s, "ILLEGAL");
4522   return s;
4523 }
4524
4525 static u8 *
4526 format_policer_action_type (u8 * s, va_list * va)
4527 {
4528   u32 i = va_arg (*va, u32);
4529
4530   if (i == SSE2_QOS_ACTION_DROP)
4531     s = format (s, "drop");
4532   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4533     s = format (s, "transmit");
4534   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4535     s = format (s, "mark-and-transmit");
4536   else
4537     s = format (s, "ILLEGAL");
4538   return s;
4539 }
4540
4541 static u8 *
4542 format_dscp (u8 * s, va_list * va)
4543 {
4544   u32 i = va_arg (*va, u32);
4545   char *t = 0;
4546
4547   switch (i)
4548     {
4549 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4550       foreach_vnet_dscp
4551 #undef _
4552     default:
4553       return format (s, "ILLEGAL");
4554     }
4555   s = format (s, "%s", t);
4556   return s;
4557 }
4558
4559 static void
4560 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4561 {
4562   vat_main_t *vam = &vat_main;
4563   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4564
4565   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4566     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4567   else
4568     conform_dscp_str = format (0, "");
4569
4570   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4571     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4572   else
4573     exceed_dscp_str = format (0, "");
4574
4575   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4576     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4577   else
4578     violate_dscp_str = format (0, "");
4579
4580   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4581          "rate type %U, round type %U, %s rate, %s color-aware, "
4582          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4583          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4584          "conform action %U%s, exceed action %U%s, violate action %U%s",
4585          mp->name,
4586          format_policer_type, mp->type,
4587          ntohl (mp->cir),
4588          ntohl (mp->eir),
4589          clib_net_to_host_u64 (mp->cb),
4590          clib_net_to_host_u64 (mp->eb),
4591          format_policer_rate_type, mp->rate_type,
4592          format_policer_round_type, mp->round_type,
4593          mp->single_rate ? "single" : "dual",
4594          mp->color_aware ? "is" : "not",
4595          ntohl (mp->cir_tokens_per_period),
4596          ntohl (mp->pir_tokens_per_period),
4597          ntohl (mp->scale),
4598          ntohl (mp->current_limit),
4599          ntohl (mp->current_bucket),
4600          ntohl (mp->extended_limit),
4601          ntohl (mp->extended_bucket),
4602          clib_net_to_host_u64 (mp->last_update_time),
4603          format_policer_action_type, mp->conform_action.type,
4604          conform_dscp_str,
4605          format_policer_action_type, mp->exceed_action.type,
4606          exceed_dscp_str,
4607          format_policer_action_type, mp->violate_action.type,
4608          violate_dscp_str);
4609
4610   vec_free (conform_dscp_str);
4611   vec_free (exceed_dscp_str);
4612   vec_free (violate_dscp_str);
4613 }
4614
4615 static void vl_api_policer_details_t_handler_json
4616   (vl_api_policer_details_t * mp)
4617 {
4618   vat_main_t *vam = &vat_main;
4619   vat_json_node_t *node;
4620   u8 *rate_type_str, *round_type_str, *type_str;
4621   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4622
4623   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4624   round_type_str =
4625     format (0, "%U", format_policer_round_type, mp->round_type);
4626   type_str = format (0, "%U", format_policer_type, mp->type);
4627   conform_action_str = format (0, "%U", format_policer_action_type,
4628                                mp->conform_action.type);
4629   exceed_action_str = format (0, "%U", format_policer_action_type,
4630                               mp->exceed_action.type);
4631   violate_action_str = format (0, "%U", format_policer_action_type,
4632                                mp->violate_action.type);
4633
4634   if (VAT_JSON_ARRAY != vam->json_tree.type)
4635     {
4636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4637       vat_json_init_array (&vam->json_tree);
4638     }
4639   node = vat_json_array_add (&vam->json_tree);
4640
4641   vat_json_init_object (node);
4642   vat_json_object_add_string_copy (node, "name", mp->name);
4643   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4644   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4645   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4646   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4647   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4648   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4649   vat_json_object_add_string_copy (node, "type", type_str);
4650   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4651   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4652   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4653   vat_json_object_add_uint (node, "cir_tokens_per_period",
4654                             ntohl (mp->cir_tokens_per_period));
4655   vat_json_object_add_uint (node, "eir_tokens_per_period",
4656                             ntohl (mp->pir_tokens_per_period));
4657   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4658   vat_json_object_add_uint (node, "current_bucket",
4659                             ntohl (mp->current_bucket));
4660   vat_json_object_add_uint (node, "extended_limit",
4661                             ntohl (mp->extended_limit));
4662   vat_json_object_add_uint (node, "extended_bucket",
4663                             ntohl (mp->extended_bucket));
4664   vat_json_object_add_uint (node, "last_update_time",
4665                             ntohl (mp->last_update_time));
4666   vat_json_object_add_string_copy (node, "conform_action",
4667                                    conform_action_str);
4668   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4669     {
4670       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4671       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4672       vec_free (dscp_str);
4673     }
4674   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4675   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4676     {
4677       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4678       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4679       vec_free (dscp_str);
4680     }
4681   vat_json_object_add_string_copy (node, "violate_action",
4682                                    violate_action_str);
4683   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4684     {
4685       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4686       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4687       vec_free (dscp_str);
4688     }
4689
4690   vec_free (rate_type_str);
4691   vec_free (round_type_str);
4692   vec_free (type_str);
4693   vec_free (conform_action_str);
4694   vec_free (exceed_action_str);
4695   vec_free (violate_action_str);
4696 }
4697
4698 static void
4699 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4700                                            mp)
4701 {
4702   vat_main_t *vam = &vat_main;
4703   int i, count = ntohl (mp->count);
4704
4705   if (count > 0)
4706     print (vam->ofp, "classify table ids (%d) : ", count);
4707   for (i = 0; i < count; i++)
4708     {
4709       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4710       print (vam->ofp, (i < count - 1) ? "," : "");
4711     }
4712   vam->retval = ntohl (mp->retval);
4713   vam->result_ready = 1;
4714 }
4715
4716 static void
4717   vl_api_classify_table_ids_reply_t_handler_json
4718   (vl_api_classify_table_ids_reply_t * mp)
4719 {
4720   vat_main_t *vam = &vat_main;
4721   int i, count = ntohl (mp->count);
4722
4723   if (count > 0)
4724     {
4725       vat_json_node_t node;
4726
4727       vat_json_init_object (&node);
4728       for (i = 0; i < count; i++)
4729         {
4730           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4731         }
4732       vat_json_print (vam->ofp, &node);
4733       vat_json_free (&node);
4734     }
4735   vam->retval = ntohl (mp->retval);
4736   vam->result_ready = 1;
4737 }
4738
4739 static void
4740   vl_api_classify_table_by_interface_reply_t_handler
4741   (vl_api_classify_table_by_interface_reply_t * mp)
4742 {
4743   vat_main_t *vam = &vat_main;
4744   u32 table_id;
4745
4746   table_id = ntohl (mp->l2_table_id);
4747   if (table_id != ~0)
4748     print (vam->ofp, "l2 table id : %d", table_id);
4749   else
4750     print (vam->ofp, "l2 table id : No input ACL tables configured");
4751   table_id = ntohl (mp->ip4_table_id);
4752   if (table_id != ~0)
4753     print (vam->ofp, "ip4 table id : %d", table_id);
4754   else
4755     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4756   table_id = ntohl (mp->ip6_table_id);
4757   if (table_id != ~0)
4758     print (vam->ofp, "ip6 table id : %d", table_id);
4759   else
4760     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4761   vam->retval = ntohl (mp->retval);
4762   vam->result_ready = 1;
4763 }
4764
4765 static void
4766   vl_api_classify_table_by_interface_reply_t_handler_json
4767   (vl_api_classify_table_by_interface_reply_t * mp)
4768 {
4769   vat_main_t *vam = &vat_main;
4770   vat_json_node_t node;
4771
4772   vat_json_init_object (&node);
4773
4774   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4775   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4776   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4777
4778   vat_json_print (vam->ofp, &node);
4779   vat_json_free (&node);
4780
4781   vam->retval = ntohl (mp->retval);
4782   vam->result_ready = 1;
4783 }
4784
4785 static void vl_api_policer_add_del_reply_t_handler
4786   (vl_api_policer_add_del_reply_t * mp)
4787 {
4788   vat_main_t *vam = &vat_main;
4789   i32 retval = ntohl (mp->retval);
4790   if (vam->async_mode)
4791     {
4792       vam->async_errors += (retval < 0);
4793     }
4794   else
4795     {
4796       vam->retval = retval;
4797       vam->result_ready = 1;
4798       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4799         /*
4800          * Note: this is just barely thread-safe, depends on
4801          * the main thread spinning waiting for an answer...
4802          */
4803         errmsg ("policer index %d", ntohl (mp->policer_index));
4804     }
4805 }
4806
4807 static void vl_api_policer_add_del_reply_t_handler_json
4808   (vl_api_policer_add_del_reply_t * mp)
4809 {
4810   vat_main_t *vam = &vat_main;
4811   vat_json_node_t node;
4812
4813   vat_json_init_object (&node);
4814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4815   vat_json_object_add_uint (&node, "policer_index",
4816                             ntohl (mp->policer_index));
4817
4818   vat_json_print (vam->ofp, &node);
4819   vat_json_free (&node);
4820
4821   vam->retval = ntohl (mp->retval);
4822   vam->result_ready = 1;
4823 }
4824
4825 /* Format hex dump. */
4826 u8 *
4827 format_hex_bytes (u8 * s, va_list * va)
4828 {
4829   u8 *bytes = va_arg (*va, u8 *);
4830   int n_bytes = va_arg (*va, int);
4831   uword i;
4832
4833   /* Print short or long form depending on byte count. */
4834   uword short_form = n_bytes <= 32;
4835   u32 indent = format_get_indent (s);
4836
4837   if (n_bytes == 0)
4838     return s;
4839
4840   for (i = 0; i < n_bytes; i++)
4841     {
4842       if (!short_form && (i % 32) == 0)
4843         s = format (s, "%08x: ", i);
4844       s = format (s, "%02x", bytes[i]);
4845       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4846         s = format (s, "\n%U", format_white_space, indent);
4847     }
4848
4849   return s;
4850 }
4851
4852 static void
4853 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4854                                             * mp)
4855 {
4856   vat_main_t *vam = &vat_main;
4857   i32 retval = ntohl (mp->retval);
4858   if (retval == 0)
4859     {
4860       print (vam->ofp, "classify table info :");
4861       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4862              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4863              ntohl (mp->miss_next_index));
4864       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4865              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4866              ntohl (mp->match_n_vectors));
4867       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4868              ntohl (mp->mask_length));
4869     }
4870   vam->retval = retval;
4871   vam->result_ready = 1;
4872 }
4873
4874 static void
4875   vl_api_classify_table_info_reply_t_handler_json
4876   (vl_api_classify_table_info_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   vat_json_node_t node;
4880
4881   i32 retval = ntohl (mp->retval);
4882   if (retval == 0)
4883     {
4884       vat_json_init_object (&node);
4885
4886       vat_json_object_add_int (&node, "sessions",
4887                                ntohl (mp->active_sessions));
4888       vat_json_object_add_int (&node, "nexttbl",
4889                                ntohl (mp->next_table_index));
4890       vat_json_object_add_int (&node, "nextnode",
4891                                ntohl (mp->miss_next_index));
4892       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4893       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4894       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4895       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4896                       ntohl (mp->mask_length), 0);
4897       vat_json_object_add_string_copy (&node, "mask", s);
4898
4899       vat_json_print (vam->ofp, &node);
4900       vat_json_free (&node);
4901     }
4902   vam->retval = ntohl (mp->retval);
4903   vam->result_ready = 1;
4904 }
4905
4906 static void
4907 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4908                                            mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911
4912   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4913          ntohl (mp->hit_next_index), ntohl (mp->advance),
4914          ntohl (mp->opaque_index));
4915   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4916          ntohl (mp->match_length));
4917 }
4918
4919 static void
4920   vl_api_classify_session_details_t_handler_json
4921   (vl_api_classify_session_details_t * mp)
4922 {
4923   vat_main_t *vam = &vat_main;
4924   vat_json_node_t *node = NULL;
4925
4926   if (VAT_JSON_ARRAY != vam->json_tree.type)
4927     {
4928       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4929       vat_json_init_array (&vam->json_tree);
4930     }
4931   node = vat_json_array_add (&vam->json_tree);
4932
4933   vat_json_init_object (node);
4934   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4935   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4936   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4937   u8 *s =
4938     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4939             0);
4940   vat_json_object_add_string_copy (node, "match", s);
4941 }
4942
4943 static void vl_api_pg_create_interface_reply_t_handler
4944   (vl_api_pg_create_interface_reply_t * mp)
4945 {
4946   vat_main_t *vam = &vat_main;
4947
4948   vam->retval = ntohl (mp->retval);
4949   vam->result_ready = 1;
4950 }
4951
4952 static void vl_api_pg_create_interface_reply_t_handler_json
4953   (vl_api_pg_create_interface_reply_t * mp)
4954 {
4955   vat_main_t *vam = &vat_main;
4956   vat_json_node_t node;
4957
4958   i32 retval = ntohl (mp->retval);
4959   if (retval == 0)
4960     {
4961       vat_json_init_object (&node);
4962
4963       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4964
4965       vat_json_print (vam->ofp, &node);
4966       vat_json_free (&node);
4967     }
4968   vam->retval = ntohl (mp->retval);
4969   vam->result_ready = 1;
4970 }
4971
4972 static void vl_api_policer_classify_details_t_handler
4973   (vl_api_policer_classify_details_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976
4977   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4978          ntohl (mp->table_index));
4979 }
4980
4981 static void vl_api_policer_classify_details_t_handler_json
4982   (vl_api_policer_classify_details_t * mp)
4983 {
4984   vat_main_t *vam = &vat_main;
4985   vat_json_node_t *node;
4986
4987   if (VAT_JSON_ARRAY != vam->json_tree.type)
4988     {
4989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4990       vat_json_init_array (&vam->json_tree);
4991     }
4992   node = vat_json_array_add (&vam->json_tree);
4993
4994   vat_json_init_object (node);
4995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4996   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4997 }
4998
4999 static void vl_api_flow_classify_details_t_handler
5000   (vl_api_flow_classify_details_t * mp)
5001 {
5002   vat_main_t *vam = &vat_main;
5003
5004   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5005          ntohl (mp->table_index));
5006 }
5007
5008 static void vl_api_flow_classify_details_t_handler_json
5009   (vl_api_flow_classify_details_t * mp)
5010 {
5011   vat_main_t *vam = &vat_main;
5012   vat_json_node_t *node;
5013
5014   if (VAT_JSON_ARRAY != vam->json_tree.type)
5015     {
5016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5017       vat_json_init_array (&vam->json_tree);
5018     }
5019   node = vat_json_array_add (&vam->json_tree);
5020
5021   vat_json_init_object (node);
5022   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5023   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5024 }
5025
5026 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5027 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5028 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5029 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5030 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5031 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5032 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5033 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5034 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5035 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5036
5037 /*
5038  * Generate boilerplate reply handlers, which
5039  * dig the return value out of the xxx_reply_t API message,
5040  * stick it into vam->retval, and set vam->result_ready
5041  *
5042  * Could also do this by pointing N message decode slots at
5043  * a single function, but that could break in subtle ways.
5044  */
5045
5046 #define foreach_standard_reply_retval_handler           \
5047 _(sw_interface_set_flags_reply)                         \
5048 _(sw_interface_add_del_address_reply)                   \
5049 _(sw_interface_set_rx_mode_reply)                       \
5050 _(sw_interface_set_rx_placement_reply)                  \
5051 _(sw_interface_set_table_reply)                         \
5052 _(sw_interface_set_mpls_enable_reply)                   \
5053 _(sw_interface_set_vpath_reply)                         \
5054 _(sw_interface_set_vxlan_bypass_reply)                  \
5055 _(sw_interface_set_geneve_bypass_reply)                 \
5056 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5057 _(sw_interface_set_l2_bridge_reply)                     \
5058 _(sw_interface_set_bond_weight_reply)                   \
5059 _(bridge_domain_add_del_reply)                          \
5060 _(sw_interface_set_l2_xconnect_reply)                   \
5061 _(l2fib_add_del_reply)                                  \
5062 _(l2fib_flush_int_reply)                                \
5063 _(l2fib_flush_bd_reply)                                 \
5064 _(ip_route_add_del_reply)                               \
5065 _(ip_table_add_del_reply)                               \
5066 _(ip_table_replace_begin_reply)                         \
5067 _(ip_table_flush_reply)                                 \
5068 _(ip_table_replace_end_reply)                           \
5069 _(ip_mroute_add_del_reply)                              \
5070 _(mpls_route_add_del_reply)                             \
5071 _(mpls_table_add_del_reply)                             \
5072 _(mpls_ip_bind_unbind_reply)                            \
5073 _(bier_route_add_del_reply)                             \
5074 _(bier_table_add_del_reply)                             \
5075 _(sw_interface_set_unnumbered_reply)                    \
5076 _(set_ip_flow_hash_reply)                               \
5077 _(sw_interface_ip6_enable_disable_reply)                \
5078 _(l2_patch_add_del_reply)                               \
5079 _(sr_mpls_policy_add_reply)                             \
5080 _(sr_mpls_policy_mod_reply)                             \
5081 _(sr_mpls_policy_del_reply)                             \
5082 _(sr_policy_add_reply)                                  \
5083 _(sr_policy_mod_reply)                                  \
5084 _(sr_policy_del_reply)                                  \
5085 _(sr_localsid_add_del_reply)                            \
5086 _(sr_steering_add_del_reply)                            \
5087 _(classify_add_del_session_reply)                       \
5088 _(classify_set_interface_ip_table_reply)                \
5089 _(classify_set_interface_l2_tables_reply)               \
5090 _(l2tpv3_set_tunnel_cookies_reply)                      \
5091 _(l2tpv3_interface_enable_disable_reply)                \
5092 _(l2tpv3_set_lookup_key_reply)                          \
5093 _(l2_fib_clear_table_reply)                             \
5094 _(l2_interface_efp_filter_reply)                        \
5095 _(l2_interface_vlan_tag_rewrite_reply)                  \
5096 _(modify_vhost_user_if_reply)                           \
5097 _(delete_vhost_user_if_reply)                           \
5098 _(want_l2_macs_events_reply)                            \
5099 _(input_acl_set_interface_reply)                        \
5100 _(ipsec_spd_add_del_reply)                              \
5101 _(ipsec_interface_add_del_spd_reply)                    \
5102 _(ipsec_spd_entry_add_del_reply)                        \
5103 _(ipsec_sad_entry_add_del_reply)                        \
5104 _(ipsec_tunnel_if_add_del_reply)                        \
5105 _(ipsec_tunnel_if_set_sa_reply)                         \
5106 _(delete_loopback_reply)                                \
5107 _(bd_ip_mac_add_del_reply)                              \
5108 _(bd_ip_mac_flush_reply)                                \
5109 _(want_interface_events_reply)                          \
5110 _(cop_interface_enable_disable_reply)                   \
5111 _(cop_whitelist_enable_disable_reply)                   \
5112 _(sw_interface_clear_stats_reply)                       \
5113 _(ioam_enable_reply)                                    \
5114 _(ioam_disable_reply)                                   \
5115 _(one_add_del_locator_reply)                            \
5116 _(one_add_del_local_eid_reply)                          \
5117 _(one_add_del_remote_mapping_reply)                     \
5118 _(one_add_del_adjacency_reply)                          \
5119 _(one_add_del_map_resolver_reply)                       \
5120 _(one_add_del_map_server_reply)                         \
5121 _(one_enable_disable_reply)                             \
5122 _(one_rloc_probe_enable_disable_reply)                  \
5123 _(one_map_register_enable_disable_reply)                \
5124 _(one_map_register_set_ttl_reply)                       \
5125 _(one_set_transport_protocol_reply)                     \
5126 _(one_map_register_fallback_threshold_reply)            \
5127 _(one_pitr_set_locator_set_reply)                       \
5128 _(one_map_request_mode_reply)                           \
5129 _(one_add_del_map_request_itr_rlocs_reply)              \
5130 _(one_eid_table_add_del_map_reply)                      \
5131 _(one_use_petr_reply)                                   \
5132 _(one_stats_enable_disable_reply)                       \
5133 _(one_add_del_l2_arp_entry_reply)                       \
5134 _(one_add_del_ndp_entry_reply)                          \
5135 _(one_stats_flush_reply)                                \
5136 _(one_enable_disable_xtr_mode_reply)                    \
5137 _(one_enable_disable_pitr_mode_reply)                   \
5138 _(one_enable_disable_petr_mode_reply)                   \
5139 _(gpe_enable_disable_reply)                             \
5140 _(gpe_set_encap_mode_reply)                             \
5141 _(gpe_add_del_iface_reply)                              \
5142 _(gpe_add_del_native_fwd_rpath_reply)                   \
5143 _(af_packet_delete_reply)                               \
5144 _(policer_classify_set_interface_reply)                 \
5145 _(set_ipfix_exporter_reply)                             \
5146 _(set_ipfix_classify_stream_reply)                      \
5147 _(ipfix_classify_table_add_del_reply)                   \
5148 _(flow_classify_set_interface_reply)                    \
5149 _(sw_interface_span_enable_disable_reply)               \
5150 _(pg_capture_reply)                                     \
5151 _(pg_enable_disable_reply)                              \
5152 _(pg_interface_enable_disable_coalesce_reply)           \
5153 _(ip_source_and_port_range_check_add_del_reply)         \
5154 _(ip_source_and_port_range_check_interface_add_del_reply)\
5155 _(delete_subif_reply)                                   \
5156 _(l2_interface_pbb_tag_rewrite_reply)                   \
5157 _(set_punt_reply)                                       \
5158 _(feature_enable_disable_reply)                         \
5159 _(feature_gso_enable_disable_reply)                     \
5160 _(sw_interface_tag_add_del_reply)                       \
5161 _(sw_interface_add_del_mac_address_reply)               \
5162 _(hw_interface_set_mtu_reply)                           \
5163 _(p2p_ethernet_add_reply)                               \
5164 _(p2p_ethernet_del_reply)                               \
5165 _(lldp_config_reply)                                    \
5166 _(sw_interface_set_lldp_reply)                          \
5167 _(tcp_configure_src_addresses_reply)                    \
5168 _(session_rule_add_del_reply)                           \
5169 _(ip_container_proxy_add_del_reply)                     \
5170 _(output_acl_set_interface_reply)                       \
5171 _(qos_record_enable_disable_reply)
5172
5173 #define _(n)                                    \
5174     static void vl_api_##n##_t_handler          \
5175     (vl_api_##n##_t * mp)                       \
5176     {                                           \
5177         vat_main_t * vam = &vat_main;           \
5178         i32 retval = ntohl(mp->retval);         \
5179         if (vam->async_mode) {                  \
5180             vam->async_errors += (retval < 0);  \
5181         } else {                                \
5182             vam->retval = retval;               \
5183             vam->result_ready = 1;              \
5184         }                                       \
5185     }
5186 foreach_standard_reply_retval_handler;
5187 #undef _
5188
5189 #define _(n)                                    \
5190     static void vl_api_##n##_t_handler_json     \
5191     (vl_api_##n##_t * mp)                       \
5192     {                                           \
5193         vat_main_t * vam = &vat_main;           \
5194         vat_json_node_t node;                   \
5195         vat_json_init_object(&node);            \
5196         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5197         vat_json_print(vam->ofp, &node);        \
5198         vam->retval = ntohl(mp->retval);        \
5199         vam->result_ready = 1;                  \
5200     }
5201 foreach_standard_reply_retval_handler;
5202 #undef _
5203
5204 /*
5205  * Table of message reply handlers, must include boilerplate handlers
5206  * we just generated
5207  */
5208
5209 #define foreach_vpe_api_reply_msg                                       \
5210 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5211 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5212 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5213 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5214 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5215 _(CLI_REPLY, cli_reply)                                                 \
5216 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5217 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5218   sw_interface_add_del_address_reply)                                   \
5219 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5220 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5221 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5222 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5223 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5224 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5225 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5226 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5227 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5228 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5229   sw_interface_set_l2_xconnect_reply)                                   \
5230 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5231   sw_interface_set_l2_bridge_reply)                                     \
5232 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5233 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5234 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5235 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5236 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5237 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5238 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5239 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5240 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5241 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5242 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5243 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5244 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5245 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5246 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5247 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5248 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
5249 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
5250 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5251 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
5252 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
5253 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5254 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5255 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5256 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5257 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5258 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5259 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5260 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5261 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5262 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5263 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5264 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5265 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5266   sw_interface_set_unnumbered_reply)                                    \
5267 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5268 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5269 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5270 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5271   sw_interface_ip6_enable_disable_reply)                                \
5272 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5273 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5274 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5275 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5276 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5277 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5278 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5279 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5280 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5281 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5282 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5283 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5284 classify_set_interface_ip_table_reply)                                  \
5285 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5286   classify_set_interface_l2_tables_reply)                               \
5287 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5288 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5289 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5290 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5291 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5292   l2tpv3_interface_enable_disable_reply)                                \
5293 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5294 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5295 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5296 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5297 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5298 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5299 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5300 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5301 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5302 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5303 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5304 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5305 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5306 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5307 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5308 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5309 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5310 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5311 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5312 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5313 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5314 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5315 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5316 _(L2_MACS_EVENT, l2_macs_event)                                         \
5317 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5318 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5319 _(IP_DETAILS, ip_details)                                               \
5320 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5321 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5322 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5323 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5324 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5325 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5326 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5327 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5328 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5329 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5330 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5331 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5332 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5333 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5334 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5335 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5336 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5337 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5338 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5339 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5340 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5341 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5342 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5343 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5344 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5345 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5346 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5347 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5348   one_map_register_enable_disable_reply)                                \
5349 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5350 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5351 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5352 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5353   one_map_register_fallback_threshold_reply)                            \
5354 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5355   one_rloc_probe_enable_disable_reply)                                  \
5356 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5357 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5358 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5359 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5360 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5361 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5362 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5363 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5364 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5365 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5366 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5367 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5368 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5369 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5370 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5371 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5372   show_one_stats_enable_disable_reply)                                  \
5373 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5374 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5375 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5376 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5377 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5378 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5379 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5380 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5381   one_enable_disable_pitr_mode_reply)                                   \
5382 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5383   one_enable_disable_petr_mode_reply)                                   \
5384 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5385 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5386 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5387 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5388 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5389 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5390 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5391 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5392 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5393 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5394 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5395 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5396   gpe_add_del_native_fwd_rpath_reply)                                   \
5397 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5398   gpe_fwd_entry_path_details)                                           \
5399 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5400 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5401   one_add_del_map_request_itr_rlocs_reply)                              \
5402 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5403   one_get_map_request_itr_rlocs_reply)                                  \
5404 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5405 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5406 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5407 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5408 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5409 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5410   show_one_map_register_state_reply)                                    \
5411 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5412 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5413   show_one_map_register_fallback_threshold_reply)                       \
5414 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5415 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5416 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5417 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5418 _(POLICER_DETAILS, policer_details)                                     \
5419 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5420 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5421 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5422 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5423 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5424 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5425 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5426 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5427 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5428 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5429 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5430 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5431 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5432 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5433 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5434 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5435 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5436 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5437 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5438 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5439 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5440 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5441 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5442 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
5443 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5444  ip_source_and_port_range_check_add_del_reply)                          \
5445 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5446  ip_source_and_port_range_check_interface_add_del_reply)                \
5447 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5448 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5449 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5450 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5451 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5452 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5453 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5454 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5455 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5456 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5457 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5458 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5459 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5460 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5461 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5462 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5463 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5464 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5465 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5466 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5467 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5468 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5469 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5470
5471 #define foreach_standalone_reply_msg                                    \
5472 _(SW_INTERFACE_EVENT, sw_interface_event)
5473
5474 typedef struct
5475 {
5476   u8 *name;
5477   u32 value;
5478 } name_sort_t;
5479
5480 #define STR_VTR_OP_CASE(op)     \
5481     case L2_VTR_ ## op:         \
5482         return "" # op;
5483
5484 static const char *
5485 str_vtr_op (u32 vtr_op)
5486 {
5487   switch (vtr_op)
5488     {
5489       STR_VTR_OP_CASE (DISABLED);
5490       STR_VTR_OP_CASE (PUSH_1);
5491       STR_VTR_OP_CASE (PUSH_2);
5492       STR_VTR_OP_CASE (POP_1);
5493       STR_VTR_OP_CASE (POP_2);
5494       STR_VTR_OP_CASE (TRANSLATE_1_1);
5495       STR_VTR_OP_CASE (TRANSLATE_1_2);
5496       STR_VTR_OP_CASE (TRANSLATE_2_1);
5497       STR_VTR_OP_CASE (TRANSLATE_2_2);
5498     }
5499
5500   return "UNKNOWN";
5501 }
5502
5503 static int
5504 dump_sub_interface_table (vat_main_t * vam)
5505 {
5506   const sw_interface_subif_t *sub = NULL;
5507
5508   if (vam->json_output)
5509     {
5510       clib_warning
5511         ("JSON output supported only for VPE API calls and dump_stats_table");
5512       return -99;
5513     }
5514
5515   print (vam->ofp,
5516          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5517          "Interface", "sw_if_index",
5518          "sub id", "dot1ad", "tags", "outer id",
5519          "inner id", "exact", "default", "outer any", "inner any");
5520
5521   vec_foreach (sub, vam->sw_if_subif_table)
5522   {
5523     print (vam->ofp,
5524            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5525            sub->interface_name,
5526            sub->sw_if_index,
5527            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5528            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5529            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5530            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5531     if (sub->vtr_op != L2_VTR_DISABLED)
5532       {
5533         print (vam->ofp,
5534                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5535                "tag1: %d tag2: %d ]",
5536                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5537                sub->vtr_tag1, sub->vtr_tag2);
5538       }
5539   }
5540
5541   return 0;
5542 }
5543
5544 static int
5545 name_sort_cmp (void *a1, void *a2)
5546 {
5547   name_sort_t *n1 = a1;
5548   name_sort_t *n2 = a2;
5549
5550   return strcmp ((char *) n1->name, (char *) n2->name);
5551 }
5552
5553 static int
5554 dump_interface_table (vat_main_t * vam)
5555 {
5556   hash_pair_t *p;
5557   name_sort_t *nses = 0, *ns;
5558
5559   if (vam->json_output)
5560     {
5561       clib_warning
5562         ("JSON output supported only for VPE API calls and dump_stats_table");
5563       return -99;
5564     }
5565
5566   /* *INDENT-OFF* */
5567   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5568   ({
5569     vec_add2 (nses, ns, 1);
5570     ns->name = (u8 *)(p->key);
5571     ns->value = (u32) p->value[0];
5572   }));
5573   /* *INDENT-ON* */
5574
5575   vec_sort_with_function (nses, name_sort_cmp);
5576
5577   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5578   vec_foreach (ns, nses)
5579   {
5580     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5581   }
5582   vec_free (nses);
5583   return 0;
5584 }
5585
5586 static int
5587 dump_ip_table (vat_main_t * vam, int is_ipv6)
5588 {
5589   const ip_details_t *det = NULL;
5590   const ip_address_details_t *address = NULL;
5591   u32 i = ~0;
5592
5593   print (vam->ofp, "%-12s", "sw_if_index");
5594
5595   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5596   {
5597     i++;
5598     if (!det->present)
5599       {
5600         continue;
5601       }
5602     print (vam->ofp, "%-12d", i);
5603     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5604     if (!det->addr)
5605       {
5606         continue;
5607       }
5608     vec_foreach (address, det->addr)
5609     {
5610       print (vam->ofp,
5611              "            %-30U%-13d",
5612              is_ipv6 ? format_ip6_address : format_ip4_address,
5613              address->ip, address->prefix_length);
5614     }
5615   }
5616
5617   return 0;
5618 }
5619
5620 static int
5621 dump_ipv4_table (vat_main_t * vam)
5622 {
5623   if (vam->json_output)
5624     {
5625       clib_warning
5626         ("JSON output supported only for VPE API calls and dump_stats_table");
5627       return -99;
5628     }
5629
5630   return dump_ip_table (vam, 0);
5631 }
5632
5633 static int
5634 dump_ipv6_table (vat_main_t * vam)
5635 {
5636   if (vam->json_output)
5637     {
5638       clib_warning
5639         ("JSON output supported only for VPE API calls and dump_stats_table");
5640       return -99;
5641     }
5642
5643   return dump_ip_table (vam, 1);
5644 }
5645
5646 /*
5647  * Pass CLI buffers directly in the CLI_INBAND API message,
5648  * instead of an additional shared memory area.
5649  */
5650 static int
5651 exec_inband (vat_main_t * vam)
5652 {
5653   vl_api_cli_inband_t *mp;
5654   unformat_input_t *i = vam->input;
5655   int ret;
5656
5657   if (vec_len (i->buffer) == 0)
5658     return -1;
5659
5660   if (vam->exec_mode == 0 && unformat (i, "mode"))
5661     {
5662       vam->exec_mode = 1;
5663       return 0;
5664     }
5665   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5666     {
5667       vam->exec_mode = 0;
5668       return 0;
5669     }
5670
5671   /*
5672    * In order for the CLI command to work, it
5673    * must be a vector ending in \n, not a C-string ending
5674    * in \n\0.
5675    */
5676   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5677   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5678
5679   S (mp);
5680   W (ret);
5681   /* json responses may or may not include a useful reply... */
5682   if (vec_len (vam->cmd_reply))
5683     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5684   return ret;
5685 }
5686
5687 int
5688 exec (vat_main_t * vam)
5689 {
5690   return exec_inband (vam);
5691 }
5692
5693 static int
5694 api_create_loopback (vat_main_t * vam)
5695 {
5696   unformat_input_t *i = vam->input;
5697   vl_api_create_loopback_t *mp;
5698   vl_api_create_loopback_instance_t *mp_lbi;
5699   u8 mac_address[6];
5700   u8 mac_set = 0;
5701   u8 is_specified = 0;
5702   u32 user_instance = 0;
5703   int ret;
5704
5705   clib_memset (mac_address, 0, sizeof (mac_address));
5706
5707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5708     {
5709       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5710         mac_set = 1;
5711       if (unformat (i, "instance %d", &user_instance))
5712         is_specified = 1;
5713       else
5714         break;
5715     }
5716
5717   if (is_specified)
5718     {
5719       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5720       mp_lbi->is_specified = is_specified;
5721       if (is_specified)
5722         mp_lbi->user_instance = htonl (user_instance);
5723       if (mac_set)
5724         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5725       S (mp_lbi);
5726     }
5727   else
5728     {
5729       /* Construct the API message */
5730       M (CREATE_LOOPBACK, mp);
5731       if (mac_set)
5732         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5733       S (mp);
5734     }
5735
5736   W (ret);
5737   return ret;
5738 }
5739
5740 static int
5741 api_delete_loopback (vat_main_t * vam)
5742 {
5743   unformat_input_t *i = vam->input;
5744   vl_api_delete_loopback_t *mp;
5745   u32 sw_if_index = ~0;
5746   int ret;
5747
5748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5749     {
5750       if (unformat (i, "sw_if_index %d", &sw_if_index))
5751         ;
5752       else
5753         break;
5754     }
5755
5756   if (sw_if_index == ~0)
5757     {
5758       errmsg ("missing sw_if_index");
5759       return -99;
5760     }
5761
5762   /* Construct the API message */
5763   M (DELETE_LOOPBACK, mp);
5764   mp->sw_if_index = ntohl (sw_if_index);
5765
5766   S (mp);
5767   W (ret);
5768   return ret;
5769 }
5770
5771 static int
5772 api_want_interface_events (vat_main_t * vam)
5773 {
5774   unformat_input_t *i = vam->input;
5775   vl_api_want_interface_events_t *mp;
5776   int enable = -1;
5777   int ret;
5778
5779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780     {
5781       if (unformat (i, "enable"))
5782         enable = 1;
5783       else if (unformat (i, "disable"))
5784         enable = 0;
5785       else
5786         break;
5787     }
5788
5789   if (enable == -1)
5790     {
5791       errmsg ("missing enable|disable");
5792       return -99;
5793     }
5794
5795   M (WANT_INTERFACE_EVENTS, mp);
5796   mp->enable_disable = enable;
5797
5798   vam->interface_event_display = enable;
5799
5800   S (mp);
5801   W (ret);
5802   return ret;
5803 }
5804
5805
5806 /* Note: non-static, called once to set up the initial intfc table */
5807 int
5808 api_sw_interface_dump (vat_main_t * vam)
5809 {
5810   vl_api_sw_interface_dump_t *mp;
5811   vl_api_control_ping_t *mp_ping;
5812   hash_pair_t *p;
5813   name_sort_t *nses = 0, *ns;
5814   sw_interface_subif_t *sub = NULL;
5815   int ret;
5816
5817   /* Toss the old name table */
5818   /* *INDENT-OFF* */
5819   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5820   ({
5821     vec_add2 (nses, ns, 1);
5822     ns->name = (u8 *)(p->key);
5823     ns->value = (u32) p->value[0];
5824   }));
5825   /* *INDENT-ON* */
5826
5827   hash_free (vam->sw_if_index_by_interface_name);
5828
5829   vec_foreach (ns, nses) vec_free (ns->name);
5830
5831   vec_free (nses);
5832
5833   vec_foreach (sub, vam->sw_if_subif_table)
5834   {
5835     vec_free (sub->interface_name);
5836   }
5837   vec_free (vam->sw_if_subif_table);
5838
5839   /* recreate the interface name hash table */
5840   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5841
5842   /*
5843    * Ask for all interface names. Otherwise, the epic catalog of
5844    * name filters becomes ridiculously long, and vat ends up needing
5845    * to be taught about new interface types.
5846    */
5847   M (SW_INTERFACE_DUMP, mp);
5848   S (mp);
5849
5850   /* Use a control ping for synchronization */
5851   MPING (CONTROL_PING, mp_ping);
5852   S (mp_ping);
5853
5854   W (ret);
5855   return ret;
5856 }
5857
5858 static int
5859 api_sw_interface_set_flags (vat_main_t * vam)
5860 {
5861   unformat_input_t *i = vam->input;
5862   vl_api_sw_interface_set_flags_t *mp;
5863   u32 sw_if_index;
5864   u8 sw_if_index_set = 0;
5865   u8 admin_up = 0;
5866   int ret;
5867
5868   /* Parse args required to build the message */
5869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5870     {
5871       if (unformat (i, "admin-up"))
5872         admin_up = 1;
5873       else if (unformat (i, "admin-down"))
5874         admin_up = 0;
5875       else
5876         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5877         sw_if_index_set = 1;
5878       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5879         sw_if_index_set = 1;
5880       else
5881         break;
5882     }
5883
5884   if (sw_if_index_set == 0)
5885     {
5886       errmsg ("missing interface name or sw_if_index");
5887       return -99;
5888     }
5889
5890   /* Construct the API message */
5891   M (SW_INTERFACE_SET_FLAGS, mp);
5892   mp->sw_if_index = ntohl (sw_if_index);
5893   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5894
5895   /* send it... */
5896   S (mp);
5897
5898   /* Wait for a reply, return the good/bad news... */
5899   W (ret);
5900   return ret;
5901 }
5902
5903 static int
5904 api_sw_interface_set_rx_mode (vat_main_t * vam)
5905 {
5906   unformat_input_t *i = vam->input;
5907   vl_api_sw_interface_set_rx_mode_t *mp;
5908   u32 sw_if_index;
5909   u8 sw_if_index_set = 0;
5910   int ret;
5911   u8 queue_id_valid = 0;
5912   u32 queue_id;
5913   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5914
5915   /* Parse args required to build the message */
5916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5917     {
5918       if (unformat (i, "queue %d", &queue_id))
5919         queue_id_valid = 1;
5920       else if (unformat (i, "polling"))
5921         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5922       else if (unformat (i, "interrupt"))
5923         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5924       else if (unformat (i, "adaptive"))
5925         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5926       else
5927         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5928         sw_if_index_set = 1;
5929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5930         sw_if_index_set = 1;
5931       else
5932         break;
5933     }
5934
5935   if (sw_if_index_set == 0)
5936     {
5937       errmsg ("missing interface name or sw_if_index");
5938       return -99;
5939     }
5940   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5941     {
5942       errmsg ("missing rx-mode");
5943       return -99;
5944     }
5945
5946   /* Construct the API message */
5947   M (SW_INTERFACE_SET_RX_MODE, mp);
5948   mp->sw_if_index = ntohl (sw_if_index);
5949   mp->mode = (vl_api_rx_mode_t) mode;
5950   mp->queue_id_valid = queue_id_valid;
5951   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5952
5953   /* send it... */
5954   S (mp);
5955
5956   /* Wait for a reply, return the good/bad news... */
5957   W (ret);
5958   return ret;
5959 }
5960
5961 static int
5962 api_sw_interface_set_rx_placement (vat_main_t * vam)
5963 {
5964   unformat_input_t *i = vam->input;
5965   vl_api_sw_interface_set_rx_placement_t *mp;
5966   u32 sw_if_index;
5967   u8 sw_if_index_set = 0;
5968   int ret;
5969   u8 is_main = 0;
5970   u32 queue_id, thread_index;
5971
5972   /* Parse args required to build the message */
5973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5974     {
5975       if (unformat (i, "queue %d", &queue_id))
5976         ;
5977       else if (unformat (i, "main"))
5978         is_main = 1;
5979       else if (unformat (i, "worker %d", &thread_index))
5980         ;
5981       else
5982         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5983         sw_if_index_set = 1;
5984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5985         sw_if_index_set = 1;
5986       else
5987         break;
5988     }
5989
5990   if (sw_if_index_set == 0)
5991     {
5992       errmsg ("missing interface name or sw_if_index");
5993       return -99;
5994     }
5995
5996   if (is_main)
5997     thread_index = 0;
5998   /* Construct the API message */
5999   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6000   mp->sw_if_index = ntohl (sw_if_index);
6001   mp->worker_id = ntohl (thread_index);
6002   mp->queue_id = ntohl (queue_id);
6003   mp->is_main = is_main;
6004
6005   /* send it... */
6006   S (mp);
6007   /* Wait for a reply, return the good/bad news... */
6008   W (ret);
6009   return ret;
6010 }
6011
6012 static void vl_api_sw_interface_rx_placement_details_t_handler
6013   (vl_api_sw_interface_rx_placement_details_t * mp)
6014 {
6015   vat_main_t *vam = &vat_main;
6016   u32 worker_id = ntohl (mp->worker_id);
6017
6018   print (vam->ofp,
6019          "\n%-11d %-11s %-6d %-5d %-9s",
6020          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6021          worker_id, ntohl (mp->queue_id),
6022          (mp->mode ==
6023           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6024 }
6025
6026 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6027   (vl_api_sw_interface_rx_placement_details_t * mp)
6028 {
6029   vat_main_t *vam = &vat_main;
6030   vat_json_node_t *node = NULL;
6031
6032   if (VAT_JSON_ARRAY != vam->json_tree.type)
6033     {
6034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6035       vat_json_init_array (&vam->json_tree);
6036     }
6037   node = vat_json_array_add (&vam->json_tree);
6038
6039   vat_json_init_object (node);
6040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6041   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6042   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6043   vat_json_object_add_uint (node, "mode", mp->mode);
6044 }
6045
6046 static int
6047 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6048 {
6049   unformat_input_t *i = vam->input;
6050   vl_api_sw_interface_rx_placement_dump_t *mp;
6051   vl_api_control_ping_t *mp_ping;
6052   int ret;
6053   u32 sw_if_index;
6054   u8 sw_if_index_set = 0;
6055
6056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6057     {
6058       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6059         sw_if_index_set++;
6060       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6061         sw_if_index_set++;
6062       else
6063         break;
6064     }
6065
6066   print (vam->ofp,
6067          "\n%-11s %-11s %-6s %-5s %-4s",
6068          "sw_if_index", "main/worker", "thread", "queue", "mode");
6069
6070   /* Dump Interface rx placement */
6071   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6072
6073   if (sw_if_index_set)
6074     mp->sw_if_index = htonl (sw_if_index);
6075   else
6076     mp->sw_if_index = ~0;
6077
6078   S (mp);
6079
6080   /* Use a control ping for synchronization */
6081   MPING (CONTROL_PING, mp_ping);
6082   S (mp_ping);
6083
6084   W (ret);
6085   return ret;
6086 }
6087
6088 static int
6089 api_sw_interface_clear_stats (vat_main_t * vam)
6090 {
6091   unformat_input_t *i = vam->input;
6092   vl_api_sw_interface_clear_stats_t *mp;
6093   u32 sw_if_index;
6094   u8 sw_if_index_set = 0;
6095   int ret;
6096
6097   /* Parse args required to build the message */
6098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6099     {
6100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6101         sw_if_index_set = 1;
6102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6103         sw_if_index_set = 1;
6104       else
6105         break;
6106     }
6107
6108   /* Construct the API message */
6109   M (SW_INTERFACE_CLEAR_STATS, mp);
6110
6111   if (sw_if_index_set == 1)
6112     mp->sw_if_index = ntohl (sw_if_index);
6113   else
6114     mp->sw_if_index = ~0;
6115
6116   /* send it... */
6117   S (mp);
6118
6119   /* Wait for a reply, return the good/bad news... */
6120   W (ret);
6121   return ret;
6122 }
6123
6124 static int
6125 api_sw_interface_add_del_address (vat_main_t * vam)
6126 {
6127   unformat_input_t *i = vam->input;
6128   vl_api_sw_interface_add_del_address_t *mp;
6129   u32 sw_if_index;
6130   u8 sw_if_index_set = 0;
6131   u8 is_add = 1, del_all = 0;
6132   u32 address_length = 0;
6133   u8 v4_address_set = 0;
6134   u8 v6_address_set = 0;
6135   ip4_address_t v4address;
6136   ip6_address_t v6address;
6137   int ret;
6138
6139   /* Parse args required to build the message */
6140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6141     {
6142       if (unformat (i, "del-all"))
6143         del_all = 1;
6144       else if (unformat (i, "del"))
6145         is_add = 0;
6146       else
6147         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6148         sw_if_index_set = 1;
6149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6150         sw_if_index_set = 1;
6151       else if (unformat (i, "%U/%d",
6152                          unformat_ip4_address, &v4address, &address_length))
6153         v4_address_set = 1;
6154       else if (unformat (i, "%U/%d",
6155                          unformat_ip6_address, &v6address, &address_length))
6156         v6_address_set = 1;
6157       else
6158         break;
6159     }
6160
6161   if (sw_if_index_set == 0)
6162     {
6163       errmsg ("missing interface name or sw_if_index");
6164       return -99;
6165     }
6166   if (v4_address_set && v6_address_set)
6167     {
6168       errmsg ("both v4 and v6 addresses set");
6169       return -99;
6170     }
6171   if (!v4_address_set && !v6_address_set && !del_all)
6172     {
6173       errmsg ("no addresses set");
6174       return -99;
6175     }
6176
6177   /* Construct the API message */
6178   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6179
6180   mp->sw_if_index = ntohl (sw_if_index);
6181   mp->is_add = is_add;
6182   mp->del_all = del_all;
6183   if (v6_address_set)
6184     {
6185       mp->prefix.address.af = ADDRESS_IP6;
6186       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6187     }
6188   else
6189     {
6190       mp->prefix.address.af = ADDRESS_IP4;
6191       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6192     }
6193   mp->prefix.len = address_length;
6194
6195   /* send it... */
6196   S (mp);
6197
6198   /* Wait for a reply, return good/bad news  */
6199   W (ret);
6200   return ret;
6201 }
6202
6203 static int
6204 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6205 {
6206   unformat_input_t *i = vam->input;
6207   vl_api_sw_interface_set_mpls_enable_t *mp;
6208   u32 sw_if_index;
6209   u8 sw_if_index_set = 0;
6210   u8 enable = 1;
6211   int ret;
6212
6213   /* Parse args required to build the message */
6214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6215     {
6216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6217         sw_if_index_set = 1;
6218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6219         sw_if_index_set = 1;
6220       else if (unformat (i, "disable"))
6221         enable = 0;
6222       else if (unformat (i, "dis"))
6223         enable = 0;
6224       else
6225         break;
6226     }
6227
6228   if (sw_if_index_set == 0)
6229     {
6230       errmsg ("missing interface name or sw_if_index");
6231       return -99;
6232     }
6233
6234   /* Construct the API message */
6235   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6236
6237   mp->sw_if_index = ntohl (sw_if_index);
6238   mp->enable = enable;
6239
6240   /* send it... */
6241   S (mp);
6242
6243   /* Wait for a reply... */
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_sw_interface_set_table (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_sw_interface_set_table_t *mp;
6253   u32 sw_if_index, vrf_id = 0;
6254   u8 sw_if_index_set = 0;
6255   u8 is_ipv6 = 0;
6256   int ret;
6257
6258   /* Parse args required to build the message */
6259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6260     {
6261       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6264         sw_if_index_set = 1;
6265       else if (unformat (i, "vrf %d", &vrf_id))
6266         ;
6267       else if (unformat (i, "ipv6"))
6268         is_ipv6 = 1;
6269       else
6270         break;
6271     }
6272
6273   if (sw_if_index_set == 0)
6274     {
6275       errmsg ("missing interface name or sw_if_index");
6276       return -99;
6277     }
6278
6279   /* Construct the API message */
6280   M (SW_INTERFACE_SET_TABLE, mp);
6281
6282   mp->sw_if_index = ntohl (sw_if_index);
6283   mp->is_ipv6 = is_ipv6;
6284   mp->vrf_id = ntohl (vrf_id);
6285
6286   /* send it... */
6287   S (mp);
6288
6289   /* Wait for a reply... */
6290   W (ret);
6291   return ret;
6292 }
6293
6294 static void vl_api_sw_interface_get_table_reply_t_handler
6295   (vl_api_sw_interface_get_table_reply_t * mp)
6296 {
6297   vat_main_t *vam = &vat_main;
6298
6299   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6300
6301   vam->retval = ntohl (mp->retval);
6302   vam->result_ready = 1;
6303
6304 }
6305
6306 static void vl_api_sw_interface_get_table_reply_t_handler_json
6307   (vl_api_sw_interface_get_table_reply_t * mp)
6308 {
6309   vat_main_t *vam = &vat_main;
6310   vat_json_node_t node;
6311
6312   vat_json_init_object (&node);
6313   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6314   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6315
6316   vat_json_print (vam->ofp, &node);
6317   vat_json_free (&node);
6318
6319   vam->retval = ntohl (mp->retval);
6320   vam->result_ready = 1;
6321 }
6322
6323 static int
6324 api_sw_interface_get_table (vat_main_t * vam)
6325 {
6326   unformat_input_t *i = vam->input;
6327   vl_api_sw_interface_get_table_t *mp;
6328   u32 sw_if_index;
6329   u8 sw_if_index_set = 0;
6330   u8 is_ipv6 = 0;
6331   int ret;
6332
6333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6334     {
6335       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6336         sw_if_index_set = 1;
6337       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6338         sw_if_index_set = 1;
6339       else if (unformat (i, "ipv6"))
6340         is_ipv6 = 1;
6341       else
6342         break;
6343     }
6344
6345   if (sw_if_index_set == 0)
6346     {
6347       errmsg ("missing interface name or sw_if_index");
6348       return -99;
6349     }
6350
6351   M (SW_INTERFACE_GET_TABLE, mp);
6352   mp->sw_if_index = htonl (sw_if_index);
6353   mp->is_ipv6 = is_ipv6;
6354
6355   S (mp);
6356   W (ret);
6357   return ret;
6358 }
6359
6360 static int
6361 api_sw_interface_set_vpath (vat_main_t * vam)
6362 {
6363   unformat_input_t *i = vam->input;
6364   vl_api_sw_interface_set_vpath_t *mp;
6365   u32 sw_if_index = 0;
6366   u8 sw_if_index_set = 0;
6367   u8 is_enable = 0;
6368   int ret;
6369
6370   /* Parse args required to build the message */
6371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6372     {
6373       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6374         sw_if_index_set = 1;
6375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6376         sw_if_index_set = 1;
6377       else if (unformat (i, "enable"))
6378         is_enable = 1;
6379       else if (unformat (i, "disable"))
6380         is_enable = 0;
6381       else
6382         break;
6383     }
6384
6385   if (sw_if_index_set == 0)
6386     {
6387       errmsg ("missing interface name or sw_if_index");
6388       return -99;
6389     }
6390
6391   /* Construct the API message */
6392   M (SW_INTERFACE_SET_VPATH, mp);
6393
6394   mp->sw_if_index = ntohl (sw_if_index);
6395   mp->enable = is_enable;
6396
6397   /* send it... */
6398   S (mp);
6399
6400   /* Wait for a reply... */
6401   W (ret);
6402   return ret;
6403 }
6404
6405 static int
6406 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6407 {
6408   unformat_input_t *i = vam->input;
6409   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6410   u32 sw_if_index = 0;
6411   u8 sw_if_index_set = 0;
6412   u8 is_enable = 1;
6413   u8 is_ipv6 = 0;
6414   int ret;
6415
6416   /* Parse args required to build the message */
6417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6418     {
6419       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6420         sw_if_index_set = 1;
6421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6422         sw_if_index_set = 1;
6423       else if (unformat (i, "enable"))
6424         is_enable = 1;
6425       else if (unformat (i, "disable"))
6426         is_enable = 0;
6427       else if (unformat (i, "ip4"))
6428         is_ipv6 = 0;
6429       else if (unformat (i, "ip6"))
6430         is_ipv6 = 1;
6431       else
6432         break;
6433     }
6434
6435   if (sw_if_index_set == 0)
6436     {
6437       errmsg ("missing interface name or sw_if_index");
6438       return -99;
6439     }
6440
6441   /* Construct the API message */
6442   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6443
6444   mp->sw_if_index = ntohl (sw_if_index);
6445   mp->enable = is_enable;
6446   mp->is_ipv6 = is_ipv6;
6447
6448   /* send it... */
6449   S (mp);
6450
6451   /* Wait for a reply... */
6452   W (ret);
6453   return ret;
6454 }
6455
6456 static int
6457 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6458 {
6459   unformat_input_t *i = vam->input;
6460   vl_api_sw_interface_set_geneve_bypass_t *mp;
6461   u32 sw_if_index = 0;
6462   u8 sw_if_index_set = 0;
6463   u8 is_enable = 1;
6464   u8 is_ipv6 = 0;
6465   int ret;
6466
6467   /* Parse args required to build the message */
6468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6469     {
6470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6471         sw_if_index_set = 1;
6472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6473         sw_if_index_set = 1;
6474       else if (unformat (i, "enable"))
6475         is_enable = 1;
6476       else if (unformat (i, "disable"))
6477         is_enable = 0;
6478       else if (unformat (i, "ip4"))
6479         is_ipv6 = 0;
6480       else if (unformat (i, "ip6"))
6481         is_ipv6 = 1;
6482       else
6483         break;
6484     }
6485
6486   if (sw_if_index_set == 0)
6487     {
6488       errmsg ("missing interface name or sw_if_index");
6489       return -99;
6490     }
6491
6492   /* Construct the API message */
6493   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6494
6495   mp->sw_if_index = ntohl (sw_if_index);
6496   mp->enable = is_enable;
6497   mp->is_ipv6 = is_ipv6;
6498
6499   /* send it... */
6500   S (mp);
6501
6502   /* Wait for a reply... */
6503   W (ret);
6504   return ret;
6505 }
6506
6507 static int
6508 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6509 {
6510   unformat_input_t *i = vam->input;
6511   vl_api_sw_interface_set_l2_xconnect_t *mp;
6512   u32 rx_sw_if_index;
6513   u8 rx_sw_if_index_set = 0;
6514   u32 tx_sw_if_index;
6515   u8 tx_sw_if_index_set = 0;
6516   u8 enable = 1;
6517   int ret;
6518
6519   /* Parse args required to build the message */
6520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6521     {
6522       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6523         rx_sw_if_index_set = 1;
6524       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6525         tx_sw_if_index_set = 1;
6526       else if (unformat (i, "rx"))
6527         {
6528           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6529             {
6530               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6531                             &rx_sw_if_index))
6532                 rx_sw_if_index_set = 1;
6533             }
6534           else
6535             break;
6536         }
6537       else if (unformat (i, "tx"))
6538         {
6539           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6540             {
6541               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6542                             &tx_sw_if_index))
6543                 tx_sw_if_index_set = 1;
6544             }
6545           else
6546             break;
6547         }
6548       else if (unformat (i, "enable"))
6549         enable = 1;
6550       else if (unformat (i, "disable"))
6551         enable = 0;
6552       else
6553         break;
6554     }
6555
6556   if (rx_sw_if_index_set == 0)
6557     {
6558       errmsg ("missing rx interface name or rx_sw_if_index");
6559       return -99;
6560     }
6561
6562   if (enable && (tx_sw_if_index_set == 0))
6563     {
6564       errmsg ("missing tx interface name or tx_sw_if_index");
6565       return -99;
6566     }
6567
6568   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6569
6570   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6571   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6572   mp->enable = enable;
6573
6574   S (mp);
6575   W (ret);
6576   return ret;
6577 }
6578
6579 static int
6580 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6581 {
6582   unformat_input_t *i = vam->input;
6583   vl_api_sw_interface_set_l2_bridge_t *mp;
6584   vl_api_l2_port_type_t port_type;
6585   u32 rx_sw_if_index;
6586   u8 rx_sw_if_index_set = 0;
6587   u32 bd_id;
6588   u8 bd_id_set = 0;
6589   u32 shg = 0;
6590   u8 enable = 1;
6591   int ret;
6592
6593   port_type = L2_API_PORT_TYPE_NORMAL;
6594
6595   /* Parse args required to build the message */
6596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6597     {
6598       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6599         rx_sw_if_index_set = 1;
6600       else if (unformat (i, "bd_id %d", &bd_id))
6601         bd_id_set = 1;
6602       else
6603         if (unformat
6604             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6605         rx_sw_if_index_set = 1;
6606       else if (unformat (i, "shg %d", &shg))
6607         ;
6608       else if (unformat (i, "bvi"))
6609         port_type = L2_API_PORT_TYPE_BVI;
6610       else if (unformat (i, "uu-fwd"))
6611         port_type = L2_API_PORT_TYPE_UU_FWD;
6612       else if (unformat (i, "enable"))
6613         enable = 1;
6614       else if (unformat (i, "disable"))
6615         enable = 0;
6616       else
6617         break;
6618     }
6619
6620   if (rx_sw_if_index_set == 0)
6621     {
6622       errmsg ("missing rx interface name or sw_if_index");
6623       return -99;
6624     }
6625
6626   if (enable && (bd_id_set == 0))
6627     {
6628       errmsg ("missing bridge domain");
6629       return -99;
6630     }
6631
6632   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6633
6634   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6635   mp->bd_id = ntohl (bd_id);
6636   mp->shg = (u8) shg;
6637   mp->port_type = ntohl (port_type);
6638   mp->enable = enable;
6639
6640   S (mp);
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_bridge_domain_dump (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_bridge_domain_dump_t *mp;
6650   vl_api_control_ping_t *mp_ping;
6651   u32 bd_id = ~0;
6652   int ret;
6653
6654   /* Parse args required to build the message */
6655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6656     {
6657       if (unformat (i, "bd_id %d", &bd_id))
6658         ;
6659       else
6660         break;
6661     }
6662
6663   M (BRIDGE_DOMAIN_DUMP, mp);
6664   mp->bd_id = ntohl (bd_id);
6665   S (mp);
6666
6667   /* Use a control ping for synchronization */
6668   MPING (CONTROL_PING, mp_ping);
6669   S (mp_ping);
6670
6671   W (ret);
6672   return ret;
6673 }
6674
6675 static int
6676 api_bridge_domain_add_del (vat_main_t * vam)
6677 {
6678   unformat_input_t *i = vam->input;
6679   vl_api_bridge_domain_add_del_t *mp;
6680   u32 bd_id = ~0;
6681   u8 is_add = 1;
6682   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6683   u8 *bd_tag = NULL;
6684   u32 mac_age = 0;
6685   int ret;
6686
6687   /* Parse args required to build the message */
6688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689     {
6690       if (unformat (i, "bd_id %d", &bd_id))
6691         ;
6692       else if (unformat (i, "flood %d", &flood))
6693         ;
6694       else if (unformat (i, "uu-flood %d", &uu_flood))
6695         ;
6696       else if (unformat (i, "forward %d", &forward))
6697         ;
6698       else if (unformat (i, "learn %d", &learn))
6699         ;
6700       else if (unformat (i, "arp-term %d", &arp_term))
6701         ;
6702       else if (unformat (i, "mac-age %d", &mac_age))
6703         ;
6704       else if (unformat (i, "bd-tag %s", &bd_tag))
6705         ;
6706       else if (unformat (i, "del"))
6707         {
6708           is_add = 0;
6709           flood = uu_flood = forward = learn = 0;
6710         }
6711       else
6712         break;
6713     }
6714
6715   if (bd_id == ~0)
6716     {
6717       errmsg ("missing bridge domain");
6718       ret = -99;
6719       goto done;
6720     }
6721
6722   if (mac_age > 255)
6723     {
6724       errmsg ("mac age must be less than 256 ");
6725       ret = -99;
6726       goto done;
6727     }
6728
6729   if ((bd_tag) && (vec_len (bd_tag) > 63))
6730     {
6731       errmsg ("bd-tag cannot be longer than 63");
6732       ret = -99;
6733       goto done;
6734     }
6735
6736   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6737
6738   mp->bd_id = ntohl (bd_id);
6739   mp->flood = flood;
6740   mp->uu_flood = uu_flood;
6741   mp->forward = forward;
6742   mp->learn = learn;
6743   mp->arp_term = arp_term;
6744   mp->is_add = is_add;
6745   mp->mac_age = (u8) mac_age;
6746   if (bd_tag)
6747     {
6748       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6749       mp->bd_tag[vec_len (bd_tag)] = 0;
6750     }
6751   S (mp);
6752   W (ret);
6753
6754 done:
6755   vec_free (bd_tag);
6756   return ret;
6757 }
6758
6759 static int
6760 api_l2fib_flush_bd (vat_main_t * vam)
6761 {
6762   unformat_input_t *i = vam->input;
6763   vl_api_l2fib_flush_bd_t *mp;
6764   u32 bd_id = ~0;
6765   int ret;
6766
6767   /* Parse args required to build the message */
6768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6769     {
6770       if (unformat (i, "bd_id %d", &bd_id));
6771       else
6772         break;
6773     }
6774
6775   if (bd_id == ~0)
6776     {
6777       errmsg ("missing bridge domain");
6778       return -99;
6779     }
6780
6781   M (L2FIB_FLUSH_BD, mp);
6782
6783   mp->bd_id = htonl (bd_id);
6784
6785   S (mp);
6786   W (ret);
6787   return ret;
6788 }
6789
6790 static int
6791 api_l2fib_flush_int (vat_main_t * vam)
6792 {
6793   unformat_input_t *i = vam->input;
6794   vl_api_l2fib_flush_int_t *mp;
6795   u32 sw_if_index = ~0;
6796   int ret;
6797
6798   /* Parse args required to build the message */
6799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6800     {
6801       if (unformat (i, "sw_if_index %d", &sw_if_index));
6802       else
6803         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6804       else
6805         break;
6806     }
6807
6808   if (sw_if_index == ~0)
6809     {
6810       errmsg ("missing interface name or sw_if_index");
6811       return -99;
6812     }
6813
6814   M (L2FIB_FLUSH_INT, mp);
6815
6816   mp->sw_if_index = ntohl (sw_if_index);
6817
6818   S (mp);
6819   W (ret);
6820   return ret;
6821 }
6822
6823 static int
6824 api_l2fib_add_del (vat_main_t * vam)
6825 {
6826   unformat_input_t *i = vam->input;
6827   vl_api_l2fib_add_del_t *mp;
6828   f64 timeout;
6829   u8 mac[6] = { 0 };
6830   u8 mac_set = 0;
6831   u32 bd_id;
6832   u8 bd_id_set = 0;
6833   u32 sw_if_index = 0;
6834   u8 sw_if_index_set = 0;
6835   u8 is_add = 1;
6836   u8 static_mac = 0;
6837   u8 filter_mac = 0;
6838   u8 bvi_mac = 0;
6839   int count = 1;
6840   f64 before = 0;
6841   int j;
6842
6843   /* Parse args required to build the message */
6844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6845     {
6846       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6847         mac_set = 1;
6848       else if (unformat (i, "bd_id %d", &bd_id))
6849         bd_id_set = 1;
6850       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6851         sw_if_index_set = 1;
6852       else if (unformat (i, "sw_if"))
6853         {
6854           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6855             {
6856               if (unformat
6857                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6858                 sw_if_index_set = 1;
6859             }
6860           else
6861             break;
6862         }
6863       else if (unformat (i, "static"))
6864         static_mac = 1;
6865       else if (unformat (i, "filter"))
6866         {
6867           filter_mac = 1;
6868           static_mac = 1;
6869         }
6870       else if (unformat (i, "bvi"))
6871         {
6872           bvi_mac = 1;
6873           static_mac = 1;
6874         }
6875       else if (unformat (i, "del"))
6876         is_add = 0;
6877       else if (unformat (i, "count %d", &count))
6878         ;
6879       else
6880         break;
6881     }
6882
6883   if (mac_set == 0)
6884     {
6885       errmsg ("missing mac address");
6886       return -99;
6887     }
6888
6889   if (bd_id_set == 0)
6890     {
6891       errmsg ("missing bridge domain");
6892       return -99;
6893     }
6894
6895   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6896     {
6897       errmsg ("missing interface name or sw_if_index");
6898       return -99;
6899     }
6900
6901   if (count > 1)
6902     {
6903       /* Turn on async mode */
6904       vam->async_mode = 1;
6905       vam->async_errors = 0;
6906       before = vat_time_now (vam);
6907     }
6908
6909   for (j = 0; j < count; j++)
6910     {
6911       M (L2FIB_ADD_DEL, mp);
6912
6913       clib_memcpy (mp->mac, mac, 6);
6914       mp->bd_id = ntohl (bd_id);
6915       mp->is_add = is_add;
6916       mp->sw_if_index = ntohl (sw_if_index);
6917
6918       if (is_add)
6919         {
6920           mp->static_mac = static_mac;
6921           mp->filter_mac = filter_mac;
6922           mp->bvi_mac = bvi_mac;
6923         }
6924       increment_mac_address (mac);
6925       /* send it... */
6926       S (mp);
6927     }
6928
6929   if (count > 1)
6930     {
6931       vl_api_control_ping_t *mp_ping;
6932       f64 after;
6933
6934       /* Shut off async mode */
6935       vam->async_mode = 0;
6936
6937       MPING (CONTROL_PING, mp_ping);
6938       S (mp_ping);
6939
6940       timeout = vat_time_now (vam) + 1.0;
6941       while (vat_time_now (vam) < timeout)
6942         if (vam->result_ready == 1)
6943           goto out;
6944       vam->retval = -99;
6945
6946     out:
6947       if (vam->retval == -99)
6948         errmsg ("timeout");
6949
6950       if (vam->async_errors > 0)
6951         {
6952           errmsg ("%d asynchronous errors", vam->async_errors);
6953           vam->retval = -98;
6954         }
6955       vam->async_errors = 0;
6956       after = vat_time_now (vam);
6957
6958       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6959              count, after - before, count / (after - before));
6960     }
6961   else
6962     {
6963       int ret;
6964
6965       /* Wait for a reply... */
6966       W (ret);
6967       return ret;
6968     }
6969   /* Return the good/bad news */
6970   return (vam->retval);
6971 }
6972
6973 static int
6974 api_bridge_domain_set_mac_age (vat_main_t * vam)
6975 {
6976   unformat_input_t *i = vam->input;
6977   vl_api_bridge_domain_set_mac_age_t *mp;
6978   u32 bd_id = ~0;
6979   u32 mac_age = 0;
6980   int ret;
6981
6982   /* Parse args required to build the message */
6983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6984     {
6985       if (unformat (i, "bd_id %d", &bd_id));
6986       else if (unformat (i, "mac-age %d", &mac_age));
6987       else
6988         break;
6989     }
6990
6991   if (bd_id == ~0)
6992     {
6993       errmsg ("missing bridge domain");
6994       return -99;
6995     }
6996
6997   if (mac_age > 255)
6998     {
6999       errmsg ("mac age must be less than 256 ");
7000       return -99;
7001     }
7002
7003   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7004
7005   mp->bd_id = htonl (bd_id);
7006   mp->mac_age = (u8) mac_age;
7007
7008   S (mp);
7009   W (ret);
7010   return ret;
7011 }
7012
7013 static int
7014 api_l2_flags (vat_main_t * vam)
7015 {
7016   unformat_input_t *i = vam->input;
7017   vl_api_l2_flags_t *mp;
7018   u32 sw_if_index;
7019   u32 flags = 0;
7020   u8 sw_if_index_set = 0;
7021   u8 is_set = 0;
7022   int ret;
7023
7024   /* Parse args required to build the message */
7025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7026     {
7027       if (unformat (i, "sw_if_index %d", &sw_if_index))
7028         sw_if_index_set = 1;
7029       else if (unformat (i, "sw_if"))
7030         {
7031           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7032             {
7033               if (unformat
7034                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7035                 sw_if_index_set = 1;
7036             }
7037           else
7038             break;
7039         }
7040       else if (unformat (i, "learn"))
7041         flags |= L2_LEARN;
7042       else if (unformat (i, "forward"))
7043         flags |= L2_FWD;
7044       else if (unformat (i, "flood"))
7045         flags |= L2_FLOOD;
7046       else if (unformat (i, "uu-flood"))
7047         flags |= L2_UU_FLOOD;
7048       else if (unformat (i, "arp-term"))
7049         flags |= L2_ARP_TERM;
7050       else if (unformat (i, "off"))
7051         is_set = 0;
7052       else if (unformat (i, "disable"))
7053         is_set = 0;
7054       else
7055         break;
7056     }
7057
7058   if (sw_if_index_set == 0)
7059     {
7060       errmsg ("missing interface name or sw_if_index");
7061       return -99;
7062     }
7063
7064   M (L2_FLAGS, mp);
7065
7066   mp->sw_if_index = ntohl (sw_if_index);
7067   mp->feature_bitmap = ntohl (flags);
7068   mp->is_set = is_set;
7069
7070   S (mp);
7071   W (ret);
7072   return ret;
7073 }
7074
7075 static int
7076 api_bridge_flags (vat_main_t * vam)
7077 {
7078   unformat_input_t *i = vam->input;
7079   vl_api_bridge_flags_t *mp;
7080   u32 bd_id;
7081   u8 bd_id_set = 0;
7082   u8 is_set = 1;
7083   bd_flags_t flags = 0;
7084   int ret;
7085
7086   /* Parse args required to build the message */
7087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7088     {
7089       if (unformat (i, "bd_id %d", &bd_id))
7090         bd_id_set = 1;
7091       else if (unformat (i, "learn"))
7092         flags |= BRIDGE_API_FLAG_LEARN;
7093       else if (unformat (i, "forward"))
7094         flags |= BRIDGE_API_FLAG_FWD;
7095       else if (unformat (i, "flood"))
7096         flags |= BRIDGE_API_FLAG_FLOOD;
7097       else if (unformat (i, "uu-flood"))
7098         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7099       else if (unformat (i, "arp-term"))
7100         flags |= BRIDGE_API_FLAG_ARP_TERM;
7101       else if (unformat (i, "off"))
7102         is_set = 0;
7103       else if (unformat (i, "disable"))
7104         is_set = 0;
7105       else
7106         break;
7107     }
7108
7109   if (bd_id_set == 0)
7110     {
7111       errmsg ("missing bridge domain");
7112       return -99;
7113     }
7114
7115   M (BRIDGE_FLAGS, mp);
7116
7117   mp->bd_id = ntohl (bd_id);
7118   mp->flags = ntohl (flags);
7119   mp->is_set = is_set;
7120
7121   S (mp);
7122   W (ret);
7123   return ret;
7124 }
7125
7126 static int
7127 api_bd_ip_mac_add_del (vat_main_t * vam)
7128 {
7129   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7130   vl_api_mac_address_t mac = { 0 };
7131   unformat_input_t *i = vam->input;
7132   vl_api_bd_ip_mac_add_del_t *mp;
7133   u32 bd_id;
7134   u8 is_add = 1;
7135   u8 bd_id_set = 0;
7136   u8 ip_set = 0;
7137   u8 mac_set = 0;
7138   int ret;
7139
7140
7141   /* Parse args required to build the message */
7142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7143     {
7144       if (unformat (i, "bd_id %d", &bd_id))
7145         {
7146           bd_id_set++;
7147         }
7148       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7149         {
7150           ip_set++;
7151         }
7152       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7153         {
7154           mac_set++;
7155         }
7156       else if (unformat (i, "del"))
7157         is_add = 0;
7158       else
7159         break;
7160     }
7161
7162   if (bd_id_set == 0)
7163     {
7164       errmsg ("missing bridge domain");
7165       return -99;
7166     }
7167   else if (ip_set == 0)
7168     {
7169       errmsg ("missing IP address");
7170       return -99;
7171     }
7172   else if (mac_set == 0)
7173     {
7174       errmsg ("missing MAC address");
7175       return -99;
7176     }
7177
7178   M (BD_IP_MAC_ADD_DEL, mp);
7179
7180   mp->entry.bd_id = ntohl (bd_id);
7181   mp->is_add = is_add;
7182
7183   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7184   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7185
7186   S (mp);
7187   W (ret);
7188   return ret;
7189 }
7190
7191 static int
7192 api_bd_ip_mac_flush (vat_main_t * vam)
7193 {
7194   unformat_input_t *i = vam->input;
7195   vl_api_bd_ip_mac_flush_t *mp;
7196   u32 bd_id;
7197   u8 bd_id_set = 0;
7198   int ret;
7199
7200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7201     {
7202       if (unformat (i, "bd_id %d", &bd_id))
7203         {
7204           bd_id_set++;
7205         }
7206       else
7207         break;
7208     }
7209
7210   if (bd_id_set == 0)
7211     {
7212       errmsg ("missing bridge domain");
7213       return -99;
7214     }
7215
7216   M (BD_IP_MAC_FLUSH, mp);
7217
7218   mp->bd_id = ntohl (bd_id);
7219
7220   S (mp);
7221   W (ret);
7222   return ret;
7223 }
7224
7225 static void vl_api_bd_ip_mac_details_t_handler
7226   (vl_api_bd_ip_mac_details_t * mp)
7227 {
7228   vat_main_t *vam = &vat_main;
7229
7230   print (vam->ofp,
7231          "\n%-5d %U %U",
7232          ntohl (mp->entry.bd_id),
7233          format_vl_api_mac_address, mp->entry.mac,
7234          format_vl_api_address, &mp->entry.ip);
7235 }
7236
7237 static void vl_api_bd_ip_mac_details_t_handler_json
7238   (vl_api_bd_ip_mac_details_t * mp)
7239 {
7240   vat_main_t *vam = &vat_main;
7241   vat_json_node_t *node = NULL;
7242
7243   if (VAT_JSON_ARRAY != vam->json_tree.type)
7244     {
7245       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7246       vat_json_init_array (&vam->json_tree);
7247     }
7248   node = vat_json_array_add (&vam->json_tree);
7249
7250   vat_json_init_object (node);
7251   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7252   vat_json_object_add_string_copy (node, "mac_address",
7253                                    format (0, "%U", format_vl_api_mac_address,
7254                                            &mp->entry.mac));
7255   u8 *ip = 0;
7256
7257   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7258   vat_json_object_add_string_copy (node, "ip_address", ip);
7259   vec_free (ip);
7260 }
7261
7262 static int
7263 api_bd_ip_mac_dump (vat_main_t * vam)
7264 {
7265   unformat_input_t *i = vam->input;
7266   vl_api_bd_ip_mac_dump_t *mp;
7267   vl_api_control_ping_t *mp_ping;
7268   int ret;
7269   u32 bd_id;
7270   u8 bd_id_set = 0;
7271
7272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7273     {
7274       if (unformat (i, "bd_id %d", &bd_id))
7275         {
7276           bd_id_set++;
7277         }
7278       else
7279         break;
7280     }
7281
7282   print (vam->ofp,
7283          "\n%-5s %-7s %-20s %-30s",
7284          "bd_id", "is_ipv6", "mac_address", "ip_address");
7285
7286   /* Dump Bridge Domain Ip to Mac entries */
7287   M (BD_IP_MAC_DUMP, mp);
7288
7289   if (bd_id_set)
7290     mp->bd_id = htonl (bd_id);
7291   else
7292     mp->bd_id = ~0;
7293
7294   S (mp);
7295
7296   /* Use a control ping for synchronization */
7297   MPING (CONTROL_PING, mp_ping);
7298   S (mp_ping);
7299
7300   W (ret);
7301   return ret;
7302 }
7303
7304 static int
7305 api_tap_create_v2 (vat_main_t * vam)
7306 {
7307   unformat_input_t *i = vam->input;
7308   vl_api_tap_create_v2_t *mp;
7309   u8 mac_address[6];
7310   u8 random_mac = 1;
7311   u32 id = ~0;
7312   u32 num_rx_queues = 0;
7313   u8 *host_if_name = 0;
7314   u8 host_if_name_set = 0;
7315   u8 *host_ns = 0;
7316   u8 host_ns_set = 0;
7317   u8 host_mac_addr[6];
7318   u8 host_mac_addr_set = 0;
7319   u8 *host_bridge = 0;
7320   u8 host_bridge_set = 0;
7321   u8 host_ip4_prefix_set = 0;
7322   u8 host_ip6_prefix_set = 0;
7323   ip4_address_t host_ip4_addr;
7324   ip4_address_t host_ip4_gw;
7325   u8 host_ip4_gw_set = 0;
7326   u32 host_ip4_prefix_len = 0;
7327   ip6_address_t host_ip6_addr;
7328   ip6_address_t host_ip6_gw;
7329   u8 host_ip6_gw_set = 0;
7330   u32 host_ip6_prefix_len = 0;
7331   u32 host_mtu_size = 0;
7332   u8 host_mtu_set = 0;
7333   u32 tap_flags = 0;
7334   int ret;
7335   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7336
7337   clib_memset (mac_address, 0, sizeof (mac_address));
7338
7339   /* Parse args required to build the message */
7340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7341     {
7342       if (unformat (i, "id %u", &id))
7343         ;
7344       else
7345         if (unformat
7346             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7347         random_mac = 0;
7348       else if (unformat (i, "host-if-name %s", &host_if_name))
7349         host_if_name_set = 1;
7350       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7351         ;
7352       else if (unformat (i, "host-ns %s", &host_ns))
7353         host_ns_set = 1;
7354       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7355                          host_mac_addr))
7356         host_mac_addr_set = 1;
7357       else if (unformat (i, "host-bridge %s", &host_bridge))
7358         host_bridge_set = 1;
7359       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7360                          &host_ip4_addr, &host_ip4_prefix_len))
7361         host_ip4_prefix_set = 1;
7362       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7363                          &host_ip6_addr, &host_ip6_prefix_len))
7364         host_ip6_prefix_set = 1;
7365       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7366                          &host_ip4_gw))
7367         host_ip4_gw_set = 1;
7368       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7369                          &host_ip6_gw))
7370         host_ip6_gw_set = 1;
7371       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7372         ;
7373       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7374         ;
7375       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7376         host_mtu_set = 1;
7377       else if (unformat (i, "no-gso"))
7378         tap_flags &= ~TAP_API_FLAG_GSO;
7379       else if (unformat (i, "gso"))
7380         tap_flags |= TAP_API_FLAG_GSO;
7381       else if (unformat (i, "csum-offload"))
7382         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7383       else if (unformat (i, "persist"))
7384         tap_flags |= TAP_API_FLAG_PERSIST;
7385       else if (unformat (i, "attach"))
7386         tap_flags |= TAP_API_FLAG_ATTACH;
7387       else if (unformat (i, "tun"))
7388         tap_flags |= TAP_API_FLAG_TUN;
7389       else if (unformat (i, "gro-coalesce"))
7390         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7391       else
7392         break;
7393     }
7394
7395   if (vec_len (host_if_name) > 63)
7396     {
7397       errmsg ("tap name too long. ");
7398       return -99;
7399     }
7400   if (vec_len (host_ns) > 63)
7401     {
7402       errmsg ("host name space too long. ");
7403       return -99;
7404     }
7405   if (vec_len (host_bridge) > 63)
7406     {
7407       errmsg ("host bridge name too long. ");
7408       return -99;
7409     }
7410   if (host_ip4_prefix_len > 32)
7411     {
7412       errmsg ("host ip4 prefix length not valid. ");
7413       return -99;
7414     }
7415   if (host_ip6_prefix_len > 128)
7416     {
7417       errmsg ("host ip6 prefix length not valid. ");
7418       return -99;
7419     }
7420   if (!is_pow2 (rx_ring_sz))
7421     {
7422       errmsg ("rx ring size must be power of 2. ");
7423       return -99;
7424     }
7425   if (rx_ring_sz > 32768)
7426     {
7427       errmsg ("rx ring size must be 32768 or lower. ");
7428       return -99;
7429     }
7430   if (!is_pow2 (tx_ring_sz))
7431     {
7432       errmsg ("tx ring size must be power of 2. ");
7433       return -99;
7434     }
7435   if (tx_ring_sz > 32768)
7436     {
7437       errmsg ("tx ring size must be 32768 or lower. ");
7438       return -99;
7439     }
7440   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7441     {
7442       errmsg ("host MTU size must be in between 64 and 65355. ");
7443       return -99;
7444     }
7445
7446   /* Construct the API message */
7447   M (TAP_CREATE_V2, mp);
7448
7449   mp->id = ntohl (id);
7450   mp->use_random_mac = random_mac;
7451   mp->num_rx_queues = (u8) num_rx_queues;
7452   mp->tx_ring_sz = ntohs (tx_ring_sz);
7453   mp->rx_ring_sz = ntohs (rx_ring_sz);
7454   mp->host_mtu_set = host_mtu_set;
7455   mp->host_mtu_size = ntohl (host_mtu_size);
7456   mp->host_mac_addr_set = host_mac_addr_set;
7457   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7458   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7459   mp->host_ip4_gw_set = host_ip4_gw_set;
7460   mp->host_ip6_gw_set = host_ip6_gw_set;
7461   mp->tap_flags = ntohl (tap_flags);
7462   mp->host_namespace_set = host_ns_set;
7463   mp->host_if_name_set = host_if_name_set;
7464   mp->host_bridge_set = host_bridge_set;
7465
7466   if (random_mac == 0)
7467     clib_memcpy (mp->mac_address, mac_address, 6);
7468   if (host_mac_addr_set)
7469     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7470   if (host_if_name_set)
7471     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7472   if (host_ns_set)
7473     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7474   if (host_bridge_set)
7475     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7476   if (host_ip4_prefix_set)
7477     {
7478       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7479       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7480     }
7481   if (host_ip6_prefix_set)
7482     {
7483       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7484       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7485     }
7486   if (host_ip4_gw_set)
7487     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7488   if (host_ip6_gw_set)
7489     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7490
7491   vec_free (host_ns);
7492   vec_free (host_if_name);
7493   vec_free (host_bridge);
7494
7495   /* send it... */
7496   S (mp);
7497
7498   /* Wait for a reply... */
7499   W (ret);
7500   return ret;
7501 }
7502
7503 static int
7504 api_tap_delete_v2 (vat_main_t * vam)
7505 {
7506   unformat_input_t *i = vam->input;
7507   vl_api_tap_delete_v2_t *mp;
7508   u32 sw_if_index = ~0;
7509   u8 sw_if_index_set = 0;
7510   int ret;
7511
7512   /* Parse args required to build the message */
7513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7514     {
7515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7516         sw_if_index_set = 1;
7517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7518         sw_if_index_set = 1;
7519       else
7520         break;
7521     }
7522
7523   if (sw_if_index_set == 0)
7524     {
7525       errmsg ("missing vpp interface name. ");
7526       return -99;
7527     }
7528
7529   /* Construct the API message */
7530   M (TAP_DELETE_V2, mp);
7531
7532   mp->sw_if_index = ntohl (sw_if_index);
7533
7534   /* send it... */
7535   S (mp);
7536
7537   /* Wait for a reply... */
7538   W (ret);
7539   return ret;
7540 }
7541
7542 uword
7543 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7544 {
7545   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7546   u32 x[4];
7547
7548   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7549     return 0;
7550
7551   addr->domain = x[0];
7552   addr->bus = x[1];
7553   addr->slot = x[2];
7554   addr->function = x[3];
7555
7556   return 1;
7557 }
7558
7559 static int
7560 api_virtio_pci_create (vat_main_t * vam)
7561 {
7562   unformat_input_t *i = vam->input;
7563   vl_api_virtio_pci_create_t *mp;
7564   u8 mac_address[6];
7565   u8 random_mac = 1;
7566   u8 gso_enabled = 0;
7567   u8 checksum_offload_enabled = 0;
7568   u32 pci_addr = 0;
7569   u64 features = (u64) ~ (0ULL);
7570   int ret;
7571
7572   clib_memset (mac_address, 0, sizeof (mac_address));
7573
7574   /* Parse args required to build the message */
7575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7576     {
7577       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7578         {
7579           random_mac = 0;
7580         }
7581       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7582         ;
7583       else if (unformat (i, "features 0x%llx", &features))
7584         ;
7585       else if (unformat (i, "gso-enabled"))
7586         gso_enabled = 1;
7587       else if (unformat (i, "csum-offload-enabled"))
7588         checksum_offload_enabled = 1;
7589       else
7590         break;
7591     }
7592
7593   if (pci_addr == 0)
7594     {
7595       errmsg ("pci address must be non zero. ");
7596       return -99;
7597     }
7598
7599   /* Construct the API message */
7600   M (VIRTIO_PCI_CREATE, mp);
7601
7602   mp->use_random_mac = random_mac;
7603
7604   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7605   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7606   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7607   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7608
7609   mp->features = clib_host_to_net_u64 (features);
7610   mp->gso_enabled = gso_enabled;
7611   mp->checksum_offload_enabled = checksum_offload_enabled;
7612
7613   if (random_mac == 0)
7614     clib_memcpy (mp->mac_address, mac_address, 6);
7615
7616   /* send it... */
7617   S (mp);
7618
7619   /* Wait for a reply... */
7620   W (ret);
7621   return ret;
7622 }
7623
7624 static int
7625 api_virtio_pci_delete (vat_main_t * vam)
7626 {
7627   unformat_input_t *i = vam->input;
7628   vl_api_virtio_pci_delete_t *mp;
7629   u32 sw_if_index = ~0;
7630   u8 sw_if_index_set = 0;
7631   int ret;
7632
7633   /* Parse args required to build the message */
7634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7635     {
7636       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7637         sw_if_index_set = 1;
7638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7639         sw_if_index_set = 1;
7640       else
7641         break;
7642     }
7643
7644   if (sw_if_index_set == 0)
7645     {
7646       errmsg ("missing vpp interface name. ");
7647       return -99;
7648     }
7649
7650   /* Construct the API message */
7651   M (VIRTIO_PCI_DELETE, mp);
7652
7653   mp->sw_if_index = htonl (sw_if_index);
7654
7655   /* send it... */
7656   S (mp);
7657
7658   /* Wait for a reply... */
7659   W (ret);
7660   return ret;
7661 }
7662
7663 static int
7664 api_bond_create (vat_main_t * vam)
7665 {
7666   unformat_input_t *i = vam->input;
7667   vl_api_bond_create_t *mp;
7668   u8 mac_address[6];
7669   u8 custom_mac = 0;
7670   int ret;
7671   u8 mode;
7672   u8 lb;
7673   u8 mode_is_set = 0;
7674   u32 id = ~0;
7675   u8 numa_only = 0;
7676
7677   clib_memset (mac_address, 0, sizeof (mac_address));
7678   lb = BOND_LB_L2;
7679
7680   /* Parse args required to build the message */
7681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7682     {
7683       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7684         mode_is_set = 1;
7685       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7686                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7687         ;
7688       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7689                          mac_address))
7690         custom_mac = 1;
7691       else if (unformat (i, "numa-only"))
7692         numa_only = 1;
7693       else if (unformat (i, "id %u", &id))
7694         ;
7695       else
7696         break;
7697     }
7698
7699   if (mode_is_set == 0)
7700     {
7701       errmsg ("Missing bond mode. ");
7702       return -99;
7703     }
7704
7705   /* Construct the API message */
7706   M (BOND_CREATE, mp);
7707
7708   mp->use_custom_mac = custom_mac;
7709
7710   mp->mode = htonl (mode);
7711   mp->lb = htonl (lb);
7712   mp->id = htonl (id);
7713   mp->numa_only = numa_only;
7714
7715   if (custom_mac)
7716     clib_memcpy (mp->mac_address, mac_address, 6);
7717
7718   /* send it... */
7719   S (mp);
7720
7721   /* Wait for a reply... */
7722   W (ret);
7723   return ret;
7724 }
7725
7726 static int
7727 api_bond_delete (vat_main_t * vam)
7728 {
7729   unformat_input_t *i = vam->input;
7730   vl_api_bond_delete_t *mp;
7731   u32 sw_if_index = ~0;
7732   u8 sw_if_index_set = 0;
7733   int ret;
7734
7735   /* Parse args required to build the message */
7736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7737     {
7738       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7739         sw_if_index_set = 1;
7740       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7741         sw_if_index_set = 1;
7742       else
7743         break;
7744     }
7745
7746   if (sw_if_index_set == 0)
7747     {
7748       errmsg ("missing vpp interface name. ");
7749       return -99;
7750     }
7751
7752   /* Construct the API message */
7753   M (BOND_DELETE, mp);
7754
7755   mp->sw_if_index = ntohl (sw_if_index);
7756
7757   /* send it... */
7758   S (mp);
7759
7760   /* Wait for a reply... */
7761   W (ret);
7762   return ret;
7763 }
7764
7765 static int
7766 api_bond_add_member (vat_main_t * vam)
7767 {
7768   unformat_input_t *i = vam->input;
7769   vl_api_bond_add_member_t *mp;
7770   u32 bond_sw_if_index;
7771   int ret;
7772   u8 is_passive;
7773   u8 is_long_timeout;
7774   u32 bond_sw_if_index_is_set = 0;
7775   u32 sw_if_index;
7776   u8 sw_if_index_is_set = 0;
7777
7778   /* Parse args required to build the message */
7779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7780     {
7781       if (unformat (i, "sw_if_index %d", &sw_if_index))
7782         sw_if_index_is_set = 1;
7783       else if (unformat (i, "bond %u", &bond_sw_if_index))
7784         bond_sw_if_index_is_set = 1;
7785       else if (unformat (i, "passive %d", &is_passive))
7786         ;
7787       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7788         ;
7789       else
7790         break;
7791     }
7792
7793   if (bond_sw_if_index_is_set == 0)
7794     {
7795       errmsg ("Missing bond sw_if_index. ");
7796       return -99;
7797     }
7798   if (sw_if_index_is_set == 0)
7799     {
7800       errmsg ("Missing member sw_if_index. ");
7801       return -99;
7802     }
7803
7804   /* Construct the API message */
7805   M (BOND_ADD_MEMBER, mp);
7806
7807   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7808   mp->sw_if_index = ntohl (sw_if_index);
7809   mp->is_long_timeout = is_long_timeout;
7810   mp->is_passive = is_passive;
7811
7812   /* send it... */
7813   S (mp);
7814
7815   /* Wait for a reply... */
7816   W (ret);
7817   return ret;
7818 }
7819
7820 static int
7821 api_bond_detach_member (vat_main_t * vam)
7822 {
7823   unformat_input_t *i = vam->input;
7824   vl_api_bond_detach_member_t *mp;
7825   u32 sw_if_index = ~0;
7826   u8 sw_if_index_set = 0;
7827   int ret;
7828
7829   /* Parse args required to build the message */
7830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7831     {
7832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7833         sw_if_index_set = 1;
7834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7835         sw_if_index_set = 1;
7836       else
7837         break;
7838     }
7839
7840   if (sw_if_index_set == 0)
7841     {
7842       errmsg ("missing vpp interface name. ");
7843       return -99;
7844     }
7845
7846   /* Construct the API message */
7847   M (BOND_DETACH_MEMBER, mp);
7848
7849   mp->sw_if_index = ntohl (sw_if_index);
7850
7851   /* send it... */
7852   S (mp);
7853
7854   /* Wait for a reply... */
7855   W (ret);
7856   return ret;
7857 }
7858
7859 static int
7860 api_ip_table_add_del (vat_main_t * vam)
7861 {
7862   unformat_input_t *i = vam->input;
7863   vl_api_ip_table_add_del_t *mp;
7864   u32 table_id = ~0;
7865   u8 is_ipv6 = 0;
7866   u8 is_add = 1;
7867   int ret = 0;
7868
7869   /* Parse args required to build the message */
7870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7871     {
7872       if (unformat (i, "ipv6"))
7873         is_ipv6 = 1;
7874       else if (unformat (i, "del"))
7875         is_add = 0;
7876       else if (unformat (i, "add"))
7877         is_add = 1;
7878       else if (unformat (i, "table %d", &table_id))
7879         ;
7880       else
7881         {
7882           clib_warning ("parse error '%U'", format_unformat_error, i);
7883           return -99;
7884         }
7885     }
7886
7887   if (~0 == table_id)
7888     {
7889       errmsg ("missing table-ID");
7890       return -99;
7891     }
7892
7893   /* Construct the API message */
7894   M (IP_TABLE_ADD_DEL, mp);
7895
7896   mp->table.table_id = ntohl (table_id);
7897   mp->table.is_ip6 = is_ipv6;
7898   mp->is_add = is_add;
7899
7900   /* send it... */
7901   S (mp);
7902
7903   /* Wait for a reply... */
7904   W (ret);
7905
7906   return ret;
7907 }
7908
7909 uword
7910 unformat_fib_path (unformat_input_t * input, va_list * args)
7911 {
7912   vat_main_t *vam = va_arg (*args, vat_main_t *);
7913   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7914   u32 weight, preference;
7915   mpls_label_t out_label;
7916
7917   clib_memset (path, 0, sizeof (*path));
7918   path->weight = 1;
7919   path->sw_if_index = ~0;
7920   path->rpf_id = ~0;
7921   path->n_labels = 0;
7922
7923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7924     {
7925       if (unformat (input, "%U %U",
7926                     unformat_vl_api_ip4_address,
7927                     &path->nh.address.ip4,
7928                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7929         {
7930           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7931         }
7932       else if (unformat (input, "%U %U",
7933                          unformat_vl_api_ip6_address,
7934                          &path->nh.address.ip6,
7935                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7936         {
7937           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7938         }
7939       else if (unformat (input, "weight %u", &weight))
7940         {
7941           path->weight = weight;
7942         }
7943       else if (unformat (input, "preference %u", &preference))
7944         {
7945           path->preference = preference;
7946         }
7947       else if (unformat (input, "%U next-hop-table %d",
7948                          unformat_vl_api_ip4_address,
7949                          &path->nh.address.ip4, &path->table_id))
7950         {
7951           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7952         }
7953       else if (unformat (input, "%U next-hop-table %d",
7954                          unformat_vl_api_ip6_address,
7955                          &path->nh.address.ip6, &path->table_id))
7956         {
7957           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7958         }
7959       else if (unformat (input, "%U",
7960                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7961         {
7962           /*
7963            * the recursive next-hops are by default in the default table
7964            */
7965           path->table_id = 0;
7966           path->sw_if_index = ~0;
7967           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7968         }
7969       else if (unformat (input, "%U",
7970                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7971         {
7972           /*
7973            * the recursive next-hops are by default in the default table
7974            */
7975           path->table_id = 0;
7976           path->sw_if_index = ~0;
7977           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7978         }
7979       else if (unformat (input, "resolve-via-host"))
7980         {
7981           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7982         }
7983       else if (unformat (input, "resolve-via-attached"))
7984         {
7985           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7986         }
7987       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7988         {
7989           path->type = FIB_API_PATH_TYPE_LOCAL;
7990           path->sw_if_index = ~0;
7991           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7992         }
7993       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7994         {
7995           path->type = FIB_API_PATH_TYPE_LOCAL;
7996           path->sw_if_index = ~0;
7997           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7998         }
7999       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8000         ;
8001       else if (unformat (input, "via-label %d", &path->nh.via_label))
8002         {
8003           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8004           path->sw_if_index = ~0;
8005         }
8006       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8007         {
8008           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8009           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8010         }
8011       else if (unformat (input, "local"))
8012         {
8013           path->type = FIB_API_PATH_TYPE_LOCAL;
8014         }
8015       else if (unformat (input, "out-labels"))
8016         {
8017           while (unformat (input, "%d", &out_label))
8018             {
8019               path->label_stack[path->n_labels].label = out_label;
8020               path->label_stack[path->n_labels].is_uniform = 0;
8021               path->label_stack[path->n_labels].ttl = 64;
8022               path->n_labels++;
8023             }
8024         }
8025       else if (unformat (input, "via"))
8026         {
8027           /* new path, back up and return */
8028           unformat_put_input (input);
8029           unformat_put_input (input);
8030           unformat_put_input (input);
8031           unformat_put_input (input);
8032           break;
8033         }
8034       else
8035         {
8036           return (0);
8037         }
8038     }
8039
8040   path->proto = ntohl (path->proto);
8041   path->type = ntohl (path->type);
8042   path->flags = ntohl (path->flags);
8043   path->table_id = ntohl (path->table_id);
8044   path->sw_if_index = ntohl (path->sw_if_index);
8045
8046   return (1);
8047 }
8048
8049 static int
8050 api_ip_route_add_del (vat_main_t * vam)
8051 {
8052   unformat_input_t *i = vam->input;
8053   vl_api_ip_route_add_del_t *mp;
8054   u32 vrf_id = 0;
8055   u8 is_add = 1;
8056   u8 is_multipath = 0;
8057   u8 prefix_set = 0;
8058   u8 path_count = 0;
8059   vl_api_prefix_t pfx = { };
8060   vl_api_fib_path_t paths[8];
8061   int count = 1;
8062   int j;
8063   f64 before = 0;
8064   u32 random_add_del = 0;
8065   u32 *random_vector = 0;
8066   u32 random_seed = 0xdeaddabe;
8067
8068   /* Parse args required to build the message */
8069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8070     {
8071       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8072         prefix_set = 1;
8073       else if (unformat (i, "del"))
8074         is_add = 0;
8075       else if (unformat (i, "add"))
8076         is_add = 1;
8077       else if (unformat (i, "vrf %d", &vrf_id))
8078         ;
8079       else if (unformat (i, "count %d", &count))
8080         ;
8081       else if (unformat (i, "random"))
8082         random_add_del = 1;
8083       else if (unformat (i, "multipath"))
8084         is_multipath = 1;
8085       else if (unformat (i, "seed %d", &random_seed))
8086         ;
8087       else
8088         if (unformat
8089             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8090         {
8091           path_count++;
8092           if (8 == path_count)
8093             {
8094               errmsg ("max 8 paths");
8095               return -99;
8096             }
8097         }
8098       else
8099         {
8100           clib_warning ("parse error '%U'", format_unformat_error, i);
8101           return -99;
8102         }
8103     }
8104
8105   if (!path_count)
8106     {
8107       errmsg ("specify a path; via ...");
8108       return -99;
8109     }
8110   if (prefix_set == 0)
8111     {
8112       errmsg ("missing prefix");
8113       return -99;
8114     }
8115
8116   /* Generate a pile of unique, random routes */
8117   if (random_add_del)
8118     {
8119       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8120       u32 this_random_address;
8121       uword *random_hash;
8122
8123       random_hash = hash_create (count, sizeof (uword));
8124
8125       hash_set (random_hash, i->as_u32, 1);
8126       for (j = 0; j <= count; j++)
8127         {
8128           do
8129             {
8130               this_random_address = random_u32 (&random_seed);
8131               this_random_address =
8132                 clib_host_to_net_u32 (this_random_address);
8133             }
8134           while (hash_get (random_hash, this_random_address));
8135           vec_add1 (random_vector, this_random_address);
8136           hash_set (random_hash, this_random_address, 1);
8137         }
8138       hash_free (random_hash);
8139       set_ip4_address (&pfx.address, random_vector[0]);
8140     }
8141
8142   if (count > 1)
8143     {
8144       /* Turn on async mode */
8145       vam->async_mode = 1;
8146       vam->async_errors = 0;
8147       before = vat_time_now (vam);
8148     }
8149
8150   for (j = 0; j < count; j++)
8151     {
8152       /* Construct the API message */
8153       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8154
8155       mp->is_add = is_add;
8156       mp->is_multipath = is_multipath;
8157
8158       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8159       mp->route.table_id = ntohl (vrf_id);
8160       mp->route.n_paths = path_count;
8161
8162       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8163
8164       if (random_add_del)
8165         set_ip4_address (&pfx.address, random_vector[j + 1]);
8166       else
8167         increment_address (&pfx.address);
8168       /* send it... */
8169       S (mp);
8170       /* If we receive SIGTERM, stop now... */
8171       if (vam->do_exit)
8172         break;
8173     }
8174
8175   /* When testing multiple add/del ops, use a control-ping to sync */
8176   if (count > 1)
8177     {
8178       vl_api_control_ping_t *mp_ping;
8179       f64 after;
8180       f64 timeout;
8181
8182       /* Shut off async mode */
8183       vam->async_mode = 0;
8184
8185       MPING (CONTROL_PING, mp_ping);
8186       S (mp_ping);
8187
8188       timeout = vat_time_now (vam) + 1.0;
8189       while (vat_time_now (vam) < timeout)
8190         if (vam->result_ready == 1)
8191           goto out;
8192       vam->retval = -99;
8193
8194     out:
8195       if (vam->retval == -99)
8196         errmsg ("timeout");
8197
8198       if (vam->async_errors > 0)
8199         {
8200           errmsg ("%d asynchronous errors", vam->async_errors);
8201           vam->retval = -98;
8202         }
8203       vam->async_errors = 0;
8204       after = vat_time_now (vam);
8205
8206       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8207       if (j > 0)
8208         count = j;
8209
8210       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8211              count, after - before, count / (after - before));
8212     }
8213   else
8214     {
8215       int ret;
8216
8217       /* Wait for a reply... */
8218       W (ret);
8219       return ret;
8220     }
8221
8222   /* Return the good/bad news */
8223   return (vam->retval);
8224 }
8225
8226 static int
8227 api_ip_mroute_add_del (vat_main_t * vam)
8228 {
8229   unformat_input_t *i = vam->input;
8230   u8 path_set = 0, prefix_set = 0, is_add = 1;
8231   vl_api_ip_mroute_add_del_t *mp;
8232   mfib_entry_flags_t eflags = 0;
8233   vl_api_mfib_path_t path;
8234   vl_api_mprefix_t pfx = { };
8235   u32 vrf_id = 0;
8236   int ret;
8237
8238   /* Parse args required to build the message */
8239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8240     {
8241       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8242         {
8243           prefix_set = 1;
8244           pfx.grp_address_length = htons (pfx.grp_address_length);
8245         }
8246       else if (unformat (i, "del"))
8247         is_add = 0;
8248       else if (unformat (i, "add"))
8249         is_add = 1;
8250       else if (unformat (i, "vrf %d", &vrf_id))
8251         ;
8252       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8253         path.itf_flags = htonl (path.itf_flags);
8254       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8255         ;
8256       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8257         path_set = 1;
8258       else
8259         {
8260           clib_warning ("parse error '%U'", format_unformat_error, i);
8261           return -99;
8262         }
8263     }
8264
8265   if (prefix_set == 0)
8266     {
8267       errmsg ("missing addresses\n");
8268       return -99;
8269     }
8270   if (path_set == 0)
8271     {
8272       errmsg ("missing path\n");
8273       return -99;
8274     }
8275
8276   /* Construct the API message */
8277   M (IP_MROUTE_ADD_DEL, mp);
8278
8279   mp->is_add = is_add;
8280   mp->is_multipath = 1;
8281
8282   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8283   mp->route.table_id = htonl (vrf_id);
8284   mp->route.n_paths = 1;
8285   mp->route.entry_flags = htonl (eflags);
8286
8287   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8288
8289   /* send it... */
8290   S (mp);
8291   /* Wait for a reply... */
8292   W (ret);
8293   return ret;
8294 }
8295
8296 static int
8297 api_mpls_table_add_del (vat_main_t * vam)
8298 {
8299   unformat_input_t *i = vam->input;
8300   vl_api_mpls_table_add_del_t *mp;
8301   u32 table_id = ~0;
8302   u8 is_add = 1;
8303   int ret = 0;
8304
8305   /* Parse args required to build the message */
8306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8307     {
8308       if (unformat (i, "table %d", &table_id))
8309         ;
8310       else if (unformat (i, "del"))
8311         is_add = 0;
8312       else if (unformat (i, "add"))
8313         is_add = 1;
8314       else
8315         {
8316           clib_warning ("parse error '%U'", format_unformat_error, i);
8317           return -99;
8318         }
8319     }
8320
8321   if (~0 == table_id)
8322     {
8323       errmsg ("missing table-ID");
8324       return -99;
8325     }
8326
8327   /* Construct the API message */
8328   M (MPLS_TABLE_ADD_DEL, mp);
8329
8330   mp->mt_table.mt_table_id = ntohl (table_id);
8331   mp->mt_is_add = is_add;
8332
8333   /* send it... */
8334   S (mp);
8335
8336   /* Wait for a reply... */
8337   W (ret);
8338
8339   return ret;
8340 }
8341
8342 static int
8343 api_mpls_route_add_del (vat_main_t * vam)
8344 {
8345   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8346   mpls_label_t local_label = MPLS_LABEL_INVALID;
8347   unformat_input_t *i = vam->input;
8348   vl_api_mpls_route_add_del_t *mp;
8349   vl_api_fib_path_t paths[8];
8350   int count = 1, j;
8351   f64 before = 0;
8352
8353   /* Parse args required to build the message */
8354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8355     {
8356       if (unformat (i, "%d", &local_label))
8357         ;
8358       else if (unformat (i, "eos"))
8359         is_eos = 1;
8360       else if (unformat (i, "non-eos"))
8361         is_eos = 0;
8362       else if (unformat (i, "del"))
8363         is_add = 0;
8364       else if (unformat (i, "add"))
8365         is_add = 1;
8366       else if (unformat (i, "multipath"))
8367         is_multipath = 1;
8368       else if (unformat (i, "count %d", &count))
8369         ;
8370       else
8371         if (unformat
8372             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8373         {
8374           path_count++;
8375           if (8 == path_count)
8376             {
8377               errmsg ("max 8 paths");
8378               return -99;
8379             }
8380         }
8381       else
8382         {
8383           clib_warning ("parse error '%U'", format_unformat_error, i);
8384           return -99;
8385         }
8386     }
8387
8388   if (!path_count)
8389     {
8390       errmsg ("specify a path; via ...");
8391       return -99;
8392     }
8393
8394   if (MPLS_LABEL_INVALID == local_label)
8395     {
8396       errmsg ("missing label");
8397       return -99;
8398     }
8399
8400   if (count > 1)
8401     {
8402       /* Turn on async mode */
8403       vam->async_mode = 1;
8404       vam->async_errors = 0;
8405       before = vat_time_now (vam);
8406     }
8407
8408   for (j = 0; j < count; j++)
8409     {
8410       /* Construct the API message */
8411       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8412
8413       mp->mr_is_add = is_add;
8414       mp->mr_is_multipath = is_multipath;
8415
8416       mp->mr_route.mr_label = local_label;
8417       mp->mr_route.mr_eos = is_eos;
8418       mp->mr_route.mr_table_id = 0;
8419       mp->mr_route.mr_n_paths = path_count;
8420
8421       clib_memcpy (&mp->mr_route.mr_paths, paths,
8422                    sizeof (paths[0]) * path_count);
8423
8424       local_label++;
8425
8426       /* send it... */
8427       S (mp);
8428       /* If we receive SIGTERM, stop now... */
8429       if (vam->do_exit)
8430         break;
8431     }
8432
8433   /* When testing multiple add/del ops, use a control-ping to sync */
8434   if (count > 1)
8435     {
8436       vl_api_control_ping_t *mp_ping;
8437       f64 after;
8438       f64 timeout;
8439
8440       /* Shut off async mode */
8441       vam->async_mode = 0;
8442
8443       MPING (CONTROL_PING, mp_ping);
8444       S (mp_ping);
8445
8446       timeout = vat_time_now (vam) + 1.0;
8447       while (vat_time_now (vam) < timeout)
8448         if (vam->result_ready == 1)
8449           goto out;
8450       vam->retval = -99;
8451
8452     out:
8453       if (vam->retval == -99)
8454         errmsg ("timeout");
8455
8456       if (vam->async_errors > 0)
8457         {
8458           errmsg ("%d asynchronous errors", vam->async_errors);
8459           vam->retval = -98;
8460         }
8461       vam->async_errors = 0;
8462       after = vat_time_now (vam);
8463
8464       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8465       if (j > 0)
8466         count = j;
8467
8468       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8469              count, after - before, count / (after - before));
8470     }
8471   else
8472     {
8473       int ret;
8474
8475       /* Wait for a reply... */
8476       W (ret);
8477       return ret;
8478     }
8479
8480   /* Return the good/bad news */
8481   return (vam->retval);
8482   return (0);
8483 }
8484
8485 static int
8486 api_mpls_ip_bind_unbind (vat_main_t * vam)
8487 {
8488   unformat_input_t *i = vam->input;
8489   vl_api_mpls_ip_bind_unbind_t *mp;
8490   u32 ip_table_id = 0;
8491   u8 is_bind = 1;
8492   vl_api_prefix_t pfx;
8493   u8 prefix_set = 0;
8494   mpls_label_t local_label = MPLS_LABEL_INVALID;
8495   int ret;
8496
8497   /* Parse args required to build the message */
8498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8499     {
8500       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8501         prefix_set = 1;
8502       else if (unformat (i, "%d", &local_label))
8503         ;
8504       else if (unformat (i, "table-id %d", &ip_table_id))
8505         ;
8506       else if (unformat (i, "unbind"))
8507         is_bind = 0;
8508       else if (unformat (i, "bind"))
8509         is_bind = 1;
8510       else
8511         {
8512           clib_warning ("parse error '%U'", format_unformat_error, i);
8513           return -99;
8514         }
8515     }
8516
8517   if (!prefix_set)
8518     {
8519       errmsg ("IP prefix not set");
8520       return -99;
8521     }
8522
8523   if (MPLS_LABEL_INVALID == local_label)
8524     {
8525       errmsg ("missing label");
8526       return -99;
8527     }
8528
8529   /* Construct the API message */
8530   M (MPLS_IP_BIND_UNBIND, mp);
8531
8532   mp->mb_is_bind = is_bind;
8533   mp->mb_ip_table_id = ntohl (ip_table_id);
8534   mp->mb_mpls_table_id = 0;
8535   mp->mb_label = ntohl (local_label);
8536   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8537
8538   /* send it... */
8539   S (mp);
8540
8541   /* Wait for a reply... */
8542   W (ret);
8543   return ret;
8544   return (0);
8545 }
8546
8547 static int
8548 api_sr_mpls_policy_add (vat_main_t * vam)
8549 {
8550   unformat_input_t *i = vam->input;
8551   vl_api_sr_mpls_policy_add_t *mp;
8552   u32 bsid = 0;
8553   u32 weight = 1;
8554   u8 type = 0;
8555   u8 n_segments = 0;
8556   u32 sid;
8557   u32 *segments = NULL;
8558   int ret;
8559
8560   /* Parse args required to build the message */
8561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8562     {
8563       if (unformat (i, "bsid %d", &bsid))
8564         ;
8565       else if (unformat (i, "weight %d", &weight))
8566         ;
8567       else if (unformat (i, "spray"))
8568         type = 1;
8569       else if (unformat (i, "next %d", &sid))
8570         {
8571           n_segments += 1;
8572           vec_add1 (segments, htonl (sid));
8573         }
8574       else
8575         {
8576           clib_warning ("parse error '%U'", format_unformat_error, i);
8577           return -99;
8578         }
8579     }
8580
8581   if (bsid == 0)
8582     {
8583       errmsg ("bsid not set");
8584       return -99;
8585     }
8586
8587   if (n_segments == 0)
8588     {
8589       errmsg ("no sid in segment stack");
8590       return -99;
8591     }
8592
8593   /* Construct the API message */
8594   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8595
8596   mp->bsid = htonl (bsid);
8597   mp->weight = htonl (weight);
8598   mp->is_spray = type;
8599   mp->n_segments = n_segments;
8600   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8601   vec_free (segments);
8602
8603   /* send it... */
8604   S (mp);
8605
8606   /* Wait for a reply... */
8607   W (ret);
8608   return ret;
8609 }
8610
8611 static int
8612 api_sr_mpls_policy_del (vat_main_t * vam)
8613 {
8614   unformat_input_t *i = vam->input;
8615   vl_api_sr_mpls_policy_del_t *mp;
8616   u32 bsid = 0;
8617   int ret;
8618
8619   /* Parse args required to build the message */
8620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8621     {
8622       if (unformat (i, "bsid %d", &bsid))
8623         ;
8624       else
8625         {
8626           clib_warning ("parse error '%U'", format_unformat_error, i);
8627           return -99;
8628         }
8629     }
8630
8631   if (bsid == 0)
8632     {
8633       errmsg ("bsid not set");
8634       return -99;
8635     }
8636
8637   /* Construct the API message */
8638   M (SR_MPLS_POLICY_DEL, mp);
8639
8640   mp->bsid = htonl (bsid);
8641
8642   /* send it... */
8643   S (mp);
8644
8645   /* Wait for a reply... */
8646   W (ret);
8647   return ret;
8648 }
8649
8650 static int
8651 api_bier_table_add_del (vat_main_t * vam)
8652 {
8653   unformat_input_t *i = vam->input;
8654   vl_api_bier_table_add_del_t *mp;
8655   u8 is_add = 1;
8656   u32 set = 0, sub_domain = 0, hdr_len = 3;
8657   mpls_label_t local_label = MPLS_LABEL_INVALID;
8658   int ret;
8659
8660   /* Parse args required to build the message */
8661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8662     {
8663       if (unformat (i, "sub-domain %d", &sub_domain))
8664         ;
8665       else if (unformat (i, "set %d", &set))
8666         ;
8667       else if (unformat (i, "label %d", &local_label))
8668         ;
8669       else if (unformat (i, "hdr-len %d", &hdr_len))
8670         ;
8671       else if (unformat (i, "add"))
8672         is_add = 1;
8673       else if (unformat (i, "del"))
8674         is_add = 0;
8675       else
8676         {
8677           clib_warning ("parse error '%U'", format_unformat_error, i);
8678           return -99;
8679         }
8680     }
8681
8682   if (MPLS_LABEL_INVALID == local_label)
8683     {
8684       errmsg ("missing label\n");
8685       return -99;
8686     }
8687
8688   /* Construct the API message */
8689   M (BIER_TABLE_ADD_DEL, mp);
8690
8691   mp->bt_is_add = is_add;
8692   mp->bt_label = ntohl (local_label);
8693   mp->bt_tbl_id.bt_set = set;
8694   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8695   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8696
8697   /* send it... */
8698   S (mp);
8699
8700   /* Wait for a reply... */
8701   W (ret);
8702
8703   return (ret);
8704 }
8705
8706 static int
8707 api_bier_route_add_del (vat_main_t * vam)
8708 {
8709   unformat_input_t *i = vam->input;
8710   vl_api_bier_route_add_del_t *mp;
8711   u8 is_add = 1;
8712   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8713   ip4_address_t v4_next_hop_address;
8714   ip6_address_t v6_next_hop_address;
8715   u8 next_hop_set = 0;
8716   u8 next_hop_proto_is_ip4 = 1;
8717   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8718   int ret;
8719
8720   /* Parse args required to build the message */
8721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8722     {
8723       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8724         {
8725           next_hop_proto_is_ip4 = 1;
8726           next_hop_set = 1;
8727         }
8728       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8729         {
8730           next_hop_proto_is_ip4 = 0;
8731           next_hop_set = 1;
8732         }
8733       if (unformat (i, "sub-domain %d", &sub_domain))
8734         ;
8735       else if (unformat (i, "set %d", &set))
8736         ;
8737       else if (unformat (i, "hdr-len %d", &hdr_len))
8738         ;
8739       else if (unformat (i, "bp %d", &bp))
8740         ;
8741       else if (unformat (i, "add"))
8742         is_add = 1;
8743       else if (unformat (i, "del"))
8744         is_add = 0;
8745       else if (unformat (i, "out-label %d", &next_hop_out_label))
8746         ;
8747       else
8748         {
8749           clib_warning ("parse error '%U'", format_unformat_error, i);
8750           return -99;
8751         }
8752     }
8753
8754   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8755     {
8756       errmsg ("next hop / label set\n");
8757       return -99;
8758     }
8759   if (0 == bp)
8760     {
8761       errmsg ("bit=position not set\n");
8762       return -99;
8763     }
8764
8765   /* Construct the API message */
8766   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8767
8768   mp->br_is_add = is_add;
8769   mp->br_route.br_tbl_id.bt_set = set;
8770   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8771   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8772   mp->br_route.br_bp = ntohs (bp);
8773   mp->br_route.br_n_paths = 1;
8774   mp->br_route.br_paths[0].n_labels = 1;
8775   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8776   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8777                                     FIB_API_PATH_NH_PROTO_IP4 :
8778                                     FIB_API_PATH_NH_PROTO_IP6);
8779
8780   if (next_hop_proto_is_ip4)
8781     {
8782       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8783                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8784     }
8785   else
8786     {
8787       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8788                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8789     }
8790
8791   /* send it... */
8792   S (mp);
8793
8794   /* Wait for a reply... */
8795   W (ret);
8796
8797   return (ret);
8798 }
8799
8800 static int
8801 api_mpls_tunnel_add_del (vat_main_t * vam)
8802 {
8803   unformat_input_t *i = vam->input;
8804   vl_api_mpls_tunnel_add_del_t *mp;
8805
8806   vl_api_fib_path_t paths[8];
8807   u32 sw_if_index = ~0;
8808   u8 path_count = 0;
8809   u8 l2_only = 0;
8810   u8 is_add = 1;
8811   int ret;
8812
8813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8814     {
8815       if (unformat (i, "add"))
8816         is_add = 1;
8817       else
8818         if (unformat
8819             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8820         is_add = 0;
8821       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8822         is_add = 0;
8823       else if (unformat (i, "l2-only"))
8824         l2_only = 1;
8825       else
8826         if (unformat
8827             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8828         {
8829           path_count++;
8830           if (8 == path_count)
8831             {
8832               errmsg ("max 8 paths");
8833               return -99;
8834             }
8835         }
8836       else
8837         {
8838           clib_warning ("parse error '%U'", format_unformat_error, i);
8839           return -99;
8840         }
8841     }
8842
8843   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8844
8845   mp->mt_is_add = is_add;
8846   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8847   mp->mt_tunnel.mt_l2_only = l2_only;
8848   mp->mt_tunnel.mt_is_multicast = 0;
8849   mp->mt_tunnel.mt_n_paths = path_count;
8850
8851   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8852                sizeof (paths[0]) * path_count);
8853
8854   S (mp);
8855   W (ret);
8856   return ret;
8857 }
8858
8859 static int
8860 api_sw_interface_set_unnumbered (vat_main_t * vam)
8861 {
8862   unformat_input_t *i = vam->input;
8863   vl_api_sw_interface_set_unnumbered_t *mp;
8864   u32 sw_if_index;
8865   u32 unnum_sw_index = ~0;
8866   u8 is_add = 1;
8867   u8 sw_if_index_set = 0;
8868   int ret;
8869
8870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8871     {
8872       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8873         sw_if_index_set = 1;
8874       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8875         sw_if_index_set = 1;
8876       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8877         ;
8878       else if (unformat (i, "del"))
8879         is_add = 0;
8880       else
8881         {
8882           clib_warning ("parse error '%U'", format_unformat_error, i);
8883           return -99;
8884         }
8885     }
8886
8887   if (sw_if_index_set == 0)
8888     {
8889       errmsg ("missing interface name or sw_if_index");
8890       return -99;
8891     }
8892
8893   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8894
8895   mp->sw_if_index = ntohl (sw_if_index);
8896   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8897   mp->is_add = is_add;
8898
8899   S (mp);
8900   W (ret);
8901   return ret;
8902 }
8903
8904
8905 static int
8906 api_create_vlan_subif (vat_main_t * vam)
8907 {
8908   unformat_input_t *i = vam->input;
8909   vl_api_create_vlan_subif_t *mp;
8910   u32 sw_if_index;
8911   u8 sw_if_index_set = 0;
8912   u32 vlan_id;
8913   u8 vlan_id_set = 0;
8914   int ret;
8915
8916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8917     {
8918       if (unformat (i, "sw_if_index %d", &sw_if_index))
8919         sw_if_index_set = 1;
8920       else
8921         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8922         sw_if_index_set = 1;
8923       else if (unformat (i, "vlan %d", &vlan_id))
8924         vlan_id_set = 1;
8925       else
8926         {
8927           clib_warning ("parse error '%U'", format_unformat_error, i);
8928           return -99;
8929         }
8930     }
8931
8932   if (sw_if_index_set == 0)
8933     {
8934       errmsg ("missing interface name or sw_if_index");
8935       return -99;
8936     }
8937
8938   if (vlan_id_set == 0)
8939     {
8940       errmsg ("missing vlan_id");
8941       return -99;
8942     }
8943   M (CREATE_VLAN_SUBIF, mp);
8944
8945   mp->sw_if_index = ntohl (sw_if_index);
8946   mp->vlan_id = ntohl (vlan_id);
8947
8948   S (mp);
8949   W (ret);
8950   return ret;
8951 }
8952
8953 #define foreach_create_subif_bit                \
8954 _(no_tags)                                      \
8955 _(one_tag)                                      \
8956 _(two_tags)                                     \
8957 _(dot1ad)                                       \
8958 _(exact_match)                                  \
8959 _(default_sub)                                  \
8960 _(outer_vlan_id_any)                            \
8961 _(inner_vlan_id_any)
8962
8963 #define foreach_create_subif_flag               \
8964 _(0, "no_tags")                                 \
8965 _(1, "one_tag")                                 \
8966 _(2, "two_tags")                                \
8967 _(3, "dot1ad")                                  \
8968 _(4, "exact_match")                             \
8969 _(5, "default_sub")                             \
8970 _(6, "outer_vlan_id_any")                       \
8971 _(7, "inner_vlan_id_any")
8972
8973 static int
8974 api_create_subif (vat_main_t * vam)
8975 {
8976   unformat_input_t *i = vam->input;
8977   vl_api_create_subif_t *mp;
8978   u32 sw_if_index;
8979   u8 sw_if_index_set = 0;
8980   u32 sub_id;
8981   u8 sub_id_set = 0;
8982   u32 __attribute__ ((unused)) no_tags = 0;
8983   u32 __attribute__ ((unused)) one_tag = 0;
8984   u32 __attribute__ ((unused)) two_tags = 0;
8985   u32 __attribute__ ((unused)) dot1ad = 0;
8986   u32 __attribute__ ((unused)) exact_match = 0;
8987   u32 __attribute__ ((unused)) default_sub = 0;
8988   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8989   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8990   u32 tmp;
8991   u16 outer_vlan_id = 0;
8992   u16 inner_vlan_id = 0;
8993   int ret;
8994
8995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8996     {
8997       if (unformat (i, "sw_if_index %d", &sw_if_index))
8998         sw_if_index_set = 1;
8999       else
9000         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9001         sw_if_index_set = 1;
9002       else if (unformat (i, "sub_id %d", &sub_id))
9003         sub_id_set = 1;
9004       else if (unformat (i, "outer_vlan_id %d", &tmp))
9005         outer_vlan_id = tmp;
9006       else if (unformat (i, "inner_vlan_id %d", &tmp))
9007         inner_vlan_id = tmp;
9008
9009 #define _(a) else if (unformat (i, #a)) a = 1 ;
9010       foreach_create_subif_bit
9011 #undef _
9012         else
9013         {
9014           clib_warning ("parse error '%U'", format_unformat_error, i);
9015           return -99;
9016         }
9017     }
9018
9019   if (sw_if_index_set == 0)
9020     {
9021       errmsg ("missing interface name or sw_if_index");
9022       return -99;
9023     }
9024
9025   if (sub_id_set == 0)
9026     {
9027       errmsg ("missing sub_id");
9028       return -99;
9029     }
9030   M (CREATE_SUBIF, mp);
9031
9032   mp->sw_if_index = ntohl (sw_if_index);
9033   mp->sub_id = ntohl (sub_id);
9034
9035 #define _(a,b) mp->sub_if_flags |= (1 << a);
9036   foreach_create_subif_flag;
9037 #undef _
9038
9039   mp->outer_vlan_id = ntohs (outer_vlan_id);
9040   mp->inner_vlan_id = ntohs (inner_vlan_id);
9041
9042   S (mp);
9043   W (ret);
9044   return ret;
9045 }
9046
9047 static int
9048 api_ip_table_replace_begin (vat_main_t * vam)
9049 {
9050   unformat_input_t *i = vam->input;
9051   vl_api_ip_table_replace_begin_t *mp;
9052   u32 table_id = 0;
9053   u8 is_ipv6 = 0;
9054
9055   int ret;
9056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9057     {
9058       if (unformat (i, "table %d", &table_id))
9059         ;
9060       else if (unformat (i, "ipv6"))
9061         is_ipv6 = 1;
9062       else
9063         {
9064           clib_warning ("parse error '%U'", format_unformat_error, i);
9065           return -99;
9066         }
9067     }
9068
9069   M (IP_TABLE_REPLACE_BEGIN, mp);
9070
9071   mp->table.table_id = ntohl (table_id);
9072   mp->table.is_ip6 = is_ipv6;
9073
9074   S (mp);
9075   W (ret);
9076   return ret;
9077 }
9078
9079 static int
9080 api_ip_table_flush (vat_main_t * vam)
9081 {
9082   unformat_input_t *i = vam->input;
9083   vl_api_ip_table_flush_t *mp;
9084   u32 table_id = 0;
9085   u8 is_ipv6 = 0;
9086
9087   int ret;
9088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9089     {
9090       if (unformat (i, "table %d", &table_id))
9091         ;
9092       else if (unformat (i, "ipv6"))
9093         is_ipv6 = 1;
9094       else
9095         {
9096           clib_warning ("parse error '%U'", format_unformat_error, i);
9097           return -99;
9098         }
9099     }
9100
9101   M (IP_TABLE_FLUSH, mp);
9102
9103   mp->table.table_id = ntohl (table_id);
9104   mp->table.is_ip6 = is_ipv6;
9105
9106   S (mp);
9107   W (ret);
9108   return ret;
9109 }
9110
9111 static int
9112 api_ip_table_replace_end (vat_main_t * vam)
9113 {
9114   unformat_input_t *i = vam->input;
9115   vl_api_ip_table_replace_end_t *mp;
9116   u32 table_id = 0;
9117   u8 is_ipv6 = 0;
9118
9119   int ret;
9120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9121     {
9122       if (unformat (i, "table %d", &table_id))
9123         ;
9124       else if (unformat (i, "ipv6"))
9125         is_ipv6 = 1;
9126       else
9127         {
9128           clib_warning ("parse error '%U'", format_unformat_error, i);
9129           return -99;
9130         }
9131     }
9132
9133   M (IP_TABLE_REPLACE_END, mp);
9134
9135   mp->table.table_id = ntohl (table_id);
9136   mp->table.is_ip6 = is_ipv6;
9137
9138   S (mp);
9139   W (ret);
9140   return ret;
9141 }
9142
9143 static int
9144 api_set_ip_flow_hash (vat_main_t * vam)
9145 {
9146   unformat_input_t *i = vam->input;
9147   vl_api_set_ip_flow_hash_t *mp;
9148   u32 vrf_id = 0;
9149   u8 is_ipv6 = 0;
9150   u8 vrf_id_set = 0;
9151   u8 src = 0;
9152   u8 dst = 0;
9153   u8 sport = 0;
9154   u8 dport = 0;
9155   u8 proto = 0;
9156   u8 reverse = 0;
9157   int ret;
9158
9159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9160     {
9161       if (unformat (i, "vrf %d", &vrf_id))
9162         vrf_id_set = 1;
9163       else if (unformat (i, "ipv6"))
9164         is_ipv6 = 1;
9165       else if (unformat (i, "src"))
9166         src = 1;
9167       else if (unformat (i, "dst"))
9168         dst = 1;
9169       else if (unformat (i, "sport"))
9170         sport = 1;
9171       else if (unformat (i, "dport"))
9172         dport = 1;
9173       else if (unformat (i, "proto"))
9174         proto = 1;
9175       else if (unformat (i, "reverse"))
9176         reverse = 1;
9177
9178       else
9179         {
9180           clib_warning ("parse error '%U'", format_unformat_error, i);
9181           return -99;
9182         }
9183     }
9184
9185   if (vrf_id_set == 0)
9186     {
9187       errmsg ("missing vrf id");
9188       return -99;
9189     }
9190
9191   M (SET_IP_FLOW_HASH, mp);
9192   mp->src = src;
9193   mp->dst = dst;
9194   mp->sport = sport;
9195   mp->dport = dport;
9196   mp->proto = proto;
9197   mp->reverse = reverse;
9198   mp->vrf_id = ntohl (vrf_id);
9199   mp->is_ipv6 = is_ipv6;
9200
9201   S (mp);
9202   W (ret);
9203   return ret;
9204 }
9205
9206 static int
9207 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9208 {
9209   unformat_input_t *i = vam->input;
9210   vl_api_sw_interface_ip6_enable_disable_t *mp;
9211   u32 sw_if_index;
9212   u8 sw_if_index_set = 0;
9213   u8 enable = 0;
9214   int ret;
9215
9216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9217     {
9218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9219         sw_if_index_set = 1;
9220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9221         sw_if_index_set = 1;
9222       else if (unformat (i, "enable"))
9223         enable = 1;
9224       else if (unformat (i, "disable"))
9225         enable = 0;
9226       else
9227         {
9228           clib_warning ("parse error '%U'", format_unformat_error, i);
9229           return -99;
9230         }
9231     }
9232
9233   if (sw_if_index_set == 0)
9234     {
9235       errmsg ("missing interface name or sw_if_index");
9236       return -99;
9237     }
9238
9239   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9240
9241   mp->sw_if_index = ntohl (sw_if_index);
9242   mp->enable = enable;
9243
9244   S (mp);
9245   W (ret);
9246   return ret;
9247 }
9248
9249
9250 static int
9251 api_l2_patch_add_del (vat_main_t * vam)
9252 {
9253   unformat_input_t *i = vam->input;
9254   vl_api_l2_patch_add_del_t *mp;
9255   u32 rx_sw_if_index;
9256   u8 rx_sw_if_index_set = 0;
9257   u32 tx_sw_if_index;
9258   u8 tx_sw_if_index_set = 0;
9259   u8 is_add = 1;
9260   int ret;
9261
9262   /* Parse args required to build the message */
9263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9264     {
9265       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9266         rx_sw_if_index_set = 1;
9267       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9268         tx_sw_if_index_set = 1;
9269       else if (unformat (i, "rx"))
9270         {
9271           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9272             {
9273               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9274                             &rx_sw_if_index))
9275                 rx_sw_if_index_set = 1;
9276             }
9277           else
9278             break;
9279         }
9280       else if (unformat (i, "tx"))
9281         {
9282           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9283             {
9284               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9285                             &tx_sw_if_index))
9286                 tx_sw_if_index_set = 1;
9287             }
9288           else
9289             break;
9290         }
9291       else if (unformat (i, "del"))
9292         is_add = 0;
9293       else
9294         break;
9295     }
9296
9297   if (rx_sw_if_index_set == 0)
9298     {
9299       errmsg ("missing rx interface name or rx_sw_if_index");
9300       return -99;
9301     }
9302
9303   if (tx_sw_if_index_set == 0)
9304     {
9305       errmsg ("missing tx interface name or tx_sw_if_index");
9306       return -99;
9307     }
9308
9309   M (L2_PATCH_ADD_DEL, mp);
9310
9311   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9312   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9313   mp->is_add = is_add;
9314
9315   S (mp);
9316   W (ret);
9317   return ret;
9318 }
9319
9320 u8 is_del;
9321 u8 localsid_addr[16];
9322 u8 end_psp;
9323 u8 behavior;
9324 u32 sw_if_index;
9325 u32 vlan_index;
9326 u32 fib_table;
9327 u8 nh_addr[16];
9328
9329 static int
9330 api_sr_localsid_add_del (vat_main_t * vam)
9331 {
9332   unformat_input_t *i = vam->input;
9333   vl_api_sr_localsid_add_del_t *mp;
9334
9335   u8 is_del;
9336   ip6_address_t localsid;
9337   u8 end_psp = 0;
9338   u8 behavior = ~0;
9339   u32 sw_if_index;
9340   u32 fib_table = ~(u32) 0;
9341   ip46_address_t nh_addr;
9342   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9343
9344   bool nexthop_set = 0;
9345
9346   int ret;
9347
9348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9349     {
9350       if (unformat (i, "del"))
9351         is_del = 1;
9352       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9353       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9354         nexthop_set = 1;
9355       else if (unformat (i, "behavior %u", &behavior));
9356       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9357       else if (unformat (i, "fib-table %u", &fib_table));
9358       else if (unformat (i, "end.psp %u", &behavior));
9359       else
9360         break;
9361     }
9362
9363   M (SR_LOCALSID_ADD_DEL, mp);
9364
9365   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9366
9367   if (nexthop_set)
9368     {
9369       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9370     }
9371   mp->behavior = behavior;
9372   mp->sw_if_index = ntohl (sw_if_index);
9373   mp->fib_table = ntohl (fib_table);
9374   mp->end_psp = end_psp;
9375   mp->is_del = is_del;
9376
9377   S (mp);
9378   W (ret);
9379   return ret;
9380 }
9381
9382 static int
9383 api_ioam_enable (vat_main_t * vam)
9384 {
9385   unformat_input_t *input = vam->input;
9386   vl_api_ioam_enable_t *mp;
9387   u32 id = 0;
9388   int has_trace_option = 0;
9389   int has_pot_option = 0;
9390   int has_seqno_option = 0;
9391   int has_analyse_option = 0;
9392   int ret;
9393
9394   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9395     {
9396       if (unformat (input, "trace"))
9397         has_trace_option = 1;
9398       else if (unformat (input, "pot"))
9399         has_pot_option = 1;
9400       else if (unformat (input, "seqno"))
9401         has_seqno_option = 1;
9402       else if (unformat (input, "analyse"))
9403         has_analyse_option = 1;
9404       else
9405         break;
9406     }
9407   M (IOAM_ENABLE, mp);
9408   mp->id = htons (id);
9409   mp->seqno = has_seqno_option;
9410   mp->analyse = has_analyse_option;
9411   mp->pot_enable = has_pot_option;
9412   mp->trace_enable = has_trace_option;
9413
9414   S (mp);
9415   W (ret);
9416   return ret;
9417 }
9418
9419
9420 static int
9421 api_ioam_disable (vat_main_t * vam)
9422 {
9423   vl_api_ioam_disable_t *mp;
9424   int ret;
9425
9426   M (IOAM_DISABLE, mp);
9427   S (mp);
9428   W (ret);
9429   return ret;
9430 }
9431
9432 #define foreach_tcp_proto_field                 \
9433 _(src_port)                                     \
9434 _(dst_port)
9435
9436 #define foreach_udp_proto_field                 \
9437 _(src_port)                                     \
9438 _(dst_port)
9439
9440 #define foreach_ip4_proto_field                 \
9441 _(src_address)                                  \
9442 _(dst_address)                                  \
9443 _(tos)                                          \
9444 _(length)                                       \
9445 _(fragment_id)                                  \
9446 _(ttl)                                          \
9447 _(protocol)                                     \
9448 _(checksum)
9449
9450 typedef struct
9451 {
9452   u16 src_port, dst_port;
9453 } tcpudp_header_t;
9454
9455 #if VPP_API_TEST_BUILTIN == 0
9456 uword
9457 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9458 {
9459   u8 **maskp = va_arg (*args, u8 **);
9460   u8 *mask = 0;
9461   u8 found_something = 0;
9462   tcp_header_t *tcp;
9463
9464 #define _(a) u8 a=0;
9465   foreach_tcp_proto_field;
9466 #undef _
9467
9468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9469     {
9470       if (0);
9471 #define _(a) else if (unformat (input, #a)) a=1;
9472       foreach_tcp_proto_field
9473 #undef _
9474         else
9475         break;
9476     }
9477
9478 #define _(a) found_something += a;
9479   foreach_tcp_proto_field;
9480 #undef _
9481
9482   if (found_something == 0)
9483     return 0;
9484
9485   vec_validate (mask, sizeof (*tcp) - 1);
9486
9487   tcp = (tcp_header_t *) mask;
9488
9489 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9490   foreach_tcp_proto_field;
9491 #undef _
9492
9493   *maskp = mask;
9494   return 1;
9495 }
9496
9497 uword
9498 unformat_udp_mask (unformat_input_t * input, va_list * args)
9499 {
9500   u8 **maskp = va_arg (*args, u8 **);
9501   u8 *mask = 0;
9502   u8 found_something = 0;
9503   udp_header_t *udp;
9504
9505 #define _(a) u8 a=0;
9506   foreach_udp_proto_field;
9507 #undef _
9508
9509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9510     {
9511       if (0);
9512 #define _(a) else if (unformat (input, #a)) a=1;
9513       foreach_udp_proto_field
9514 #undef _
9515         else
9516         break;
9517     }
9518
9519 #define _(a) found_something += a;
9520   foreach_udp_proto_field;
9521 #undef _
9522
9523   if (found_something == 0)
9524     return 0;
9525
9526   vec_validate (mask, sizeof (*udp) - 1);
9527
9528   udp = (udp_header_t *) mask;
9529
9530 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9531   foreach_udp_proto_field;
9532 #undef _
9533
9534   *maskp = mask;
9535   return 1;
9536 }
9537
9538 uword
9539 unformat_l4_mask (unformat_input_t * input, va_list * args)
9540 {
9541   u8 **maskp = va_arg (*args, u8 **);
9542   u16 src_port = 0, dst_port = 0;
9543   tcpudp_header_t *tcpudp;
9544
9545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9546     {
9547       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9548         return 1;
9549       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9550         return 1;
9551       else if (unformat (input, "src_port"))
9552         src_port = 0xFFFF;
9553       else if (unformat (input, "dst_port"))
9554         dst_port = 0xFFFF;
9555       else
9556         return 0;
9557     }
9558
9559   if (!src_port && !dst_port)
9560     return 0;
9561
9562   u8 *mask = 0;
9563   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9564
9565   tcpudp = (tcpudp_header_t *) mask;
9566   tcpudp->src_port = src_port;
9567   tcpudp->dst_port = dst_port;
9568
9569   *maskp = mask;
9570
9571   return 1;
9572 }
9573
9574 uword
9575 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9576 {
9577   u8 **maskp = va_arg (*args, u8 **);
9578   u8 *mask = 0;
9579   u8 found_something = 0;
9580   ip4_header_t *ip;
9581
9582 #define _(a) u8 a=0;
9583   foreach_ip4_proto_field;
9584 #undef _
9585   u8 version = 0;
9586   u8 hdr_length = 0;
9587
9588
9589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9590     {
9591       if (unformat (input, "version"))
9592         version = 1;
9593       else if (unformat (input, "hdr_length"))
9594         hdr_length = 1;
9595       else if (unformat (input, "src"))
9596         src_address = 1;
9597       else if (unformat (input, "dst"))
9598         dst_address = 1;
9599       else if (unformat (input, "proto"))
9600         protocol = 1;
9601
9602 #define _(a) else if (unformat (input, #a)) a=1;
9603       foreach_ip4_proto_field
9604 #undef _
9605         else
9606         break;
9607     }
9608
9609 #define _(a) found_something += a;
9610   foreach_ip4_proto_field;
9611 #undef _
9612
9613   if (found_something == 0)
9614     return 0;
9615
9616   vec_validate (mask, sizeof (*ip) - 1);
9617
9618   ip = (ip4_header_t *) mask;
9619
9620 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9621   foreach_ip4_proto_field;
9622 #undef _
9623
9624   ip->ip_version_and_header_length = 0;
9625
9626   if (version)
9627     ip->ip_version_and_header_length |= 0xF0;
9628
9629   if (hdr_length)
9630     ip->ip_version_and_header_length |= 0x0F;
9631
9632   *maskp = mask;
9633   return 1;
9634 }
9635
9636 #define foreach_ip6_proto_field                 \
9637 _(src_address)                                  \
9638 _(dst_address)                                  \
9639 _(payload_length)                               \
9640 _(hop_limit)                                    \
9641 _(protocol)
9642
9643 uword
9644 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9645 {
9646   u8 **maskp = va_arg (*args, u8 **);
9647   u8 *mask = 0;
9648   u8 found_something = 0;
9649   ip6_header_t *ip;
9650   u32 ip_version_traffic_class_and_flow_label;
9651
9652 #define _(a) u8 a=0;
9653   foreach_ip6_proto_field;
9654 #undef _
9655   u8 version = 0;
9656   u8 traffic_class = 0;
9657   u8 flow_label = 0;
9658
9659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9660     {
9661       if (unformat (input, "version"))
9662         version = 1;
9663       else if (unformat (input, "traffic-class"))
9664         traffic_class = 1;
9665       else if (unformat (input, "flow-label"))
9666         flow_label = 1;
9667       else if (unformat (input, "src"))
9668         src_address = 1;
9669       else if (unformat (input, "dst"))
9670         dst_address = 1;
9671       else if (unformat (input, "proto"))
9672         protocol = 1;
9673
9674 #define _(a) else if (unformat (input, #a)) a=1;
9675       foreach_ip6_proto_field
9676 #undef _
9677         else
9678         break;
9679     }
9680
9681 #define _(a) found_something += a;
9682   foreach_ip6_proto_field;
9683 #undef _
9684
9685   if (found_something == 0)
9686     return 0;
9687
9688   vec_validate (mask, sizeof (*ip) - 1);
9689
9690   ip = (ip6_header_t *) mask;
9691
9692 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9693   foreach_ip6_proto_field;
9694 #undef _
9695
9696   ip_version_traffic_class_and_flow_label = 0;
9697
9698   if (version)
9699     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9700
9701   if (traffic_class)
9702     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9703
9704   if (flow_label)
9705     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9706
9707   ip->ip_version_traffic_class_and_flow_label =
9708     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9709
9710   *maskp = mask;
9711   return 1;
9712 }
9713
9714 uword
9715 unformat_l3_mask (unformat_input_t * input, va_list * args)
9716 {
9717   u8 **maskp = va_arg (*args, u8 **);
9718
9719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9720     {
9721       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9722         return 1;
9723       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9724         return 1;
9725       else
9726         break;
9727     }
9728   return 0;
9729 }
9730
9731 uword
9732 unformat_l2_mask (unformat_input_t * input, va_list * args)
9733 {
9734   u8 **maskp = va_arg (*args, u8 **);
9735   u8 *mask = 0;
9736   u8 src = 0;
9737   u8 dst = 0;
9738   u8 proto = 0;
9739   u8 tag1 = 0;
9740   u8 tag2 = 0;
9741   u8 ignore_tag1 = 0;
9742   u8 ignore_tag2 = 0;
9743   u8 cos1 = 0;
9744   u8 cos2 = 0;
9745   u8 dot1q = 0;
9746   u8 dot1ad = 0;
9747   int len = 14;
9748
9749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9750     {
9751       if (unformat (input, "src"))
9752         src = 1;
9753       else if (unformat (input, "dst"))
9754         dst = 1;
9755       else if (unformat (input, "proto"))
9756         proto = 1;
9757       else if (unformat (input, "tag1"))
9758         tag1 = 1;
9759       else if (unformat (input, "tag2"))
9760         tag2 = 1;
9761       else if (unformat (input, "ignore-tag1"))
9762         ignore_tag1 = 1;
9763       else if (unformat (input, "ignore-tag2"))
9764         ignore_tag2 = 1;
9765       else if (unformat (input, "cos1"))
9766         cos1 = 1;
9767       else if (unformat (input, "cos2"))
9768         cos2 = 1;
9769       else if (unformat (input, "dot1q"))
9770         dot1q = 1;
9771       else if (unformat (input, "dot1ad"))
9772         dot1ad = 1;
9773       else
9774         break;
9775     }
9776   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9777        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9778     return 0;
9779
9780   if (tag1 || ignore_tag1 || cos1 || dot1q)
9781     len = 18;
9782   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9783     len = 22;
9784
9785   vec_validate (mask, len - 1);
9786
9787   if (dst)
9788     clib_memset (mask, 0xff, 6);
9789
9790   if (src)
9791     clib_memset (mask + 6, 0xff, 6);
9792
9793   if (tag2 || dot1ad)
9794     {
9795       /* inner vlan tag */
9796       if (tag2)
9797         {
9798           mask[19] = 0xff;
9799           mask[18] = 0x0f;
9800         }
9801       if (cos2)
9802         mask[18] |= 0xe0;
9803       if (proto)
9804         mask[21] = mask[20] = 0xff;
9805       if (tag1)
9806         {
9807           mask[15] = 0xff;
9808           mask[14] = 0x0f;
9809         }
9810       if (cos1)
9811         mask[14] |= 0xe0;
9812       *maskp = mask;
9813       return 1;
9814     }
9815   if (tag1 | dot1q)
9816     {
9817       if (tag1)
9818         {
9819           mask[15] = 0xff;
9820           mask[14] = 0x0f;
9821         }
9822       if (cos1)
9823         mask[14] |= 0xe0;
9824       if (proto)
9825         mask[16] = mask[17] = 0xff;
9826
9827       *maskp = mask;
9828       return 1;
9829     }
9830   if (cos2)
9831     mask[18] |= 0xe0;
9832   if (cos1)
9833     mask[14] |= 0xe0;
9834   if (proto)
9835     mask[12] = mask[13] = 0xff;
9836
9837   *maskp = mask;
9838   return 1;
9839 }
9840
9841 uword
9842 unformat_classify_mask (unformat_input_t * input, va_list * args)
9843 {
9844   u8 **maskp = va_arg (*args, u8 **);
9845   u32 *skipp = va_arg (*args, u32 *);
9846   u32 *matchp = va_arg (*args, u32 *);
9847   u32 match;
9848   u8 *mask = 0;
9849   u8 *l2 = 0;
9850   u8 *l3 = 0;
9851   u8 *l4 = 0;
9852   int i;
9853
9854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9855     {
9856       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9857         ;
9858       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9859         ;
9860       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9861         ;
9862       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9863         ;
9864       else
9865         break;
9866     }
9867
9868   if (l4 && !l3)
9869     {
9870       vec_free (mask);
9871       vec_free (l2);
9872       vec_free (l4);
9873       return 0;
9874     }
9875
9876   if (mask || l2 || l3 || l4)
9877     {
9878       if (l2 || l3 || l4)
9879         {
9880           /* "With a free Ethernet header in every package" */
9881           if (l2 == 0)
9882             vec_validate (l2, 13);
9883           mask = l2;
9884           if (vec_len (l3))
9885             {
9886               vec_append (mask, l3);
9887               vec_free (l3);
9888             }
9889           if (vec_len (l4))
9890             {
9891               vec_append (mask, l4);
9892               vec_free (l4);
9893             }
9894         }
9895
9896       /* Scan forward looking for the first significant mask octet */
9897       for (i = 0; i < vec_len (mask); i++)
9898         if (mask[i])
9899           break;
9900
9901       /* compute (skip, match) params */
9902       *skipp = i / sizeof (u32x4);
9903       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9904
9905       /* Pad mask to an even multiple of the vector size */
9906       while (vec_len (mask) % sizeof (u32x4))
9907         vec_add1 (mask, 0);
9908
9909       match = vec_len (mask) / sizeof (u32x4);
9910
9911       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9912         {
9913           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9914           if (*tmp || *(tmp + 1))
9915             break;
9916           match--;
9917         }
9918       if (match == 0)
9919         clib_warning ("BUG: match 0");
9920
9921       _vec_len (mask) = match * sizeof (u32x4);
9922
9923       *matchp = match;
9924       *maskp = mask;
9925
9926       return 1;
9927     }
9928
9929   return 0;
9930 }
9931 #endif /* VPP_API_TEST_BUILTIN */
9932
9933 #define foreach_l2_next                         \
9934 _(drop, DROP)                                   \
9935 _(ethernet, ETHERNET_INPUT)                     \
9936 _(ip4, IP4_INPUT)                               \
9937 _(ip6, IP6_INPUT)
9938
9939 uword
9940 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9941 {
9942   u32 *miss_next_indexp = va_arg (*args, u32 *);
9943   u32 next_index = 0;
9944   u32 tmp;
9945
9946 #define _(n,N) \
9947   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9948   foreach_l2_next;
9949 #undef _
9950
9951   if (unformat (input, "%d", &tmp))
9952     {
9953       next_index = tmp;
9954       goto out;
9955     }
9956
9957   return 0;
9958
9959 out:
9960   *miss_next_indexp = next_index;
9961   return 1;
9962 }
9963
9964 #define foreach_ip_next                         \
9965 _(drop, DROP)                                   \
9966 _(local, LOCAL)                                 \
9967 _(rewrite, REWRITE)
9968
9969 uword
9970 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9971 {
9972   u32 *miss_next_indexp = va_arg (*args, u32 *);
9973   u32 next_index = 0;
9974   u32 tmp;
9975
9976 #define _(n,N) \
9977   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9978   foreach_ip_next;
9979 #undef _
9980
9981   if (unformat (input, "%d", &tmp))
9982     {
9983       next_index = tmp;
9984       goto out;
9985     }
9986
9987   return 0;
9988
9989 out:
9990   *miss_next_indexp = next_index;
9991   return 1;
9992 }
9993
9994 #define foreach_acl_next                        \
9995 _(deny, DENY)
9996
9997 uword
9998 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9999 {
10000   u32 *miss_next_indexp = va_arg (*args, u32 *);
10001   u32 next_index = 0;
10002   u32 tmp;
10003
10004 #define _(n,N) \
10005   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10006   foreach_acl_next;
10007 #undef _
10008
10009   if (unformat (input, "permit"))
10010     {
10011       next_index = ~0;
10012       goto out;
10013     }
10014   else if (unformat (input, "%d", &tmp))
10015     {
10016       next_index = tmp;
10017       goto out;
10018     }
10019
10020   return 0;
10021
10022 out:
10023   *miss_next_indexp = next_index;
10024   return 1;
10025 }
10026
10027 uword
10028 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10029 {
10030   u32 *r = va_arg (*args, u32 *);
10031
10032   if (unformat (input, "conform-color"))
10033     *r = POLICE_CONFORM;
10034   else if (unformat (input, "exceed-color"))
10035     *r = POLICE_EXCEED;
10036   else
10037     return 0;
10038
10039   return 1;
10040 }
10041
10042 static int
10043 api_classify_add_del_table (vat_main_t * vam)
10044 {
10045   unformat_input_t *i = vam->input;
10046   vl_api_classify_add_del_table_t *mp;
10047
10048   u32 nbuckets = 2;
10049   u32 skip = ~0;
10050   u32 match = ~0;
10051   int is_add = 1;
10052   int del_chain = 0;
10053   u32 table_index = ~0;
10054   u32 next_table_index = ~0;
10055   u32 miss_next_index = ~0;
10056   u32 memory_size = 32 << 20;
10057   u8 *mask = 0;
10058   u32 current_data_flag = 0;
10059   int current_data_offset = 0;
10060   int ret;
10061
10062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10063     {
10064       if (unformat (i, "del"))
10065         is_add = 0;
10066       else if (unformat (i, "del-chain"))
10067         {
10068           is_add = 0;
10069           del_chain = 1;
10070         }
10071       else if (unformat (i, "buckets %d", &nbuckets))
10072         ;
10073       else if (unformat (i, "memory_size %d", &memory_size))
10074         ;
10075       else if (unformat (i, "skip %d", &skip))
10076         ;
10077       else if (unformat (i, "match %d", &match))
10078         ;
10079       else if (unformat (i, "table %d", &table_index))
10080         ;
10081       else if (unformat (i, "mask %U", unformat_classify_mask,
10082                          &mask, &skip, &match))
10083         ;
10084       else if (unformat (i, "next-table %d", &next_table_index))
10085         ;
10086       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10087                          &miss_next_index))
10088         ;
10089       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10090                          &miss_next_index))
10091         ;
10092       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10093                          &miss_next_index))
10094         ;
10095       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10096         ;
10097       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10098         ;
10099       else
10100         break;
10101     }
10102
10103   if (is_add && mask == 0)
10104     {
10105       errmsg ("Mask required");
10106       return -99;
10107     }
10108
10109   if (is_add && skip == ~0)
10110     {
10111       errmsg ("skip count required");
10112       return -99;
10113     }
10114
10115   if (is_add && match == ~0)
10116     {
10117       errmsg ("match count required");
10118       return -99;
10119     }
10120
10121   if (!is_add && table_index == ~0)
10122     {
10123       errmsg ("table index required for delete");
10124       return -99;
10125     }
10126
10127   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10128
10129   mp->is_add = is_add;
10130   mp->del_chain = del_chain;
10131   mp->table_index = ntohl (table_index);
10132   mp->nbuckets = ntohl (nbuckets);
10133   mp->memory_size = ntohl (memory_size);
10134   mp->skip_n_vectors = ntohl (skip);
10135   mp->match_n_vectors = ntohl (match);
10136   mp->next_table_index = ntohl (next_table_index);
10137   mp->miss_next_index = ntohl (miss_next_index);
10138   mp->current_data_flag = ntohl (current_data_flag);
10139   mp->current_data_offset = ntohl (current_data_offset);
10140   mp->mask_len = ntohl (vec_len (mask));
10141   clib_memcpy (mp->mask, mask, vec_len (mask));
10142
10143   vec_free (mask);
10144
10145   S (mp);
10146   W (ret);
10147   return ret;
10148 }
10149
10150 #if VPP_API_TEST_BUILTIN == 0
10151 uword
10152 unformat_l4_match (unformat_input_t * input, va_list * args)
10153 {
10154   u8 **matchp = va_arg (*args, u8 **);
10155
10156   u8 *proto_header = 0;
10157   int src_port = 0;
10158   int dst_port = 0;
10159
10160   tcpudp_header_t h;
10161
10162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10163     {
10164       if (unformat (input, "src_port %d", &src_port))
10165         ;
10166       else if (unformat (input, "dst_port %d", &dst_port))
10167         ;
10168       else
10169         return 0;
10170     }
10171
10172   h.src_port = clib_host_to_net_u16 (src_port);
10173   h.dst_port = clib_host_to_net_u16 (dst_port);
10174   vec_validate (proto_header, sizeof (h) - 1);
10175   memcpy (proto_header, &h, sizeof (h));
10176
10177   *matchp = proto_header;
10178
10179   return 1;
10180 }
10181
10182 uword
10183 unformat_ip4_match (unformat_input_t * input, va_list * args)
10184 {
10185   u8 **matchp = va_arg (*args, u8 **);
10186   u8 *match = 0;
10187   ip4_header_t *ip;
10188   int version = 0;
10189   u32 version_val;
10190   int hdr_length = 0;
10191   u32 hdr_length_val;
10192   int src = 0, dst = 0;
10193   ip4_address_t src_val, dst_val;
10194   int proto = 0;
10195   u32 proto_val;
10196   int tos = 0;
10197   u32 tos_val;
10198   int length = 0;
10199   u32 length_val;
10200   int fragment_id = 0;
10201   u32 fragment_id_val;
10202   int ttl = 0;
10203   int ttl_val;
10204   int checksum = 0;
10205   u32 checksum_val;
10206
10207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10208     {
10209       if (unformat (input, "version %d", &version_val))
10210         version = 1;
10211       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10212         hdr_length = 1;
10213       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10214         src = 1;
10215       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10216         dst = 1;
10217       else if (unformat (input, "proto %d", &proto_val))
10218         proto = 1;
10219       else if (unformat (input, "tos %d", &tos_val))
10220         tos = 1;
10221       else if (unformat (input, "length %d", &length_val))
10222         length = 1;
10223       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10224         fragment_id = 1;
10225       else if (unformat (input, "ttl %d", &ttl_val))
10226         ttl = 1;
10227       else if (unformat (input, "checksum %d", &checksum_val))
10228         checksum = 1;
10229       else
10230         break;
10231     }
10232
10233   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10234       + ttl + checksum == 0)
10235     return 0;
10236
10237   /*
10238    * Aligned because we use the real comparison functions
10239    */
10240   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10241
10242   ip = (ip4_header_t *) match;
10243
10244   /* These are realistically matched in practice */
10245   if (src)
10246     ip->src_address.as_u32 = src_val.as_u32;
10247
10248   if (dst)
10249     ip->dst_address.as_u32 = dst_val.as_u32;
10250
10251   if (proto)
10252     ip->protocol = proto_val;
10253
10254
10255   /* These are not, but they're included for completeness */
10256   if (version)
10257     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10258
10259   if (hdr_length)
10260     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10261
10262   if (tos)
10263     ip->tos = tos_val;
10264
10265   if (length)
10266     ip->length = clib_host_to_net_u16 (length_val);
10267
10268   if (ttl)
10269     ip->ttl = ttl_val;
10270
10271   if (checksum)
10272     ip->checksum = clib_host_to_net_u16 (checksum_val);
10273
10274   *matchp = match;
10275   return 1;
10276 }
10277
10278 uword
10279 unformat_ip6_match (unformat_input_t * input, va_list * args)
10280 {
10281   u8 **matchp = va_arg (*args, u8 **);
10282   u8 *match = 0;
10283   ip6_header_t *ip;
10284   int version = 0;
10285   u32 version_val;
10286   u8 traffic_class = 0;
10287   u32 traffic_class_val = 0;
10288   u8 flow_label = 0;
10289   u8 flow_label_val;
10290   int src = 0, dst = 0;
10291   ip6_address_t src_val, dst_val;
10292   int proto = 0;
10293   u32 proto_val;
10294   int payload_length = 0;
10295   u32 payload_length_val;
10296   int hop_limit = 0;
10297   int hop_limit_val;
10298   u32 ip_version_traffic_class_and_flow_label;
10299
10300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10301     {
10302       if (unformat (input, "version %d", &version_val))
10303         version = 1;
10304       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10305         traffic_class = 1;
10306       else if (unformat (input, "flow_label %d", &flow_label_val))
10307         flow_label = 1;
10308       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10309         src = 1;
10310       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10311         dst = 1;
10312       else if (unformat (input, "proto %d", &proto_val))
10313         proto = 1;
10314       else if (unformat (input, "payload_length %d", &payload_length_val))
10315         payload_length = 1;
10316       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10317         hop_limit = 1;
10318       else
10319         break;
10320     }
10321
10322   if (version + traffic_class + flow_label + src + dst + proto +
10323       payload_length + hop_limit == 0)
10324     return 0;
10325
10326   /*
10327    * Aligned because we use the real comparison functions
10328    */
10329   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10330
10331   ip = (ip6_header_t *) match;
10332
10333   if (src)
10334     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10335
10336   if (dst)
10337     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10338
10339   if (proto)
10340     ip->protocol = proto_val;
10341
10342   ip_version_traffic_class_and_flow_label = 0;
10343
10344   if (version)
10345     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10346
10347   if (traffic_class)
10348     ip_version_traffic_class_and_flow_label |=
10349       (traffic_class_val & 0xFF) << 20;
10350
10351   if (flow_label)
10352     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10353
10354   ip->ip_version_traffic_class_and_flow_label =
10355     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10356
10357   if (payload_length)
10358     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10359
10360   if (hop_limit)
10361     ip->hop_limit = hop_limit_val;
10362
10363   *matchp = match;
10364   return 1;
10365 }
10366
10367 uword
10368 unformat_l3_match (unformat_input_t * input, va_list * args)
10369 {
10370   u8 **matchp = va_arg (*args, u8 **);
10371
10372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10373     {
10374       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10375         return 1;
10376       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10377         return 1;
10378       else
10379         break;
10380     }
10381   return 0;
10382 }
10383
10384 uword
10385 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10386 {
10387   u8 *tagp = va_arg (*args, u8 *);
10388   u32 tag;
10389
10390   if (unformat (input, "%d", &tag))
10391     {
10392       tagp[0] = (tag >> 8) & 0x0F;
10393       tagp[1] = tag & 0xFF;
10394       return 1;
10395     }
10396
10397   return 0;
10398 }
10399
10400 uword
10401 unformat_l2_match (unformat_input_t * input, va_list * args)
10402 {
10403   u8 **matchp = va_arg (*args, u8 **);
10404   u8 *match = 0;
10405   u8 src = 0;
10406   u8 src_val[6];
10407   u8 dst = 0;
10408   u8 dst_val[6];
10409   u8 proto = 0;
10410   u16 proto_val;
10411   u8 tag1 = 0;
10412   u8 tag1_val[2];
10413   u8 tag2 = 0;
10414   u8 tag2_val[2];
10415   int len = 14;
10416   u8 ignore_tag1 = 0;
10417   u8 ignore_tag2 = 0;
10418   u8 cos1 = 0;
10419   u8 cos2 = 0;
10420   u32 cos1_val = 0;
10421   u32 cos2_val = 0;
10422
10423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10424     {
10425       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10426         src = 1;
10427       else
10428         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10429         dst = 1;
10430       else if (unformat (input, "proto %U",
10431                          unformat_ethernet_type_host_byte_order, &proto_val))
10432         proto = 1;
10433       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10434         tag1 = 1;
10435       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10436         tag2 = 1;
10437       else if (unformat (input, "ignore-tag1"))
10438         ignore_tag1 = 1;
10439       else if (unformat (input, "ignore-tag2"))
10440         ignore_tag2 = 1;
10441       else if (unformat (input, "cos1 %d", &cos1_val))
10442         cos1 = 1;
10443       else if (unformat (input, "cos2 %d", &cos2_val))
10444         cos2 = 1;
10445       else
10446         break;
10447     }
10448   if ((src + dst + proto + tag1 + tag2 +
10449        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10450     return 0;
10451
10452   if (tag1 || ignore_tag1 || cos1)
10453     len = 18;
10454   if (tag2 || ignore_tag2 || cos2)
10455     len = 22;
10456
10457   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10458
10459   if (dst)
10460     clib_memcpy (match, dst_val, 6);
10461
10462   if (src)
10463     clib_memcpy (match + 6, src_val, 6);
10464
10465   if (tag2)
10466     {
10467       /* inner vlan tag */
10468       match[19] = tag2_val[1];
10469       match[18] = tag2_val[0];
10470       if (cos2)
10471         match[18] |= (cos2_val & 0x7) << 5;
10472       if (proto)
10473         {
10474           match[21] = proto_val & 0xff;
10475           match[20] = proto_val >> 8;
10476         }
10477       if (tag1)
10478         {
10479           match[15] = tag1_val[1];
10480           match[14] = tag1_val[0];
10481         }
10482       if (cos1)
10483         match[14] |= (cos1_val & 0x7) << 5;
10484       *matchp = match;
10485       return 1;
10486     }
10487   if (tag1)
10488     {
10489       match[15] = tag1_val[1];
10490       match[14] = tag1_val[0];
10491       if (proto)
10492         {
10493           match[17] = proto_val & 0xff;
10494           match[16] = proto_val >> 8;
10495         }
10496       if (cos1)
10497         match[14] |= (cos1_val & 0x7) << 5;
10498
10499       *matchp = match;
10500       return 1;
10501     }
10502   if (cos2)
10503     match[18] |= (cos2_val & 0x7) << 5;
10504   if (cos1)
10505     match[14] |= (cos1_val & 0x7) << 5;
10506   if (proto)
10507     {
10508       match[13] = proto_val & 0xff;
10509       match[12] = proto_val >> 8;
10510     }
10511
10512   *matchp = match;
10513   return 1;
10514 }
10515
10516 uword
10517 unformat_qos_source (unformat_input_t * input, va_list * args)
10518 {
10519   int *qs = va_arg (*args, int *);
10520
10521   if (unformat (input, "ip"))
10522     *qs = QOS_SOURCE_IP;
10523   else if (unformat (input, "mpls"))
10524     *qs = QOS_SOURCE_MPLS;
10525   else if (unformat (input, "ext"))
10526     *qs = QOS_SOURCE_EXT;
10527   else if (unformat (input, "vlan"))
10528     *qs = QOS_SOURCE_VLAN;
10529   else
10530     return 0;
10531
10532   return 1;
10533 }
10534 #endif
10535
10536 uword
10537 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10538 {
10539   u8 **matchp = va_arg (*args, u8 **);
10540   u32 skip_n_vectors = va_arg (*args, u32);
10541   u32 match_n_vectors = va_arg (*args, u32);
10542
10543   u8 *match = 0;
10544   u8 *l2 = 0;
10545   u8 *l3 = 0;
10546   u8 *l4 = 0;
10547
10548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10549     {
10550       if (unformat (input, "hex %U", unformat_hex_string, &match))
10551         ;
10552       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10553         ;
10554       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10555         ;
10556       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10557         ;
10558       else
10559         break;
10560     }
10561
10562   if (l4 && !l3)
10563     {
10564       vec_free (match);
10565       vec_free (l2);
10566       vec_free (l4);
10567       return 0;
10568     }
10569
10570   if (match || l2 || l3 || l4)
10571     {
10572       if (l2 || l3 || l4)
10573         {
10574           /* "Win a free Ethernet header in every packet" */
10575           if (l2 == 0)
10576             vec_validate_aligned (l2, 13, sizeof (u32x4));
10577           match = l2;
10578           if (vec_len (l3))
10579             {
10580               vec_append_aligned (match, l3, sizeof (u32x4));
10581               vec_free (l3);
10582             }
10583           if (vec_len (l4))
10584             {
10585               vec_append_aligned (match, l4, sizeof (u32x4));
10586               vec_free (l4);
10587             }
10588         }
10589
10590       /* Make sure the vector is big enough even if key is all 0's */
10591       vec_validate_aligned
10592         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10593          sizeof (u32x4));
10594
10595       /* Set size, include skipped vectors */
10596       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10597
10598       *matchp = match;
10599
10600       return 1;
10601     }
10602
10603   return 0;
10604 }
10605
10606 static int
10607 api_classify_add_del_session (vat_main_t * vam)
10608 {
10609   unformat_input_t *i = vam->input;
10610   vl_api_classify_add_del_session_t *mp;
10611   int is_add = 1;
10612   u32 table_index = ~0;
10613   u32 hit_next_index = ~0;
10614   u32 opaque_index = ~0;
10615   u8 *match = 0;
10616   i32 advance = 0;
10617   u32 skip_n_vectors = 0;
10618   u32 match_n_vectors = 0;
10619   u32 action = 0;
10620   u32 metadata = 0;
10621   int ret;
10622
10623   /*
10624    * Warning: you have to supply skip_n and match_n
10625    * because the API client cant simply look at the classify
10626    * table object.
10627    */
10628
10629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10630     {
10631       if (unformat (i, "del"))
10632         is_add = 0;
10633       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10634                          &hit_next_index))
10635         ;
10636       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10637                          &hit_next_index))
10638         ;
10639       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10640                          &hit_next_index))
10641         ;
10642       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10643         ;
10644       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10645         ;
10646       else if (unformat (i, "opaque-index %d", &opaque_index))
10647         ;
10648       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10649         ;
10650       else if (unformat (i, "match_n %d", &match_n_vectors))
10651         ;
10652       else if (unformat (i, "match %U", api_unformat_classify_match,
10653                          &match, skip_n_vectors, match_n_vectors))
10654         ;
10655       else if (unformat (i, "advance %d", &advance))
10656         ;
10657       else if (unformat (i, "table-index %d", &table_index))
10658         ;
10659       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10660         action = 1;
10661       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10662         action = 2;
10663       else if (unformat (i, "action %d", &action))
10664         ;
10665       else if (unformat (i, "metadata %d", &metadata))
10666         ;
10667       else
10668         break;
10669     }
10670
10671   if (table_index == ~0)
10672     {
10673       errmsg ("Table index required");
10674       return -99;
10675     }
10676
10677   if (is_add && match == 0)
10678     {
10679       errmsg ("Match value required");
10680       return -99;
10681     }
10682
10683   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10684
10685   mp->is_add = is_add;
10686   mp->table_index = ntohl (table_index);
10687   mp->hit_next_index = ntohl (hit_next_index);
10688   mp->opaque_index = ntohl (opaque_index);
10689   mp->advance = ntohl (advance);
10690   mp->action = action;
10691   mp->metadata = ntohl (metadata);
10692   mp->match_len = ntohl (vec_len (match));
10693   clib_memcpy (mp->match, match, vec_len (match));
10694   vec_free (match);
10695
10696   S (mp);
10697   W (ret);
10698   return ret;
10699 }
10700
10701 static int
10702 api_classify_set_interface_ip_table (vat_main_t * vam)
10703 {
10704   unformat_input_t *i = vam->input;
10705   vl_api_classify_set_interface_ip_table_t *mp;
10706   u32 sw_if_index;
10707   int sw_if_index_set;
10708   u32 table_index = ~0;
10709   u8 is_ipv6 = 0;
10710   int ret;
10711
10712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10713     {
10714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10715         sw_if_index_set = 1;
10716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10717         sw_if_index_set = 1;
10718       else if (unformat (i, "table %d", &table_index))
10719         ;
10720       else
10721         {
10722           clib_warning ("parse error '%U'", format_unformat_error, i);
10723           return -99;
10724         }
10725     }
10726
10727   if (sw_if_index_set == 0)
10728     {
10729       errmsg ("missing interface name or sw_if_index");
10730       return -99;
10731     }
10732
10733
10734   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10735
10736   mp->sw_if_index = ntohl (sw_if_index);
10737   mp->table_index = ntohl (table_index);
10738   mp->is_ipv6 = is_ipv6;
10739
10740   S (mp);
10741   W (ret);
10742   return ret;
10743 }
10744
10745 static int
10746 api_classify_set_interface_l2_tables (vat_main_t * vam)
10747 {
10748   unformat_input_t *i = vam->input;
10749   vl_api_classify_set_interface_l2_tables_t *mp;
10750   u32 sw_if_index;
10751   int sw_if_index_set;
10752   u32 ip4_table_index = ~0;
10753   u32 ip6_table_index = ~0;
10754   u32 other_table_index = ~0;
10755   u32 is_input = 1;
10756   int ret;
10757
10758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10759     {
10760       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10761         sw_if_index_set = 1;
10762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10763         sw_if_index_set = 1;
10764       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10765         ;
10766       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10767         ;
10768       else if (unformat (i, "other-table %d", &other_table_index))
10769         ;
10770       else if (unformat (i, "is-input %d", &is_input))
10771         ;
10772       else
10773         {
10774           clib_warning ("parse error '%U'", format_unformat_error, i);
10775           return -99;
10776         }
10777     }
10778
10779   if (sw_if_index_set == 0)
10780     {
10781       errmsg ("missing interface name or sw_if_index");
10782       return -99;
10783     }
10784
10785
10786   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10787
10788   mp->sw_if_index = ntohl (sw_if_index);
10789   mp->ip4_table_index = ntohl (ip4_table_index);
10790   mp->ip6_table_index = ntohl (ip6_table_index);
10791   mp->other_table_index = ntohl (other_table_index);
10792   mp->is_input = (u8) is_input;
10793
10794   S (mp);
10795   W (ret);
10796   return ret;
10797 }
10798
10799 static int
10800 api_set_ipfix_exporter (vat_main_t * vam)
10801 {
10802   unformat_input_t *i = vam->input;
10803   vl_api_set_ipfix_exporter_t *mp;
10804   ip4_address_t collector_address;
10805   u8 collector_address_set = 0;
10806   u32 collector_port = ~0;
10807   ip4_address_t src_address;
10808   u8 src_address_set = 0;
10809   u32 vrf_id = ~0;
10810   u32 path_mtu = ~0;
10811   u32 template_interval = ~0;
10812   u8 udp_checksum = 0;
10813   int ret;
10814
10815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10816     {
10817       if (unformat (i, "collector_address %U", unformat_ip4_address,
10818                     &collector_address))
10819         collector_address_set = 1;
10820       else if (unformat (i, "collector_port %d", &collector_port))
10821         ;
10822       else if (unformat (i, "src_address %U", unformat_ip4_address,
10823                          &src_address))
10824         src_address_set = 1;
10825       else if (unformat (i, "vrf_id %d", &vrf_id))
10826         ;
10827       else if (unformat (i, "path_mtu %d", &path_mtu))
10828         ;
10829       else if (unformat (i, "template_interval %d", &template_interval))
10830         ;
10831       else if (unformat (i, "udp_checksum"))
10832         udp_checksum = 1;
10833       else
10834         break;
10835     }
10836
10837   if (collector_address_set == 0)
10838     {
10839       errmsg ("collector_address required");
10840       return -99;
10841     }
10842
10843   if (src_address_set == 0)
10844     {
10845       errmsg ("src_address required");
10846       return -99;
10847     }
10848
10849   M (SET_IPFIX_EXPORTER, mp);
10850
10851   memcpy (mp->collector_address.un.ip4, collector_address.data,
10852           sizeof (collector_address.data));
10853   mp->collector_port = htons ((u16) collector_port);
10854   memcpy (mp->src_address.un.ip4, src_address.data,
10855           sizeof (src_address.data));
10856   mp->vrf_id = htonl (vrf_id);
10857   mp->path_mtu = htonl (path_mtu);
10858   mp->template_interval = htonl (template_interval);
10859   mp->udp_checksum = udp_checksum;
10860
10861   S (mp);
10862   W (ret);
10863   return ret;
10864 }
10865
10866 static int
10867 api_set_ipfix_classify_stream (vat_main_t * vam)
10868 {
10869   unformat_input_t *i = vam->input;
10870   vl_api_set_ipfix_classify_stream_t *mp;
10871   u32 domain_id = 0;
10872   u32 src_port = UDP_DST_PORT_ipfix;
10873   int ret;
10874
10875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10876     {
10877       if (unformat (i, "domain %d", &domain_id))
10878         ;
10879       else if (unformat (i, "src_port %d", &src_port))
10880         ;
10881       else
10882         {
10883           errmsg ("unknown input `%U'", format_unformat_error, i);
10884           return -99;
10885         }
10886     }
10887
10888   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10889
10890   mp->domain_id = htonl (domain_id);
10891   mp->src_port = htons ((u16) src_port);
10892
10893   S (mp);
10894   W (ret);
10895   return ret;
10896 }
10897
10898 static int
10899 api_ipfix_classify_table_add_del (vat_main_t * vam)
10900 {
10901   unformat_input_t *i = vam->input;
10902   vl_api_ipfix_classify_table_add_del_t *mp;
10903   int is_add = -1;
10904   u32 classify_table_index = ~0;
10905   u8 ip_version = 0;
10906   u8 transport_protocol = 255;
10907   int ret;
10908
10909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10910     {
10911       if (unformat (i, "add"))
10912         is_add = 1;
10913       else if (unformat (i, "del"))
10914         is_add = 0;
10915       else if (unformat (i, "table %d", &classify_table_index))
10916         ;
10917       else if (unformat (i, "ip4"))
10918         ip_version = 4;
10919       else if (unformat (i, "ip6"))
10920         ip_version = 6;
10921       else if (unformat (i, "tcp"))
10922         transport_protocol = 6;
10923       else if (unformat (i, "udp"))
10924         transport_protocol = 17;
10925       else
10926         {
10927           errmsg ("unknown input `%U'", format_unformat_error, i);
10928           return -99;
10929         }
10930     }
10931
10932   if (is_add == -1)
10933     {
10934       errmsg ("expecting: add|del");
10935       return -99;
10936     }
10937   if (classify_table_index == ~0)
10938     {
10939       errmsg ("classifier table not specified");
10940       return -99;
10941     }
10942   if (ip_version == 0)
10943     {
10944       errmsg ("IP version not specified");
10945       return -99;
10946     }
10947
10948   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10949
10950   mp->is_add = is_add;
10951   mp->table_id = htonl (classify_table_index);
10952   mp->ip_version = ip_version;
10953   mp->transport_protocol = transport_protocol;
10954
10955   S (mp);
10956   W (ret);
10957   return ret;
10958 }
10959
10960 static int
10961 api_get_node_index (vat_main_t * vam)
10962 {
10963   unformat_input_t *i = vam->input;
10964   vl_api_get_node_index_t *mp;
10965   u8 *name = 0;
10966   int ret;
10967
10968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10969     {
10970       if (unformat (i, "node %s", &name))
10971         ;
10972       else
10973         break;
10974     }
10975   if (name == 0)
10976     {
10977       errmsg ("node name required");
10978       return -99;
10979     }
10980   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10981     {
10982       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10983       return -99;
10984     }
10985
10986   M (GET_NODE_INDEX, mp);
10987   clib_memcpy (mp->node_name, name, vec_len (name));
10988   vec_free (name);
10989
10990   S (mp);
10991   W (ret);
10992   return ret;
10993 }
10994
10995 static int
10996 api_get_next_index (vat_main_t * vam)
10997 {
10998   unformat_input_t *i = vam->input;
10999   vl_api_get_next_index_t *mp;
11000   u8 *node_name = 0, *next_node_name = 0;
11001   int ret;
11002
11003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11004     {
11005       if (unformat (i, "node-name %s", &node_name))
11006         ;
11007       else if (unformat (i, "next-node-name %s", &next_node_name))
11008         break;
11009     }
11010
11011   if (node_name == 0)
11012     {
11013       errmsg ("node name required");
11014       return -99;
11015     }
11016   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11017     {
11018       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11019       return -99;
11020     }
11021
11022   if (next_node_name == 0)
11023     {
11024       errmsg ("next node name required");
11025       return -99;
11026     }
11027   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11028     {
11029       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11030       return -99;
11031     }
11032
11033   M (GET_NEXT_INDEX, mp);
11034   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11035   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11036   vec_free (node_name);
11037   vec_free (next_node_name);
11038
11039   S (mp);
11040   W (ret);
11041   return ret;
11042 }
11043
11044 static int
11045 api_add_node_next (vat_main_t * vam)
11046 {
11047   unformat_input_t *i = vam->input;
11048   vl_api_add_node_next_t *mp;
11049   u8 *name = 0;
11050   u8 *next = 0;
11051   int ret;
11052
11053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11054     {
11055       if (unformat (i, "node %s", &name))
11056         ;
11057       else if (unformat (i, "next %s", &next))
11058         ;
11059       else
11060         break;
11061     }
11062   if (name == 0)
11063     {
11064       errmsg ("node name required");
11065       return -99;
11066     }
11067   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11068     {
11069       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11070       return -99;
11071     }
11072   if (next == 0)
11073     {
11074       errmsg ("next node required");
11075       return -99;
11076     }
11077   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11078     {
11079       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11080       return -99;
11081     }
11082
11083   M (ADD_NODE_NEXT, mp);
11084   clib_memcpy (mp->node_name, name, vec_len (name));
11085   clib_memcpy (mp->next_name, next, vec_len (next));
11086   vec_free (name);
11087   vec_free (next);
11088
11089   S (mp);
11090   W (ret);
11091   return ret;
11092 }
11093
11094 static int
11095 api_l2tpv3_create_tunnel (vat_main_t * vam)
11096 {
11097   unformat_input_t *i = vam->input;
11098   ip6_address_t client_address, our_address;
11099   int client_address_set = 0;
11100   int our_address_set = 0;
11101   u32 local_session_id = 0;
11102   u32 remote_session_id = 0;
11103   u64 local_cookie = 0;
11104   u64 remote_cookie = 0;
11105   u8 l2_sublayer_present = 0;
11106   vl_api_l2tpv3_create_tunnel_t *mp;
11107   int ret;
11108
11109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11110     {
11111       if (unformat (i, "client_address %U", unformat_ip6_address,
11112                     &client_address))
11113         client_address_set = 1;
11114       else if (unformat (i, "our_address %U", unformat_ip6_address,
11115                          &our_address))
11116         our_address_set = 1;
11117       else if (unformat (i, "local_session_id %d", &local_session_id))
11118         ;
11119       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11120         ;
11121       else if (unformat (i, "local_cookie %lld", &local_cookie))
11122         ;
11123       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11124         ;
11125       else if (unformat (i, "l2-sublayer-present"))
11126         l2_sublayer_present = 1;
11127       else
11128         break;
11129     }
11130
11131   if (client_address_set == 0)
11132     {
11133       errmsg ("client_address required");
11134       return -99;
11135     }
11136
11137   if (our_address_set == 0)
11138     {
11139       errmsg ("our_address required");
11140       return -99;
11141     }
11142
11143   M (L2TPV3_CREATE_TUNNEL, mp);
11144
11145   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11146                sizeof (ip6_address_t));
11147
11148   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11149                sizeof (ip6_address_t));
11150
11151   mp->local_session_id = ntohl (local_session_id);
11152   mp->remote_session_id = ntohl (remote_session_id);
11153   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11154   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11155   mp->l2_sublayer_present = l2_sublayer_present;
11156
11157   S (mp);
11158   W (ret);
11159   return ret;
11160 }
11161
11162 static int
11163 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11164 {
11165   unformat_input_t *i = vam->input;
11166   u32 sw_if_index;
11167   u8 sw_if_index_set = 0;
11168   u64 new_local_cookie = 0;
11169   u64 new_remote_cookie = 0;
11170   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11171   int ret;
11172
11173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11174     {
11175       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11176         sw_if_index_set = 1;
11177       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11178         sw_if_index_set = 1;
11179       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11180         ;
11181       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11182         ;
11183       else
11184         break;
11185     }
11186
11187   if (sw_if_index_set == 0)
11188     {
11189       errmsg ("missing interface name or sw_if_index");
11190       return -99;
11191     }
11192
11193   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11194
11195   mp->sw_if_index = ntohl (sw_if_index);
11196   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11197   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11198
11199   S (mp);
11200   W (ret);
11201   return ret;
11202 }
11203
11204 static int
11205 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11206 {
11207   unformat_input_t *i = vam->input;
11208   vl_api_l2tpv3_interface_enable_disable_t *mp;
11209   u32 sw_if_index;
11210   u8 sw_if_index_set = 0;
11211   u8 enable_disable = 1;
11212   int ret;
11213
11214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11215     {
11216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11217         sw_if_index_set = 1;
11218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11219         sw_if_index_set = 1;
11220       else if (unformat (i, "enable"))
11221         enable_disable = 1;
11222       else if (unformat (i, "disable"))
11223         enable_disable = 0;
11224       else
11225         break;
11226     }
11227
11228   if (sw_if_index_set == 0)
11229     {
11230       errmsg ("missing interface name or sw_if_index");
11231       return -99;
11232     }
11233
11234   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11235
11236   mp->sw_if_index = ntohl (sw_if_index);
11237   mp->enable_disable = enable_disable;
11238
11239   S (mp);
11240   W (ret);
11241   return ret;
11242 }
11243
11244 static int
11245 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11246 {
11247   unformat_input_t *i = vam->input;
11248   vl_api_l2tpv3_set_lookup_key_t *mp;
11249   u8 key = ~0;
11250   int ret;
11251
11252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11253     {
11254       if (unformat (i, "lookup_v6_src"))
11255         key = L2T_LOOKUP_SRC_ADDRESS;
11256       else if (unformat (i, "lookup_v6_dst"))
11257         key = L2T_LOOKUP_DST_ADDRESS;
11258       else if (unformat (i, "lookup_session_id"))
11259         key = L2T_LOOKUP_SESSION_ID;
11260       else
11261         break;
11262     }
11263
11264   if (key == (u8) ~ 0)
11265     {
11266       errmsg ("l2tp session lookup key unset");
11267       return -99;
11268     }
11269
11270   M (L2TPV3_SET_LOOKUP_KEY, mp);
11271
11272   mp->key = key;
11273
11274   S (mp);
11275   W (ret);
11276   return ret;
11277 }
11278
11279 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11280   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11281 {
11282   vat_main_t *vam = &vat_main;
11283
11284   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11285          format_ip6_address, mp->our_address,
11286          format_ip6_address, mp->client_address,
11287          clib_net_to_host_u32 (mp->sw_if_index));
11288
11289   print (vam->ofp,
11290          "   local cookies %016llx %016llx remote cookie %016llx",
11291          clib_net_to_host_u64 (mp->local_cookie[0]),
11292          clib_net_to_host_u64 (mp->local_cookie[1]),
11293          clib_net_to_host_u64 (mp->remote_cookie));
11294
11295   print (vam->ofp, "   local session-id %d remote session-id %d",
11296          clib_net_to_host_u32 (mp->local_session_id),
11297          clib_net_to_host_u32 (mp->remote_session_id));
11298
11299   print (vam->ofp, "   l2 specific sublayer %s\n",
11300          mp->l2_sublayer_present ? "preset" : "absent");
11301
11302 }
11303
11304 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11305   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11306 {
11307   vat_main_t *vam = &vat_main;
11308   vat_json_node_t *node = NULL;
11309   struct in6_addr addr;
11310
11311   if (VAT_JSON_ARRAY != vam->json_tree.type)
11312     {
11313       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11314       vat_json_init_array (&vam->json_tree);
11315     }
11316   node = vat_json_array_add (&vam->json_tree);
11317
11318   vat_json_init_object (node);
11319
11320   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11321   vat_json_object_add_ip6 (node, "our_address", addr);
11322   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11323   vat_json_object_add_ip6 (node, "client_address", addr);
11324
11325   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11326   vat_json_init_array (lc);
11327   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11328   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11329   vat_json_object_add_uint (node, "remote_cookie",
11330                             clib_net_to_host_u64 (mp->remote_cookie));
11331
11332   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11333   vat_json_object_add_uint (node, "local_session_id",
11334                             clib_net_to_host_u32 (mp->local_session_id));
11335   vat_json_object_add_uint (node, "remote_session_id",
11336                             clib_net_to_host_u32 (mp->remote_session_id));
11337   vat_json_object_add_string_copy (node, "l2_sublayer",
11338                                    mp->l2_sublayer_present ? (u8 *) "present"
11339                                    : (u8 *) "absent");
11340 }
11341
11342 static int
11343 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11344 {
11345   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11346   vl_api_control_ping_t *mp_ping;
11347   int ret;
11348
11349   /* Get list of l2tpv3-tunnel interfaces */
11350   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11351   S (mp);
11352
11353   /* Use a control ping for synchronization */
11354   MPING (CONTROL_PING, mp_ping);
11355   S (mp_ping);
11356
11357   W (ret);
11358   return ret;
11359 }
11360
11361
11362 static void vl_api_sw_interface_tap_v2_details_t_handler
11363   (vl_api_sw_interface_tap_v2_details_t * mp)
11364 {
11365   vat_main_t *vam = &vat_main;
11366
11367   u8 *ip4 =
11368     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11369             mp->host_ip4_prefix.len);
11370   u8 *ip6 =
11371     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11372             mp->host_ip6_prefix.len);
11373
11374   print (vam->ofp,
11375          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11376          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11377          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11378          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11379          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11380
11381   vec_free (ip4);
11382   vec_free (ip6);
11383 }
11384
11385 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11386   (vl_api_sw_interface_tap_v2_details_t * mp)
11387 {
11388   vat_main_t *vam = &vat_main;
11389   vat_json_node_t *node = NULL;
11390
11391   if (VAT_JSON_ARRAY != vam->json_tree.type)
11392     {
11393       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11394       vat_json_init_array (&vam->json_tree);
11395     }
11396   node = vat_json_array_add (&vam->json_tree);
11397
11398   vat_json_init_object (node);
11399   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11400   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11401   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11402   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11403   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11404   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11405   vat_json_object_add_string_copy (node, "host_mac_addr",
11406                                    format (0, "%U", format_ethernet_address,
11407                                            &mp->host_mac_addr));
11408   vat_json_object_add_string_copy (node, "host_namespace",
11409                                    mp->host_namespace);
11410   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11411   vat_json_object_add_string_copy (node, "host_ip4_addr",
11412                                    format (0, "%U/%d", format_ip4_address,
11413                                            mp->host_ip4_prefix.address,
11414                                            mp->host_ip4_prefix.len));
11415   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11416                                    format (0, "%U/%d", format_ip6_address,
11417                                            mp->host_ip6_prefix.address,
11418                                            mp->host_ip6_prefix.len));
11419
11420 }
11421
11422 static int
11423 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11424 {
11425   vl_api_sw_interface_tap_v2_dump_t *mp;
11426   vl_api_control_ping_t *mp_ping;
11427   int ret;
11428
11429   print (vam->ofp,
11430          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11431          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11432          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11433          "host_ip6_addr");
11434
11435   /* Get list of tap interfaces */
11436   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11437   S (mp);
11438
11439   /* Use a control ping for synchronization */
11440   MPING (CONTROL_PING, mp_ping);
11441   S (mp_ping);
11442
11443   W (ret);
11444   return ret;
11445 }
11446
11447 static void vl_api_sw_interface_virtio_pci_details_t_handler
11448   (vl_api_sw_interface_virtio_pci_details_t * mp)
11449 {
11450   vat_main_t *vam = &vat_main;
11451
11452   typedef union
11453   {
11454     struct
11455     {
11456       u16 domain;
11457       u8 bus;
11458       u8 slot:5;
11459       u8 function:3;
11460     };
11461     u32 as_u32;
11462   } pci_addr_t;
11463   pci_addr_t addr;
11464
11465   addr.domain = ntohs (mp->pci_addr.domain);
11466   addr.bus = mp->pci_addr.bus;
11467   addr.slot = mp->pci_addr.slot;
11468   addr.function = mp->pci_addr.function;
11469
11470   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11471                          addr.slot, addr.function);
11472
11473   print (vam->ofp,
11474          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11475          pci_addr, ntohl (mp->sw_if_index),
11476          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11477          format_ethernet_address, mp->mac_addr,
11478          clib_net_to_host_u64 (mp->features));
11479   vec_free (pci_addr);
11480 }
11481
11482 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11483   (vl_api_sw_interface_virtio_pci_details_t * mp)
11484 {
11485   vat_main_t *vam = &vat_main;
11486   vat_json_node_t *node = NULL;
11487   vlib_pci_addr_t pci_addr;
11488
11489   if (VAT_JSON_ARRAY != vam->json_tree.type)
11490     {
11491       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11492       vat_json_init_array (&vam->json_tree);
11493     }
11494   node = vat_json_array_add (&vam->json_tree);
11495
11496   pci_addr.domain = ntohs (mp->pci_addr.domain);
11497   pci_addr.bus = mp->pci_addr.bus;
11498   pci_addr.slot = mp->pci_addr.slot;
11499   pci_addr.function = mp->pci_addr.function;
11500
11501   vat_json_init_object (node);
11502   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11503   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11504   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11505   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11506   vat_json_object_add_uint (node, "features",
11507                             clib_net_to_host_u64 (mp->features));
11508   vat_json_object_add_string_copy (node, "mac_addr",
11509                                    format (0, "%U", format_ethernet_address,
11510                                            &mp->mac_addr));
11511 }
11512
11513 static int
11514 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11515 {
11516   vl_api_sw_interface_virtio_pci_dump_t *mp;
11517   vl_api_control_ping_t *mp_ping;
11518   int ret;
11519
11520   print (vam->ofp,
11521          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11522          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11523          "mac_addr", "features");
11524
11525   /* Get list of tap interfaces */
11526   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11527   S (mp);
11528
11529   /* Use a control ping for synchronization */
11530   MPING (CONTROL_PING, mp_ping);
11531   S (mp_ping);
11532
11533   W (ret);
11534   return ret;
11535 }
11536
11537 static int
11538 api_vxlan_offload_rx (vat_main_t * vam)
11539 {
11540   unformat_input_t *line_input = vam->input;
11541   vl_api_vxlan_offload_rx_t *mp;
11542   u32 hw_if_index = ~0, rx_if_index = ~0;
11543   u8 is_add = 1;
11544   int ret;
11545
11546   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11547     {
11548       if (unformat (line_input, "del"))
11549         is_add = 0;
11550       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11551                          &hw_if_index))
11552         ;
11553       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11554         ;
11555       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11556                          &rx_if_index))
11557         ;
11558       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11559         ;
11560       else
11561         {
11562           errmsg ("parse error '%U'", format_unformat_error, line_input);
11563           return -99;
11564         }
11565     }
11566
11567   if (hw_if_index == ~0)
11568     {
11569       errmsg ("no hw interface");
11570       return -99;
11571     }
11572
11573   if (rx_if_index == ~0)
11574     {
11575       errmsg ("no rx tunnel");
11576       return -99;
11577     }
11578
11579   M (VXLAN_OFFLOAD_RX, mp);
11580
11581   mp->hw_if_index = ntohl (hw_if_index);
11582   mp->sw_if_index = ntohl (rx_if_index);
11583   mp->enable = is_add;
11584
11585   S (mp);
11586   W (ret);
11587   return ret;
11588 }
11589
11590 static uword unformat_vxlan_decap_next
11591   (unformat_input_t * input, va_list * args)
11592 {
11593   u32 *result = va_arg (*args, u32 *);
11594   u32 tmp;
11595
11596   if (unformat (input, "l2"))
11597     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11598   else if (unformat (input, "%d", &tmp))
11599     *result = tmp;
11600   else
11601     return 0;
11602   return 1;
11603 }
11604
11605 static int
11606 api_vxlan_add_del_tunnel (vat_main_t * vam)
11607 {
11608   unformat_input_t *line_input = vam->input;
11609   vl_api_vxlan_add_del_tunnel_t *mp;
11610   ip46_address_t src, dst;
11611   u8 is_add = 1;
11612   u8 ipv4_set = 0, ipv6_set = 0;
11613   u8 src_set = 0;
11614   u8 dst_set = 0;
11615   u8 grp_set = 0;
11616   u32 instance = ~0;
11617   u32 mcast_sw_if_index = ~0;
11618   u32 encap_vrf_id = 0;
11619   u32 decap_next_index = ~0;
11620   u32 vni = 0;
11621   int ret;
11622
11623   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11624   clib_memset (&src, 0, sizeof src);
11625   clib_memset (&dst, 0, sizeof dst);
11626
11627   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11628     {
11629       if (unformat (line_input, "del"))
11630         is_add = 0;
11631       else if (unformat (line_input, "instance %d", &instance))
11632         ;
11633       else
11634         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11635         {
11636           ipv4_set = 1;
11637           src_set = 1;
11638         }
11639       else
11640         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11641         {
11642           ipv4_set = 1;
11643           dst_set = 1;
11644         }
11645       else
11646         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11647         {
11648           ipv6_set = 1;
11649           src_set = 1;
11650         }
11651       else
11652         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11653         {
11654           ipv6_set = 1;
11655           dst_set = 1;
11656         }
11657       else if (unformat (line_input, "group %U %U",
11658                          unformat_ip4_address, &dst.ip4,
11659                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11660         {
11661           grp_set = dst_set = 1;
11662           ipv4_set = 1;
11663         }
11664       else if (unformat (line_input, "group %U",
11665                          unformat_ip4_address, &dst.ip4))
11666         {
11667           grp_set = dst_set = 1;
11668           ipv4_set = 1;
11669         }
11670       else if (unformat (line_input, "group %U %U",
11671                          unformat_ip6_address, &dst.ip6,
11672                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11673         {
11674           grp_set = dst_set = 1;
11675           ipv6_set = 1;
11676         }
11677       else if (unformat (line_input, "group %U",
11678                          unformat_ip6_address, &dst.ip6))
11679         {
11680           grp_set = dst_set = 1;
11681           ipv6_set = 1;
11682         }
11683       else
11684         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11685         ;
11686       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11687         ;
11688       else if (unformat (line_input, "decap-next %U",
11689                          unformat_vxlan_decap_next, &decap_next_index))
11690         ;
11691       else if (unformat (line_input, "vni %d", &vni))
11692         ;
11693       else
11694         {
11695           errmsg ("parse error '%U'", format_unformat_error, line_input);
11696           return -99;
11697         }
11698     }
11699
11700   if (src_set == 0)
11701     {
11702       errmsg ("tunnel src address not specified");
11703       return -99;
11704     }
11705   if (dst_set == 0)
11706     {
11707       errmsg ("tunnel dst address not specified");
11708       return -99;
11709     }
11710
11711   if (grp_set && !ip46_address_is_multicast (&dst))
11712     {
11713       errmsg ("tunnel group address not multicast");
11714       return -99;
11715     }
11716   if (grp_set && mcast_sw_if_index == ~0)
11717     {
11718       errmsg ("tunnel nonexistent multicast device");
11719       return -99;
11720     }
11721   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11722     {
11723       errmsg ("tunnel dst address must be unicast");
11724       return -99;
11725     }
11726
11727
11728   if (ipv4_set && ipv6_set)
11729     {
11730       errmsg ("both IPv4 and IPv6 addresses specified");
11731       return -99;
11732     }
11733
11734   if ((vni == 0) || (vni >> 24))
11735     {
11736       errmsg ("vni not specified or out of range");
11737       return -99;
11738     }
11739
11740   M (VXLAN_ADD_DEL_TUNNEL, mp);
11741
11742   if (ipv6_set)
11743     {
11744       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11745       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11746     }
11747   else
11748     {
11749       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11750       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11751     }
11752   mp->src_address.af = ipv6_set;
11753   mp->dst_address.af = ipv6_set;
11754
11755   mp->instance = htonl (instance);
11756   mp->encap_vrf_id = ntohl (encap_vrf_id);
11757   mp->decap_next_index = ntohl (decap_next_index);
11758   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11759   mp->vni = ntohl (vni);
11760   mp->is_add = is_add;
11761
11762   S (mp);
11763   W (ret);
11764   return ret;
11765 }
11766
11767 static void vl_api_vxlan_tunnel_details_t_handler
11768   (vl_api_vxlan_tunnel_details_t * mp)
11769 {
11770   vat_main_t *vam = &vat_main;
11771   ip46_address_t src =
11772     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11773   ip46_address_t dst =
11774     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11775
11776   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11777          ntohl (mp->sw_if_index),
11778          ntohl (mp->instance),
11779          format_ip46_address, &src, IP46_TYPE_ANY,
11780          format_ip46_address, &dst, IP46_TYPE_ANY,
11781          ntohl (mp->encap_vrf_id),
11782          ntohl (mp->decap_next_index), ntohl (mp->vni),
11783          ntohl (mp->mcast_sw_if_index));
11784 }
11785
11786 static void vl_api_vxlan_tunnel_details_t_handler_json
11787   (vl_api_vxlan_tunnel_details_t * mp)
11788 {
11789   vat_main_t *vam = &vat_main;
11790   vat_json_node_t *node = NULL;
11791
11792   if (VAT_JSON_ARRAY != vam->json_tree.type)
11793     {
11794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11795       vat_json_init_array (&vam->json_tree);
11796     }
11797   node = vat_json_array_add (&vam->json_tree);
11798
11799   vat_json_init_object (node);
11800   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11801
11802   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11803
11804   if (mp->src_address.af)
11805     {
11806       struct in6_addr ip6;
11807
11808       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11809       vat_json_object_add_ip6 (node, "src_address", ip6);
11810       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11811       vat_json_object_add_ip6 (node, "dst_address", ip6);
11812     }
11813   else
11814     {
11815       struct in_addr ip4;
11816
11817       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11818       vat_json_object_add_ip4 (node, "src_address", ip4);
11819       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11820       vat_json_object_add_ip4 (node, "dst_address", ip4);
11821     }
11822   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11823   vat_json_object_add_uint (node, "decap_next_index",
11824                             ntohl (mp->decap_next_index));
11825   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11826   vat_json_object_add_uint (node, "mcast_sw_if_index",
11827                             ntohl (mp->mcast_sw_if_index));
11828 }
11829
11830 static int
11831 api_vxlan_tunnel_dump (vat_main_t * vam)
11832 {
11833   unformat_input_t *i = vam->input;
11834   vl_api_vxlan_tunnel_dump_t *mp;
11835   vl_api_control_ping_t *mp_ping;
11836   u32 sw_if_index;
11837   u8 sw_if_index_set = 0;
11838   int ret;
11839
11840   /* Parse args required to build the message */
11841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11842     {
11843       if (unformat (i, "sw_if_index %d", &sw_if_index))
11844         sw_if_index_set = 1;
11845       else
11846         break;
11847     }
11848
11849   if (sw_if_index_set == 0)
11850     {
11851       sw_if_index = ~0;
11852     }
11853
11854   if (!vam->json_output)
11855     {
11856       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11857              "sw_if_index", "instance", "src_address", "dst_address",
11858              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11859     }
11860
11861   /* Get list of vxlan-tunnel interfaces */
11862   M (VXLAN_TUNNEL_DUMP, mp);
11863
11864   mp->sw_if_index = htonl (sw_if_index);
11865
11866   S (mp);
11867
11868   /* Use a control ping for synchronization */
11869   MPING (CONTROL_PING, mp_ping);
11870   S (mp_ping);
11871
11872   W (ret);
11873   return ret;
11874 }
11875
11876 static uword unformat_geneve_decap_next
11877   (unformat_input_t * input, va_list * args)
11878 {
11879   u32 *result = va_arg (*args, u32 *);
11880   u32 tmp;
11881
11882   if (unformat (input, "l2"))
11883     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11884   else if (unformat (input, "%d", &tmp))
11885     *result = tmp;
11886   else
11887     return 0;
11888   return 1;
11889 }
11890
11891 static int
11892 api_geneve_add_del_tunnel (vat_main_t * vam)
11893 {
11894   unformat_input_t *line_input = vam->input;
11895   vl_api_geneve_add_del_tunnel_t *mp;
11896   ip46_address_t src, dst;
11897   u8 is_add = 1;
11898   u8 ipv4_set = 0, ipv6_set = 0;
11899   u8 src_set = 0;
11900   u8 dst_set = 0;
11901   u8 grp_set = 0;
11902   u32 mcast_sw_if_index = ~0;
11903   u32 encap_vrf_id = 0;
11904   u32 decap_next_index = ~0;
11905   u32 vni = 0;
11906   int ret;
11907
11908   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11909   clib_memset (&src, 0, sizeof src);
11910   clib_memset (&dst, 0, sizeof dst);
11911
11912   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11913     {
11914       if (unformat (line_input, "del"))
11915         is_add = 0;
11916       else
11917         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11918         {
11919           ipv4_set = 1;
11920           src_set = 1;
11921         }
11922       else
11923         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11924         {
11925           ipv4_set = 1;
11926           dst_set = 1;
11927         }
11928       else
11929         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11930         {
11931           ipv6_set = 1;
11932           src_set = 1;
11933         }
11934       else
11935         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11936         {
11937           ipv6_set = 1;
11938           dst_set = 1;
11939         }
11940       else if (unformat (line_input, "group %U %U",
11941                          unformat_ip4_address, &dst.ip4,
11942                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11943         {
11944           grp_set = dst_set = 1;
11945           ipv4_set = 1;
11946         }
11947       else if (unformat (line_input, "group %U",
11948                          unformat_ip4_address, &dst.ip4))
11949         {
11950           grp_set = dst_set = 1;
11951           ipv4_set = 1;
11952         }
11953       else if (unformat (line_input, "group %U %U",
11954                          unformat_ip6_address, &dst.ip6,
11955                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11956         {
11957           grp_set = dst_set = 1;
11958           ipv6_set = 1;
11959         }
11960       else if (unformat (line_input, "group %U",
11961                          unformat_ip6_address, &dst.ip6))
11962         {
11963           grp_set = dst_set = 1;
11964           ipv6_set = 1;
11965         }
11966       else
11967         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11968         ;
11969       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11970         ;
11971       else if (unformat (line_input, "decap-next %U",
11972                          unformat_geneve_decap_next, &decap_next_index))
11973         ;
11974       else if (unformat (line_input, "vni %d", &vni))
11975         ;
11976       else
11977         {
11978           errmsg ("parse error '%U'", format_unformat_error, line_input);
11979           return -99;
11980         }
11981     }
11982
11983   if (src_set == 0)
11984     {
11985       errmsg ("tunnel src address not specified");
11986       return -99;
11987     }
11988   if (dst_set == 0)
11989     {
11990       errmsg ("tunnel dst address not specified");
11991       return -99;
11992     }
11993
11994   if (grp_set && !ip46_address_is_multicast (&dst))
11995     {
11996       errmsg ("tunnel group address not multicast");
11997       return -99;
11998     }
11999   if (grp_set && mcast_sw_if_index == ~0)
12000     {
12001       errmsg ("tunnel nonexistent multicast device");
12002       return -99;
12003     }
12004   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12005     {
12006       errmsg ("tunnel dst address must be unicast");
12007       return -99;
12008     }
12009
12010
12011   if (ipv4_set && ipv6_set)
12012     {
12013       errmsg ("both IPv4 and IPv6 addresses specified");
12014       return -99;
12015     }
12016
12017   if ((vni == 0) || (vni >> 24))
12018     {
12019       errmsg ("vni not specified or out of range");
12020       return -99;
12021     }
12022
12023   M (GENEVE_ADD_DEL_TUNNEL, mp);
12024
12025   if (ipv6_set)
12026     {
12027       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12028       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12029     }
12030   else
12031     {
12032       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12033       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12034     }
12035   mp->encap_vrf_id = ntohl (encap_vrf_id);
12036   mp->decap_next_index = ntohl (decap_next_index);
12037   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12038   mp->vni = ntohl (vni);
12039   mp->is_add = is_add;
12040
12041   S (mp);
12042   W (ret);
12043   return ret;
12044 }
12045
12046 static void vl_api_geneve_tunnel_details_t_handler
12047   (vl_api_geneve_tunnel_details_t * mp)
12048 {
12049   vat_main_t *vam = &vat_main;
12050   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12051   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12052
12053   if (mp->src_address.af == ADDRESS_IP6)
12054     {
12055       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12056       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12057     }
12058   else
12059     {
12060       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12061       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12062     }
12063
12064   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12065          ntohl (mp->sw_if_index),
12066          format_ip46_address, &src, IP46_TYPE_ANY,
12067          format_ip46_address, &dst, IP46_TYPE_ANY,
12068          ntohl (mp->encap_vrf_id),
12069          ntohl (mp->decap_next_index), ntohl (mp->vni),
12070          ntohl (mp->mcast_sw_if_index));
12071 }
12072
12073 static void vl_api_geneve_tunnel_details_t_handler_json
12074   (vl_api_geneve_tunnel_details_t * mp)
12075 {
12076   vat_main_t *vam = &vat_main;
12077   vat_json_node_t *node = NULL;
12078   bool is_ipv6;
12079
12080   if (VAT_JSON_ARRAY != vam->json_tree.type)
12081     {
12082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12083       vat_json_init_array (&vam->json_tree);
12084     }
12085   node = vat_json_array_add (&vam->json_tree);
12086
12087   vat_json_init_object (node);
12088   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12089   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12090   if (is_ipv6)
12091     {
12092       struct in6_addr ip6;
12093
12094       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12095       vat_json_object_add_ip6 (node, "src_address", ip6);
12096       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12097       vat_json_object_add_ip6 (node, "dst_address", ip6);
12098     }
12099   else
12100     {
12101       struct in_addr ip4;
12102
12103       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12104       vat_json_object_add_ip4 (node, "src_address", ip4);
12105       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12106       vat_json_object_add_ip4 (node, "dst_address", ip4);
12107     }
12108   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12109   vat_json_object_add_uint (node, "decap_next_index",
12110                             ntohl (mp->decap_next_index));
12111   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12112   vat_json_object_add_uint (node, "mcast_sw_if_index",
12113                             ntohl (mp->mcast_sw_if_index));
12114 }
12115
12116 static int
12117 api_geneve_tunnel_dump (vat_main_t * vam)
12118 {
12119   unformat_input_t *i = vam->input;
12120   vl_api_geneve_tunnel_dump_t *mp;
12121   vl_api_control_ping_t *mp_ping;
12122   u32 sw_if_index;
12123   u8 sw_if_index_set = 0;
12124   int ret;
12125
12126   /* Parse args required to build the message */
12127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12128     {
12129       if (unformat (i, "sw_if_index %d", &sw_if_index))
12130         sw_if_index_set = 1;
12131       else
12132         break;
12133     }
12134
12135   if (sw_if_index_set == 0)
12136     {
12137       sw_if_index = ~0;
12138     }
12139
12140   if (!vam->json_output)
12141     {
12142       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12143              "sw_if_index", "local_address", "remote_address",
12144              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12145     }
12146
12147   /* Get list of geneve-tunnel interfaces */
12148   M (GENEVE_TUNNEL_DUMP, mp);
12149
12150   mp->sw_if_index = htonl (sw_if_index);
12151
12152   S (mp);
12153
12154   /* Use a control ping for synchronization */
12155   M (CONTROL_PING, mp_ping);
12156   S (mp_ping);
12157
12158   W (ret);
12159   return ret;
12160 }
12161
12162 static int
12163 api_gre_tunnel_add_del (vat_main_t * vam)
12164 {
12165   unformat_input_t *line_input = vam->input;
12166   vl_api_address_t src = { }, dst =
12167   {
12168   };
12169   vl_api_gre_tunnel_add_del_t *mp;
12170   vl_api_gre_tunnel_type_t t_type;
12171   u8 is_add = 1;
12172   u8 src_set = 0;
12173   u8 dst_set = 0;
12174   u32 outer_table_id = 0;
12175   u32 session_id = 0;
12176   u32 instance = ~0;
12177   int ret;
12178
12179   t_type = GRE_API_TUNNEL_TYPE_L3;
12180
12181   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12182     {
12183       if (unformat (line_input, "del"))
12184         is_add = 0;
12185       else if (unformat (line_input, "instance %d", &instance))
12186         ;
12187       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12188         {
12189           src_set = 1;
12190         }
12191       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12192         {
12193           dst_set = 1;
12194         }
12195       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12196         ;
12197       else if (unformat (line_input, "teb"))
12198         t_type = GRE_API_TUNNEL_TYPE_TEB;
12199       else if (unformat (line_input, "erspan %d", &session_id))
12200         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12201       else
12202         {
12203           errmsg ("parse error '%U'", format_unformat_error, line_input);
12204           return -99;
12205         }
12206     }
12207
12208   if (src_set == 0)
12209     {
12210       errmsg ("tunnel src address not specified");
12211       return -99;
12212     }
12213   if (dst_set == 0)
12214     {
12215       errmsg ("tunnel dst address not specified");
12216       return -99;
12217     }
12218
12219   M (GRE_TUNNEL_ADD_DEL, mp);
12220
12221   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12222   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12223
12224   mp->tunnel.instance = htonl (instance);
12225   mp->tunnel.outer_table_id = htonl (outer_table_id);
12226   mp->is_add = is_add;
12227   mp->tunnel.session_id = htons ((u16) session_id);
12228   mp->tunnel.type = htonl (t_type);
12229
12230   S (mp);
12231   W (ret);
12232   return ret;
12233 }
12234
12235 static void vl_api_gre_tunnel_details_t_handler
12236   (vl_api_gre_tunnel_details_t * mp)
12237 {
12238   vat_main_t *vam = &vat_main;
12239
12240   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12241          ntohl (mp->tunnel.sw_if_index),
12242          ntohl (mp->tunnel.instance),
12243          format_vl_api_address, &mp->tunnel.src,
12244          format_vl_api_address, &mp->tunnel.dst,
12245          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12246          ntohl (mp->tunnel.session_id));
12247 }
12248
12249 static void vl_api_gre_tunnel_details_t_handler_json
12250   (vl_api_gre_tunnel_details_t * mp)
12251 {
12252   vat_main_t *vam = &vat_main;
12253   vat_json_node_t *node = NULL;
12254
12255   if (VAT_JSON_ARRAY != vam->json_tree.type)
12256     {
12257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12258       vat_json_init_array (&vam->json_tree);
12259     }
12260   node = vat_json_array_add (&vam->json_tree);
12261
12262   vat_json_init_object (node);
12263   vat_json_object_add_uint (node, "sw_if_index",
12264                             ntohl (mp->tunnel.sw_if_index));
12265   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12266
12267   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12268   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12269   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12270   vat_json_object_add_uint (node, "outer_table_id",
12271                             ntohl (mp->tunnel.outer_table_id));
12272   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12273 }
12274
12275 static int
12276 api_gre_tunnel_dump (vat_main_t * vam)
12277 {
12278   unformat_input_t *i = vam->input;
12279   vl_api_gre_tunnel_dump_t *mp;
12280   vl_api_control_ping_t *mp_ping;
12281   u32 sw_if_index;
12282   u8 sw_if_index_set = 0;
12283   int ret;
12284
12285   /* Parse args required to build the message */
12286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12287     {
12288       if (unformat (i, "sw_if_index %d", &sw_if_index))
12289         sw_if_index_set = 1;
12290       else
12291         break;
12292     }
12293
12294   if (sw_if_index_set == 0)
12295     {
12296       sw_if_index = ~0;
12297     }
12298
12299   if (!vam->json_output)
12300     {
12301       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12302              "sw_if_index", "instance", "src_address", "dst_address",
12303              "tunnel_type", "outer_fib_id", "session_id");
12304     }
12305
12306   /* Get list of gre-tunnel interfaces */
12307   M (GRE_TUNNEL_DUMP, mp);
12308
12309   mp->sw_if_index = htonl (sw_if_index);
12310
12311   S (mp);
12312
12313   /* Use a control ping for synchronization */
12314   MPING (CONTROL_PING, mp_ping);
12315   S (mp_ping);
12316
12317   W (ret);
12318   return ret;
12319 }
12320
12321 static int
12322 api_l2_fib_clear_table (vat_main_t * vam)
12323 {
12324 //  unformat_input_t * i = vam->input;
12325   vl_api_l2_fib_clear_table_t *mp;
12326   int ret;
12327
12328   M (L2_FIB_CLEAR_TABLE, mp);
12329
12330   S (mp);
12331   W (ret);
12332   return ret;
12333 }
12334
12335 static int
12336 api_l2_interface_efp_filter (vat_main_t * vam)
12337 {
12338   unformat_input_t *i = vam->input;
12339   vl_api_l2_interface_efp_filter_t *mp;
12340   u32 sw_if_index;
12341   u8 enable = 1;
12342   u8 sw_if_index_set = 0;
12343   int ret;
12344
12345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12346     {
12347       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12348         sw_if_index_set = 1;
12349       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12350         sw_if_index_set = 1;
12351       else if (unformat (i, "enable"))
12352         enable = 1;
12353       else if (unformat (i, "disable"))
12354         enable = 0;
12355       else
12356         {
12357           clib_warning ("parse error '%U'", format_unformat_error, i);
12358           return -99;
12359         }
12360     }
12361
12362   if (sw_if_index_set == 0)
12363     {
12364       errmsg ("missing sw_if_index");
12365       return -99;
12366     }
12367
12368   M (L2_INTERFACE_EFP_FILTER, mp);
12369
12370   mp->sw_if_index = ntohl (sw_if_index);
12371   mp->enable_disable = enable;
12372
12373   S (mp);
12374   W (ret);
12375   return ret;
12376 }
12377
12378 #define foreach_vtr_op                          \
12379 _("disable",  L2_VTR_DISABLED)                  \
12380 _("push-1",  L2_VTR_PUSH_1)                     \
12381 _("push-2",  L2_VTR_PUSH_2)                     \
12382 _("pop-1",  L2_VTR_POP_1)                       \
12383 _("pop-2",  L2_VTR_POP_2)                       \
12384 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12385 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12386 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12387 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12388
12389 static int
12390 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12391 {
12392   unformat_input_t *i = vam->input;
12393   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12394   u32 sw_if_index;
12395   u8 sw_if_index_set = 0;
12396   u8 vtr_op_set = 0;
12397   u32 vtr_op = 0;
12398   u32 push_dot1q = 1;
12399   u32 tag1 = ~0;
12400   u32 tag2 = ~0;
12401   int ret;
12402
12403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12404     {
12405       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12406         sw_if_index_set = 1;
12407       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12408         sw_if_index_set = 1;
12409       else if (unformat (i, "vtr_op %d", &vtr_op))
12410         vtr_op_set = 1;
12411 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12412       foreach_vtr_op
12413 #undef _
12414         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12415         ;
12416       else if (unformat (i, "tag1 %d", &tag1))
12417         ;
12418       else if (unformat (i, "tag2 %d", &tag2))
12419         ;
12420       else
12421         {
12422           clib_warning ("parse error '%U'", format_unformat_error, i);
12423           return -99;
12424         }
12425     }
12426
12427   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12428     {
12429       errmsg ("missing vtr operation or sw_if_index");
12430       return -99;
12431     }
12432
12433   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12434   mp->sw_if_index = ntohl (sw_if_index);
12435   mp->vtr_op = ntohl (vtr_op);
12436   mp->push_dot1q = ntohl (push_dot1q);
12437   mp->tag1 = ntohl (tag1);
12438   mp->tag2 = ntohl (tag2);
12439
12440   S (mp);
12441   W (ret);
12442   return ret;
12443 }
12444
12445 static int
12446 api_create_vhost_user_if (vat_main_t * vam)
12447 {
12448   unformat_input_t *i = vam->input;
12449   vl_api_create_vhost_user_if_t *mp;
12450   u8 *file_name;
12451   u8 is_server = 0;
12452   u8 file_name_set = 0;
12453   u32 custom_dev_instance = ~0;
12454   u8 hwaddr[6];
12455   u8 use_custom_mac = 0;
12456   u8 disable_mrg_rxbuf = 0;
12457   u8 disable_indirect_desc = 0;
12458   u8 *tag = 0;
12459   u8 enable_gso = 0;
12460   u8 enable_packed = 0;
12461   int ret;
12462
12463   /* Shut up coverity */
12464   clib_memset (hwaddr, 0, sizeof (hwaddr));
12465
12466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12467     {
12468       if (unformat (i, "socket %s", &file_name))
12469         {
12470           file_name_set = 1;
12471         }
12472       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12473         ;
12474       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12475         use_custom_mac = 1;
12476       else if (unformat (i, "server"))
12477         is_server = 1;
12478       else if (unformat (i, "disable_mrg_rxbuf"))
12479         disable_mrg_rxbuf = 1;
12480       else if (unformat (i, "disable_indirect_desc"))
12481         disable_indirect_desc = 1;
12482       else if (unformat (i, "gso"))
12483         enable_gso = 1;
12484       else if (unformat (i, "packed"))
12485         enable_packed = 1;
12486       else if (unformat (i, "tag %s", &tag))
12487         ;
12488       else
12489         break;
12490     }
12491
12492   if (file_name_set == 0)
12493     {
12494       errmsg ("missing socket file name");
12495       return -99;
12496     }
12497
12498   if (vec_len (file_name) > 255)
12499     {
12500       errmsg ("socket file name too long");
12501       return -99;
12502     }
12503   vec_add1 (file_name, 0);
12504
12505   M (CREATE_VHOST_USER_IF, mp);
12506
12507   mp->is_server = is_server;
12508   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12509   mp->disable_indirect_desc = disable_indirect_desc;
12510   mp->enable_gso = enable_gso;
12511   mp->enable_packed = enable_packed;
12512   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12513   vec_free (file_name);
12514   if (custom_dev_instance != ~0)
12515     {
12516       mp->renumber = 1;
12517       mp->custom_dev_instance = ntohl (custom_dev_instance);
12518     }
12519
12520   mp->use_custom_mac = use_custom_mac;
12521   clib_memcpy (mp->mac_address, hwaddr, 6);
12522   if (tag)
12523     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12524   vec_free (tag);
12525
12526   S (mp);
12527   W (ret);
12528   return ret;
12529 }
12530
12531 static int
12532 api_modify_vhost_user_if (vat_main_t * vam)
12533 {
12534   unformat_input_t *i = vam->input;
12535   vl_api_modify_vhost_user_if_t *mp;
12536   u8 *file_name;
12537   u8 is_server = 0;
12538   u8 file_name_set = 0;
12539   u32 custom_dev_instance = ~0;
12540   u8 sw_if_index_set = 0;
12541   u32 sw_if_index = (u32) ~ 0;
12542   u8 enable_gso = 0;
12543   u8 enable_packed = 0;
12544   int ret;
12545
12546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12547     {
12548       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12549         sw_if_index_set = 1;
12550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12551         sw_if_index_set = 1;
12552       else if (unformat (i, "socket %s", &file_name))
12553         {
12554           file_name_set = 1;
12555         }
12556       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12557         ;
12558       else if (unformat (i, "server"))
12559         is_server = 1;
12560       else if (unformat (i, "gso"))
12561         enable_gso = 1;
12562       else if (unformat (i, "packed"))
12563         enable_packed = 1;
12564       else
12565         break;
12566     }
12567
12568   if (sw_if_index_set == 0)
12569     {
12570       errmsg ("missing sw_if_index or interface name");
12571       return -99;
12572     }
12573
12574   if (file_name_set == 0)
12575     {
12576       errmsg ("missing socket file name");
12577       return -99;
12578     }
12579
12580   if (vec_len (file_name) > 255)
12581     {
12582       errmsg ("socket file name too long");
12583       return -99;
12584     }
12585   vec_add1 (file_name, 0);
12586
12587   M (MODIFY_VHOST_USER_IF, mp);
12588
12589   mp->sw_if_index = ntohl (sw_if_index);
12590   mp->is_server = is_server;
12591   mp->enable_gso = enable_gso;
12592   mp->enable_packed = enable_packed;
12593   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12594   vec_free (file_name);
12595   if (custom_dev_instance != ~0)
12596     {
12597       mp->renumber = 1;
12598       mp->custom_dev_instance = ntohl (custom_dev_instance);
12599     }
12600
12601   S (mp);
12602   W (ret);
12603   return ret;
12604 }
12605
12606 static int
12607 api_delete_vhost_user_if (vat_main_t * vam)
12608 {
12609   unformat_input_t *i = vam->input;
12610   vl_api_delete_vhost_user_if_t *mp;
12611   u32 sw_if_index = ~0;
12612   u8 sw_if_index_set = 0;
12613   int ret;
12614
12615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12616     {
12617       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12618         sw_if_index_set = 1;
12619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12620         sw_if_index_set = 1;
12621       else
12622         break;
12623     }
12624
12625   if (sw_if_index_set == 0)
12626     {
12627       errmsg ("missing sw_if_index or interface name");
12628       return -99;
12629     }
12630
12631
12632   M (DELETE_VHOST_USER_IF, mp);
12633
12634   mp->sw_if_index = ntohl (sw_if_index);
12635
12636   S (mp);
12637   W (ret);
12638   return ret;
12639 }
12640
12641 static void vl_api_sw_interface_vhost_user_details_t_handler
12642   (vl_api_sw_interface_vhost_user_details_t * mp)
12643 {
12644   vat_main_t *vam = &vat_main;
12645   u64 features;
12646
12647   features =
12648     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12649                                                     clib_net_to_host_u32
12650                                                     (mp->features_last_32) <<
12651                                                     32);
12652
12653   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12654          (char *) mp->interface_name,
12655          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12656          features, mp->is_server,
12657          ntohl (mp->num_regions), (char *) mp->sock_filename);
12658   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12659 }
12660
12661 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12662   (vl_api_sw_interface_vhost_user_details_t * mp)
12663 {
12664   vat_main_t *vam = &vat_main;
12665   vat_json_node_t *node = NULL;
12666
12667   if (VAT_JSON_ARRAY != vam->json_tree.type)
12668     {
12669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12670       vat_json_init_array (&vam->json_tree);
12671     }
12672   node = vat_json_array_add (&vam->json_tree);
12673
12674   vat_json_init_object (node);
12675   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12676   vat_json_object_add_string_copy (node, "interface_name",
12677                                    mp->interface_name);
12678   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12679                             ntohl (mp->virtio_net_hdr_sz));
12680   vat_json_object_add_uint (node, "features_first_32",
12681                             clib_net_to_host_u32 (mp->features_first_32));
12682   vat_json_object_add_uint (node, "features_last_32",
12683                             clib_net_to_host_u32 (mp->features_last_32));
12684   vat_json_object_add_uint (node, "is_server", mp->is_server);
12685   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12686   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12687   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12688 }
12689
12690 static int
12691 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12692 {
12693   unformat_input_t *i = vam->input;
12694   vl_api_sw_interface_vhost_user_dump_t *mp;
12695   vl_api_control_ping_t *mp_ping;
12696   int ret;
12697   u32 sw_if_index = ~0;
12698
12699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12700     {
12701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12702         ;
12703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12704         ;
12705       else
12706         break;
12707     }
12708
12709   print (vam->ofp,
12710          "Interface name            idx hdr_sz features server regions filename");
12711
12712   /* Get list of vhost-user interfaces */
12713   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12714   mp->sw_if_index = ntohl (sw_if_index);
12715   S (mp);
12716
12717   /* Use a control ping for synchronization */
12718   MPING (CONTROL_PING, mp_ping);
12719   S (mp_ping);
12720
12721   W (ret);
12722   return ret;
12723 }
12724
12725 static int
12726 api_show_version (vat_main_t * vam)
12727 {
12728   vl_api_show_version_t *mp;
12729   int ret;
12730
12731   M (SHOW_VERSION, mp);
12732
12733   S (mp);
12734   W (ret);
12735   return ret;
12736 }
12737
12738
12739 static int
12740 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12741 {
12742   unformat_input_t *line_input = vam->input;
12743   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12744   ip46_address_t local, remote;
12745   u8 is_add = 1;
12746   u8 local_set = 0;
12747   u8 remote_set = 0;
12748   u8 grp_set = 0;
12749   u32 mcast_sw_if_index = ~0;
12750   u32 encap_vrf_id = 0;
12751   u32 decap_vrf_id = 0;
12752   u8 protocol = ~0;
12753   u32 vni;
12754   u8 vni_set = 0;
12755   int ret;
12756
12757   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12758     {
12759       if (unformat (line_input, "del"))
12760         is_add = 0;
12761       else if (unformat (line_input, "local %U",
12762                          unformat_ip46_address, &local))
12763         {
12764           local_set = 1;
12765         }
12766       else if (unformat (line_input, "remote %U",
12767                          unformat_ip46_address, &remote))
12768         {
12769           remote_set = 1;
12770         }
12771       else if (unformat (line_input, "group %U %U",
12772                          unformat_ip46_address, &remote,
12773                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12774         {
12775           grp_set = remote_set = 1;
12776         }
12777       else if (unformat (line_input, "group %U",
12778                          unformat_ip46_address, &remote))
12779         {
12780           grp_set = remote_set = 1;
12781         }
12782       else
12783         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12784         ;
12785       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12786         ;
12787       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12788         ;
12789       else if (unformat (line_input, "vni %d", &vni))
12790         vni_set = 1;
12791       else if (unformat (line_input, "next-ip4"))
12792         protocol = 1;
12793       else if (unformat (line_input, "next-ip6"))
12794         protocol = 2;
12795       else if (unformat (line_input, "next-ethernet"))
12796         protocol = 3;
12797       else if (unformat (line_input, "next-nsh"))
12798         protocol = 4;
12799       else
12800         {
12801           errmsg ("parse error '%U'", format_unformat_error, line_input);
12802           return -99;
12803         }
12804     }
12805
12806   if (local_set == 0)
12807     {
12808       errmsg ("tunnel local address not specified");
12809       return -99;
12810     }
12811   if (remote_set == 0)
12812     {
12813       errmsg ("tunnel remote address not specified");
12814       return -99;
12815     }
12816   if (grp_set && mcast_sw_if_index == ~0)
12817     {
12818       errmsg ("tunnel nonexistent multicast device");
12819       return -99;
12820     }
12821   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12822     {
12823       errmsg ("both IPv4 and IPv6 addresses specified");
12824       return -99;
12825     }
12826
12827   if (vni_set == 0)
12828     {
12829       errmsg ("vni not specified");
12830       return -99;
12831     }
12832
12833   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12834
12835   ip_address_encode (&local,
12836                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12837                      IP46_TYPE_IP6, &mp->local);
12838   ip_address_encode (&remote,
12839                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12840                      IP46_TYPE_IP6, &mp->remote);
12841
12842   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12843   mp->encap_vrf_id = ntohl (encap_vrf_id);
12844   mp->decap_vrf_id = ntohl (decap_vrf_id);
12845   mp->protocol = protocol;
12846   mp->vni = ntohl (vni);
12847   mp->is_add = is_add;
12848
12849   S (mp);
12850   W (ret);
12851   return ret;
12852 }
12853
12854 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12855   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12856 {
12857   vat_main_t *vam = &vat_main;
12858   ip46_address_t local, remote;
12859
12860   ip_address_decode (&mp->local, &local);
12861   ip_address_decode (&mp->remote, &remote);
12862
12863   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12864          ntohl (mp->sw_if_index),
12865          format_ip46_address, &local, IP46_TYPE_ANY,
12866          format_ip46_address, &remote, IP46_TYPE_ANY,
12867          ntohl (mp->vni), mp->protocol,
12868          ntohl (mp->mcast_sw_if_index),
12869          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12870 }
12871
12872
12873 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12874   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12875 {
12876   vat_main_t *vam = &vat_main;
12877   vat_json_node_t *node = NULL;
12878   struct in_addr ip4;
12879   struct in6_addr ip6;
12880   ip46_address_t local, remote;
12881
12882   ip_address_decode (&mp->local, &local);
12883   ip_address_decode (&mp->remote, &remote);
12884
12885   if (VAT_JSON_ARRAY != vam->json_tree.type)
12886     {
12887       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12888       vat_json_init_array (&vam->json_tree);
12889     }
12890   node = vat_json_array_add (&vam->json_tree);
12891
12892   vat_json_init_object (node);
12893   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12894   if (ip46_address_is_ip4 (&local))
12895     {
12896       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12897       vat_json_object_add_ip4 (node, "local", ip4);
12898       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12899       vat_json_object_add_ip4 (node, "remote", ip4);
12900     }
12901   else
12902     {
12903       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12904       vat_json_object_add_ip6 (node, "local", ip6);
12905       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12906       vat_json_object_add_ip6 (node, "remote", ip6);
12907     }
12908   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12909   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12910   vat_json_object_add_uint (node, "mcast_sw_if_index",
12911                             ntohl (mp->mcast_sw_if_index));
12912   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12913   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12914   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12915 }
12916
12917 static int
12918 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12919 {
12920   unformat_input_t *i = vam->input;
12921   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12922   vl_api_control_ping_t *mp_ping;
12923   u32 sw_if_index;
12924   u8 sw_if_index_set = 0;
12925   int ret;
12926
12927   /* Parse args required to build the message */
12928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12929     {
12930       if (unformat (i, "sw_if_index %d", &sw_if_index))
12931         sw_if_index_set = 1;
12932       else
12933         break;
12934     }
12935
12936   if (sw_if_index_set == 0)
12937     {
12938       sw_if_index = ~0;
12939     }
12940
12941   if (!vam->json_output)
12942     {
12943       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12944              "sw_if_index", "local", "remote", "vni",
12945              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12946     }
12947
12948   /* Get list of vxlan-tunnel interfaces */
12949   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12950
12951   mp->sw_if_index = htonl (sw_if_index);
12952
12953   S (mp);
12954
12955   /* Use a control ping for synchronization */
12956   MPING (CONTROL_PING, mp_ping);
12957   S (mp_ping);
12958
12959   W (ret);
12960   return ret;
12961 }
12962
12963 static void vl_api_l2_fib_table_details_t_handler
12964   (vl_api_l2_fib_table_details_t * mp)
12965 {
12966   vat_main_t *vam = &vat_main;
12967
12968   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12969          "       %d       %d     %d",
12970          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12971          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12972          mp->bvi_mac);
12973 }
12974
12975 static void vl_api_l2_fib_table_details_t_handler_json
12976   (vl_api_l2_fib_table_details_t * mp)
12977 {
12978   vat_main_t *vam = &vat_main;
12979   vat_json_node_t *node = NULL;
12980
12981   if (VAT_JSON_ARRAY != vam->json_tree.type)
12982     {
12983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12984       vat_json_init_array (&vam->json_tree);
12985     }
12986   node = vat_json_array_add (&vam->json_tree);
12987
12988   vat_json_init_object (node);
12989   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12990   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12991   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12992   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12993   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12994   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12995 }
12996
12997 static int
12998 api_l2_fib_table_dump (vat_main_t * vam)
12999 {
13000   unformat_input_t *i = vam->input;
13001   vl_api_l2_fib_table_dump_t *mp;
13002   vl_api_control_ping_t *mp_ping;
13003   u32 bd_id;
13004   u8 bd_id_set = 0;
13005   int ret;
13006
13007   /* Parse args required to build the message */
13008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13009     {
13010       if (unformat (i, "bd_id %d", &bd_id))
13011         bd_id_set = 1;
13012       else
13013         break;
13014     }
13015
13016   if (bd_id_set == 0)
13017     {
13018       errmsg ("missing bridge domain");
13019       return -99;
13020     }
13021
13022   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13023
13024   /* Get list of l2 fib entries */
13025   M (L2_FIB_TABLE_DUMP, mp);
13026
13027   mp->bd_id = ntohl (bd_id);
13028   S (mp);
13029
13030   /* Use a control ping for synchronization */
13031   MPING (CONTROL_PING, mp_ping);
13032   S (mp_ping);
13033
13034   W (ret);
13035   return ret;
13036 }
13037
13038
13039 static int
13040 api_interface_name_renumber (vat_main_t * vam)
13041 {
13042   unformat_input_t *line_input = vam->input;
13043   vl_api_interface_name_renumber_t *mp;
13044   u32 sw_if_index = ~0;
13045   u32 new_show_dev_instance = ~0;
13046   int ret;
13047
13048   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13049     {
13050       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13051                     &sw_if_index))
13052         ;
13053       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13054         ;
13055       else if (unformat (line_input, "new_show_dev_instance %d",
13056                          &new_show_dev_instance))
13057         ;
13058       else
13059         break;
13060     }
13061
13062   if (sw_if_index == ~0)
13063     {
13064       errmsg ("missing interface name or sw_if_index");
13065       return -99;
13066     }
13067
13068   if (new_show_dev_instance == ~0)
13069     {
13070       errmsg ("missing new_show_dev_instance");
13071       return -99;
13072     }
13073
13074   M (INTERFACE_NAME_RENUMBER, mp);
13075
13076   mp->sw_if_index = ntohl (sw_if_index);
13077   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13078
13079   S (mp);
13080   W (ret);
13081   return ret;
13082 }
13083
13084 static int
13085 api_want_l2_macs_events (vat_main_t * vam)
13086 {
13087   unformat_input_t *line_input = vam->input;
13088   vl_api_want_l2_macs_events_t *mp;
13089   u8 enable_disable = 1;
13090   u32 scan_delay = 0;
13091   u32 max_macs_in_event = 0;
13092   u32 learn_limit = 0;
13093   int ret;
13094
13095   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13096     {
13097       if (unformat (line_input, "learn-limit %d", &learn_limit))
13098         ;
13099       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13100         ;
13101       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13102         ;
13103       else if (unformat (line_input, "disable"))
13104         enable_disable = 0;
13105       else
13106         break;
13107     }
13108
13109   M (WANT_L2_MACS_EVENTS, mp);
13110   mp->enable_disable = enable_disable;
13111   mp->pid = htonl (getpid ());
13112   mp->learn_limit = htonl (learn_limit);
13113   mp->scan_delay = (u8) scan_delay;
13114   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13115   S (mp);
13116   W (ret);
13117   return ret;
13118 }
13119
13120 static int
13121 api_input_acl_set_interface (vat_main_t * vam)
13122 {
13123   unformat_input_t *i = vam->input;
13124   vl_api_input_acl_set_interface_t *mp;
13125   u32 sw_if_index;
13126   int sw_if_index_set;
13127   u32 ip4_table_index = ~0;
13128   u32 ip6_table_index = ~0;
13129   u32 l2_table_index = ~0;
13130   u8 is_add = 1;
13131   int ret;
13132
13133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13134     {
13135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13136         sw_if_index_set = 1;
13137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13138         sw_if_index_set = 1;
13139       else if (unformat (i, "del"))
13140         is_add = 0;
13141       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13142         ;
13143       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13144         ;
13145       else if (unformat (i, "l2-table %d", &l2_table_index))
13146         ;
13147       else
13148         {
13149           clib_warning ("parse error '%U'", format_unformat_error, i);
13150           return -99;
13151         }
13152     }
13153
13154   if (sw_if_index_set == 0)
13155     {
13156       errmsg ("missing interface name or sw_if_index");
13157       return -99;
13158     }
13159
13160   M (INPUT_ACL_SET_INTERFACE, mp);
13161
13162   mp->sw_if_index = ntohl (sw_if_index);
13163   mp->ip4_table_index = ntohl (ip4_table_index);
13164   mp->ip6_table_index = ntohl (ip6_table_index);
13165   mp->l2_table_index = ntohl (l2_table_index);
13166   mp->is_add = is_add;
13167
13168   S (mp);
13169   W (ret);
13170   return ret;
13171 }
13172
13173 static int
13174 api_output_acl_set_interface (vat_main_t * vam)
13175 {
13176   unformat_input_t *i = vam->input;
13177   vl_api_output_acl_set_interface_t *mp;
13178   u32 sw_if_index;
13179   int sw_if_index_set;
13180   u32 ip4_table_index = ~0;
13181   u32 ip6_table_index = ~0;
13182   u32 l2_table_index = ~0;
13183   u8 is_add = 1;
13184   int ret;
13185
13186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13187     {
13188       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13189         sw_if_index_set = 1;
13190       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13191         sw_if_index_set = 1;
13192       else if (unformat (i, "del"))
13193         is_add = 0;
13194       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13195         ;
13196       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13197         ;
13198       else if (unformat (i, "l2-table %d", &l2_table_index))
13199         ;
13200       else
13201         {
13202           clib_warning ("parse error '%U'", format_unformat_error, i);
13203           return -99;
13204         }
13205     }
13206
13207   if (sw_if_index_set == 0)
13208     {
13209       errmsg ("missing interface name or sw_if_index");
13210       return -99;
13211     }
13212
13213   M (OUTPUT_ACL_SET_INTERFACE, mp);
13214
13215   mp->sw_if_index = ntohl (sw_if_index);
13216   mp->ip4_table_index = ntohl (ip4_table_index);
13217   mp->ip6_table_index = ntohl (ip6_table_index);
13218   mp->l2_table_index = ntohl (l2_table_index);
13219   mp->is_add = is_add;
13220
13221   S (mp);
13222   W (ret);
13223   return ret;
13224 }
13225
13226 static int
13227 api_ip_address_dump (vat_main_t * vam)
13228 {
13229   unformat_input_t *i = vam->input;
13230   vl_api_ip_address_dump_t *mp;
13231   vl_api_control_ping_t *mp_ping;
13232   u32 sw_if_index = ~0;
13233   u8 sw_if_index_set = 0;
13234   u8 ipv4_set = 0;
13235   u8 ipv6_set = 0;
13236   int ret;
13237
13238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13239     {
13240       if (unformat (i, "sw_if_index %d", &sw_if_index))
13241         sw_if_index_set = 1;
13242       else
13243         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13244         sw_if_index_set = 1;
13245       else if (unformat (i, "ipv4"))
13246         ipv4_set = 1;
13247       else if (unformat (i, "ipv6"))
13248         ipv6_set = 1;
13249       else
13250         break;
13251     }
13252
13253   if (ipv4_set && ipv6_set)
13254     {
13255       errmsg ("ipv4 and ipv6 flags cannot be both set");
13256       return -99;
13257     }
13258
13259   if ((!ipv4_set) && (!ipv6_set))
13260     {
13261       errmsg ("no ipv4 nor ipv6 flag set");
13262       return -99;
13263     }
13264
13265   if (sw_if_index_set == 0)
13266     {
13267       errmsg ("missing interface name or sw_if_index");
13268       return -99;
13269     }
13270
13271   vam->current_sw_if_index = sw_if_index;
13272   vam->is_ipv6 = ipv6_set;
13273
13274   M (IP_ADDRESS_DUMP, mp);
13275   mp->sw_if_index = ntohl (sw_if_index);
13276   mp->is_ipv6 = ipv6_set;
13277   S (mp);
13278
13279   /* Use a control ping for synchronization */
13280   MPING (CONTROL_PING, mp_ping);
13281   S (mp_ping);
13282
13283   W (ret);
13284   return ret;
13285 }
13286
13287 static int
13288 api_ip_dump (vat_main_t * vam)
13289 {
13290   vl_api_ip_dump_t *mp;
13291   vl_api_control_ping_t *mp_ping;
13292   unformat_input_t *in = vam->input;
13293   int ipv4_set = 0;
13294   int ipv6_set = 0;
13295   int is_ipv6;
13296   int i;
13297   int ret;
13298
13299   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13300     {
13301       if (unformat (in, "ipv4"))
13302         ipv4_set = 1;
13303       else if (unformat (in, "ipv6"))
13304         ipv6_set = 1;
13305       else
13306         break;
13307     }
13308
13309   if (ipv4_set && ipv6_set)
13310     {
13311       errmsg ("ipv4 and ipv6 flags cannot be both set");
13312       return -99;
13313     }
13314
13315   if ((!ipv4_set) && (!ipv6_set))
13316     {
13317       errmsg ("no ipv4 nor ipv6 flag set");
13318       return -99;
13319     }
13320
13321   is_ipv6 = ipv6_set;
13322   vam->is_ipv6 = is_ipv6;
13323
13324   /* free old data */
13325   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13326     {
13327       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13328     }
13329   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13330
13331   M (IP_DUMP, mp);
13332   mp->is_ipv6 = ipv6_set;
13333   S (mp);
13334
13335   /* Use a control ping for synchronization */
13336   MPING (CONTROL_PING, mp_ping);
13337   S (mp_ping);
13338
13339   W (ret);
13340   return ret;
13341 }
13342
13343 static int
13344 api_ipsec_spd_add_del (vat_main_t * vam)
13345 {
13346   unformat_input_t *i = vam->input;
13347   vl_api_ipsec_spd_add_del_t *mp;
13348   u32 spd_id = ~0;
13349   u8 is_add = 1;
13350   int ret;
13351
13352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (i, "spd_id %d", &spd_id))
13355         ;
13356       else if (unformat (i, "del"))
13357         is_add = 0;
13358       else
13359         {
13360           clib_warning ("parse error '%U'", format_unformat_error, i);
13361           return -99;
13362         }
13363     }
13364   if (spd_id == ~0)
13365     {
13366       errmsg ("spd_id must be set");
13367       return -99;
13368     }
13369
13370   M (IPSEC_SPD_ADD_DEL, mp);
13371
13372   mp->spd_id = ntohl (spd_id);
13373   mp->is_add = is_add;
13374
13375   S (mp);
13376   W (ret);
13377   return ret;
13378 }
13379
13380 static int
13381 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13382 {
13383   unformat_input_t *i = vam->input;
13384   vl_api_ipsec_interface_add_del_spd_t *mp;
13385   u32 sw_if_index;
13386   u8 sw_if_index_set = 0;
13387   u32 spd_id = (u32) ~ 0;
13388   u8 is_add = 1;
13389   int ret;
13390
13391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13392     {
13393       if (unformat (i, "del"))
13394         is_add = 0;
13395       else if (unformat (i, "spd_id %d", &spd_id))
13396         ;
13397       else
13398         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13399         sw_if_index_set = 1;
13400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13401         sw_if_index_set = 1;
13402       else
13403         {
13404           clib_warning ("parse error '%U'", format_unformat_error, i);
13405           return -99;
13406         }
13407
13408     }
13409
13410   if (spd_id == (u32) ~ 0)
13411     {
13412       errmsg ("spd_id must be set");
13413       return -99;
13414     }
13415
13416   if (sw_if_index_set == 0)
13417     {
13418       errmsg ("missing interface name or sw_if_index");
13419       return -99;
13420     }
13421
13422   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13423
13424   mp->spd_id = ntohl (spd_id);
13425   mp->sw_if_index = ntohl (sw_if_index);
13426   mp->is_add = is_add;
13427
13428   S (mp);
13429   W (ret);
13430   return ret;
13431 }
13432
13433 static int
13434 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13435 {
13436   unformat_input_t *i = vam->input;
13437   vl_api_ipsec_spd_entry_add_del_t *mp;
13438   u8 is_add = 1, is_outbound = 0;
13439   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13440   i32 priority = 0;
13441   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13442   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13443   vl_api_address_t laddr_start = { }, laddr_stop =
13444   {
13445   }, raddr_start =
13446   {
13447   }, raddr_stop =
13448   {
13449   };
13450   int ret;
13451
13452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13453     {
13454       if (unformat (i, "del"))
13455         is_add = 0;
13456       if (unformat (i, "outbound"))
13457         is_outbound = 1;
13458       if (unformat (i, "inbound"))
13459         is_outbound = 0;
13460       else if (unformat (i, "spd_id %d", &spd_id))
13461         ;
13462       else if (unformat (i, "sa_id %d", &sa_id))
13463         ;
13464       else if (unformat (i, "priority %d", &priority))
13465         ;
13466       else if (unformat (i, "protocol %d", &protocol))
13467         ;
13468       else if (unformat (i, "lport_start %d", &lport_start))
13469         ;
13470       else if (unformat (i, "lport_stop %d", &lport_stop))
13471         ;
13472       else if (unformat (i, "rport_start %d", &rport_start))
13473         ;
13474       else if (unformat (i, "rport_stop %d", &rport_stop))
13475         ;
13476       else if (unformat (i, "laddr_start %U",
13477                          unformat_vl_api_address, &laddr_start))
13478         ;
13479       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13480                          &laddr_stop))
13481         ;
13482       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13483                          &raddr_start))
13484         ;
13485       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13486                          &raddr_stop))
13487         ;
13488       else
13489         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13490         {
13491           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13492             {
13493               clib_warning ("unsupported action: 'resolve'");
13494               return -99;
13495             }
13496         }
13497       else
13498         {
13499           clib_warning ("parse error '%U'", format_unformat_error, i);
13500           return -99;
13501         }
13502
13503     }
13504
13505   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13506
13507   mp->is_add = is_add;
13508
13509   mp->entry.spd_id = ntohl (spd_id);
13510   mp->entry.priority = ntohl (priority);
13511   mp->entry.is_outbound = is_outbound;
13512
13513   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13514                sizeof (vl_api_address_t));
13515   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13516                sizeof (vl_api_address_t));
13517   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13518                sizeof (vl_api_address_t));
13519   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13520                sizeof (vl_api_address_t));
13521
13522   mp->entry.protocol = (u8) protocol;
13523   mp->entry.local_port_start = ntohs ((u16) lport_start);
13524   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13525   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13526   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13527   mp->entry.policy = (u8) policy;
13528   mp->entry.sa_id = ntohl (sa_id);
13529
13530   S (mp);
13531   W (ret);
13532   return ret;
13533 }
13534
13535 static int
13536 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13537 {
13538   unformat_input_t *i = vam->input;
13539   vl_api_ipsec_sad_entry_add_del_t *mp;
13540   u32 sad_id = 0, spi = 0;
13541   u8 *ck = 0, *ik = 0;
13542   u8 is_add = 1;
13543
13544   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13545   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13546   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13547   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13548   vl_api_address_t tun_src, tun_dst;
13549   int ret;
13550
13551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13552     {
13553       if (unformat (i, "del"))
13554         is_add = 0;
13555       else if (unformat (i, "sad_id %d", &sad_id))
13556         ;
13557       else if (unformat (i, "spi %d", &spi))
13558         ;
13559       else if (unformat (i, "esp"))
13560         protocol = IPSEC_API_PROTO_ESP;
13561       else
13562         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13563         {
13564           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13565           if (ADDRESS_IP6 == tun_src.af)
13566             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13567         }
13568       else
13569         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13570         {
13571           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13572           if (ADDRESS_IP6 == tun_src.af)
13573             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13574         }
13575       else
13576         if (unformat (i, "crypto_alg %U",
13577                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13578         ;
13579       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13580         ;
13581       else if (unformat (i, "integ_alg %U",
13582                          unformat_ipsec_api_integ_alg, &integ_alg))
13583         ;
13584       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13585         ;
13586       else
13587         {
13588           clib_warning ("parse error '%U'", format_unformat_error, i);
13589           return -99;
13590         }
13591
13592     }
13593
13594   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13595
13596   mp->is_add = is_add;
13597   mp->entry.sad_id = ntohl (sad_id);
13598   mp->entry.protocol = protocol;
13599   mp->entry.spi = ntohl (spi);
13600   mp->entry.flags = flags;
13601
13602   mp->entry.crypto_algorithm = crypto_alg;
13603   mp->entry.integrity_algorithm = integ_alg;
13604   mp->entry.crypto_key.length = vec_len (ck);
13605   mp->entry.integrity_key.length = vec_len (ik);
13606
13607   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13608     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13609
13610   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13611     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13612
13613   if (ck)
13614     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13615   if (ik)
13616     clib_memcpy (mp->entry.integrity_key.data, ik,
13617                  mp->entry.integrity_key.length);
13618
13619   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13620     {
13621       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13622                    sizeof (mp->entry.tunnel_src));
13623       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13624                    sizeof (mp->entry.tunnel_dst));
13625     }
13626
13627   S (mp);
13628   W (ret);
13629   return ret;
13630 }
13631
13632 static int
13633 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13634 {
13635   unformat_input_t *i = vam->input;
13636   vl_api_ipsec_tunnel_if_add_del_t *mp;
13637   u32 local_spi = 0, remote_spi = 0;
13638   u32 crypto_alg = 0, integ_alg = 0;
13639   u8 *lck = NULL, *rck = NULL;
13640   u8 *lik = NULL, *rik = NULL;
13641   vl_api_address_t local_ip = { 0 };
13642   vl_api_address_t remote_ip = { 0 };
13643   f64 before = 0;
13644   u8 is_add = 1;
13645   u8 esn = 0;
13646   u8 anti_replay = 0;
13647   u8 renumber = 0;
13648   u32 instance = ~0;
13649   u32 count = 1, jj;
13650   int ret = -1;
13651
13652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13653     {
13654       if (unformat (i, "del"))
13655         is_add = 0;
13656       else if (unformat (i, "esn"))
13657         esn = 1;
13658       else if (unformat (i, "anti-replay"))
13659         anti_replay = 1;
13660       else if (unformat (i, "count %d", &count))
13661         ;
13662       else if (unformat (i, "local_spi %d", &local_spi))
13663         ;
13664       else if (unformat (i, "remote_spi %d", &remote_spi))
13665         ;
13666       else
13667         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13668         ;
13669       else
13670         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13671         ;
13672       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13673         ;
13674       else
13675         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13676         ;
13677       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13678         ;
13679       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13680         ;
13681       else
13682         if (unformat
13683             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13684         {
13685           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13686             {
13687               errmsg ("unsupported crypto-alg: '%U'\n",
13688                       format_ipsec_crypto_alg, crypto_alg);
13689               return -99;
13690             }
13691         }
13692       else
13693         if (unformat
13694             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13695         {
13696           if (integ_alg >= IPSEC_INTEG_N_ALG)
13697             {
13698               errmsg ("unsupported integ-alg: '%U'\n",
13699                       format_ipsec_integ_alg, integ_alg);
13700               return -99;
13701             }
13702         }
13703       else if (unformat (i, "instance %u", &instance))
13704         renumber = 1;
13705       else
13706         {
13707           errmsg ("parse error '%U'\n", format_unformat_error, i);
13708           return -99;
13709         }
13710     }
13711
13712   if (count > 1)
13713     {
13714       /* Turn on async mode */
13715       vam->async_mode = 1;
13716       vam->async_errors = 0;
13717       before = vat_time_now (vam);
13718     }
13719
13720   for (jj = 0; jj < count; jj++)
13721     {
13722       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13723
13724       mp->is_add = is_add;
13725       mp->esn = esn;
13726       mp->anti_replay = anti_replay;
13727
13728       if (jj > 0)
13729         increment_address (&remote_ip);
13730
13731       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13732       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13733
13734       mp->local_spi = htonl (local_spi + jj);
13735       mp->remote_spi = htonl (remote_spi + jj);
13736       mp->crypto_alg = (u8) crypto_alg;
13737
13738       mp->local_crypto_key_len = 0;
13739       if (lck)
13740         {
13741           mp->local_crypto_key_len = vec_len (lck);
13742           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13743             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13744           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13745         }
13746
13747       mp->remote_crypto_key_len = 0;
13748       if (rck)
13749         {
13750           mp->remote_crypto_key_len = vec_len (rck);
13751           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13752             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13753           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13754         }
13755
13756       mp->integ_alg = (u8) integ_alg;
13757
13758       mp->local_integ_key_len = 0;
13759       if (lik)
13760         {
13761           mp->local_integ_key_len = vec_len (lik);
13762           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13763             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13764           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13765         }
13766
13767       mp->remote_integ_key_len = 0;
13768       if (rik)
13769         {
13770           mp->remote_integ_key_len = vec_len (rik);
13771           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13772             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13773           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13774         }
13775
13776       if (renumber)
13777         {
13778           mp->renumber = renumber;
13779           mp->show_instance = ntohl (instance);
13780         }
13781       S (mp);
13782     }
13783
13784   /* When testing multiple add/del ops, use a control-ping to sync */
13785   if (count > 1)
13786     {
13787       vl_api_control_ping_t *mp_ping;
13788       f64 after;
13789       f64 timeout;
13790
13791       /* Shut off async mode */
13792       vam->async_mode = 0;
13793
13794       MPING (CONTROL_PING, mp_ping);
13795       S (mp_ping);
13796
13797       timeout = vat_time_now (vam) + 1.0;
13798       while (vat_time_now (vam) < timeout)
13799         if (vam->result_ready == 1)
13800           goto out;
13801       vam->retval = -99;
13802
13803     out:
13804       if (vam->retval == -99)
13805         errmsg ("timeout");
13806
13807       if (vam->async_errors > 0)
13808         {
13809           errmsg ("%d asynchronous errors", vam->async_errors);
13810           vam->retval = -98;
13811         }
13812       vam->async_errors = 0;
13813       after = vat_time_now (vam);
13814
13815       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13816       if (jj > 0)
13817         count = jj;
13818
13819       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13820              count, after - before, count / (after - before));
13821     }
13822   else
13823     {
13824       /* Wait for a reply... */
13825       W (ret);
13826       return ret;
13827     }
13828
13829   return ret;
13830 }
13831
13832 static void
13833 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13834 {
13835   vat_main_t *vam = &vat_main;
13836
13837   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13838          "crypto_key %U integ_alg %u integ_key %U flags %x "
13839          "tunnel_src_addr %U tunnel_dst_addr %U "
13840          "salt %u seq_outbound %lu last_seq_inbound %lu "
13841          "replay_window %lu stat_index %u\n",
13842          ntohl (mp->entry.sad_id),
13843          ntohl (mp->sw_if_index),
13844          ntohl (mp->entry.spi),
13845          ntohl (mp->entry.protocol),
13846          ntohl (mp->entry.crypto_algorithm),
13847          format_hex_bytes, mp->entry.crypto_key.data,
13848          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13849          format_hex_bytes, mp->entry.integrity_key.data,
13850          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13851          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13852          &mp->entry.tunnel_dst, ntohl (mp->salt),
13853          clib_net_to_host_u64 (mp->seq_outbound),
13854          clib_net_to_host_u64 (mp->last_seq_inbound),
13855          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13856 }
13857
13858 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13859 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13860
13861 static void vl_api_ipsec_sa_details_t_handler_json
13862   (vl_api_ipsec_sa_details_t * mp)
13863 {
13864   vat_main_t *vam = &vat_main;
13865   vat_json_node_t *node = NULL;
13866   vl_api_ipsec_sad_flags_t flags;
13867
13868   if (VAT_JSON_ARRAY != vam->json_tree.type)
13869     {
13870       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13871       vat_json_init_array (&vam->json_tree);
13872     }
13873   node = vat_json_array_add (&vam->json_tree);
13874
13875   vat_json_init_object (node);
13876   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13877   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13878   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13879   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13880   vat_json_object_add_uint (node, "crypto_alg",
13881                             ntohl (mp->entry.crypto_algorithm));
13882   vat_json_object_add_uint (node, "integ_alg",
13883                             ntohl (mp->entry.integrity_algorithm));
13884   flags = ntohl (mp->entry.flags);
13885   vat_json_object_add_uint (node, "use_esn",
13886                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13887   vat_json_object_add_uint (node, "use_anti_replay",
13888                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13889   vat_json_object_add_uint (node, "is_tunnel",
13890                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13891   vat_json_object_add_uint (node, "is_tunnel_ip6",
13892                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13893   vat_json_object_add_uint (node, "udp_encap",
13894                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13895   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13896                              mp->entry.crypto_key.length);
13897   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13898                              mp->entry.integrity_key.length);
13899   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13900   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13901   vat_json_object_add_uint (node, "replay_window",
13902                             clib_net_to_host_u64 (mp->replay_window));
13903   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13904 }
13905
13906 static int
13907 api_ipsec_sa_dump (vat_main_t * vam)
13908 {
13909   unformat_input_t *i = vam->input;
13910   vl_api_ipsec_sa_dump_t *mp;
13911   vl_api_control_ping_t *mp_ping;
13912   u32 sa_id = ~0;
13913   int ret;
13914
13915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13916     {
13917       if (unformat (i, "sa_id %d", &sa_id))
13918         ;
13919       else
13920         {
13921           clib_warning ("parse error '%U'", format_unformat_error, i);
13922           return -99;
13923         }
13924     }
13925
13926   M (IPSEC_SA_DUMP, mp);
13927
13928   mp->sa_id = ntohl (sa_id);
13929
13930   S (mp);
13931
13932   /* Use a control ping for synchronization */
13933   M (CONTROL_PING, mp_ping);
13934   S (mp_ping);
13935
13936   W (ret);
13937   return ret;
13938 }
13939
13940 static int
13941 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13942 {
13943   unformat_input_t *i = vam->input;
13944   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13945   u32 sw_if_index = ~0;
13946   u32 sa_id = ~0;
13947   u8 is_outbound = (u8) ~ 0;
13948   int ret;
13949
13950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13951     {
13952       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13953         ;
13954       else if (unformat (i, "sa_id %d", &sa_id))
13955         ;
13956       else if (unformat (i, "outbound"))
13957         is_outbound = 1;
13958       else if (unformat (i, "inbound"))
13959         is_outbound = 0;
13960       else
13961         {
13962           clib_warning ("parse error '%U'", format_unformat_error, i);
13963           return -99;
13964         }
13965     }
13966
13967   if (sw_if_index == ~0)
13968     {
13969       errmsg ("interface must be specified");
13970       return -99;
13971     }
13972
13973   if (sa_id == ~0)
13974     {
13975       errmsg ("SA ID must be specified");
13976       return -99;
13977     }
13978
13979   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13980
13981   mp->sw_if_index = htonl (sw_if_index);
13982   mp->sa_id = htonl (sa_id);
13983   mp->is_outbound = is_outbound;
13984
13985   S (mp);
13986   W (ret);
13987
13988   return ret;
13989 }
13990
13991 static int
13992 api_get_first_msg_id (vat_main_t * vam)
13993 {
13994   vl_api_get_first_msg_id_t *mp;
13995   unformat_input_t *i = vam->input;
13996   u8 *name;
13997   u8 name_set = 0;
13998   int ret;
13999
14000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14001     {
14002       if (unformat (i, "client %s", &name))
14003         name_set = 1;
14004       else
14005         break;
14006     }
14007
14008   if (name_set == 0)
14009     {
14010       errmsg ("missing client name");
14011       return -99;
14012     }
14013   vec_add1 (name, 0);
14014
14015   if (vec_len (name) > 63)
14016     {
14017       errmsg ("client name too long");
14018       return -99;
14019     }
14020
14021   M (GET_FIRST_MSG_ID, mp);
14022   clib_memcpy (mp->name, name, vec_len (name));
14023   S (mp);
14024   W (ret);
14025   return ret;
14026 }
14027
14028 static int
14029 api_cop_interface_enable_disable (vat_main_t * vam)
14030 {
14031   unformat_input_t *line_input = vam->input;
14032   vl_api_cop_interface_enable_disable_t *mp;
14033   u32 sw_if_index = ~0;
14034   u8 enable_disable = 1;
14035   int ret;
14036
14037   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14038     {
14039       if (unformat (line_input, "disable"))
14040         enable_disable = 0;
14041       if (unformat (line_input, "enable"))
14042         enable_disable = 1;
14043       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14044                          vam, &sw_if_index))
14045         ;
14046       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14047         ;
14048       else
14049         break;
14050     }
14051
14052   if (sw_if_index == ~0)
14053     {
14054       errmsg ("missing interface name or sw_if_index");
14055       return -99;
14056     }
14057
14058   /* Construct the API message */
14059   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14060   mp->sw_if_index = ntohl (sw_if_index);
14061   mp->enable_disable = enable_disable;
14062
14063   /* send it... */
14064   S (mp);
14065   /* Wait for the reply */
14066   W (ret);
14067   return ret;
14068 }
14069
14070 static int
14071 api_cop_whitelist_enable_disable (vat_main_t * vam)
14072 {
14073   unformat_input_t *line_input = vam->input;
14074   vl_api_cop_whitelist_enable_disable_t *mp;
14075   u32 sw_if_index = ~0;
14076   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14077   u32 fib_id = 0;
14078   int ret;
14079
14080   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat (line_input, "ip4"))
14083         ip4 = 1;
14084       else if (unformat (line_input, "ip6"))
14085         ip6 = 1;
14086       else if (unformat (line_input, "default"))
14087         default_cop = 1;
14088       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14089                          vam, &sw_if_index))
14090         ;
14091       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14092         ;
14093       else if (unformat (line_input, "fib-id %d", &fib_id))
14094         ;
14095       else
14096         break;
14097     }
14098
14099   if (sw_if_index == ~0)
14100     {
14101       errmsg ("missing interface name or sw_if_index");
14102       return -99;
14103     }
14104
14105   /* Construct the API message */
14106   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14107   mp->sw_if_index = ntohl (sw_if_index);
14108   mp->fib_id = ntohl (fib_id);
14109   mp->ip4 = ip4;
14110   mp->ip6 = ip6;
14111   mp->default_cop = default_cop;
14112
14113   /* send it... */
14114   S (mp);
14115   /* Wait for the reply */
14116   W (ret);
14117   return ret;
14118 }
14119
14120 static int
14121 api_get_node_graph (vat_main_t * vam)
14122 {
14123   vl_api_get_node_graph_t *mp;
14124   int ret;
14125
14126   M (GET_NODE_GRAPH, mp);
14127
14128   /* send it... */
14129   S (mp);
14130   /* Wait for the reply */
14131   W (ret);
14132   return ret;
14133 }
14134
14135 /* *INDENT-OFF* */
14136 /** Used for parsing LISP eids */
14137 typedef CLIB_PACKED(struct{
14138   union {
14139           ip46_address_t ip;
14140           mac_address_t mac;
14141           lisp_nsh_api_t nsh;
14142   } addr;
14143   u32 len;       /**< prefix length if IP */
14144   u8 type;      /**< type of eid */
14145 }) lisp_eid_vat_t;
14146 /* *INDENT-ON* */
14147
14148 static uword
14149 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14150 {
14151   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14152
14153   clib_memset (a, 0, sizeof (a[0]));
14154
14155   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14156     {
14157       a->type = 0;              /* ip prefix type */
14158     }
14159   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14160     {
14161       a->type = 1;              /* mac type */
14162     }
14163   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14164     {
14165       a->type = 2;              /* NSH type */
14166       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14167     }
14168   else
14169     {
14170       return 0;
14171     }
14172
14173   if (a->type == 0)
14174     {
14175       if (ip46_address_is_ip4 (&a->addr.ip))
14176         return a->len > 32 ? 1 : 0;
14177       else
14178         return a->len > 128 ? 1 : 0;
14179     }
14180
14181   return 1;
14182 }
14183
14184 static void
14185 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14186 {
14187   eid->type = vat_eid->type;
14188   switch (eid->type)
14189     {
14190     case EID_TYPE_API_PREFIX:
14191       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14192         {
14193           clib_memcpy (&eid->address.prefix.address.un.ip4,
14194                        &vat_eid->addr.ip.ip4, 4);
14195           eid->address.prefix.address.af = ADDRESS_IP4;
14196           eid->address.prefix.len = vat_eid->len;
14197         }
14198       else
14199         {
14200           clib_memcpy (&eid->address.prefix.address.un.ip6,
14201                        &vat_eid->addr.ip.ip6, 16);
14202           eid->address.prefix.address.af = ADDRESS_IP6;
14203           eid->address.prefix.len = vat_eid->len;
14204         }
14205       return;
14206     case EID_TYPE_API_MAC:
14207       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14208                    sizeof (eid->address.mac));
14209       return;
14210     case EID_TYPE_API_NSH:
14211       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14212                    sizeof (eid->address.nsh));
14213       return;
14214     default:
14215       ASSERT (0);
14216       return;
14217     }
14218 }
14219
14220 static int
14221 api_one_add_del_locator_set (vat_main_t * vam)
14222 {
14223   unformat_input_t *input = vam->input;
14224   vl_api_one_add_del_locator_set_t *mp;
14225   u8 is_add = 1;
14226   u8 *locator_set_name = NULL;
14227   u8 locator_set_name_set = 0;
14228   vl_api_local_locator_t locator, *locators = 0;
14229   u32 sw_if_index, priority, weight;
14230   u32 data_len = 0;
14231
14232   int ret;
14233   /* Parse args required to build the message */
14234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14235     {
14236       if (unformat (input, "del"))
14237         {
14238           is_add = 0;
14239         }
14240       else if (unformat (input, "locator-set %s", &locator_set_name))
14241         {
14242           locator_set_name_set = 1;
14243         }
14244       else if (unformat (input, "sw_if_index %u p %u w %u",
14245                          &sw_if_index, &priority, &weight))
14246         {
14247           locator.sw_if_index = htonl (sw_if_index);
14248           locator.priority = priority;
14249           locator.weight = weight;
14250           vec_add1 (locators, locator);
14251         }
14252       else
14253         if (unformat
14254             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14255              &sw_if_index, &priority, &weight))
14256         {
14257           locator.sw_if_index = htonl (sw_if_index);
14258           locator.priority = priority;
14259           locator.weight = weight;
14260           vec_add1 (locators, locator);
14261         }
14262       else
14263         break;
14264     }
14265
14266   if (locator_set_name_set == 0)
14267     {
14268       errmsg ("missing locator-set name");
14269       vec_free (locators);
14270       return -99;
14271     }
14272
14273   if (vec_len (locator_set_name) > 64)
14274     {
14275       errmsg ("locator-set name too long");
14276       vec_free (locator_set_name);
14277       vec_free (locators);
14278       return -99;
14279     }
14280   vec_add1 (locator_set_name, 0);
14281
14282   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14283
14284   /* Construct the API message */
14285   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14286
14287   mp->is_add = is_add;
14288   clib_memcpy (mp->locator_set_name, locator_set_name,
14289                vec_len (locator_set_name));
14290   vec_free (locator_set_name);
14291
14292   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14293   if (locators)
14294     clib_memcpy (mp->locators, locators, data_len);
14295   vec_free (locators);
14296
14297   /* send it... */
14298   S (mp);
14299
14300   /* Wait for a reply... */
14301   W (ret);
14302   return ret;
14303 }
14304
14305 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14306
14307 static int
14308 api_one_add_del_locator (vat_main_t * vam)
14309 {
14310   unformat_input_t *input = vam->input;
14311   vl_api_one_add_del_locator_t *mp;
14312   u32 tmp_if_index = ~0;
14313   u32 sw_if_index = ~0;
14314   u8 sw_if_index_set = 0;
14315   u8 sw_if_index_if_name_set = 0;
14316   u32 priority = ~0;
14317   u8 priority_set = 0;
14318   u32 weight = ~0;
14319   u8 weight_set = 0;
14320   u8 is_add = 1;
14321   u8 *locator_set_name = NULL;
14322   u8 locator_set_name_set = 0;
14323   int ret;
14324
14325   /* Parse args required to build the message */
14326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14327     {
14328       if (unformat (input, "del"))
14329         {
14330           is_add = 0;
14331         }
14332       else if (unformat (input, "locator-set %s", &locator_set_name))
14333         {
14334           locator_set_name_set = 1;
14335         }
14336       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14337                          &tmp_if_index))
14338         {
14339           sw_if_index_if_name_set = 1;
14340           sw_if_index = tmp_if_index;
14341         }
14342       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14343         {
14344           sw_if_index_set = 1;
14345           sw_if_index = tmp_if_index;
14346         }
14347       else if (unformat (input, "p %d", &priority))
14348         {
14349           priority_set = 1;
14350         }
14351       else if (unformat (input, "w %d", &weight))
14352         {
14353           weight_set = 1;
14354         }
14355       else
14356         break;
14357     }
14358
14359   if (locator_set_name_set == 0)
14360     {
14361       errmsg ("missing locator-set name");
14362       return -99;
14363     }
14364
14365   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14366     {
14367       errmsg ("missing sw_if_index");
14368       vec_free (locator_set_name);
14369       return -99;
14370     }
14371
14372   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14373     {
14374       errmsg ("cannot use both params interface name and sw_if_index");
14375       vec_free (locator_set_name);
14376       return -99;
14377     }
14378
14379   if (priority_set == 0)
14380     {
14381       errmsg ("missing locator-set priority");
14382       vec_free (locator_set_name);
14383       return -99;
14384     }
14385
14386   if (weight_set == 0)
14387     {
14388       errmsg ("missing locator-set weight");
14389       vec_free (locator_set_name);
14390       return -99;
14391     }
14392
14393   if (vec_len (locator_set_name) > 64)
14394     {
14395       errmsg ("locator-set name too long");
14396       vec_free (locator_set_name);
14397       return -99;
14398     }
14399   vec_add1 (locator_set_name, 0);
14400
14401   /* Construct the API message */
14402   M (ONE_ADD_DEL_LOCATOR, mp);
14403
14404   mp->is_add = is_add;
14405   mp->sw_if_index = ntohl (sw_if_index);
14406   mp->priority = priority;
14407   mp->weight = weight;
14408   clib_memcpy (mp->locator_set_name, locator_set_name,
14409                vec_len (locator_set_name));
14410   vec_free (locator_set_name);
14411
14412   /* send it... */
14413   S (mp);
14414
14415   /* Wait for a reply... */
14416   W (ret);
14417   return ret;
14418 }
14419
14420 #define api_lisp_add_del_locator api_one_add_del_locator
14421
14422 uword
14423 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14424 {
14425   u32 *key_id = va_arg (*args, u32 *);
14426   u8 *s = 0;
14427
14428   if (unformat (input, "%s", &s))
14429     {
14430       if (!strcmp ((char *) s, "sha1"))
14431         key_id[0] = HMAC_SHA_1_96;
14432       else if (!strcmp ((char *) s, "sha256"))
14433         key_id[0] = HMAC_SHA_256_128;
14434       else
14435         {
14436           clib_warning ("invalid key_id: '%s'", s);
14437           key_id[0] = HMAC_NO_KEY;
14438         }
14439     }
14440   else
14441     return 0;
14442
14443   vec_free (s);
14444   return 1;
14445 }
14446
14447 static int
14448 api_one_add_del_local_eid (vat_main_t * vam)
14449 {
14450   unformat_input_t *input = vam->input;
14451   vl_api_one_add_del_local_eid_t *mp;
14452   u8 is_add = 1;
14453   u8 eid_set = 0;
14454   lisp_eid_vat_t _eid, *eid = &_eid;
14455   u8 *locator_set_name = 0;
14456   u8 locator_set_name_set = 0;
14457   u32 vni = 0;
14458   u16 key_id = 0;
14459   u8 *key = 0;
14460   int ret;
14461
14462   /* Parse args required to build the message */
14463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14464     {
14465       if (unformat (input, "del"))
14466         {
14467           is_add = 0;
14468         }
14469       else if (unformat (input, "vni %d", &vni))
14470         {
14471           ;
14472         }
14473       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14474         {
14475           eid_set = 1;
14476         }
14477       else if (unformat (input, "locator-set %s", &locator_set_name))
14478         {
14479           locator_set_name_set = 1;
14480         }
14481       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14482         ;
14483       else if (unformat (input, "secret-key %_%v%_", &key))
14484         ;
14485       else
14486         break;
14487     }
14488
14489   if (locator_set_name_set == 0)
14490     {
14491       errmsg ("missing locator-set name");
14492       return -99;
14493     }
14494
14495   if (0 == eid_set)
14496     {
14497       errmsg ("EID address not set!");
14498       vec_free (locator_set_name);
14499       return -99;
14500     }
14501
14502   if (key && (0 == key_id))
14503     {
14504       errmsg ("invalid key_id!");
14505       return -99;
14506     }
14507
14508   if (vec_len (key) > 64)
14509     {
14510       errmsg ("key too long");
14511       vec_free (key);
14512       return -99;
14513     }
14514
14515   if (vec_len (locator_set_name) > 64)
14516     {
14517       errmsg ("locator-set name too long");
14518       vec_free (locator_set_name);
14519       return -99;
14520     }
14521   vec_add1 (locator_set_name, 0);
14522
14523   /* Construct the API message */
14524   M (ONE_ADD_DEL_LOCAL_EID, mp);
14525
14526   mp->is_add = is_add;
14527   lisp_eid_put_vat (&mp->eid, eid);
14528   mp->vni = clib_host_to_net_u32 (vni);
14529   mp->key.id = key_id;
14530   clib_memcpy (mp->locator_set_name, locator_set_name,
14531                vec_len (locator_set_name));
14532   clib_memcpy (mp->key.key, key, vec_len (key));
14533
14534   vec_free (locator_set_name);
14535   vec_free (key);
14536
14537   /* send it... */
14538   S (mp);
14539
14540   /* Wait for a reply... */
14541   W (ret);
14542   return ret;
14543 }
14544
14545 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14546
14547 static int
14548 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14549 {
14550   u32 dp_table = 0, vni = 0;;
14551   unformat_input_t *input = vam->input;
14552   vl_api_gpe_add_del_fwd_entry_t *mp;
14553   u8 is_add = 1;
14554   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14555   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14556   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14557   u32 action = ~0, w;
14558   ip4_address_t rmt_rloc4, lcl_rloc4;
14559   ip6_address_t rmt_rloc6, lcl_rloc6;
14560   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14561   int ret;
14562
14563   clib_memset (&rloc, 0, sizeof (rloc));
14564
14565   /* Parse args required to build the message */
14566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14567     {
14568       if (unformat (input, "del"))
14569         is_add = 0;
14570       else if (unformat (input, "add"))
14571         is_add = 1;
14572       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14573         {
14574           rmt_eid_set = 1;
14575         }
14576       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14577         {
14578           lcl_eid_set = 1;
14579         }
14580       else if (unformat (input, "vrf %d", &dp_table))
14581         ;
14582       else if (unformat (input, "bd %d", &dp_table))
14583         ;
14584       else if (unformat (input, "vni %d", &vni))
14585         ;
14586       else if (unformat (input, "w %d", &w))
14587         {
14588           if (!curr_rloc)
14589             {
14590               errmsg ("No RLOC configured for setting priority/weight!");
14591               return -99;
14592             }
14593           curr_rloc->weight = w;
14594         }
14595       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14596                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14597         {
14598           rloc.addr.af = 0;
14599           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14600           rloc.weight = 0;
14601           vec_add1 (lcl_locs, rloc);
14602
14603           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14604           vec_add1 (rmt_locs, rloc);
14605           /* weight saved in rmt loc */
14606           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14607         }
14608       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14609                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14610         {
14611           rloc.addr.af = 1;
14612           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14613           rloc.weight = 0;
14614           vec_add1 (lcl_locs, rloc);
14615
14616           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14617           vec_add1 (rmt_locs, rloc);
14618           /* weight saved in rmt loc */
14619           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14620         }
14621       else if (unformat (input, "action %d", &action))
14622         {
14623           ;
14624         }
14625       else
14626         {
14627           clib_warning ("parse error '%U'", format_unformat_error, input);
14628           return -99;
14629         }
14630     }
14631
14632   if (!rmt_eid_set)
14633     {
14634       errmsg ("remote eid addresses not set");
14635       return -99;
14636     }
14637
14638   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14639     {
14640       errmsg ("eid types don't match");
14641       return -99;
14642     }
14643
14644   if (0 == rmt_locs && (u32) ~ 0 == action)
14645     {
14646       errmsg ("action not set for negative mapping");
14647       return -99;
14648     }
14649
14650   /* Construct the API message */
14651   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14652       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14653
14654   mp->is_add = is_add;
14655   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14656   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14657   mp->dp_table = clib_host_to_net_u32 (dp_table);
14658   mp->vni = clib_host_to_net_u32 (vni);
14659   mp->action = action;
14660
14661   if (0 != rmt_locs && 0 != lcl_locs)
14662     {
14663       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14664       clib_memcpy (mp->locs, lcl_locs,
14665                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14666
14667       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14668       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14669                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14670     }
14671   vec_free (lcl_locs);
14672   vec_free (rmt_locs);
14673
14674   /* send it... */
14675   S (mp);
14676
14677   /* Wait for a reply... */
14678   W (ret);
14679   return ret;
14680 }
14681
14682 static int
14683 api_one_add_del_map_server (vat_main_t * vam)
14684 {
14685   unformat_input_t *input = vam->input;
14686   vl_api_one_add_del_map_server_t *mp;
14687   u8 is_add = 1;
14688   u8 ipv4_set = 0;
14689   u8 ipv6_set = 0;
14690   ip4_address_t ipv4;
14691   ip6_address_t ipv6;
14692   int ret;
14693
14694   /* Parse args required to build the message */
14695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14696     {
14697       if (unformat (input, "del"))
14698         {
14699           is_add = 0;
14700         }
14701       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14702         {
14703           ipv4_set = 1;
14704         }
14705       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14706         {
14707           ipv6_set = 1;
14708         }
14709       else
14710         break;
14711     }
14712
14713   if (ipv4_set && ipv6_set)
14714     {
14715       errmsg ("both eid v4 and v6 addresses set");
14716       return -99;
14717     }
14718
14719   if (!ipv4_set && !ipv6_set)
14720     {
14721       errmsg ("eid addresses not set");
14722       return -99;
14723     }
14724
14725   /* Construct the API message */
14726   M (ONE_ADD_DEL_MAP_SERVER, mp);
14727
14728   mp->is_add = is_add;
14729   if (ipv6_set)
14730     {
14731       mp->ip_address.af = 1;
14732       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14733     }
14734   else
14735     {
14736       mp->ip_address.af = 0;
14737       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14738     }
14739
14740   /* send it... */
14741   S (mp);
14742
14743   /* Wait for a reply... */
14744   W (ret);
14745   return ret;
14746 }
14747
14748 #define api_lisp_add_del_map_server api_one_add_del_map_server
14749
14750 static int
14751 api_one_add_del_map_resolver (vat_main_t * vam)
14752 {
14753   unformat_input_t *input = vam->input;
14754   vl_api_one_add_del_map_resolver_t *mp;
14755   u8 is_add = 1;
14756   u8 ipv4_set = 0;
14757   u8 ipv6_set = 0;
14758   ip4_address_t ipv4;
14759   ip6_address_t ipv6;
14760   int ret;
14761
14762   /* Parse args required to build the message */
14763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14764     {
14765       if (unformat (input, "del"))
14766         {
14767           is_add = 0;
14768         }
14769       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14770         {
14771           ipv4_set = 1;
14772         }
14773       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14774         {
14775           ipv6_set = 1;
14776         }
14777       else
14778         break;
14779     }
14780
14781   if (ipv4_set && ipv6_set)
14782     {
14783       errmsg ("both eid v4 and v6 addresses set");
14784       return -99;
14785     }
14786
14787   if (!ipv4_set && !ipv6_set)
14788     {
14789       errmsg ("eid addresses not set");
14790       return -99;
14791     }
14792
14793   /* Construct the API message */
14794   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14795
14796   mp->is_add = is_add;
14797   if (ipv6_set)
14798     {
14799       mp->ip_address.af = 1;
14800       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14801     }
14802   else
14803     {
14804       mp->ip_address.af = 0;
14805       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14806     }
14807
14808   /* send it... */
14809   S (mp);
14810
14811   /* Wait for a reply... */
14812   W (ret);
14813   return ret;
14814 }
14815
14816 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14817
14818 static int
14819 api_lisp_gpe_enable_disable (vat_main_t * vam)
14820 {
14821   unformat_input_t *input = vam->input;
14822   vl_api_gpe_enable_disable_t *mp;
14823   u8 is_set = 0;
14824   u8 is_enable = 1;
14825   int ret;
14826
14827   /* Parse args required to build the message */
14828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat (input, "enable"))
14831         {
14832           is_set = 1;
14833           is_enable = 1;
14834         }
14835       else if (unformat (input, "disable"))
14836         {
14837           is_set = 1;
14838           is_enable = 0;
14839         }
14840       else
14841         break;
14842     }
14843
14844   if (is_set == 0)
14845     {
14846       errmsg ("Value not set");
14847       return -99;
14848     }
14849
14850   /* Construct the API message */
14851   M (GPE_ENABLE_DISABLE, mp);
14852
14853   mp->is_enable = is_enable;
14854
14855   /* send it... */
14856   S (mp);
14857
14858   /* Wait for a reply... */
14859   W (ret);
14860   return ret;
14861 }
14862
14863 static int
14864 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14865 {
14866   unformat_input_t *input = vam->input;
14867   vl_api_one_rloc_probe_enable_disable_t *mp;
14868   u8 is_set = 0;
14869   u8 is_enable = 0;
14870   int ret;
14871
14872   /* Parse args required to build the message */
14873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14874     {
14875       if (unformat (input, "enable"))
14876         {
14877           is_set = 1;
14878           is_enable = 1;
14879         }
14880       else if (unformat (input, "disable"))
14881         is_set = 1;
14882       else
14883         break;
14884     }
14885
14886   if (!is_set)
14887     {
14888       errmsg ("Value not set");
14889       return -99;
14890     }
14891
14892   /* Construct the API message */
14893   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14894
14895   mp->is_enable = is_enable;
14896
14897   /* send it... */
14898   S (mp);
14899
14900   /* Wait for a reply... */
14901   W (ret);
14902   return ret;
14903 }
14904
14905 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14906
14907 static int
14908 api_one_map_register_enable_disable (vat_main_t * vam)
14909 {
14910   unformat_input_t *input = vam->input;
14911   vl_api_one_map_register_enable_disable_t *mp;
14912   u8 is_set = 0;
14913   u8 is_enable = 0;
14914   int ret;
14915
14916   /* Parse args required to build the message */
14917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14918     {
14919       if (unformat (input, "enable"))
14920         {
14921           is_set = 1;
14922           is_enable = 1;
14923         }
14924       else if (unformat (input, "disable"))
14925         is_set = 1;
14926       else
14927         break;
14928     }
14929
14930   if (!is_set)
14931     {
14932       errmsg ("Value not set");
14933       return -99;
14934     }
14935
14936   /* Construct the API message */
14937   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14938
14939   mp->is_enable = is_enable;
14940
14941   /* send it... */
14942   S (mp);
14943
14944   /* Wait for a reply... */
14945   W (ret);
14946   return ret;
14947 }
14948
14949 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14950
14951 static int
14952 api_one_enable_disable (vat_main_t * vam)
14953 {
14954   unformat_input_t *input = vam->input;
14955   vl_api_one_enable_disable_t *mp;
14956   u8 is_set = 0;
14957   u8 is_enable = 0;
14958   int ret;
14959
14960   /* Parse args required to build the message */
14961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14962     {
14963       if (unformat (input, "enable"))
14964         {
14965           is_set = 1;
14966           is_enable = 1;
14967         }
14968       else if (unformat (input, "disable"))
14969         {
14970           is_set = 1;
14971         }
14972       else
14973         break;
14974     }
14975
14976   if (!is_set)
14977     {
14978       errmsg ("Value not set");
14979       return -99;
14980     }
14981
14982   /* Construct the API message */
14983   M (ONE_ENABLE_DISABLE, mp);
14984
14985   mp->is_enable = is_enable;
14986
14987   /* send it... */
14988   S (mp);
14989
14990   /* Wait for a reply... */
14991   W (ret);
14992   return ret;
14993 }
14994
14995 #define api_lisp_enable_disable api_one_enable_disable
14996
14997 static int
14998 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14999 {
15000   unformat_input_t *input = vam->input;
15001   vl_api_one_enable_disable_xtr_mode_t *mp;
15002   u8 is_set = 0;
15003   u8 is_enable = 0;
15004   int ret;
15005
15006   /* Parse args required to build the message */
15007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15008     {
15009       if (unformat (input, "enable"))
15010         {
15011           is_set = 1;
15012           is_enable = 1;
15013         }
15014       else if (unformat (input, "disable"))
15015         {
15016           is_set = 1;
15017         }
15018       else
15019         break;
15020     }
15021
15022   if (!is_set)
15023     {
15024       errmsg ("Value not set");
15025       return -99;
15026     }
15027
15028   /* Construct the API message */
15029   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15030
15031   mp->is_enable = is_enable;
15032
15033   /* send it... */
15034   S (mp);
15035
15036   /* Wait for a reply... */
15037   W (ret);
15038   return ret;
15039 }
15040
15041 static int
15042 api_one_show_xtr_mode (vat_main_t * vam)
15043 {
15044   vl_api_one_show_xtr_mode_t *mp;
15045   int ret;
15046
15047   /* Construct the API message */
15048   M (ONE_SHOW_XTR_MODE, mp);
15049
15050   /* send it... */
15051   S (mp);
15052
15053   /* Wait for a reply... */
15054   W (ret);
15055   return ret;
15056 }
15057
15058 static int
15059 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15060 {
15061   unformat_input_t *input = vam->input;
15062   vl_api_one_enable_disable_pitr_mode_t *mp;
15063   u8 is_set = 0;
15064   u8 is_enable = 0;
15065   int ret;
15066
15067   /* Parse args required to build the message */
15068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15069     {
15070       if (unformat (input, "enable"))
15071         {
15072           is_set = 1;
15073           is_enable = 1;
15074         }
15075       else if (unformat (input, "disable"))
15076         {
15077           is_set = 1;
15078         }
15079       else
15080         break;
15081     }
15082
15083   if (!is_set)
15084     {
15085       errmsg ("Value not set");
15086       return -99;
15087     }
15088
15089   /* Construct the API message */
15090   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15091
15092   mp->is_enable = is_enable;
15093
15094   /* send it... */
15095   S (mp);
15096
15097   /* Wait for a reply... */
15098   W (ret);
15099   return ret;
15100 }
15101
15102 static int
15103 api_one_show_pitr_mode (vat_main_t * vam)
15104 {
15105   vl_api_one_show_pitr_mode_t *mp;
15106   int ret;
15107
15108   /* Construct the API message */
15109   M (ONE_SHOW_PITR_MODE, mp);
15110
15111   /* send it... */
15112   S (mp);
15113
15114   /* Wait for a reply... */
15115   W (ret);
15116   return ret;
15117 }
15118
15119 static int
15120 api_one_enable_disable_petr_mode (vat_main_t * vam)
15121 {
15122   unformat_input_t *input = vam->input;
15123   vl_api_one_enable_disable_petr_mode_t *mp;
15124   u8 is_set = 0;
15125   u8 is_enable = 0;
15126   int ret;
15127
15128   /* Parse args required to build the message */
15129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15130     {
15131       if (unformat (input, "enable"))
15132         {
15133           is_set = 1;
15134           is_enable = 1;
15135         }
15136       else if (unformat (input, "disable"))
15137         {
15138           is_set = 1;
15139         }
15140       else
15141         break;
15142     }
15143
15144   if (!is_set)
15145     {
15146       errmsg ("Value not set");
15147       return -99;
15148     }
15149
15150   /* Construct the API message */
15151   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15152
15153   mp->is_enable = is_enable;
15154
15155   /* send it... */
15156   S (mp);
15157
15158   /* Wait for a reply... */
15159   W (ret);
15160   return ret;
15161 }
15162
15163 static int
15164 api_one_show_petr_mode (vat_main_t * vam)
15165 {
15166   vl_api_one_show_petr_mode_t *mp;
15167   int ret;
15168
15169   /* Construct the API message */
15170   M (ONE_SHOW_PETR_MODE, mp);
15171
15172   /* send it... */
15173   S (mp);
15174
15175   /* Wait for a reply... */
15176   W (ret);
15177   return ret;
15178 }
15179
15180 static int
15181 api_show_one_map_register_state (vat_main_t * vam)
15182 {
15183   vl_api_show_one_map_register_state_t *mp;
15184   int ret;
15185
15186   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15187
15188   /* send */
15189   S (mp);
15190
15191   /* wait for reply */
15192   W (ret);
15193   return ret;
15194 }
15195
15196 #define api_show_lisp_map_register_state api_show_one_map_register_state
15197
15198 static int
15199 api_show_one_rloc_probe_state (vat_main_t * vam)
15200 {
15201   vl_api_show_one_rloc_probe_state_t *mp;
15202   int ret;
15203
15204   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15205
15206   /* send */
15207   S (mp);
15208
15209   /* wait for reply */
15210   W (ret);
15211   return ret;
15212 }
15213
15214 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15215
15216 static int
15217 api_one_add_del_ndp_entry (vat_main_t * vam)
15218 {
15219   vl_api_one_add_del_ndp_entry_t *mp;
15220   unformat_input_t *input = vam->input;
15221   u8 is_add = 1;
15222   u8 mac_set = 0;
15223   u8 bd_set = 0;
15224   u8 ip_set = 0;
15225   u8 mac[6] = { 0, };
15226   u8 ip6[16] = { 0, };
15227   u32 bd = ~0;
15228   int ret;
15229
15230   /* Parse args required to build the message */
15231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15232     {
15233       if (unformat (input, "del"))
15234         is_add = 0;
15235       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15236         mac_set = 1;
15237       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15238         ip_set = 1;
15239       else if (unformat (input, "bd %d", &bd))
15240         bd_set = 1;
15241       else
15242         {
15243           errmsg ("parse error '%U'", format_unformat_error, input);
15244           return -99;
15245         }
15246     }
15247
15248   if (!bd_set || !ip_set || (!mac_set && is_add))
15249     {
15250       errmsg ("Missing BD, IP or MAC!");
15251       return -99;
15252     }
15253
15254   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15255   mp->is_add = is_add;
15256   clib_memcpy (&mp->entry.mac, mac, 6);
15257   mp->bd = clib_host_to_net_u32 (bd);
15258   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15259
15260   /* send */
15261   S (mp);
15262
15263   /* wait for reply */
15264   W (ret);
15265   return ret;
15266 }
15267
15268 static int
15269 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15270 {
15271   vl_api_one_add_del_l2_arp_entry_t *mp;
15272   unformat_input_t *input = vam->input;
15273   u8 is_add = 1;
15274   u8 mac_set = 0;
15275   u8 bd_set = 0;
15276   u8 ip_set = 0;
15277   u8 mac[6] = { 0, };
15278   u32 ip4 = 0, bd = ~0;
15279   int ret;
15280
15281   /* Parse args required to build the message */
15282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15283     {
15284       if (unformat (input, "del"))
15285         is_add = 0;
15286       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15287         mac_set = 1;
15288       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15289         ip_set = 1;
15290       else if (unformat (input, "bd %d", &bd))
15291         bd_set = 1;
15292       else
15293         {
15294           errmsg ("parse error '%U'", format_unformat_error, input);
15295           return -99;
15296         }
15297     }
15298
15299   if (!bd_set || !ip_set || (!mac_set && is_add))
15300     {
15301       errmsg ("Missing BD, IP or MAC!");
15302       return -99;
15303     }
15304
15305   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15306   mp->is_add = is_add;
15307   clib_memcpy (&mp->entry.mac, mac, 6);
15308   mp->bd = clib_host_to_net_u32 (bd);
15309   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15310
15311   /* send */
15312   S (mp);
15313
15314   /* wait for reply */
15315   W (ret);
15316   return ret;
15317 }
15318
15319 static int
15320 api_one_ndp_bd_get (vat_main_t * vam)
15321 {
15322   vl_api_one_ndp_bd_get_t *mp;
15323   int ret;
15324
15325   M (ONE_NDP_BD_GET, mp);
15326
15327   /* send */
15328   S (mp);
15329
15330   /* wait for reply */
15331   W (ret);
15332   return ret;
15333 }
15334
15335 static int
15336 api_one_ndp_entries_get (vat_main_t * vam)
15337 {
15338   vl_api_one_ndp_entries_get_t *mp;
15339   unformat_input_t *input = vam->input;
15340   u8 bd_set = 0;
15341   u32 bd = ~0;
15342   int ret;
15343
15344   /* Parse args required to build the message */
15345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15346     {
15347       if (unformat (input, "bd %d", &bd))
15348         bd_set = 1;
15349       else
15350         {
15351           errmsg ("parse error '%U'", format_unformat_error, input);
15352           return -99;
15353         }
15354     }
15355
15356   if (!bd_set)
15357     {
15358       errmsg ("Expected bridge domain!");
15359       return -99;
15360     }
15361
15362   M (ONE_NDP_ENTRIES_GET, mp);
15363   mp->bd = clib_host_to_net_u32 (bd);
15364
15365   /* send */
15366   S (mp);
15367
15368   /* wait for reply */
15369   W (ret);
15370   return ret;
15371 }
15372
15373 static int
15374 api_one_l2_arp_bd_get (vat_main_t * vam)
15375 {
15376   vl_api_one_l2_arp_bd_get_t *mp;
15377   int ret;
15378
15379   M (ONE_L2_ARP_BD_GET, mp);
15380
15381   /* send */
15382   S (mp);
15383
15384   /* wait for reply */
15385   W (ret);
15386   return ret;
15387 }
15388
15389 static int
15390 api_one_l2_arp_entries_get (vat_main_t * vam)
15391 {
15392   vl_api_one_l2_arp_entries_get_t *mp;
15393   unformat_input_t *input = vam->input;
15394   u8 bd_set = 0;
15395   u32 bd = ~0;
15396   int ret;
15397
15398   /* Parse args required to build the message */
15399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15400     {
15401       if (unformat (input, "bd %d", &bd))
15402         bd_set = 1;
15403       else
15404         {
15405           errmsg ("parse error '%U'", format_unformat_error, input);
15406           return -99;
15407         }
15408     }
15409
15410   if (!bd_set)
15411     {
15412       errmsg ("Expected bridge domain!");
15413       return -99;
15414     }
15415
15416   M (ONE_L2_ARP_ENTRIES_GET, mp);
15417   mp->bd = clib_host_to_net_u32 (bd);
15418
15419   /* send */
15420   S (mp);
15421
15422   /* wait for reply */
15423   W (ret);
15424   return ret;
15425 }
15426
15427 static int
15428 api_one_stats_enable_disable (vat_main_t * vam)
15429 {
15430   vl_api_one_stats_enable_disable_t *mp;
15431   unformat_input_t *input = vam->input;
15432   u8 is_set = 0;
15433   u8 is_enable = 0;
15434   int ret;
15435
15436   /* Parse args required to build the message */
15437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15438     {
15439       if (unformat (input, "enable"))
15440         {
15441           is_set = 1;
15442           is_enable = 1;
15443         }
15444       else if (unformat (input, "disable"))
15445         {
15446           is_set = 1;
15447         }
15448       else
15449         break;
15450     }
15451
15452   if (!is_set)
15453     {
15454       errmsg ("Value not set");
15455       return -99;
15456     }
15457
15458   M (ONE_STATS_ENABLE_DISABLE, mp);
15459   mp->is_enable = is_enable;
15460
15461   /* send */
15462   S (mp);
15463
15464   /* wait for reply */
15465   W (ret);
15466   return ret;
15467 }
15468
15469 static int
15470 api_show_one_stats_enable_disable (vat_main_t * vam)
15471 {
15472   vl_api_show_one_stats_enable_disable_t *mp;
15473   int ret;
15474
15475   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15476
15477   /* send */
15478   S (mp);
15479
15480   /* wait for reply */
15481   W (ret);
15482   return ret;
15483 }
15484
15485 static int
15486 api_show_one_map_request_mode (vat_main_t * vam)
15487 {
15488   vl_api_show_one_map_request_mode_t *mp;
15489   int ret;
15490
15491   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15492
15493   /* send */
15494   S (mp);
15495
15496   /* wait for reply */
15497   W (ret);
15498   return ret;
15499 }
15500
15501 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15502
15503 static int
15504 api_one_map_request_mode (vat_main_t * vam)
15505 {
15506   unformat_input_t *input = vam->input;
15507   vl_api_one_map_request_mode_t *mp;
15508   u8 mode = 0;
15509   int ret;
15510
15511   /* Parse args required to build the message */
15512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15513     {
15514       if (unformat (input, "dst-only"))
15515         mode = 0;
15516       else if (unformat (input, "src-dst"))
15517         mode = 1;
15518       else
15519         {
15520           errmsg ("parse error '%U'", format_unformat_error, input);
15521           return -99;
15522         }
15523     }
15524
15525   M (ONE_MAP_REQUEST_MODE, mp);
15526
15527   mp->mode = mode;
15528
15529   /* send */
15530   S (mp);
15531
15532   /* wait for reply */
15533   W (ret);
15534   return ret;
15535 }
15536
15537 #define api_lisp_map_request_mode api_one_map_request_mode
15538
15539 /**
15540  * Enable/disable ONE proxy ITR.
15541  *
15542  * @param vam vpp API test context
15543  * @return return code
15544  */
15545 static int
15546 api_one_pitr_set_locator_set (vat_main_t * vam)
15547 {
15548   u8 ls_name_set = 0;
15549   unformat_input_t *input = vam->input;
15550   vl_api_one_pitr_set_locator_set_t *mp;
15551   u8 is_add = 1;
15552   u8 *ls_name = 0;
15553   int ret;
15554
15555   /* Parse args required to build the message */
15556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15557     {
15558       if (unformat (input, "del"))
15559         is_add = 0;
15560       else if (unformat (input, "locator-set %s", &ls_name))
15561         ls_name_set = 1;
15562       else
15563         {
15564           errmsg ("parse error '%U'", format_unformat_error, input);
15565           return -99;
15566         }
15567     }
15568
15569   if (!ls_name_set)
15570     {
15571       errmsg ("locator-set name not set!");
15572       return -99;
15573     }
15574
15575   M (ONE_PITR_SET_LOCATOR_SET, mp);
15576
15577   mp->is_add = is_add;
15578   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15579   vec_free (ls_name);
15580
15581   /* send */
15582   S (mp);
15583
15584   /* wait for reply */
15585   W (ret);
15586   return ret;
15587 }
15588
15589 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15590
15591 static int
15592 api_one_nsh_set_locator_set (vat_main_t * vam)
15593 {
15594   u8 ls_name_set = 0;
15595   unformat_input_t *input = vam->input;
15596   vl_api_one_nsh_set_locator_set_t *mp;
15597   u8 is_add = 1;
15598   u8 *ls_name = 0;
15599   int ret;
15600
15601   /* Parse args required to build the message */
15602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15603     {
15604       if (unformat (input, "del"))
15605         is_add = 0;
15606       else if (unformat (input, "ls %s", &ls_name))
15607         ls_name_set = 1;
15608       else
15609         {
15610           errmsg ("parse error '%U'", format_unformat_error, input);
15611           return -99;
15612         }
15613     }
15614
15615   if (!ls_name_set && is_add)
15616     {
15617       errmsg ("locator-set name not set!");
15618       return -99;
15619     }
15620
15621   M (ONE_NSH_SET_LOCATOR_SET, mp);
15622
15623   mp->is_add = is_add;
15624   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15625   vec_free (ls_name);
15626
15627   /* send */
15628   S (mp);
15629
15630   /* wait for reply */
15631   W (ret);
15632   return ret;
15633 }
15634
15635 static int
15636 api_show_one_pitr (vat_main_t * vam)
15637 {
15638   vl_api_show_one_pitr_t *mp;
15639   int ret;
15640
15641   if (!vam->json_output)
15642     {
15643       print (vam->ofp, "%=20s", "lisp status:");
15644     }
15645
15646   M (SHOW_ONE_PITR, mp);
15647   /* send it... */
15648   S (mp);
15649
15650   /* Wait for a reply... */
15651   W (ret);
15652   return ret;
15653 }
15654
15655 #define api_show_lisp_pitr api_show_one_pitr
15656
15657 static int
15658 api_one_use_petr (vat_main_t * vam)
15659 {
15660   unformat_input_t *input = vam->input;
15661   vl_api_one_use_petr_t *mp;
15662   u8 is_add = 0;
15663   ip_address_t ip;
15664   int ret;
15665
15666   clib_memset (&ip, 0, sizeof (ip));
15667
15668   /* Parse args required to build the message */
15669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (input, "disable"))
15672         is_add = 0;
15673       else
15674         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15675         {
15676           is_add = 1;
15677           ip_addr_version (&ip) = AF_IP4;
15678         }
15679       else
15680         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15681         {
15682           is_add = 1;
15683           ip_addr_version (&ip) = AF_IP6;
15684         }
15685       else
15686         {
15687           errmsg ("parse error '%U'", format_unformat_error, input);
15688           return -99;
15689         }
15690     }
15691
15692   M (ONE_USE_PETR, mp);
15693
15694   mp->is_add = is_add;
15695   if (is_add)
15696     {
15697       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15698       if (mp->ip_address.af)
15699         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15700       else
15701         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15702     }
15703
15704   /* send */
15705   S (mp);
15706
15707   /* wait for reply */
15708   W (ret);
15709   return ret;
15710 }
15711
15712 #define api_lisp_use_petr api_one_use_petr
15713
15714 static int
15715 api_show_one_nsh_mapping (vat_main_t * vam)
15716 {
15717   vl_api_show_one_use_petr_t *mp;
15718   int ret;
15719
15720   if (!vam->json_output)
15721     {
15722       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15723     }
15724
15725   M (SHOW_ONE_NSH_MAPPING, mp);
15726   /* send it... */
15727   S (mp);
15728
15729   /* Wait for a reply... */
15730   W (ret);
15731   return ret;
15732 }
15733
15734 static int
15735 api_show_one_use_petr (vat_main_t * vam)
15736 {
15737   vl_api_show_one_use_petr_t *mp;
15738   int ret;
15739
15740   if (!vam->json_output)
15741     {
15742       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15743     }
15744
15745   M (SHOW_ONE_USE_PETR, mp);
15746   /* send it... */
15747   S (mp);
15748
15749   /* Wait for a reply... */
15750   W (ret);
15751   return ret;
15752 }
15753
15754 #define api_show_lisp_use_petr api_show_one_use_petr
15755
15756 /**
15757  * Add/delete mapping between vni and vrf
15758  */
15759 static int
15760 api_one_eid_table_add_del_map (vat_main_t * vam)
15761 {
15762   unformat_input_t *input = vam->input;
15763   vl_api_one_eid_table_add_del_map_t *mp;
15764   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15765   u32 vni, vrf, bd_index;
15766   int ret;
15767
15768   /* Parse args required to build the message */
15769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15770     {
15771       if (unformat (input, "del"))
15772         is_add = 0;
15773       else if (unformat (input, "vrf %d", &vrf))
15774         vrf_set = 1;
15775       else if (unformat (input, "bd_index %d", &bd_index))
15776         bd_index_set = 1;
15777       else if (unformat (input, "vni %d", &vni))
15778         vni_set = 1;
15779       else
15780         break;
15781     }
15782
15783   if (!vni_set || (!vrf_set && !bd_index_set))
15784     {
15785       errmsg ("missing arguments!");
15786       return -99;
15787     }
15788
15789   if (vrf_set && bd_index_set)
15790     {
15791       errmsg ("error: both vrf and bd entered!");
15792       return -99;
15793     }
15794
15795   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15796
15797   mp->is_add = is_add;
15798   mp->vni = htonl (vni);
15799   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15800   mp->is_l2 = bd_index_set;
15801
15802   /* send */
15803   S (mp);
15804
15805   /* wait for reply */
15806   W (ret);
15807   return ret;
15808 }
15809
15810 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15811
15812 uword
15813 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15814 {
15815   u32 *action = va_arg (*args, u32 *);
15816   u8 *s = 0;
15817
15818   if (unformat (input, "%s", &s))
15819     {
15820       if (!strcmp ((char *) s, "no-action"))
15821         action[0] = 0;
15822       else if (!strcmp ((char *) s, "natively-forward"))
15823         action[0] = 1;
15824       else if (!strcmp ((char *) s, "send-map-request"))
15825         action[0] = 2;
15826       else if (!strcmp ((char *) s, "drop"))
15827         action[0] = 3;
15828       else
15829         {
15830           clib_warning ("invalid action: '%s'", s);
15831           action[0] = 3;
15832         }
15833     }
15834   else
15835     return 0;
15836
15837   vec_free (s);
15838   return 1;
15839 }
15840
15841 /**
15842  * Add/del remote mapping to/from ONE control plane
15843  *
15844  * @param vam vpp API test context
15845  * @return return code
15846  */
15847 static int
15848 api_one_add_del_remote_mapping (vat_main_t * vam)
15849 {
15850   unformat_input_t *input = vam->input;
15851   vl_api_one_add_del_remote_mapping_t *mp;
15852   u32 vni = 0;
15853   lisp_eid_vat_t _eid, *eid = &_eid;
15854   lisp_eid_vat_t _seid, *seid = &_seid;
15855   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15856   u32 action = ~0, p, w, data_len;
15857   ip4_address_t rloc4;
15858   ip6_address_t rloc6;
15859   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15860   int ret;
15861
15862   clib_memset (&rloc, 0, sizeof (rloc));
15863
15864   /* Parse args required to build the message */
15865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15866     {
15867       if (unformat (input, "del-all"))
15868         {
15869           del_all = 1;
15870         }
15871       else if (unformat (input, "del"))
15872         {
15873           is_add = 0;
15874         }
15875       else if (unformat (input, "add"))
15876         {
15877           is_add = 1;
15878         }
15879       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15880         {
15881           eid_set = 1;
15882         }
15883       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15884         {
15885           seid_set = 1;
15886         }
15887       else if (unformat (input, "vni %d", &vni))
15888         {
15889           ;
15890         }
15891       else if (unformat (input, "p %d w %d", &p, &w))
15892         {
15893           if (!curr_rloc)
15894             {
15895               errmsg ("No RLOC configured for setting priority/weight!");
15896               return -99;
15897             }
15898           curr_rloc->priority = p;
15899           curr_rloc->weight = w;
15900         }
15901       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15902         {
15903           rloc.ip_address.af = 0;
15904           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15905           vec_add1 (rlocs, rloc);
15906           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15907         }
15908       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15909         {
15910           rloc.ip_address.af = 1;
15911           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15912           vec_add1 (rlocs, rloc);
15913           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15914         }
15915       else if (unformat (input, "action %U",
15916                          unformat_negative_mapping_action, &action))
15917         {
15918           ;
15919         }
15920       else
15921         {
15922           clib_warning ("parse error '%U'", format_unformat_error, input);
15923           return -99;
15924         }
15925     }
15926
15927   if (0 == eid_set)
15928     {
15929       errmsg ("missing params!");
15930       return -99;
15931     }
15932
15933   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15934     {
15935       errmsg ("no action set for negative map-reply!");
15936       return -99;
15937     }
15938
15939   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15940
15941   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15942   mp->is_add = is_add;
15943   mp->vni = htonl (vni);
15944   mp->action = (u8) action;
15945   mp->is_src_dst = seid_set;
15946   mp->del_all = del_all;
15947   lisp_eid_put_vat (&mp->deid, eid);
15948   lisp_eid_put_vat (&mp->seid, seid);
15949
15950   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15951   clib_memcpy (mp->rlocs, rlocs, data_len);
15952   vec_free (rlocs);
15953
15954   /* send it... */
15955   S (mp);
15956
15957   /* Wait for a reply... */
15958   W (ret);
15959   return ret;
15960 }
15961
15962 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15963
15964 /**
15965  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15966  * forwarding entries in data-plane accordingly.
15967  *
15968  * @param vam vpp API test context
15969  * @return return code
15970  */
15971 static int
15972 api_one_add_del_adjacency (vat_main_t * vam)
15973 {
15974   unformat_input_t *input = vam->input;
15975   vl_api_one_add_del_adjacency_t *mp;
15976   u32 vni = 0;
15977   u8 is_add = 1;
15978   int ret;
15979   lisp_eid_vat_t leid, reid;
15980
15981   leid.type = reid.type = (u8) ~ 0;
15982
15983   /* Parse args required to build the message */
15984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15985     {
15986       if (unformat (input, "del"))
15987         {
15988           is_add = 0;
15989         }
15990       else if (unformat (input, "add"))
15991         {
15992           is_add = 1;
15993         }
15994       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15995                          &reid.addr.ip, &reid.len))
15996         {
15997           reid.type = 0;        /* ipv4 */
15998         }
15999       else if (unformat (input, "reid %U", unformat_ethernet_address,
16000                          &reid.addr.mac))
16001         {
16002           reid.type = 1;        /* mac */
16003         }
16004       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
16005                          &leid.addr.ip, &leid.len))
16006         {
16007           leid.type = 0;        /* ipv4 */
16008         }
16009       else if (unformat (input, "leid %U", unformat_ethernet_address,
16010                          &leid.addr.mac))
16011         {
16012           leid.type = 1;        /* mac */
16013         }
16014       else if (unformat (input, "vni %d", &vni))
16015         {
16016           ;
16017         }
16018       else
16019         {
16020           errmsg ("parse error '%U'", format_unformat_error, input);
16021           return -99;
16022         }
16023     }
16024
16025   if ((u8) ~ 0 == reid.type)
16026     {
16027       errmsg ("missing params!");
16028       return -99;
16029     }
16030
16031   if (leid.type != reid.type)
16032     {
16033       errmsg ("remote and local EIDs are of different types!");
16034       return -99;
16035     }
16036
16037   M (ONE_ADD_DEL_ADJACENCY, mp);
16038   mp->is_add = is_add;
16039   mp->vni = htonl (vni);
16040   lisp_eid_put_vat (&mp->leid, &leid);
16041   lisp_eid_put_vat (&mp->reid, &reid);
16042
16043   /* send it... */
16044   S (mp);
16045
16046   /* Wait for a reply... */
16047   W (ret);
16048   return ret;
16049 }
16050
16051 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16052
16053 uword
16054 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16055 {
16056   u32 *mode = va_arg (*args, u32 *);
16057
16058   if (unformat (input, "lisp"))
16059     *mode = 0;
16060   else if (unformat (input, "vxlan"))
16061     *mode = 1;
16062   else
16063     return 0;
16064
16065   return 1;
16066 }
16067
16068 static int
16069 api_gpe_get_encap_mode (vat_main_t * vam)
16070 {
16071   vl_api_gpe_get_encap_mode_t *mp;
16072   int ret;
16073
16074   /* Construct the API message */
16075   M (GPE_GET_ENCAP_MODE, mp);
16076
16077   /* send it... */
16078   S (mp);
16079
16080   /* Wait for a reply... */
16081   W (ret);
16082   return ret;
16083 }
16084
16085 static int
16086 api_gpe_set_encap_mode (vat_main_t * vam)
16087 {
16088   unformat_input_t *input = vam->input;
16089   vl_api_gpe_set_encap_mode_t *mp;
16090   int ret;
16091   u32 mode = 0;
16092
16093   /* Parse args required to build the message */
16094   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16095     {
16096       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16097         ;
16098       else
16099         break;
16100     }
16101
16102   /* Construct the API message */
16103   M (GPE_SET_ENCAP_MODE, mp);
16104
16105   mp->is_vxlan = mode;
16106
16107   /* send it... */
16108   S (mp);
16109
16110   /* Wait for a reply... */
16111   W (ret);
16112   return ret;
16113 }
16114
16115 static int
16116 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16117 {
16118   unformat_input_t *input = vam->input;
16119   vl_api_gpe_add_del_iface_t *mp;
16120   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16121   u32 dp_table = 0, vni = 0;
16122   int ret;
16123
16124   /* Parse args required to build the message */
16125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16126     {
16127       if (unformat (input, "up"))
16128         {
16129           action_set = 1;
16130           is_add = 1;
16131         }
16132       else if (unformat (input, "down"))
16133         {
16134           action_set = 1;
16135           is_add = 0;
16136         }
16137       else if (unformat (input, "table_id %d", &dp_table))
16138         {
16139           dp_table_set = 1;
16140         }
16141       else if (unformat (input, "bd_id %d", &dp_table))
16142         {
16143           dp_table_set = 1;
16144           is_l2 = 1;
16145         }
16146       else if (unformat (input, "vni %d", &vni))
16147         {
16148           vni_set = 1;
16149         }
16150       else
16151         break;
16152     }
16153
16154   if (action_set == 0)
16155     {
16156       errmsg ("Action not set");
16157       return -99;
16158     }
16159   if (dp_table_set == 0 || vni_set == 0)
16160     {
16161       errmsg ("vni and dp_table must be set");
16162       return -99;
16163     }
16164
16165   /* Construct the API message */
16166   M (GPE_ADD_DEL_IFACE, mp);
16167
16168   mp->is_add = is_add;
16169   mp->dp_table = clib_host_to_net_u32 (dp_table);
16170   mp->is_l2 = is_l2;
16171   mp->vni = clib_host_to_net_u32 (vni);
16172
16173   /* send it... */
16174   S (mp);
16175
16176   /* Wait for a reply... */
16177   W (ret);
16178   return ret;
16179 }
16180
16181 static int
16182 api_one_map_register_fallback_threshold (vat_main_t * vam)
16183 {
16184   unformat_input_t *input = vam->input;
16185   vl_api_one_map_register_fallback_threshold_t *mp;
16186   u32 value = 0;
16187   u8 is_set = 0;
16188   int ret;
16189
16190   /* Parse args required to build the message */
16191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16192     {
16193       if (unformat (input, "%u", &value))
16194         is_set = 1;
16195       else
16196         {
16197           clib_warning ("parse error '%U'", format_unformat_error, input);
16198           return -99;
16199         }
16200     }
16201
16202   if (!is_set)
16203     {
16204       errmsg ("fallback threshold value is missing!");
16205       return -99;
16206     }
16207
16208   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16209   mp->value = clib_host_to_net_u32 (value);
16210
16211   /* send it... */
16212   S (mp);
16213
16214   /* Wait for a reply... */
16215   W (ret);
16216   return ret;
16217 }
16218
16219 static int
16220 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16221 {
16222   vl_api_show_one_map_register_fallback_threshold_t *mp;
16223   int ret;
16224
16225   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16226
16227   /* send it... */
16228   S (mp);
16229
16230   /* Wait for a reply... */
16231   W (ret);
16232   return ret;
16233 }
16234
16235 uword
16236 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16237 {
16238   u32 *proto = va_arg (*args, u32 *);
16239
16240   if (unformat (input, "udp"))
16241     *proto = 1;
16242   else if (unformat (input, "api"))
16243     *proto = 2;
16244   else
16245     return 0;
16246
16247   return 1;
16248 }
16249
16250 static int
16251 api_one_set_transport_protocol (vat_main_t * vam)
16252 {
16253   unformat_input_t *input = vam->input;
16254   vl_api_one_set_transport_protocol_t *mp;
16255   u8 is_set = 0;
16256   u32 protocol = 0;
16257   int ret;
16258
16259   /* Parse args required to build the message */
16260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16261     {
16262       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16263         is_set = 1;
16264       else
16265         {
16266           clib_warning ("parse error '%U'", format_unformat_error, input);
16267           return -99;
16268         }
16269     }
16270
16271   if (!is_set)
16272     {
16273       errmsg ("Transport protocol missing!");
16274       return -99;
16275     }
16276
16277   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16278   mp->protocol = (u8) protocol;
16279
16280   /* send it... */
16281   S (mp);
16282
16283   /* Wait for a reply... */
16284   W (ret);
16285   return ret;
16286 }
16287
16288 static int
16289 api_one_get_transport_protocol (vat_main_t * vam)
16290 {
16291   vl_api_one_get_transport_protocol_t *mp;
16292   int ret;
16293
16294   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16295
16296   /* send it... */
16297   S (mp);
16298
16299   /* Wait for a reply... */
16300   W (ret);
16301   return ret;
16302 }
16303
16304 static int
16305 api_one_map_register_set_ttl (vat_main_t * vam)
16306 {
16307   unformat_input_t *input = vam->input;
16308   vl_api_one_map_register_set_ttl_t *mp;
16309   u32 ttl = 0;
16310   u8 is_set = 0;
16311   int ret;
16312
16313   /* Parse args required to build the message */
16314   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16315     {
16316       if (unformat (input, "%u", &ttl))
16317         is_set = 1;
16318       else
16319         {
16320           clib_warning ("parse error '%U'", format_unformat_error, input);
16321           return -99;
16322         }
16323     }
16324
16325   if (!is_set)
16326     {
16327       errmsg ("TTL value missing!");
16328       return -99;
16329     }
16330
16331   M (ONE_MAP_REGISTER_SET_TTL, mp);
16332   mp->ttl = clib_host_to_net_u32 (ttl);
16333
16334   /* send it... */
16335   S (mp);
16336
16337   /* Wait for a reply... */
16338   W (ret);
16339   return ret;
16340 }
16341
16342 static int
16343 api_show_one_map_register_ttl (vat_main_t * vam)
16344 {
16345   vl_api_show_one_map_register_ttl_t *mp;
16346   int ret;
16347
16348   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16349
16350   /* send it... */
16351   S (mp);
16352
16353   /* Wait for a reply... */
16354   W (ret);
16355   return ret;
16356 }
16357
16358 /**
16359  * Add/del map request itr rlocs from ONE control plane and updates
16360  *
16361  * @param vam vpp API test context
16362  * @return return code
16363  */
16364 static int
16365 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16366 {
16367   unformat_input_t *input = vam->input;
16368   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16369   u8 *locator_set_name = 0;
16370   u8 locator_set_name_set = 0;
16371   u8 is_add = 1;
16372   int ret;
16373
16374   /* Parse args required to build the message */
16375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16376     {
16377       if (unformat (input, "del"))
16378         {
16379           is_add = 0;
16380         }
16381       else if (unformat (input, "%_%v%_", &locator_set_name))
16382         {
16383           locator_set_name_set = 1;
16384         }
16385       else
16386         {
16387           clib_warning ("parse error '%U'", format_unformat_error, input);
16388           return -99;
16389         }
16390     }
16391
16392   if (is_add && !locator_set_name_set)
16393     {
16394       errmsg ("itr-rloc is not set!");
16395       return -99;
16396     }
16397
16398   if (is_add && vec_len (locator_set_name) > 64)
16399     {
16400       errmsg ("itr-rloc locator-set name too long");
16401       vec_free (locator_set_name);
16402       return -99;
16403     }
16404
16405   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16406   mp->is_add = is_add;
16407   if (is_add)
16408     {
16409       clib_memcpy (mp->locator_set_name, locator_set_name,
16410                    vec_len (locator_set_name));
16411     }
16412   else
16413     {
16414       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16415     }
16416   vec_free (locator_set_name);
16417
16418   /* send it... */
16419   S (mp);
16420
16421   /* Wait for a reply... */
16422   W (ret);
16423   return ret;
16424 }
16425
16426 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16427
16428 static int
16429 api_one_locator_dump (vat_main_t * vam)
16430 {
16431   unformat_input_t *input = vam->input;
16432   vl_api_one_locator_dump_t *mp;
16433   vl_api_control_ping_t *mp_ping;
16434   u8 is_index_set = 0, is_name_set = 0;
16435   u8 *ls_name = 0;
16436   u32 ls_index = ~0;
16437   int ret;
16438
16439   /* Parse args required to build the message */
16440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16441     {
16442       if (unformat (input, "ls_name %_%v%_", &ls_name))
16443         {
16444           is_name_set = 1;
16445         }
16446       else if (unformat (input, "ls_index %d", &ls_index))
16447         {
16448           is_index_set = 1;
16449         }
16450       else
16451         {
16452           errmsg ("parse error '%U'", format_unformat_error, input);
16453           return -99;
16454         }
16455     }
16456
16457   if (!is_index_set && !is_name_set)
16458     {
16459       errmsg ("error: expected one of index or name!");
16460       return -99;
16461     }
16462
16463   if (is_index_set && is_name_set)
16464     {
16465       errmsg ("error: only one param expected!");
16466       return -99;
16467     }
16468
16469   if (vec_len (ls_name) > 62)
16470     {
16471       errmsg ("error: locator set name too long!");
16472       return -99;
16473     }
16474
16475   if (!vam->json_output)
16476     {
16477       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16478     }
16479
16480   M (ONE_LOCATOR_DUMP, mp);
16481   mp->is_index_set = is_index_set;
16482
16483   if (is_index_set)
16484     mp->ls_index = clib_host_to_net_u32 (ls_index);
16485   else
16486     {
16487       vec_add1 (ls_name, 0);
16488       strncpy ((char *) mp->ls_name, (char *) ls_name,
16489                sizeof (mp->ls_name) - 1);
16490     }
16491
16492   /* send it... */
16493   S (mp);
16494
16495   /* Use a control ping for synchronization */
16496   MPING (CONTROL_PING, mp_ping);
16497   S (mp_ping);
16498
16499   /* Wait for a reply... */
16500   W (ret);
16501   return ret;
16502 }
16503
16504 #define api_lisp_locator_dump api_one_locator_dump
16505
16506 static int
16507 api_one_locator_set_dump (vat_main_t * vam)
16508 {
16509   vl_api_one_locator_set_dump_t *mp;
16510   vl_api_control_ping_t *mp_ping;
16511   unformat_input_t *input = vam->input;
16512   u8 filter = 0;
16513   int ret;
16514
16515   /* Parse args required to build the message */
16516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16517     {
16518       if (unformat (input, "local"))
16519         {
16520           filter = 1;
16521         }
16522       else if (unformat (input, "remote"))
16523         {
16524           filter = 2;
16525         }
16526       else
16527         {
16528           errmsg ("parse error '%U'", format_unformat_error, input);
16529           return -99;
16530         }
16531     }
16532
16533   if (!vam->json_output)
16534     {
16535       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16536     }
16537
16538   M (ONE_LOCATOR_SET_DUMP, mp);
16539
16540   mp->filter = filter;
16541
16542   /* send it... */
16543   S (mp);
16544
16545   /* Use a control ping for synchronization */
16546   MPING (CONTROL_PING, mp_ping);
16547   S (mp_ping);
16548
16549   /* Wait for a reply... */
16550   W (ret);
16551   return ret;
16552 }
16553
16554 #define api_lisp_locator_set_dump api_one_locator_set_dump
16555
16556 static int
16557 api_one_eid_table_map_dump (vat_main_t * vam)
16558 {
16559   u8 is_l2 = 0;
16560   u8 mode_set = 0;
16561   unformat_input_t *input = vam->input;
16562   vl_api_one_eid_table_map_dump_t *mp;
16563   vl_api_control_ping_t *mp_ping;
16564   int ret;
16565
16566   /* Parse args required to build the message */
16567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16568     {
16569       if (unformat (input, "l2"))
16570         {
16571           is_l2 = 1;
16572           mode_set = 1;
16573         }
16574       else if (unformat (input, "l3"))
16575         {
16576           is_l2 = 0;
16577           mode_set = 1;
16578         }
16579       else
16580         {
16581           errmsg ("parse error '%U'", format_unformat_error, input);
16582           return -99;
16583         }
16584     }
16585
16586   if (!mode_set)
16587     {
16588       errmsg ("expected one of 'l2' or 'l3' parameter!");
16589       return -99;
16590     }
16591
16592   if (!vam->json_output)
16593     {
16594       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16595     }
16596
16597   M (ONE_EID_TABLE_MAP_DUMP, mp);
16598   mp->is_l2 = is_l2;
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_map_dump api_one_eid_table_map_dump
16613
16614 static int
16615 api_one_eid_table_vni_dump (vat_main_t * vam)
16616 {
16617   vl_api_one_eid_table_vni_dump_t *mp;
16618   vl_api_control_ping_t *mp_ping;
16619   int ret;
16620
16621   if (!vam->json_output)
16622     {
16623       print (vam->ofp, "VNI");
16624     }
16625
16626   M (ONE_EID_TABLE_VNI_DUMP, mp);
16627
16628   /* send it... */
16629   S (mp);
16630
16631   /* Use a control ping for synchronization */
16632   MPING (CONTROL_PING, mp_ping);
16633   S (mp_ping);
16634
16635   /* Wait for a reply... */
16636   W (ret);
16637   return ret;
16638 }
16639
16640 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16641
16642 static int
16643 api_one_eid_table_dump (vat_main_t * vam)
16644 {
16645   unformat_input_t *i = vam->input;
16646   vl_api_one_eid_table_dump_t *mp;
16647   vl_api_control_ping_t *mp_ping;
16648   u8 filter = 0;
16649   int ret;
16650   u32 vni, t = 0;
16651   lisp_eid_vat_t eid;
16652   u8 eid_set = 0;
16653
16654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16655     {
16656       if (unformat
16657           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16658         {
16659           eid_set = 1;
16660           eid.type = 0;
16661         }
16662       else
16663         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16664         {
16665           eid_set = 1;
16666           eid.type = 1;
16667         }
16668       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16669         {
16670           eid_set = 1;
16671           eid.type = 2;
16672         }
16673       else if (unformat (i, "vni %d", &t))
16674         {
16675           vni = t;
16676         }
16677       else if (unformat (i, "local"))
16678         {
16679           filter = 1;
16680         }
16681       else if (unformat (i, "remote"))
16682         {
16683           filter = 2;
16684         }
16685       else
16686         {
16687           errmsg ("parse error '%U'", format_unformat_error, i);
16688           return -99;
16689         }
16690     }
16691
16692   if (!vam->json_output)
16693     {
16694       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16695              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16696     }
16697
16698   M (ONE_EID_TABLE_DUMP, mp);
16699
16700   mp->filter = filter;
16701   if (eid_set)
16702     {
16703       mp->eid_set = 1;
16704       mp->vni = htonl (vni);
16705       lisp_eid_put_vat (&mp->eid, &eid);
16706     }
16707
16708   /* send it... */
16709   S (mp);
16710
16711   /* Use a control ping for synchronization */
16712   MPING (CONTROL_PING, mp_ping);
16713   S (mp_ping);
16714
16715   /* Wait for a reply... */
16716   W (ret);
16717   return ret;
16718 }
16719
16720 #define api_lisp_eid_table_dump api_one_eid_table_dump
16721
16722 static int
16723 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16724 {
16725   unformat_input_t *i = vam->input;
16726   vl_api_gpe_fwd_entries_get_t *mp;
16727   u8 vni_set = 0;
16728   u32 vni = ~0;
16729   int ret;
16730
16731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16732     {
16733       if (unformat (i, "vni %d", &vni))
16734         {
16735           vni_set = 1;
16736         }
16737       else
16738         {
16739           errmsg ("parse error '%U'", format_unformat_error, i);
16740           return -99;
16741         }
16742     }
16743
16744   if (!vni_set)
16745     {
16746       errmsg ("vni not set!");
16747       return -99;
16748     }
16749
16750   if (!vam->json_output)
16751     {
16752       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16753              "leid", "reid");
16754     }
16755
16756   M (GPE_FWD_ENTRIES_GET, mp);
16757   mp->vni = clib_host_to_net_u32 (vni);
16758
16759   /* send it... */
16760   S (mp);
16761
16762   /* Wait for a reply... */
16763   W (ret);
16764   return ret;
16765 }
16766
16767 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16768 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16769 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16770 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16771 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16772 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16773 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16774 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16775
16776 static int
16777 api_one_adjacencies_get (vat_main_t * vam)
16778 {
16779   unformat_input_t *i = vam->input;
16780   vl_api_one_adjacencies_get_t *mp;
16781   u8 vni_set = 0;
16782   u32 vni = ~0;
16783   int ret;
16784
16785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16786     {
16787       if (unformat (i, "vni %d", &vni))
16788         {
16789           vni_set = 1;
16790         }
16791       else
16792         {
16793           errmsg ("parse error '%U'", format_unformat_error, i);
16794           return -99;
16795         }
16796     }
16797
16798   if (!vni_set)
16799     {
16800       errmsg ("vni not set!");
16801       return -99;
16802     }
16803
16804   if (!vam->json_output)
16805     {
16806       print (vam->ofp, "%s %40s", "leid", "reid");
16807     }
16808
16809   M (ONE_ADJACENCIES_GET, mp);
16810   mp->vni = clib_host_to_net_u32 (vni);
16811
16812   /* send it... */
16813   S (mp);
16814
16815   /* Wait for a reply... */
16816   W (ret);
16817   return ret;
16818 }
16819
16820 #define api_lisp_adjacencies_get api_one_adjacencies_get
16821
16822 static int
16823 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16824 {
16825   unformat_input_t *i = vam->input;
16826   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16827   int ret;
16828   u8 ip_family_set = 0, is_ip4 = 1;
16829
16830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16831     {
16832       if (unformat (i, "ip4"))
16833         {
16834           ip_family_set = 1;
16835           is_ip4 = 1;
16836         }
16837       else if (unformat (i, "ip6"))
16838         {
16839           ip_family_set = 1;
16840           is_ip4 = 0;
16841         }
16842       else
16843         {
16844           errmsg ("parse error '%U'", format_unformat_error, i);
16845           return -99;
16846         }
16847     }
16848
16849   if (!ip_family_set)
16850     {
16851       errmsg ("ip family not set!");
16852       return -99;
16853     }
16854
16855   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16856   mp->is_ip4 = is_ip4;
16857
16858   /* send it... */
16859   S (mp);
16860
16861   /* Wait for a reply... */
16862   W (ret);
16863   return ret;
16864 }
16865
16866 static int
16867 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16868 {
16869   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16870   int ret;
16871
16872   if (!vam->json_output)
16873     {
16874       print (vam->ofp, "VNIs");
16875     }
16876
16877   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16878
16879   /* send it... */
16880   S (mp);
16881
16882   /* Wait for a reply... */
16883   W (ret);
16884   return ret;
16885 }
16886
16887 static int
16888 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16889 {
16890   unformat_input_t *i = vam->input;
16891   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16892   int ret = 0;
16893   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16894   struct in_addr ip4;
16895   struct in6_addr ip6;
16896   u32 table_id = 0, nh_sw_if_index = ~0;
16897
16898   clib_memset (&ip4, 0, sizeof (ip4));
16899   clib_memset (&ip6, 0, sizeof (ip6));
16900
16901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16902     {
16903       if (unformat (i, "del"))
16904         is_add = 0;
16905       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16906                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16907         {
16908           ip_set = 1;
16909           is_ip4 = 1;
16910         }
16911       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16912                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16913         {
16914           ip_set = 1;
16915           is_ip4 = 0;
16916         }
16917       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16918         {
16919           ip_set = 1;
16920           is_ip4 = 1;
16921           nh_sw_if_index = ~0;
16922         }
16923       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16924         {
16925           ip_set = 1;
16926           is_ip4 = 0;
16927           nh_sw_if_index = ~0;
16928         }
16929       else if (unformat (i, "table %d", &table_id))
16930         ;
16931       else
16932         {
16933           errmsg ("parse error '%U'", format_unformat_error, i);
16934           return -99;
16935         }
16936     }
16937
16938   if (!ip_set)
16939     {
16940       errmsg ("nh addr not set!");
16941       return -99;
16942     }
16943
16944   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16945   mp->is_add = is_add;
16946   mp->table_id = clib_host_to_net_u32 (table_id);
16947   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16948   mp->nh_addr.af = is_ip4 ? 0 : 1;
16949   if (is_ip4)
16950     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16951   else
16952     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16953
16954   /* send it... */
16955   S (mp);
16956
16957   /* Wait for a reply... */
16958   W (ret);
16959   return ret;
16960 }
16961
16962 static int
16963 api_one_map_server_dump (vat_main_t * vam)
16964 {
16965   vl_api_one_map_server_dump_t *mp;
16966   vl_api_control_ping_t *mp_ping;
16967   int ret;
16968
16969   if (!vam->json_output)
16970     {
16971       print (vam->ofp, "%=20s", "Map server");
16972     }
16973
16974   M (ONE_MAP_SERVER_DUMP, mp);
16975   /* send it... */
16976   S (mp);
16977
16978   /* Use a control ping for synchronization */
16979   MPING (CONTROL_PING, mp_ping);
16980   S (mp_ping);
16981
16982   /* Wait for a reply... */
16983   W (ret);
16984   return ret;
16985 }
16986
16987 #define api_lisp_map_server_dump api_one_map_server_dump
16988
16989 static int
16990 api_one_map_resolver_dump (vat_main_t * vam)
16991 {
16992   vl_api_one_map_resolver_dump_t *mp;
16993   vl_api_control_ping_t *mp_ping;
16994   int ret;
16995
16996   if (!vam->json_output)
16997     {
16998       print (vam->ofp, "%=20s", "Map resolver");
16999     }
17000
17001   M (ONE_MAP_RESOLVER_DUMP, mp);
17002   /* send it... */
17003   S (mp);
17004
17005   /* Use a control ping for synchronization */
17006   MPING (CONTROL_PING, mp_ping);
17007   S (mp_ping);
17008
17009   /* Wait for a reply... */
17010   W (ret);
17011   return ret;
17012 }
17013
17014 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17015
17016 static int
17017 api_one_stats_flush (vat_main_t * vam)
17018 {
17019   vl_api_one_stats_flush_t *mp;
17020   int ret = 0;
17021
17022   M (ONE_STATS_FLUSH, mp);
17023   S (mp);
17024   W (ret);
17025   return ret;
17026 }
17027
17028 static int
17029 api_one_stats_dump (vat_main_t * vam)
17030 {
17031   vl_api_one_stats_dump_t *mp;
17032   vl_api_control_ping_t *mp_ping;
17033   int ret;
17034
17035   M (ONE_STATS_DUMP, mp);
17036   /* send it... */
17037   S (mp);
17038
17039   /* Use a control ping for synchronization */
17040   MPING (CONTROL_PING, mp_ping);
17041   S (mp_ping);
17042
17043   /* Wait for a reply... */
17044   W (ret);
17045   return ret;
17046 }
17047
17048 static int
17049 api_show_one_status (vat_main_t * vam)
17050 {
17051   vl_api_show_one_status_t *mp;
17052   int ret;
17053
17054   if (!vam->json_output)
17055     {
17056       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17057     }
17058
17059   M (SHOW_ONE_STATUS, mp);
17060   /* send it... */
17061   S (mp);
17062   /* Wait for a reply... */
17063   W (ret);
17064   return ret;
17065 }
17066
17067 #define api_show_lisp_status api_show_one_status
17068
17069 static int
17070 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17071 {
17072   vl_api_gpe_fwd_entry_path_dump_t *mp;
17073   vl_api_control_ping_t *mp_ping;
17074   unformat_input_t *i = vam->input;
17075   u32 fwd_entry_index = ~0;
17076   int ret;
17077
17078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17079     {
17080       if (unformat (i, "index %d", &fwd_entry_index))
17081         ;
17082       else
17083         break;
17084     }
17085
17086   if (~0 == fwd_entry_index)
17087     {
17088       errmsg ("no index specified!");
17089       return -99;
17090     }
17091
17092   if (!vam->json_output)
17093     {
17094       print (vam->ofp, "first line");
17095     }
17096
17097   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17098
17099   /* send it... */
17100   S (mp);
17101   /* Use a control ping for synchronization */
17102   MPING (CONTROL_PING, mp_ping);
17103   S (mp_ping);
17104
17105   /* Wait for a reply... */
17106   W (ret);
17107   return ret;
17108 }
17109
17110 static int
17111 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17112 {
17113   vl_api_one_get_map_request_itr_rlocs_t *mp;
17114   int ret;
17115
17116   if (!vam->json_output)
17117     {
17118       print (vam->ofp, "%=20s", "itr-rlocs:");
17119     }
17120
17121   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17122   /* send it... */
17123   S (mp);
17124   /* Wait for a reply... */
17125   W (ret);
17126   return ret;
17127 }
17128
17129 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17130
17131 static int
17132 api_af_packet_create (vat_main_t * vam)
17133 {
17134   unformat_input_t *i = vam->input;
17135   vl_api_af_packet_create_t *mp;
17136   u8 *host_if_name = 0;
17137   u8 hw_addr[6];
17138   u8 random_hw_addr = 1;
17139   int ret;
17140
17141   clib_memset (hw_addr, 0, sizeof (hw_addr));
17142
17143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17144     {
17145       if (unformat (i, "name %s", &host_if_name))
17146         vec_add1 (host_if_name, 0);
17147       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17148         random_hw_addr = 0;
17149       else
17150         break;
17151     }
17152
17153   if (!vec_len (host_if_name))
17154     {
17155       errmsg ("host-interface name must be specified");
17156       return -99;
17157     }
17158
17159   if (vec_len (host_if_name) > 64)
17160     {
17161       errmsg ("host-interface name too long");
17162       return -99;
17163     }
17164
17165   M (AF_PACKET_CREATE, mp);
17166
17167   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17168   clib_memcpy (mp->hw_addr, hw_addr, 6);
17169   mp->use_random_hw_addr = random_hw_addr;
17170   vec_free (host_if_name);
17171
17172   S (mp);
17173
17174   /* *INDENT-OFF* */
17175   W2 (ret,
17176       ({
17177         if (ret == 0)
17178           fprintf (vam->ofp ? vam->ofp : stderr,
17179                    " new sw_if_index = %d\n", vam->sw_if_index);
17180       }));
17181   /* *INDENT-ON* */
17182   return ret;
17183 }
17184
17185 static int
17186 api_af_packet_delete (vat_main_t * vam)
17187 {
17188   unformat_input_t *i = vam->input;
17189   vl_api_af_packet_delete_t *mp;
17190   u8 *host_if_name = 0;
17191   int ret;
17192
17193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17194     {
17195       if (unformat (i, "name %s", &host_if_name))
17196         vec_add1 (host_if_name, 0);
17197       else
17198         break;
17199     }
17200
17201   if (!vec_len (host_if_name))
17202     {
17203       errmsg ("host-interface name must be specified");
17204       return -99;
17205     }
17206
17207   if (vec_len (host_if_name) > 64)
17208     {
17209       errmsg ("host-interface name too long");
17210       return -99;
17211     }
17212
17213   M (AF_PACKET_DELETE, mp);
17214
17215   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17216   vec_free (host_if_name);
17217
17218   S (mp);
17219   W (ret);
17220   return ret;
17221 }
17222
17223 static void vl_api_af_packet_details_t_handler
17224   (vl_api_af_packet_details_t * mp)
17225 {
17226   vat_main_t *vam = &vat_main;
17227
17228   print (vam->ofp, "%-16s %d",
17229          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17230 }
17231
17232 static void vl_api_af_packet_details_t_handler_json
17233   (vl_api_af_packet_details_t * mp)
17234 {
17235   vat_main_t *vam = &vat_main;
17236   vat_json_node_t *node = NULL;
17237
17238   if (VAT_JSON_ARRAY != vam->json_tree.type)
17239     {
17240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17241       vat_json_init_array (&vam->json_tree);
17242     }
17243   node = vat_json_array_add (&vam->json_tree);
17244
17245   vat_json_init_object (node);
17246   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17247   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17248 }
17249
17250 static int
17251 api_af_packet_dump (vat_main_t * vam)
17252 {
17253   vl_api_af_packet_dump_t *mp;
17254   vl_api_control_ping_t *mp_ping;
17255   int ret;
17256
17257   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17258   /* Get list of tap interfaces */
17259   M (AF_PACKET_DUMP, mp);
17260   S (mp);
17261
17262   /* Use a control ping for synchronization */
17263   MPING (CONTROL_PING, mp_ping);
17264   S (mp_ping);
17265
17266   W (ret);
17267   return ret;
17268 }
17269
17270 static int
17271 api_policer_add_del (vat_main_t * vam)
17272 {
17273   unformat_input_t *i = vam->input;
17274   vl_api_policer_add_del_t *mp;
17275   u8 is_add = 1;
17276   u8 *name = 0;
17277   u32 cir = 0;
17278   u32 eir = 0;
17279   u64 cb = 0;
17280   u64 eb = 0;
17281   u8 rate_type = 0;
17282   u8 round_type = 0;
17283   u8 type = 0;
17284   u8 color_aware = 0;
17285   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17286   int ret;
17287
17288   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17289   conform_action.dscp = 0;
17290   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17291   exceed_action.dscp = 0;
17292   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17293   violate_action.dscp = 0;
17294
17295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17296     {
17297       if (unformat (i, "del"))
17298         is_add = 0;
17299       else if (unformat (i, "name %s", &name))
17300         vec_add1 (name, 0);
17301       else if (unformat (i, "cir %u", &cir))
17302         ;
17303       else if (unformat (i, "eir %u", &eir))
17304         ;
17305       else if (unformat (i, "cb %u", &cb))
17306         ;
17307       else if (unformat (i, "eb %u", &eb))
17308         ;
17309       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17310                          &rate_type))
17311         ;
17312       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17313                          &round_type))
17314         ;
17315       else if (unformat (i, "type %U", unformat_policer_type, &type))
17316         ;
17317       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17318                          &conform_action))
17319         ;
17320       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17321                          &exceed_action))
17322         ;
17323       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17324                          &violate_action))
17325         ;
17326       else if (unformat (i, "color-aware"))
17327         color_aware = 1;
17328       else
17329         break;
17330     }
17331
17332   if (!vec_len (name))
17333     {
17334       errmsg ("policer name must be specified");
17335       return -99;
17336     }
17337
17338   if (vec_len (name) > 64)
17339     {
17340       errmsg ("policer name too long");
17341       return -99;
17342     }
17343
17344   M (POLICER_ADD_DEL, mp);
17345
17346   clib_memcpy (mp->name, name, vec_len (name));
17347   vec_free (name);
17348   mp->is_add = is_add;
17349   mp->cir = ntohl (cir);
17350   mp->eir = ntohl (eir);
17351   mp->cb = clib_net_to_host_u64 (cb);
17352   mp->eb = clib_net_to_host_u64 (eb);
17353   mp->rate_type = rate_type;
17354   mp->round_type = round_type;
17355   mp->type = type;
17356   mp->conform_action.type = conform_action.action_type;
17357   mp->conform_action.dscp = conform_action.dscp;
17358   mp->exceed_action.type = exceed_action.action_type;
17359   mp->exceed_action.dscp = exceed_action.dscp;
17360   mp->violate_action.type = violate_action.action_type;
17361   mp->violate_action.dscp = violate_action.dscp;
17362   mp->color_aware = color_aware;
17363
17364   S (mp);
17365   W (ret);
17366   return ret;
17367 }
17368
17369 static int
17370 api_policer_dump (vat_main_t * vam)
17371 {
17372   unformat_input_t *i = vam->input;
17373   vl_api_policer_dump_t *mp;
17374   vl_api_control_ping_t *mp_ping;
17375   u8 *match_name = 0;
17376   u8 match_name_valid = 0;
17377   int ret;
17378
17379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17380     {
17381       if (unformat (i, "name %s", &match_name))
17382         {
17383           vec_add1 (match_name, 0);
17384           match_name_valid = 1;
17385         }
17386       else
17387         break;
17388     }
17389
17390   M (POLICER_DUMP, mp);
17391   mp->match_name_valid = match_name_valid;
17392   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17393   vec_free (match_name);
17394   /* send it... */
17395   S (mp);
17396
17397   /* Use a control ping for synchronization */
17398   MPING (CONTROL_PING, mp_ping);
17399   S (mp_ping);
17400
17401   /* Wait for a reply... */
17402   W (ret);
17403   return ret;
17404 }
17405
17406 static int
17407 api_policer_classify_set_interface (vat_main_t * vam)
17408 {
17409   unformat_input_t *i = vam->input;
17410   vl_api_policer_classify_set_interface_t *mp;
17411   u32 sw_if_index;
17412   int sw_if_index_set;
17413   u32 ip4_table_index = ~0;
17414   u32 ip6_table_index = ~0;
17415   u32 l2_table_index = ~0;
17416   u8 is_add = 1;
17417   int ret;
17418
17419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17420     {
17421       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17422         sw_if_index_set = 1;
17423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17424         sw_if_index_set = 1;
17425       else if (unformat (i, "del"))
17426         is_add = 0;
17427       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17428         ;
17429       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17430         ;
17431       else if (unformat (i, "l2-table %d", &l2_table_index))
17432         ;
17433       else
17434         {
17435           clib_warning ("parse error '%U'", format_unformat_error, i);
17436           return -99;
17437         }
17438     }
17439
17440   if (sw_if_index_set == 0)
17441     {
17442       errmsg ("missing interface name or sw_if_index");
17443       return -99;
17444     }
17445
17446   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17447
17448   mp->sw_if_index = ntohl (sw_if_index);
17449   mp->ip4_table_index = ntohl (ip4_table_index);
17450   mp->ip6_table_index = ntohl (ip6_table_index);
17451   mp->l2_table_index = ntohl (l2_table_index);
17452   mp->is_add = is_add;
17453
17454   S (mp);
17455   W (ret);
17456   return ret;
17457 }
17458
17459 static int
17460 api_policer_classify_dump (vat_main_t * vam)
17461 {
17462   unformat_input_t *i = vam->input;
17463   vl_api_policer_classify_dump_t *mp;
17464   vl_api_control_ping_t *mp_ping;
17465   u8 type = POLICER_CLASSIFY_N_TABLES;
17466   int ret;
17467
17468   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17469     ;
17470   else
17471     {
17472       errmsg ("classify table type must be specified");
17473       return -99;
17474     }
17475
17476   if (!vam->json_output)
17477     {
17478       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17479     }
17480
17481   M (POLICER_CLASSIFY_DUMP, mp);
17482   mp->type = type;
17483   /* send it... */
17484   S (mp);
17485
17486   /* Use a control ping for synchronization */
17487   MPING (CONTROL_PING, mp_ping);
17488   S (mp_ping);
17489
17490   /* Wait for a reply... */
17491   W (ret);
17492   return ret;
17493 }
17494
17495 static u8 *
17496 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17497 {
17498   vl_api_fib_path_nh_proto_t proto =
17499     va_arg (*args, vl_api_fib_path_nh_proto_t);
17500
17501   switch (proto)
17502     {
17503     case FIB_API_PATH_NH_PROTO_IP4:
17504       s = format (s, "ip4");
17505       break;
17506     case FIB_API_PATH_NH_PROTO_IP6:
17507       s = format (s, "ip6");
17508       break;
17509     case FIB_API_PATH_NH_PROTO_MPLS:
17510       s = format (s, "mpls");
17511       break;
17512     case FIB_API_PATH_NH_PROTO_BIER:
17513       s = format (s, "bier");
17514       break;
17515     case FIB_API_PATH_NH_PROTO_ETHERNET:
17516       s = format (s, "ethernet");
17517       break;
17518     }
17519
17520   return (s);
17521 }
17522
17523 static u8 *
17524 format_vl_api_ip_address_union (u8 * s, va_list * args)
17525 {
17526   vl_api_address_family_t af = va_arg (*args, int);
17527   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17528
17529   switch (af)
17530     {
17531     case ADDRESS_IP4:
17532       s = format (s, "%U", format_ip4_address, u->ip4);
17533       break;
17534     case ADDRESS_IP6:
17535       s = format (s, "%U", format_ip6_address, u->ip6);
17536       break;
17537     }
17538   return (s);
17539 }
17540
17541 static u8 *
17542 format_vl_api_fib_path_type (u8 * s, va_list * args)
17543 {
17544   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17545
17546   switch (t)
17547     {
17548     case FIB_API_PATH_TYPE_NORMAL:
17549       s = format (s, "normal");
17550       break;
17551     case FIB_API_PATH_TYPE_LOCAL:
17552       s = format (s, "local");
17553       break;
17554     case FIB_API_PATH_TYPE_DROP:
17555       s = format (s, "drop");
17556       break;
17557     case FIB_API_PATH_TYPE_UDP_ENCAP:
17558       s = format (s, "udp-encap");
17559       break;
17560     case FIB_API_PATH_TYPE_BIER_IMP:
17561       s = format (s, "bier-imp");
17562       break;
17563     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17564       s = format (s, "unreach");
17565       break;
17566     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17567       s = format (s, "prohibit");
17568       break;
17569     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17570       s = format (s, "src-lookup");
17571       break;
17572     case FIB_API_PATH_TYPE_DVR:
17573       s = format (s, "dvr");
17574       break;
17575     case FIB_API_PATH_TYPE_INTERFACE_RX:
17576       s = format (s, "interface-rx");
17577       break;
17578     case FIB_API_PATH_TYPE_CLASSIFY:
17579       s = format (s, "classify");
17580       break;
17581     }
17582
17583   return (s);
17584 }
17585
17586 static void
17587 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17588 {
17589   print (vam->ofp,
17590          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17591          ntohl (fp->weight), ntohl (fp->sw_if_index),
17592          format_vl_api_fib_path_type, fp->type,
17593          format_fib_api_path_nh_proto, fp->proto,
17594          format_vl_api_ip_address_union, &fp->nh.address);
17595 }
17596
17597 static void
17598 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17599                                  vl_api_fib_path_t * fp)
17600 {
17601   struct in_addr ip4;
17602   struct in6_addr ip6;
17603
17604   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17605   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17606   vat_json_object_add_uint (node, "type", fp->type);
17607   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17608   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17609     {
17610       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17611       vat_json_object_add_ip4 (node, "next_hop", ip4);
17612     }
17613   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17614     {
17615       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17616       vat_json_object_add_ip6 (node, "next_hop", ip6);
17617     }
17618 }
17619
17620 static void
17621 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17622 {
17623   vat_main_t *vam = &vat_main;
17624   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17625   vl_api_fib_path_t *fp;
17626   i32 i;
17627
17628   print (vam->ofp, "sw_if_index %d via:",
17629          ntohl (mp->mt_tunnel.mt_sw_if_index));
17630   fp = mp->mt_tunnel.mt_paths;
17631   for (i = 0; i < count; i++)
17632     {
17633       vl_api_fib_path_print (vam, fp);
17634       fp++;
17635     }
17636
17637   print (vam->ofp, "");
17638 }
17639
17640 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17641 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17642
17643 static void
17644 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17645 {
17646   vat_main_t *vam = &vat_main;
17647   vat_json_node_t *node = NULL;
17648   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17649   vl_api_fib_path_t *fp;
17650   i32 i;
17651
17652   if (VAT_JSON_ARRAY != vam->json_tree.type)
17653     {
17654       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17655       vat_json_init_array (&vam->json_tree);
17656     }
17657   node = vat_json_array_add (&vam->json_tree);
17658
17659   vat_json_init_object (node);
17660   vat_json_object_add_uint (node, "sw_if_index",
17661                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17662
17663   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17664
17665   fp = mp->mt_tunnel.mt_paths;
17666   for (i = 0; i < count; i++)
17667     {
17668       vl_api_mpls_fib_path_json_print (node, fp);
17669       fp++;
17670     }
17671 }
17672
17673 static int
17674 api_mpls_tunnel_dump (vat_main_t * vam)
17675 {
17676   vl_api_mpls_tunnel_dump_t *mp;
17677   vl_api_control_ping_t *mp_ping;
17678   int ret;
17679
17680   M (MPLS_TUNNEL_DUMP, mp);
17681
17682   S (mp);
17683
17684   /* Use a control ping for synchronization */
17685   MPING (CONTROL_PING, mp_ping);
17686   S (mp_ping);
17687
17688   W (ret);
17689   return ret;
17690 }
17691
17692 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17693 #define vl_api_mpls_table_details_t_print vl_noop_handler
17694
17695
17696 static void
17697 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17698 {
17699   vat_main_t *vam = &vat_main;
17700
17701   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17702 }
17703
17704 static void vl_api_mpls_table_details_t_handler_json
17705   (vl_api_mpls_table_details_t * mp)
17706 {
17707   vat_main_t *vam = &vat_main;
17708   vat_json_node_t *node = NULL;
17709
17710   if (VAT_JSON_ARRAY != vam->json_tree.type)
17711     {
17712       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17713       vat_json_init_array (&vam->json_tree);
17714     }
17715   node = vat_json_array_add (&vam->json_tree);
17716
17717   vat_json_init_object (node);
17718   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17719 }
17720
17721 static int
17722 api_mpls_table_dump (vat_main_t * vam)
17723 {
17724   vl_api_mpls_table_dump_t *mp;
17725   vl_api_control_ping_t *mp_ping;
17726   int ret;
17727
17728   M (MPLS_TABLE_DUMP, mp);
17729   S (mp);
17730
17731   /* Use a control ping for synchronization */
17732   MPING (CONTROL_PING, mp_ping);
17733   S (mp_ping);
17734
17735   W (ret);
17736   return ret;
17737 }
17738
17739 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17740 #define vl_api_mpls_route_details_t_print vl_noop_handler
17741
17742 static void
17743 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17744 {
17745   vat_main_t *vam = &vat_main;
17746   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17747   vl_api_fib_path_t *fp;
17748   int i;
17749
17750   print (vam->ofp,
17751          "table-id %d, label %u, ess_bit %u",
17752          ntohl (mp->mr_route.mr_table_id),
17753          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17754   fp = mp->mr_route.mr_paths;
17755   for (i = 0; i < count; i++)
17756     {
17757       vl_api_fib_path_print (vam, fp);
17758       fp++;
17759     }
17760 }
17761
17762 static void vl_api_mpls_route_details_t_handler_json
17763   (vl_api_mpls_route_details_t * mp)
17764 {
17765   vat_main_t *vam = &vat_main;
17766   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17767   vat_json_node_t *node = NULL;
17768   vl_api_fib_path_t *fp;
17769   int i;
17770
17771   if (VAT_JSON_ARRAY != vam->json_tree.type)
17772     {
17773       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17774       vat_json_init_array (&vam->json_tree);
17775     }
17776   node = vat_json_array_add (&vam->json_tree);
17777
17778   vat_json_init_object (node);
17779   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17780   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17781   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17782   vat_json_object_add_uint (node, "path_count", count);
17783   fp = mp->mr_route.mr_paths;
17784   for (i = 0; i < count; i++)
17785     {
17786       vl_api_mpls_fib_path_json_print (node, fp);
17787       fp++;
17788     }
17789 }
17790
17791 static int
17792 api_mpls_route_dump (vat_main_t * vam)
17793 {
17794   unformat_input_t *input = vam->input;
17795   vl_api_mpls_route_dump_t *mp;
17796   vl_api_control_ping_t *mp_ping;
17797   u32 table_id;
17798   int ret;
17799
17800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17801     {
17802       if (unformat (input, "table_id %d", &table_id))
17803         ;
17804       else
17805         break;
17806     }
17807   if (table_id == ~0)
17808     {
17809       errmsg ("missing table id");
17810       return -99;
17811     }
17812
17813   M (MPLS_ROUTE_DUMP, mp);
17814
17815   mp->table.mt_table_id = ntohl (table_id);
17816   S (mp);
17817
17818   /* Use a control ping for synchronization */
17819   MPING (CONTROL_PING, mp_ping);
17820   S (mp_ping);
17821
17822   W (ret);
17823   return ret;
17824 }
17825
17826 #define vl_api_ip_table_details_t_endian vl_noop_handler
17827 #define vl_api_ip_table_details_t_print vl_noop_handler
17828
17829 static void
17830 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17831 {
17832   vat_main_t *vam = &vat_main;
17833
17834   print (vam->ofp,
17835          "%s; table-id %d, prefix %U/%d",
17836          mp->table.name, ntohl (mp->table.table_id));
17837 }
17838
17839
17840 static void vl_api_ip_table_details_t_handler_json
17841   (vl_api_ip_table_details_t * mp)
17842 {
17843   vat_main_t *vam = &vat_main;
17844   vat_json_node_t *node = NULL;
17845
17846   if (VAT_JSON_ARRAY != vam->json_tree.type)
17847     {
17848       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17849       vat_json_init_array (&vam->json_tree);
17850     }
17851   node = vat_json_array_add (&vam->json_tree);
17852
17853   vat_json_init_object (node);
17854   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17855 }
17856
17857 static int
17858 api_ip_table_dump (vat_main_t * vam)
17859 {
17860   vl_api_ip_table_dump_t *mp;
17861   vl_api_control_ping_t *mp_ping;
17862   int ret;
17863
17864   M (IP_TABLE_DUMP, mp);
17865   S (mp);
17866
17867   /* Use a control ping for synchronization */
17868   MPING (CONTROL_PING, mp_ping);
17869   S (mp_ping);
17870
17871   W (ret);
17872   return ret;
17873 }
17874
17875 static int
17876 api_ip_mtable_dump (vat_main_t * vam)
17877 {
17878   vl_api_ip_mtable_dump_t *mp;
17879   vl_api_control_ping_t *mp_ping;
17880   int ret;
17881
17882   M (IP_MTABLE_DUMP, mp);
17883   S (mp);
17884
17885   /* Use a control ping for synchronization */
17886   MPING (CONTROL_PING, mp_ping);
17887   S (mp_ping);
17888
17889   W (ret);
17890   return ret;
17891 }
17892
17893 static int
17894 api_ip_mroute_dump (vat_main_t * vam)
17895 {
17896   unformat_input_t *input = vam->input;
17897   vl_api_control_ping_t *mp_ping;
17898   vl_api_ip_mroute_dump_t *mp;
17899   int ret, is_ip6;
17900   u32 table_id;
17901
17902   is_ip6 = 0;
17903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17904     {
17905       if (unformat (input, "table_id %d", &table_id))
17906         ;
17907       else if (unformat (input, "ip6"))
17908         is_ip6 = 1;
17909       else if (unformat (input, "ip4"))
17910         is_ip6 = 0;
17911       else
17912         break;
17913     }
17914   if (table_id == ~0)
17915     {
17916       errmsg ("missing table id");
17917       return -99;
17918     }
17919
17920   M (IP_MROUTE_DUMP, mp);
17921   mp->table.table_id = table_id;
17922   mp->table.is_ip6 = is_ip6;
17923   S (mp);
17924
17925   /* Use a control ping for synchronization */
17926   MPING (CONTROL_PING, mp_ping);
17927   S (mp_ping);
17928
17929   W (ret);
17930   return ret;
17931 }
17932
17933 #define vl_api_ip_route_details_t_endian vl_noop_handler
17934 #define vl_api_ip_route_details_t_print vl_noop_handler
17935
17936 static void
17937 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17938 {
17939   vat_main_t *vam = &vat_main;
17940   u8 count = mp->route.n_paths;
17941   vl_api_fib_path_t *fp;
17942   int i;
17943
17944   print (vam->ofp,
17945          "table-id %d, prefix %U/%d",
17946          ntohl (mp->route.table_id),
17947          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17948   for (i = 0; i < count; i++)
17949     {
17950       fp = &mp->route.paths[i];
17951
17952       vl_api_fib_path_print (vam, fp);
17953       fp++;
17954     }
17955 }
17956
17957 static void vl_api_ip_route_details_t_handler_json
17958   (vl_api_ip_route_details_t * mp)
17959 {
17960   vat_main_t *vam = &vat_main;
17961   u8 count = mp->route.n_paths;
17962   vat_json_node_t *node = NULL;
17963   struct in_addr ip4;
17964   struct in6_addr ip6;
17965   vl_api_fib_path_t *fp;
17966   int i;
17967
17968   if (VAT_JSON_ARRAY != vam->json_tree.type)
17969     {
17970       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17971       vat_json_init_array (&vam->json_tree);
17972     }
17973   node = vat_json_array_add (&vam->json_tree);
17974
17975   vat_json_init_object (node);
17976   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17977   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17978     {
17979       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17980       vat_json_object_add_ip6 (node, "prefix", ip6);
17981     }
17982   else
17983     {
17984       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17985       vat_json_object_add_ip4 (node, "prefix", ip4);
17986     }
17987   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17988   vat_json_object_add_uint (node, "path_count", count);
17989   for (i = 0; i < count; i++)
17990     {
17991       fp = &mp->route.paths[i];
17992       vl_api_mpls_fib_path_json_print (node, fp);
17993     }
17994 }
17995
17996 static int
17997 api_ip_route_dump (vat_main_t * vam)
17998 {
17999   unformat_input_t *input = vam->input;
18000   vl_api_ip_route_dump_t *mp;
18001   vl_api_control_ping_t *mp_ping;
18002   u32 table_id;
18003   u8 is_ip6;
18004   int ret;
18005
18006   is_ip6 = 0;
18007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18008     {
18009       if (unformat (input, "table_id %d", &table_id))
18010         ;
18011       else if (unformat (input, "ip6"))
18012         is_ip6 = 1;
18013       else if (unformat (input, "ip4"))
18014         is_ip6 = 0;
18015       else
18016         break;
18017     }
18018   if (table_id == ~0)
18019     {
18020       errmsg ("missing table id");
18021       return -99;
18022     }
18023
18024   M (IP_ROUTE_DUMP, mp);
18025
18026   mp->table.table_id = table_id;
18027   mp->table.is_ip6 = is_ip6;
18028
18029   S (mp);
18030
18031   /* Use a control ping for synchronization */
18032   MPING (CONTROL_PING, mp_ping);
18033   S (mp_ping);
18034
18035   W (ret);
18036   return ret;
18037 }
18038
18039 int
18040 api_classify_table_ids (vat_main_t * vam)
18041 {
18042   vl_api_classify_table_ids_t *mp;
18043   int ret;
18044
18045   /* Construct the API message */
18046   M (CLASSIFY_TABLE_IDS, mp);
18047   mp->context = 0;
18048
18049   S (mp);
18050   W (ret);
18051   return ret;
18052 }
18053
18054 int
18055 api_classify_table_by_interface (vat_main_t * vam)
18056 {
18057   unformat_input_t *input = vam->input;
18058   vl_api_classify_table_by_interface_t *mp;
18059
18060   u32 sw_if_index = ~0;
18061   int ret;
18062   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18063     {
18064       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18065         ;
18066       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18067         ;
18068       else
18069         break;
18070     }
18071   if (sw_if_index == ~0)
18072     {
18073       errmsg ("missing interface name or sw_if_index");
18074       return -99;
18075     }
18076
18077   /* Construct the API message */
18078   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18079   mp->context = 0;
18080   mp->sw_if_index = ntohl (sw_if_index);
18081
18082   S (mp);
18083   W (ret);
18084   return ret;
18085 }
18086
18087 int
18088 api_classify_table_info (vat_main_t * vam)
18089 {
18090   unformat_input_t *input = vam->input;
18091   vl_api_classify_table_info_t *mp;
18092
18093   u32 table_id = ~0;
18094   int ret;
18095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18096     {
18097       if (unformat (input, "table_id %d", &table_id))
18098         ;
18099       else
18100         break;
18101     }
18102   if (table_id == ~0)
18103     {
18104       errmsg ("missing table id");
18105       return -99;
18106     }
18107
18108   /* Construct the API message */
18109   M (CLASSIFY_TABLE_INFO, mp);
18110   mp->context = 0;
18111   mp->table_id = ntohl (table_id);
18112
18113   S (mp);
18114   W (ret);
18115   return ret;
18116 }
18117
18118 int
18119 api_classify_session_dump (vat_main_t * vam)
18120 {
18121   unformat_input_t *input = vam->input;
18122   vl_api_classify_session_dump_t *mp;
18123   vl_api_control_ping_t *mp_ping;
18124
18125   u32 table_id = ~0;
18126   int ret;
18127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18128     {
18129       if (unformat (input, "table_id %d", &table_id))
18130         ;
18131       else
18132         break;
18133     }
18134   if (table_id == ~0)
18135     {
18136       errmsg ("missing table id");
18137       return -99;
18138     }
18139
18140   /* Construct the API message */
18141   M (CLASSIFY_SESSION_DUMP, mp);
18142   mp->context = 0;
18143   mp->table_id = ntohl (table_id);
18144   S (mp);
18145
18146   /* Use a control ping for synchronization */
18147   MPING (CONTROL_PING, mp_ping);
18148   S (mp_ping);
18149
18150   W (ret);
18151   return ret;
18152 }
18153
18154 static void
18155 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18156 {
18157   vat_main_t *vam = &vat_main;
18158
18159   print (vam->ofp, "collector_address %U, collector_port %d, "
18160          "src_address %U, vrf_id %d, path_mtu %u, "
18161          "template_interval %u, udp_checksum %d",
18162          format_ip4_address, mp->collector_address,
18163          ntohs (mp->collector_port),
18164          format_ip4_address, mp->src_address,
18165          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18166          ntohl (mp->template_interval), mp->udp_checksum);
18167
18168   vam->retval = 0;
18169   vam->result_ready = 1;
18170 }
18171
18172 static void
18173   vl_api_ipfix_exporter_details_t_handler_json
18174   (vl_api_ipfix_exporter_details_t * mp)
18175 {
18176   vat_main_t *vam = &vat_main;
18177   vat_json_node_t node;
18178   struct in_addr collector_address;
18179   struct in_addr src_address;
18180
18181   vat_json_init_object (&node);
18182   clib_memcpy (&collector_address, &mp->collector_address,
18183                sizeof (collector_address));
18184   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18185   vat_json_object_add_uint (&node, "collector_port",
18186                             ntohs (mp->collector_port));
18187   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18188   vat_json_object_add_ip4 (&node, "src_address", src_address);
18189   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18190   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18191   vat_json_object_add_uint (&node, "template_interval",
18192                             ntohl (mp->template_interval));
18193   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18194
18195   vat_json_print (vam->ofp, &node);
18196   vat_json_free (&node);
18197   vam->retval = 0;
18198   vam->result_ready = 1;
18199 }
18200
18201 int
18202 api_ipfix_exporter_dump (vat_main_t * vam)
18203 {
18204   vl_api_ipfix_exporter_dump_t *mp;
18205   int ret;
18206
18207   /* Construct the API message */
18208   M (IPFIX_EXPORTER_DUMP, mp);
18209   mp->context = 0;
18210
18211   S (mp);
18212   W (ret);
18213   return ret;
18214 }
18215
18216 static int
18217 api_ipfix_classify_stream_dump (vat_main_t * vam)
18218 {
18219   vl_api_ipfix_classify_stream_dump_t *mp;
18220   int ret;
18221
18222   /* Construct the API message */
18223   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18224   mp->context = 0;
18225
18226   S (mp);
18227   W (ret);
18228   return ret;
18229   /* NOTREACHED */
18230   return 0;
18231 }
18232
18233 static void
18234   vl_api_ipfix_classify_stream_details_t_handler
18235   (vl_api_ipfix_classify_stream_details_t * mp)
18236 {
18237   vat_main_t *vam = &vat_main;
18238   print (vam->ofp, "domain_id %d, src_port %d",
18239          ntohl (mp->domain_id), ntohs (mp->src_port));
18240   vam->retval = 0;
18241   vam->result_ready = 1;
18242 }
18243
18244 static void
18245   vl_api_ipfix_classify_stream_details_t_handler_json
18246   (vl_api_ipfix_classify_stream_details_t * mp)
18247 {
18248   vat_main_t *vam = &vat_main;
18249   vat_json_node_t node;
18250
18251   vat_json_init_object (&node);
18252   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18253   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18254
18255   vat_json_print (vam->ofp, &node);
18256   vat_json_free (&node);
18257   vam->retval = 0;
18258   vam->result_ready = 1;
18259 }
18260
18261 static int
18262 api_ipfix_classify_table_dump (vat_main_t * vam)
18263 {
18264   vl_api_ipfix_classify_table_dump_t *mp;
18265   vl_api_control_ping_t *mp_ping;
18266   int ret;
18267
18268   if (!vam->json_output)
18269     {
18270       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18271              "transport_protocol");
18272     }
18273
18274   /* Construct the API message */
18275   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18276
18277   /* send it... */
18278   S (mp);
18279
18280   /* Use a control ping for synchronization */
18281   MPING (CONTROL_PING, mp_ping);
18282   S (mp_ping);
18283
18284   W (ret);
18285   return ret;
18286 }
18287
18288 static void
18289   vl_api_ipfix_classify_table_details_t_handler
18290   (vl_api_ipfix_classify_table_details_t * mp)
18291 {
18292   vat_main_t *vam = &vat_main;
18293   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18294          mp->transport_protocol);
18295 }
18296
18297 static void
18298   vl_api_ipfix_classify_table_details_t_handler_json
18299   (vl_api_ipfix_classify_table_details_t * mp)
18300 {
18301   vat_json_node_t *node = NULL;
18302   vat_main_t *vam = &vat_main;
18303
18304   if (VAT_JSON_ARRAY != vam->json_tree.type)
18305     {
18306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18307       vat_json_init_array (&vam->json_tree);
18308     }
18309
18310   node = vat_json_array_add (&vam->json_tree);
18311   vat_json_init_object (node);
18312
18313   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18314   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18315   vat_json_object_add_uint (node, "transport_protocol",
18316                             mp->transport_protocol);
18317 }
18318
18319 static int
18320 api_sw_interface_span_enable_disable (vat_main_t * vam)
18321 {
18322   unformat_input_t *i = vam->input;
18323   vl_api_sw_interface_span_enable_disable_t *mp;
18324   u32 src_sw_if_index = ~0;
18325   u32 dst_sw_if_index = ~0;
18326   u8 state = 3;
18327   int ret;
18328   u8 is_l2 = 0;
18329
18330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18331     {
18332       if (unformat
18333           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18334         ;
18335       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18336         ;
18337       else
18338         if (unformat
18339             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18340         ;
18341       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18342         ;
18343       else if (unformat (i, "disable"))
18344         state = 0;
18345       else if (unformat (i, "rx"))
18346         state = 1;
18347       else if (unformat (i, "tx"))
18348         state = 2;
18349       else if (unformat (i, "both"))
18350         state = 3;
18351       else if (unformat (i, "l2"))
18352         is_l2 = 1;
18353       else
18354         break;
18355     }
18356
18357   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18358
18359   mp->sw_if_index_from = htonl (src_sw_if_index);
18360   mp->sw_if_index_to = htonl (dst_sw_if_index);
18361   mp->state = state;
18362   mp->is_l2 = is_l2;
18363
18364   S (mp);
18365   W (ret);
18366   return ret;
18367 }
18368
18369 static void
18370 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18371                                             * mp)
18372 {
18373   vat_main_t *vam = &vat_main;
18374   u8 *sw_if_from_name = 0;
18375   u8 *sw_if_to_name = 0;
18376   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18377   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18378   char *states[] = { "none", "rx", "tx", "both" };
18379   hash_pair_t *p;
18380
18381   /* *INDENT-OFF* */
18382   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18383   ({
18384     if ((u32) p->value[0] == sw_if_index_from)
18385       {
18386         sw_if_from_name = (u8 *)(p->key);
18387         if (sw_if_to_name)
18388           break;
18389       }
18390     if ((u32) p->value[0] == sw_if_index_to)
18391       {
18392         sw_if_to_name = (u8 *)(p->key);
18393         if (sw_if_from_name)
18394           break;
18395       }
18396   }));
18397   /* *INDENT-ON* */
18398   print (vam->ofp, "%20s => %20s (%s) %s",
18399          sw_if_from_name, sw_if_to_name, states[mp->state],
18400          mp->is_l2 ? "l2" : "device");
18401 }
18402
18403 static void
18404   vl_api_sw_interface_span_details_t_handler_json
18405   (vl_api_sw_interface_span_details_t * mp)
18406 {
18407   vat_main_t *vam = &vat_main;
18408   vat_json_node_t *node = NULL;
18409   u8 *sw_if_from_name = 0;
18410   u8 *sw_if_to_name = 0;
18411   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18412   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18413   hash_pair_t *p;
18414
18415   /* *INDENT-OFF* */
18416   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18417   ({
18418     if ((u32) p->value[0] == sw_if_index_from)
18419       {
18420         sw_if_from_name = (u8 *)(p->key);
18421         if (sw_if_to_name)
18422           break;
18423       }
18424     if ((u32) p->value[0] == sw_if_index_to)
18425       {
18426         sw_if_to_name = (u8 *)(p->key);
18427         if (sw_if_from_name)
18428           break;
18429       }
18430   }));
18431   /* *INDENT-ON* */
18432
18433   if (VAT_JSON_ARRAY != vam->json_tree.type)
18434     {
18435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18436       vat_json_init_array (&vam->json_tree);
18437     }
18438   node = vat_json_array_add (&vam->json_tree);
18439
18440   vat_json_init_object (node);
18441   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18442   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18443   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18444   if (0 != sw_if_to_name)
18445     {
18446       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18447     }
18448   vat_json_object_add_uint (node, "state", mp->state);
18449   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18450 }
18451
18452 static int
18453 api_sw_interface_span_dump (vat_main_t * vam)
18454 {
18455   unformat_input_t *input = vam->input;
18456   vl_api_sw_interface_span_dump_t *mp;
18457   vl_api_control_ping_t *mp_ping;
18458   u8 is_l2 = 0;
18459   int ret;
18460
18461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18462     {
18463       if (unformat (input, "l2"))
18464         is_l2 = 1;
18465       else
18466         break;
18467     }
18468
18469   M (SW_INTERFACE_SPAN_DUMP, mp);
18470   mp->is_l2 = is_l2;
18471   S (mp);
18472
18473   /* Use a control ping for synchronization */
18474   MPING (CONTROL_PING, mp_ping);
18475   S (mp_ping);
18476
18477   W (ret);
18478   return ret;
18479 }
18480
18481 int
18482 api_pg_create_interface (vat_main_t * vam)
18483 {
18484   unformat_input_t *input = vam->input;
18485   vl_api_pg_create_interface_t *mp;
18486
18487   u32 if_id = ~0, gso_size = 0;
18488   u8 gso_enabled = 0;
18489   int ret;
18490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18491     {
18492       if (unformat (input, "if_id %d", &if_id))
18493         ;
18494       else if (unformat (input, "gso-enabled"))
18495         {
18496           gso_enabled = 1;
18497           if (unformat (input, "gso-size %u", &gso_size))
18498             ;
18499           else
18500             {
18501               errmsg ("missing gso-size");
18502               return -99;
18503             }
18504         }
18505       else
18506         break;
18507     }
18508   if (if_id == ~0)
18509     {
18510       errmsg ("missing pg interface index");
18511       return -99;
18512     }
18513
18514   /* Construct the API message */
18515   M (PG_CREATE_INTERFACE, mp);
18516   mp->context = 0;
18517   mp->interface_id = ntohl (if_id);
18518   mp->gso_enabled = gso_enabled;
18519
18520   S (mp);
18521   W (ret);
18522   return ret;
18523 }
18524
18525 int
18526 api_pg_capture (vat_main_t * vam)
18527 {
18528   unformat_input_t *input = vam->input;
18529   vl_api_pg_capture_t *mp;
18530
18531   u32 if_id = ~0;
18532   u8 enable = 1;
18533   u32 count = 1;
18534   u8 pcap_file_set = 0;
18535   u8 *pcap_file = 0;
18536   int ret;
18537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18538     {
18539       if (unformat (input, "if_id %d", &if_id))
18540         ;
18541       else if (unformat (input, "pcap %s", &pcap_file))
18542         pcap_file_set = 1;
18543       else if (unformat (input, "count %d", &count))
18544         ;
18545       else if (unformat (input, "disable"))
18546         enable = 0;
18547       else
18548         break;
18549     }
18550   if (if_id == ~0)
18551     {
18552       errmsg ("missing pg interface index");
18553       return -99;
18554     }
18555   if (pcap_file_set > 0)
18556     {
18557       if (vec_len (pcap_file) > 255)
18558         {
18559           errmsg ("pcap file name is too long");
18560           return -99;
18561         }
18562     }
18563
18564   /* Construct the API message */
18565   M (PG_CAPTURE, mp);
18566   mp->context = 0;
18567   mp->interface_id = ntohl (if_id);
18568   mp->is_enabled = enable;
18569   mp->count = ntohl (count);
18570   if (pcap_file_set != 0)
18571     {
18572       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18573     }
18574   vec_free (pcap_file);
18575
18576   S (mp);
18577   W (ret);
18578   return ret;
18579 }
18580
18581 int
18582 api_pg_enable_disable (vat_main_t * vam)
18583 {
18584   unformat_input_t *input = vam->input;
18585   vl_api_pg_enable_disable_t *mp;
18586
18587   u8 enable = 1;
18588   u8 stream_name_set = 0;
18589   u8 *stream_name = 0;
18590   int ret;
18591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18592     {
18593       if (unformat (input, "stream %s", &stream_name))
18594         stream_name_set = 1;
18595       else if (unformat (input, "disable"))
18596         enable = 0;
18597       else
18598         break;
18599     }
18600
18601   if (stream_name_set > 0)
18602     {
18603       if (vec_len (stream_name) > 255)
18604         {
18605           errmsg ("stream name too long");
18606           return -99;
18607         }
18608     }
18609
18610   /* Construct the API message */
18611   M (PG_ENABLE_DISABLE, mp);
18612   mp->context = 0;
18613   mp->is_enabled = enable;
18614   if (stream_name_set != 0)
18615     {
18616       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18617     }
18618   vec_free (stream_name);
18619
18620   S (mp);
18621   W (ret);
18622   return ret;
18623 }
18624
18625 int
18626 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
18627 {
18628   unformat_input_t *input = vam->input;
18629   vl_api_pg_interface_enable_disable_coalesce_t *mp;
18630
18631   u32 sw_if_index = ~0;
18632   u8 enable = 1;
18633   int ret;
18634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18635     {
18636       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18637         ;
18638       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18639         ;
18640       else if (unformat (input, "disable"))
18641         enable = 0;
18642       else
18643         break;
18644     }
18645
18646   if (sw_if_index == ~0)
18647     {
18648       errmsg ("Interface required but not specified");
18649       return -99;
18650     }
18651
18652   /* Construct the API message */
18653   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
18654   mp->context = 0;
18655   mp->coalesce_enabled = enable;
18656   mp->sw_if_index = htonl (sw_if_index);
18657
18658   S (mp);
18659   W (ret);
18660   return ret;
18661 }
18662
18663 int
18664 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18665 {
18666   unformat_input_t *input = vam->input;
18667   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18668
18669   u16 *low_ports = 0;
18670   u16 *high_ports = 0;
18671   u16 this_low;
18672   u16 this_hi;
18673   vl_api_prefix_t prefix;
18674   u32 tmp, tmp2;
18675   u8 prefix_set = 0;
18676   u32 vrf_id = ~0;
18677   u8 is_add = 1;
18678   int ret;
18679
18680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18681     {
18682       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18683         prefix_set = 1;
18684       else if (unformat (input, "vrf %d", &vrf_id))
18685         ;
18686       else if (unformat (input, "del"))
18687         is_add = 0;
18688       else if (unformat (input, "port %d", &tmp))
18689         {
18690           if (tmp == 0 || tmp > 65535)
18691             {
18692               errmsg ("port %d out of range", tmp);
18693               return -99;
18694             }
18695           this_low = tmp;
18696           this_hi = this_low + 1;
18697           vec_add1 (low_ports, this_low);
18698           vec_add1 (high_ports, this_hi);
18699         }
18700       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18701         {
18702           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18703             {
18704               errmsg ("incorrect range parameters");
18705               return -99;
18706             }
18707           this_low = tmp;
18708           /* Note: in debug CLI +1 is added to high before
18709              passing to real fn that does "the work"
18710              (ip_source_and_port_range_check_add_del).
18711              This fn is a wrapper around the binary API fn a
18712              control plane will call, which expects this increment
18713              to have occurred. Hence letting the binary API control
18714              plane fn do the increment for consistency between VAT
18715              and other control planes.
18716            */
18717           this_hi = tmp2;
18718           vec_add1 (low_ports, this_low);
18719           vec_add1 (high_ports, this_hi);
18720         }
18721       else
18722         break;
18723     }
18724
18725   if (prefix_set == 0)
18726     {
18727       errmsg ("<address>/<mask> not specified");
18728       return -99;
18729     }
18730
18731   if (vrf_id == ~0)
18732     {
18733       errmsg ("VRF ID required, not specified");
18734       return -99;
18735     }
18736
18737   if (vrf_id == 0)
18738     {
18739       errmsg
18740         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18741       return -99;
18742     }
18743
18744   if (vec_len (low_ports) == 0)
18745     {
18746       errmsg ("At least one port or port range required");
18747       return -99;
18748     }
18749
18750   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18751
18752   mp->is_add = is_add;
18753
18754   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18755
18756   mp->number_of_ranges = vec_len (low_ports);
18757
18758   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18759   vec_free (low_ports);
18760
18761   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18762   vec_free (high_ports);
18763
18764   mp->vrf_id = ntohl (vrf_id);
18765
18766   S (mp);
18767   W (ret);
18768   return ret;
18769 }
18770
18771 int
18772 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18773 {
18774   unformat_input_t *input = vam->input;
18775   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18776   u32 sw_if_index = ~0;
18777   int vrf_set = 0;
18778   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18779   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18780   u8 is_add = 1;
18781   int ret;
18782
18783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18784     {
18785       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18786         ;
18787       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18788         ;
18789       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18790         vrf_set = 1;
18791       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18792         vrf_set = 1;
18793       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18794         vrf_set = 1;
18795       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18796         vrf_set = 1;
18797       else if (unformat (input, "del"))
18798         is_add = 0;
18799       else
18800         break;
18801     }
18802
18803   if (sw_if_index == ~0)
18804     {
18805       errmsg ("Interface required but not specified");
18806       return -99;
18807     }
18808
18809   if (vrf_set == 0)
18810     {
18811       errmsg ("VRF ID required but not specified");
18812       return -99;
18813     }
18814
18815   if (tcp_out_vrf_id == 0
18816       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18817     {
18818       errmsg
18819         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18820       return -99;
18821     }
18822
18823   /* Construct the API message */
18824   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18825
18826   mp->sw_if_index = ntohl (sw_if_index);
18827   mp->is_add = is_add;
18828   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18829   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18830   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18831   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18832
18833   /* send it... */
18834   S (mp);
18835
18836   /* Wait for a reply... */
18837   W (ret);
18838   return ret;
18839 }
18840
18841 static int
18842 api_set_punt (vat_main_t * vam)
18843 {
18844   unformat_input_t *i = vam->input;
18845   vl_api_address_family_t af;
18846   vl_api_set_punt_t *mp;
18847   u32 protocol = ~0;
18848   u32 port = ~0;
18849   int is_add = 1;
18850   int ret;
18851
18852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18853     {
18854       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18855         ;
18856       else if (unformat (i, "protocol %d", &protocol))
18857         ;
18858       else if (unformat (i, "port %d", &port))
18859         ;
18860       else if (unformat (i, "del"))
18861         is_add = 0;
18862       else
18863         {
18864           clib_warning ("parse error '%U'", format_unformat_error, i);
18865           return -99;
18866         }
18867     }
18868
18869   M (SET_PUNT, mp);
18870
18871   mp->is_add = (u8) is_add;
18872   mp->punt.type = PUNT_API_TYPE_L4;
18873   mp->punt.punt.l4.af = af;
18874   mp->punt.punt.l4.protocol = (u8) protocol;
18875   mp->punt.punt.l4.port = htons ((u16) port);
18876
18877   S (mp);
18878   W (ret);
18879   return ret;
18880 }
18881
18882 static int
18883 api_delete_subif (vat_main_t * vam)
18884 {
18885   unformat_input_t *i = vam->input;
18886   vl_api_delete_subif_t *mp;
18887   u32 sw_if_index = ~0;
18888   int ret;
18889
18890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18891     {
18892       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18893         ;
18894       if (unformat (i, "sw_if_index %d", &sw_if_index))
18895         ;
18896       else
18897         break;
18898     }
18899
18900   if (sw_if_index == ~0)
18901     {
18902       errmsg ("missing sw_if_index");
18903       return -99;
18904     }
18905
18906   /* Construct the API message */
18907   M (DELETE_SUBIF, mp);
18908   mp->sw_if_index = ntohl (sw_if_index);
18909
18910   S (mp);
18911   W (ret);
18912   return ret;
18913 }
18914
18915 #define foreach_pbb_vtr_op      \
18916 _("disable",  L2_VTR_DISABLED)  \
18917 _("pop",  L2_VTR_POP_2)         \
18918 _("push",  L2_VTR_PUSH_2)
18919
18920 static int
18921 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18922 {
18923   unformat_input_t *i = vam->input;
18924   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18925   u32 sw_if_index = ~0, vtr_op = ~0;
18926   u16 outer_tag = ~0;
18927   u8 dmac[6], smac[6];
18928   u8 dmac_set = 0, smac_set = 0;
18929   u16 vlanid = 0;
18930   u32 sid = ~0;
18931   u32 tmp;
18932   int ret;
18933
18934   /* Shut up coverity */
18935   clib_memset (dmac, 0, sizeof (dmac));
18936   clib_memset (smac, 0, sizeof (smac));
18937
18938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18939     {
18940       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18941         ;
18942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18943         ;
18944       else if (unformat (i, "vtr_op %d", &vtr_op))
18945         ;
18946 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18947       foreach_pbb_vtr_op
18948 #undef _
18949         else if (unformat (i, "translate_pbb_stag"))
18950         {
18951           if (unformat (i, "%d", &tmp))
18952             {
18953               vtr_op = L2_VTR_TRANSLATE_2_1;
18954               outer_tag = tmp;
18955             }
18956           else
18957             {
18958               errmsg
18959                 ("translate_pbb_stag operation requires outer tag definition");
18960               return -99;
18961             }
18962         }
18963       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18964         dmac_set++;
18965       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18966         smac_set++;
18967       else if (unformat (i, "sid %d", &sid))
18968         ;
18969       else if (unformat (i, "vlanid %d", &tmp))
18970         vlanid = tmp;
18971       else
18972         {
18973           clib_warning ("parse error '%U'", format_unformat_error, i);
18974           return -99;
18975         }
18976     }
18977
18978   if ((sw_if_index == ~0) || (vtr_op == ~0))
18979     {
18980       errmsg ("missing sw_if_index or vtr operation");
18981       return -99;
18982     }
18983   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18984       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18985     {
18986       errmsg
18987         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18988       return -99;
18989     }
18990
18991   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18992   mp->sw_if_index = ntohl (sw_if_index);
18993   mp->vtr_op = ntohl (vtr_op);
18994   mp->outer_tag = ntohs (outer_tag);
18995   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18996   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18997   mp->b_vlanid = ntohs (vlanid);
18998   mp->i_sid = ntohl (sid);
18999
19000   S (mp);
19001   W (ret);
19002   return ret;
19003 }
19004
19005 static int
19006 api_flow_classify_set_interface (vat_main_t * vam)
19007 {
19008   unformat_input_t *i = vam->input;
19009   vl_api_flow_classify_set_interface_t *mp;
19010   u32 sw_if_index;
19011   int sw_if_index_set;
19012   u32 ip4_table_index = ~0;
19013   u32 ip6_table_index = ~0;
19014   u8 is_add = 1;
19015   int ret;
19016
19017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19018     {
19019       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19020         sw_if_index_set = 1;
19021       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19022         sw_if_index_set = 1;
19023       else if (unformat (i, "del"))
19024         is_add = 0;
19025       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19026         ;
19027       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19028         ;
19029       else
19030         {
19031           clib_warning ("parse error '%U'", format_unformat_error, i);
19032           return -99;
19033         }
19034     }
19035
19036   if (sw_if_index_set == 0)
19037     {
19038       errmsg ("missing interface name or sw_if_index");
19039       return -99;
19040     }
19041
19042   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19043
19044   mp->sw_if_index = ntohl (sw_if_index);
19045   mp->ip4_table_index = ntohl (ip4_table_index);
19046   mp->ip6_table_index = ntohl (ip6_table_index);
19047   mp->is_add = is_add;
19048
19049   S (mp);
19050   W (ret);
19051   return ret;
19052 }
19053
19054 static int
19055 api_flow_classify_dump (vat_main_t * vam)
19056 {
19057   unformat_input_t *i = vam->input;
19058   vl_api_flow_classify_dump_t *mp;
19059   vl_api_control_ping_t *mp_ping;
19060   u8 type = FLOW_CLASSIFY_N_TABLES;
19061   int ret;
19062
19063   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19064     ;
19065   else
19066     {
19067       errmsg ("classify table type must be specified");
19068       return -99;
19069     }
19070
19071   if (!vam->json_output)
19072     {
19073       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19074     }
19075
19076   M (FLOW_CLASSIFY_DUMP, mp);
19077   mp->type = type;
19078   /* send it... */
19079   S (mp);
19080
19081   /* Use a control ping for synchronization */
19082   MPING (CONTROL_PING, mp_ping);
19083   S (mp_ping);
19084
19085   /* Wait for a reply... */
19086   W (ret);
19087   return ret;
19088 }
19089
19090 static int
19091 api_feature_enable_disable (vat_main_t * vam)
19092 {
19093   unformat_input_t *i = vam->input;
19094   vl_api_feature_enable_disable_t *mp;
19095   u8 *arc_name = 0;
19096   u8 *feature_name = 0;
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, "arc_name %s", &arc_name))
19104         ;
19105       else if (unformat (i, "feature_name %s", &feature_name))
19106         ;
19107       else
19108         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19109         ;
19110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19111         ;
19112       else if (unformat (i, "disable"))
19113         enable = 0;
19114       else
19115         break;
19116     }
19117
19118   if (arc_name == 0)
19119     {
19120       errmsg ("missing arc name");
19121       return -99;
19122     }
19123   if (vec_len (arc_name) > 63)
19124     {
19125       errmsg ("arc name too long");
19126     }
19127
19128   if (feature_name == 0)
19129     {
19130       errmsg ("missing feature name");
19131       return -99;
19132     }
19133   if (vec_len (feature_name) > 63)
19134     {
19135       errmsg ("feature name too long");
19136     }
19137
19138   if (sw_if_index == ~0)
19139     {
19140       errmsg ("missing interface name or sw_if_index");
19141       return -99;
19142     }
19143
19144   /* Construct the API message */
19145   M (FEATURE_ENABLE_DISABLE, mp);
19146   mp->sw_if_index = ntohl (sw_if_index);
19147   mp->enable = enable;
19148   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19149   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19150   vec_free (arc_name);
19151   vec_free (feature_name);
19152
19153   S (mp);
19154   W (ret);
19155   return ret;
19156 }
19157
19158 static int
19159 api_feature_gso_enable_disable (vat_main_t * vam)
19160 {
19161   unformat_input_t *i = vam->input;
19162   vl_api_feature_gso_enable_disable_t *mp;
19163   u32 sw_if_index = ~0;
19164   u8 enable = 1;
19165   int ret;
19166
19167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19168     {
19169       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19170         ;
19171       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19172         ;
19173       else if (unformat (i, "enable"))
19174         enable = 1;
19175       else if (unformat (i, "disable"))
19176         enable = 0;
19177       else
19178         break;
19179     }
19180
19181   if (sw_if_index == ~0)
19182     {
19183       errmsg ("missing interface name or sw_if_index");
19184       return -99;
19185     }
19186
19187   /* Construct the API message */
19188   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19189   mp->sw_if_index = ntohl (sw_if_index);
19190   mp->enable_disable = enable;
19191
19192   S (mp);
19193   W (ret);
19194   return ret;
19195 }
19196
19197 static int
19198 api_sw_interface_tag_add_del (vat_main_t * vam)
19199 {
19200   unformat_input_t *i = vam->input;
19201   vl_api_sw_interface_tag_add_del_t *mp;
19202   u32 sw_if_index = ~0;
19203   u8 *tag = 0;
19204   u8 enable = 1;
19205   int ret;
19206
19207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19208     {
19209       if (unformat (i, "tag %s", &tag))
19210         ;
19211       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19212         ;
19213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19214         ;
19215       else if (unformat (i, "del"))
19216         enable = 0;
19217       else
19218         break;
19219     }
19220
19221   if (sw_if_index == ~0)
19222     {
19223       errmsg ("missing interface name or sw_if_index");
19224       return -99;
19225     }
19226
19227   if (enable && (tag == 0))
19228     {
19229       errmsg ("no tag specified");
19230       return -99;
19231     }
19232
19233   /* Construct the API message */
19234   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19235   mp->sw_if_index = ntohl (sw_if_index);
19236   mp->is_add = enable;
19237   if (enable)
19238     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19239   vec_free (tag);
19240
19241   S (mp);
19242   W (ret);
19243   return ret;
19244 }
19245
19246 static int
19247 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19248 {
19249   unformat_input_t *i = vam->input;
19250   vl_api_mac_address_t mac = { 0 };
19251   vl_api_sw_interface_add_del_mac_address_t *mp;
19252   u32 sw_if_index = ~0;
19253   u8 is_add = 1;
19254   u8 mac_set = 0;
19255   int ret;
19256
19257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19258     {
19259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19260         ;
19261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19262         ;
19263       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19264         mac_set++;
19265       else if (unformat (i, "del"))
19266         is_add = 0;
19267       else
19268         break;
19269     }
19270
19271   if (sw_if_index == ~0)
19272     {
19273       errmsg ("missing interface name or sw_if_index");
19274       return -99;
19275     }
19276
19277   if (!mac_set)
19278     {
19279       errmsg ("missing MAC address");
19280       return -99;
19281     }
19282
19283   /* Construct the API message */
19284   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19285   mp->sw_if_index = ntohl (sw_if_index);
19286   mp->is_add = is_add;
19287   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19288
19289   S (mp);
19290   W (ret);
19291   return ret;
19292 }
19293
19294 static void vl_api_l2_xconnect_details_t_handler
19295   (vl_api_l2_xconnect_details_t * mp)
19296 {
19297   vat_main_t *vam = &vat_main;
19298
19299   print (vam->ofp, "%15d%15d",
19300          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19301 }
19302
19303 static void vl_api_l2_xconnect_details_t_handler_json
19304   (vl_api_l2_xconnect_details_t * mp)
19305 {
19306   vat_main_t *vam = &vat_main;
19307   vat_json_node_t *node = NULL;
19308
19309   if (VAT_JSON_ARRAY != vam->json_tree.type)
19310     {
19311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19312       vat_json_init_array (&vam->json_tree);
19313     }
19314   node = vat_json_array_add (&vam->json_tree);
19315
19316   vat_json_init_object (node);
19317   vat_json_object_add_uint (node, "rx_sw_if_index",
19318                             ntohl (mp->rx_sw_if_index));
19319   vat_json_object_add_uint (node, "tx_sw_if_index",
19320                             ntohl (mp->tx_sw_if_index));
19321 }
19322
19323 static int
19324 api_l2_xconnect_dump (vat_main_t * vam)
19325 {
19326   vl_api_l2_xconnect_dump_t *mp;
19327   vl_api_control_ping_t *mp_ping;
19328   int ret;
19329
19330   if (!vam->json_output)
19331     {
19332       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19333     }
19334
19335   M (L2_XCONNECT_DUMP, mp);
19336
19337   S (mp);
19338
19339   /* Use a control ping for synchronization */
19340   MPING (CONTROL_PING, mp_ping);
19341   S (mp_ping);
19342
19343   W (ret);
19344   return ret;
19345 }
19346
19347 static int
19348 api_hw_interface_set_mtu (vat_main_t * vam)
19349 {
19350   unformat_input_t *i = vam->input;
19351   vl_api_hw_interface_set_mtu_t *mp;
19352   u32 sw_if_index = ~0;
19353   u32 mtu = 0;
19354   int ret;
19355
19356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19357     {
19358       if (unformat (i, "mtu %d", &mtu))
19359         ;
19360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19361         ;
19362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19363         ;
19364       else
19365         break;
19366     }
19367
19368   if (sw_if_index == ~0)
19369     {
19370       errmsg ("missing interface name or sw_if_index");
19371       return -99;
19372     }
19373
19374   if (mtu == 0)
19375     {
19376       errmsg ("no mtu specified");
19377       return -99;
19378     }
19379
19380   /* Construct the API message */
19381   M (HW_INTERFACE_SET_MTU, mp);
19382   mp->sw_if_index = ntohl (sw_if_index);
19383   mp->mtu = ntohs ((u16) mtu);
19384
19385   S (mp);
19386   W (ret);
19387   return ret;
19388 }
19389
19390 static int
19391 api_p2p_ethernet_add (vat_main_t * vam)
19392 {
19393   unformat_input_t *i = vam->input;
19394   vl_api_p2p_ethernet_add_t *mp;
19395   u32 parent_if_index = ~0;
19396   u32 sub_id = ~0;
19397   u8 remote_mac[6];
19398   u8 mac_set = 0;
19399   int ret;
19400
19401   clib_memset (remote_mac, 0, sizeof (remote_mac));
19402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19403     {
19404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19405         ;
19406       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19407         ;
19408       else
19409         if (unformat
19410             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19411         mac_set++;
19412       else if (unformat (i, "sub_id %d", &sub_id))
19413         ;
19414       else
19415         {
19416           clib_warning ("parse error '%U'", format_unformat_error, i);
19417           return -99;
19418         }
19419     }
19420
19421   if (parent_if_index == ~0)
19422     {
19423       errmsg ("missing interface name or sw_if_index");
19424       return -99;
19425     }
19426   if (mac_set == 0)
19427     {
19428       errmsg ("missing remote mac address");
19429       return -99;
19430     }
19431   if (sub_id == ~0)
19432     {
19433       errmsg ("missing sub-interface id");
19434       return -99;
19435     }
19436
19437   M (P2P_ETHERNET_ADD, mp);
19438   mp->parent_if_index = ntohl (parent_if_index);
19439   mp->subif_id = ntohl (sub_id);
19440   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19441
19442   S (mp);
19443   W (ret);
19444   return ret;
19445 }
19446
19447 static int
19448 api_p2p_ethernet_del (vat_main_t * vam)
19449 {
19450   unformat_input_t *i = vam->input;
19451   vl_api_p2p_ethernet_del_t *mp;
19452   u32 parent_if_index = ~0;
19453   u8 remote_mac[6];
19454   u8 mac_set = 0;
19455   int ret;
19456
19457   clib_memset (remote_mac, 0, sizeof (remote_mac));
19458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19459     {
19460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19461         ;
19462       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19463         ;
19464       else
19465         if (unformat
19466             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19467         mac_set++;
19468       else
19469         {
19470           clib_warning ("parse error '%U'", format_unformat_error, i);
19471           return -99;
19472         }
19473     }
19474
19475   if (parent_if_index == ~0)
19476     {
19477       errmsg ("missing interface name or sw_if_index");
19478       return -99;
19479     }
19480   if (mac_set == 0)
19481     {
19482       errmsg ("missing remote mac address");
19483       return -99;
19484     }
19485
19486   M (P2P_ETHERNET_DEL, mp);
19487   mp->parent_if_index = ntohl (parent_if_index);
19488   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19489
19490   S (mp);
19491   W (ret);
19492   return ret;
19493 }
19494
19495 static int
19496 api_lldp_config (vat_main_t * vam)
19497 {
19498   unformat_input_t *i = vam->input;
19499   vl_api_lldp_config_t *mp;
19500   int tx_hold = 0;
19501   int tx_interval = 0;
19502   u8 *sys_name = NULL;
19503   int ret;
19504
19505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19506     {
19507       if (unformat (i, "system-name %s", &sys_name))
19508         ;
19509       else if (unformat (i, "tx-hold %d", &tx_hold))
19510         ;
19511       else if (unformat (i, "tx-interval %d", &tx_interval))
19512         ;
19513       else
19514         {
19515           clib_warning ("parse error '%U'", format_unformat_error, i);
19516           return -99;
19517         }
19518     }
19519
19520   vec_add1 (sys_name, 0);
19521
19522   M (LLDP_CONFIG, mp);
19523   mp->tx_hold = htonl (tx_hold);
19524   mp->tx_interval = htonl (tx_interval);
19525   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19526   vec_free (sys_name);
19527
19528   S (mp);
19529   W (ret);
19530   return ret;
19531 }
19532
19533 static int
19534 api_sw_interface_set_lldp (vat_main_t * vam)
19535 {
19536   unformat_input_t *i = vam->input;
19537   vl_api_sw_interface_set_lldp_t *mp;
19538   u32 sw_if_index = ~0;
19539   u32 enable = 1;
19540   u8 *port_desc = NULL, *mgmt_oid = NULL;
19541   ip4_address_t ip4_addr;
19542   ip6_address_t ip6_addr;
19543   int ret;
19544
19545   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19546   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19547
19548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19549     {
19550       if (unformat (i, "disable"))
19551         enable = 0;
19552       else
19553         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19554         ;
19555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19556         ;
19557       else if (unformat (i, "port-desc %s", &port_desc))
19558         ;
19559       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19560         ;
19561       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19562         ;
19563       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19564         ;
19565       else
19566         break;
19567     }
19568
19569   if (sw_if_index == ~0)
19570     {
19571       errmsg ("missing interface name or sw_if_index");
19572       return -99;
19573     }
19574
19575   /* Construct the API message */
19576   vec_add1 (port_desc, 0);
19577   vec_add1 (mgmt_oid, 0);
19578   M (SW_INTERFACE_SET_LLDP, mp);
19579   mp->sw_if_index = ntohl (sw_if_index);
19580   mp->enable = enable;
19581   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19582   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19583   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19584   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19585   vec_free (port_desc);
19586   vec_free (mgmt_oid);
19587
19588   S (mp);
19589   W (ret);
19590   return ret;
19591 }
19592
19593 static int
19594 api_tcp_configure_src_addresses (vat_main_t * vam)
19595 {
19596   vl_api_tcp_configure_src_addresses_t *mp;
19597   unformat_input_t *i = vam->input;
19598   vl_api_address_t first, last;
19599   u8 range_set = 0;
19600   u32 vrf_id = 0;
19601   int ret;
19602
19603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19604     {
19605       if (unformat (i, "%U - %U",
19606                     unformat_vl_api_address, &first,
19607                     unformat_vl_api_address, &last))
19608         {
19609           if (range_set)
19610             {
19611               errmsg ("one range per message (range already set)");
19612               return -99;
19613             }
19614           range_set = 1;
19615         }
19616       else if (unformat (i, "vrf %d", &vrf_id))
19617         ;
19618       else
19619         break;
19620     }
19621
19622   if (range_set == 0)
19623     {
19624       errmsg ("address range not set");
19625       return -99;
19626     }
19627
19628   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19629
19630   mp->vrf_id = ntohl (vrf_id);
19631   clib_memcpy (&mp->first_address, &first, sizeof (first));
19632   clib_memcpy (&mp->last_address, &last, sizeof (last));
19633
19634   S (mp);
19635   W (ret);
19636   return ret;
19637 }
19638
19639 static void vl_api_app_namespace_add_del_reply_t_handler
19640   (vl_api_app_namespace_add_del_reply_t * mp)
19641 {
19642   vat_main_t *vam = &vat_main;
19643   i32 retval = ntohl (mp->retval);
19644   if (vam->async_mode)
19645     {
19646       vam->async_errors += (retval < 0);
19647     }
19648   else
19649     {
19650       vam->retval = retval;
19651       if (retval == 0)
19652         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19653       vam->result_ready = 1;
19654     }
19655 }
19656
19657 static void vl_api_app_namespace_add_del_reply_t_handler_json
19658   (vl_api_app_namespace_add_del_reply_t * mp)
19659 {
19660   vat_main_t *vam = &vat_main;
19661   vat_json_node_t node;
19662
19663   vat_json_init_object (&node);
19664   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19665   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19666
19667   vat_json_print (vam->ofp, &node);
19668   vat_json_free (&node);
19669
19670   vam->retval = ntohl (mp->retval);
19671   vam->result_ready = 1;
19672 }
19673
19674 static int
19675 api_app_namespace_add_del (vat_main_t * vam)
19676 {
19677   vl_api_app_namespace_add_del_t *mp;
19678   unformat_input_t *i = vam->input;
19679   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19680   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19681   u64 secret;
19682   int ret;
19683
19684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19685     {
19686       if (unformat (i, "id %_%v%_", &ns_id))
19687         ;
19688       else if (unformat (i, "secret %lu", &secret))
19689         secret_set = 1;
19690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19691         sw_if_index_set = 1;
19692       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19693         ;
19694       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19695         ;
19696       else
19697         break;
19698     }
19699   if (!ns_id || !secret_set || !sw_if_index_set)
19700     {
19701       errmsg ("namespace id, secret and sw_if_index must be set");
19702       return -99;
19703     }
19704   if (vec_len (ns_id) > 64)
19705     {
19706       errmsg ("namespace id too long");
19707       return -99;
19708     }
19709   M (APP_NAMESPACE_ADD_DEL, mp);
19710
19711   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19712   mp->secret = clib_host_to_net_u64 (secret);
19713   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19714   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19715   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19716   vec_free (ns_id);
19717   S (mp);
19718   W (ret);
19719   return ret;
19720 }
19721
19722 static int
19723 api_sock_init_shm (vat_main_t * vam)
19724 {
19725 #if VPP_API_TEST_BUILTIN == 0
19726   unformat_input_t *i = vam->input;
19727   vl_api_shm_elem_config_t *config = 0;
19728   u64 size = 64 << 20;
19729   int rv;
19730
19731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19732     {
19733       if (unformat (i, "size %U", unformat_memory_size, &size))
19734         ;
19735       else
19736         break;
19737     }
19738
19739   /*
19740    * Canned custom ring allocator config.
19741    * Should probably parse all of this
19742    */
19743   vec_validate (config, 6);
19744   config[0].type = VL_API_VLIB_RING;
19745   config[0].size = 256;
19746   config[0].count = 32;
19747
19748   config[1].type = VL_API_VLIB_RING;
19749   config[1].size = 1024;
19750   config[1].count = 16;
19751
19752   config[2].type = VL_API_VLIB_RING;
19753   config[2].size = 4096;
19754   config[2].count = 2;
19755
19756   config[3].type = VL_API_CLIENT_RING;
19757   config[3].size = 256;
19758   config[3].count = 32;
19759
19760   config[4].type = VL_API_CLIENT_RING;
19761   config[4].size = 1024;
19762   config[4].count = 16;
19763
19764   config[5].type = VL_API_CLIENT_RING;
19765   config[5].size = 4096;
19766   config[5].count = 2;
19767
19768   config[6].type = VL_API_QUEUE;
19769   config[6].count = 128;
19770   config[6].size = sizeof (uword);
19771
19772   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19773   if (!rv)
19774     vam->client_index_invalid = 1;
19775   return rv;
19776 #else
19777   return -99;
19778 #endif
19779 }
19780
19781 static void
19782 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19783 {
19784   vat_main_t *vam = &vat_main;
19785   fib_prefix_t lcl, rmt;
19786
19787   ip_prefix_decode (&mp->lcl, &lcl);
19788   ip_prefix_decode (&mp->rmt, &rmt);
19789
19790   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19791     {
19792       print (vam->ofp,
19793              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19794              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19795              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19796              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19797              &rmt.fp_addr.ip4, rmt.fp_len,
19798              clib_net_to_host_u16 (mp->rmt_port),
19799              clib_net_to_host_u32 (mp->action_index), mp->tag);
19800     }
19801   else
19802     {
19803       print (vam->ofp,
19804              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19805              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19806              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19807              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19808              &rmt.fp_addr.ip6, rmt.fp_len,
19809              clib_net_to_host_u16 (mp->rmt_port),
19810              clib_net_to_host_u32 (mp->action_index), mp->tag);
19811     }
19812 }
19813
19814 static void
19815 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19816                                              mp)
19817 {
19818   vat_main_t *vam = &vat_main;
19819   vat_json_node_t *node = NULL;
19820   struct in6_addr ip6;
19821   struct in_addr ip4;
19822
19823   fib_prefix_t lcl, rmt;
19824
19825   ip_prefix_decode (&mp->lcl, &lcl);
19826   ip_prefix_decode (&mp->rmt, &rmt);
19827
19828   if (VAT_JSON_ARRAY != vam->json_tree.type)
19829     {
19830       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19831       vat_json_init_array (&vam->json_tree);
19832     }
19833   node = vat_json_array_add (&vam->json_tree);
19834   vat_json_init_object (node);
19835
19836   vat_json_object_add_uint (node, "appns_index",
19837                             clib_net_to_host_u32 (mp->appns_index));
19838   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19839   vat_json_object_add_uint (node, "scope", mp->scope);
19840   vat_json_object_add_uint (node, "action_index",
19841                             clib_net_to_host_u32 (mp->action_index));
19842   vat_json_object_add_uint (node, "lcl_port",
19843                             clib_net_to_host_u16 (mp->lcl_port));
19844   vat_json_object_add_uint (node, "rmt_port",
19845                             clib_net_to_host_u16 (mp->rmt_port));
19846   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19847   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19848   vat_json_object_add_string_copy (node, "tag", mp->tag);
19849   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19850     {
19851       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19852       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19853       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19854       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19855     }
19856   else
19857     {
19858       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19859       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19860       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19861       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19862     }
19863 }
19864
19865 static int
19866 api_session_rule_add_del (vat_main_t * vam)
19867 {
19868   vl_api_session_rule_add_del_t *mp;
19869   unformat_input_t *i = vam->input;
19870   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19871   u32 appns_index = 0, scope = 0;
19872   ip4_address_t lcl_ip4, rmt_ip4;
19873   ip6_address_t lcl_ip6, rmt_ip6;
19874   u8 is_ip4 = 1, conn_set = 0;
19875   u8 is_add = 1, *tag = 0;
19876   int ret;
19877   fib_prefix_t lcl, rmt;
19878
19879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19880     {
19881       if (unformat (i, "del"))
19882         is_add = 0;
19883       else if (unformat (i, "add"))
19884         ;
19885       else if (unformat (i, "proto tcp"))
19886         proto = 0;
19887       else if (unformat (i, "proto udp"))
19888         proto = 1;
19889       else if (unformat (i, "appns %d", &appns_index))
19890         ;
19891       else if (unformat (i, "scope %d", &scope))
19892         ;
19893       else if (unformat (i, "tag %_%v%_", &tag))
19894         ;
19895       else
19896         if (unformat
19897             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19898              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19899              &rmt_port))
19900         {
19901           is_ip4 = 1;
19902           conn_set = 1;
19903         }
19904       else
19905         if (unformat
19906             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19907              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19908              &rmt_port))
19909         {
19910           is_ip4 = 0;
19911           conn_set = 1;
19912         }
19913       else if (unformat (i, "action %d", &action))
19914         ;
19915       else
19916         break;
19917     }
19918   if (proto == ~0 || !conn_set || action == ~0)
19919     {
19920       errmsg ("transport proto, connection and action must be set");
19921       return -99;
19922     }
19923
19924   if (scope > 3)
19925     {
19926       errmsg ("scope should be 0-3");
19927       return -99;
19928     }
19929
19930   M (SESSION_RULE_ADD_DEL, mp);
19931
19932   clib_memset (&lcl, 0, sizeof (lcl));
19933   clib_memset (&rmt, 0, sizeof (rmt));
19934   if (is_ip4)
19935     {
19936       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19937       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19938       lcl.fp_len = lcl_plen;
19939       rmt.fp_len = rmt_plen;
19940     }
19941   else
19942     {
19943       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19944       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19945       lcl.fp_len = lcl_plen;
19946       rmt.fp_len = rmt_plen;
19947     }
19948
19949
19950   ip_prefix_encode (&lcl, &mp->lcl);
19951   ip_prefix_encode (&rmt, &mp->rmt);
19952   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19953   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19954   mp->transport_proto =
19955     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19956   mp->action_index = clib_host_to_net_u32 (action);
19957   mp->appns_index = clib_host_to_net_u32 (appns_index);
19958   mp->scope = scope;
19959   mp->is_add = is_add;
19960   if (tag)
19961     {
19962       clib_memcpy (mp->tag, tag, vec_len (tag));
19963       vec_free (tag);
19964     }
19965
19966   S (mp);
19967   W (ret);
19968   return ret;
19969 }
19970
19971 static int
19972 api_session_rules_dump (vat_main_t * vam)
19973 {
19974   vl_api_session_rules_dump_t *mp;
19975   vl_api_control_ping_t *mp_ping;
19976   int ret;
19977
19978   if (!vam->json_output)
19979     {
19980       print (vam->ofp, "%=20s", "Session Rules");
19981     }
19982
19983   M (SESSION_RULES_DUMP, mp);
19984   /* send it... */
19985   S (mp);
19986
19987   /* Use a control ping for synchronization */
19988   MPING (CONTROL_PING, mp_ping);
19989   S (mp_ping);
19990
19991   /* Wait for a reply... */
19992   W (ret);
19993   return ret;
19994 }
19995
19996 static int
19997 api_ip_container_proxy_add_del (vat_main_t * vam)
19998 {
19999   vl_api_ip_container_proxy_add_del_t *mp;
20000   unformat_input_t *i = vam->input;
20001   u32 sw_if_index = ~0;
20002   vl_api_prefix_t pfx = { };
20003   u8 is_add = 1;
20004   int ret;
20005
20006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20007     {
20008       if (unformat (i, "del"))
20009         is_add = 0;
20010       else if (unformat (i, "add"))
20011         ;
20012       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20013         ;
20014       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20015         ;
20016       else
20017         break;
20018     }
20019   if (sw_if_index == ~0 || pfx.len == 0)
20020     {
20021       errmsg ("address and sw_if_index must be set");
20022       return -99;
20023     }
20024
20025   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20026
20027   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20028   mp->is_add = is_add;
20029   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20030
20031   S (mp);
20032   W (ret);
20033   return ret;
20034 }
20035
20036 static int
20037 api_qos_record_enable_disable (vat_main_t * vam)
20038 {
20039   unformat_input_t *i = vam->input;
20040   vl_api_qos_record_enable_disable_t *mp;
20041   u32 sw_if_index, qs = 0xff;
20042   u8 sw_if_index_set = 0;
20043   u8 enable = 1;
20044   int ret;
20045
20046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20047     {
20048       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20049         sw_if_index_set = 1;
20050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20051         sw_if_index_set = 1;
20052       else if (unformat (i, "%U", unformat_qos_source, &qs))
20053         ;
20054       else if (unformat (i, "disable"))
20055         enable = 0;
20056       else
20057         {
20058           clib_warning ("parse error '%U'", format_unformat_error, i);
20059           return -99;
20060         }
20061     }
20062
20063   if (sw_if_index_set == 0)
20064     {
20065       errmsg ("missing interface name or sw_if_index");
20066       return -99;
20067     }
20068   if (qs == 0xff)
20069     {
20070       errmsg ("input location must be specified");
20071       return -99;
20072     }
20073
20074   M (QOS_RECORD_ENABLE_DISABLE, mp);
20075
20076   mp->record.sw_if_index = ntohl (sw_if_index);
20077   mp->record.input_source = qs;
20078   mp->enable = enable;
20079
20080   S (mp);
20081   W (ret);
20082   return ret;
20083 }
20084
20085
20086 static int
20087 q_or_quit (vat_main_t * vam)
20088 {
20089 #if VPP_API_TEST_BUILTIN == 0
20090   longjmp (vam->jump_buf, 1);
20091 #endif
20092   return 0;                     /* not so much */
20093 }
20094
20095 static int
20096 q (vat_main_t * vam)
20097 {
20098   return q_or_quit (vam);
20099 }
20100
20101 static int
20102 quit (vat_main_t * vam)
20103 {
20104   return q_or_quit (vam);
20105 }
20106
20107 static int
20108 comment (vat_main_t * vam)
20109 {
20110   return 0;
20111 }
20112
20113 static int
20114 elog_save (vat_main_t * vam)
20115 {
20116 #if VPP_API_TEST_BUILTIN == 0
20117   elog_main_t *em = &vam->elog_main;
20118   unformat_input_t *i = vam->input;
20119   char *file, *chroot_file;
20120   clib_error_t *error;
20121
20122   if (!unformat (i, "%s", &file))
20123     {
20124       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20125       return 0;
20126     }
20127
20128   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20129   if (strstr (file, "..") || index (file, '/'))
20130     {
20131       errmsg ("illegal characters in filename '%s'", file);
20132       return 0;
20133     }
20134
20135   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20136
20137   vec_free (file);
20138
20139   errmsg ("Saving %wd of %wd events to %s",
20140           elog_n_events_in_buffer (em),
20141           elog_buffer_capacity (em), chroot_file);
20142
20143   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20144   vec_free (chroot_file);
20145
20146   if (error)
20147     clib_error_report (error);
20148 #else
20149   errmsg ("Use the vpp event loger...");
20150 #endif
20151
20152   return 0;
20153 }
20154
20155 static int
20156 elog_setup (vat_main_t * vam)
20157 {
20158 #if VPP_API_TEST_BUILTIN == 0
20159   elog_main_t *em = &vam->elog_main;
20160   unformat_input_t *i = vam->input;
20161   u32 nevents = 128 << 10;
20162
20163   (void) unformat (i, "nevents %d", &nevents);
20164
20165   elog_init (em, nevents);
20166   vl_api_set_elog_main (em);
20167   vl_api_set_elog_trace_api_messages (1);
20168   errmsg ("Event logger initialized with %u events", nevents);
20169 #else
20170   errmsg ("Use the vpp event loger...");
20171 #endif
20172   return 0;
20173 }
20174
20175 static int
20176 elog_enable (vat_main_t * vam)
20177 {
20178 #if VPP_API_TEST_BUILTIN == 0
20179   elog_main_t *em = &vam->elog_main;
20180
20181   elog_enable_disable (em, 1 /* enable */ );
20182   vl_api_set_elog_trace_api_messages (1);
20183   errmsg ("Event logger enabled...");
20184 #else
20185   errmsg ("Use the vpp event loger...");
20186 #endif
20187   return 0;
20188 }
20189
20190 static int
20191 elog_disable (vat_main_t * vam)
20192 {
20193 #if VPP_API_TEST_BUILTIN == 0
20194   elog_main_t *em = &vam->elog_main;
20195
20196   elog_enable_disable (em, 0 /* enable */ );
20197   vl_api_set_elog_trace_api_messages (1);
20198   errmsg ("Event logger disabled...");
20199 #else
20200   errmsg ("Use the vpp event loger...");
20201 #endif
20202   return 0;
20203 }
20204
20205 static int
20206 statseg (vat_main_t * vam)
20207 {
20208   ssvm_private_t *ssvmp = &vam->stat_segment;
20209   ssvm_shared_header_t *shared_header = ssvmp->sh;
20210   vlib_counter_t **counters;
20211   u64 thread0_index1_packets;
20212   u64 thread0_index1_bytes;
20213   f64 vector_rate, input_rate;
20214   uword *p;
20215
20216   uword *counter_vector_by_name;
20217   if (vam->stat_segment_lockp == 0)
20218     {
20219       errmsg ("Stat segment not mapped...");
20220       return -99;
20221     }
20222
20223   /* look up "/if/rx for sw_if_index 1 as a test */
20224
20225   clib_spinlock_lock (vam->stat_segment_lockp);
20226
20227   counter_vector_by_name = (uword *) shared_header->opaque[1];
20228
20229   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20230   if (p == 0)
20231     {
20232       clib_spinlock_unlock (vam->stat_segment_lockp);
20233       errmsg ("/if/tx not found?");
20234       return -99;
20235     }
20236
20237   /* Fish per-thread vector of combined counters from shared memory */
20238   counters = (vlib_counter_t **) p[0];
20239
20240   if (vec_len (counters[0]) < 2)
20241     {
20242       clib_spinlock_unlock (vam->stat_segment_lockp);
20243       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20244       return -99;
20245     }
20246
20247   /* Read thread 0 sw_if_index 1 counter */
20248   thread0_index1_packets = counters[0][1].packets;
20249   thread0_index1_bytes = counters[0][1].bytes;
20250
20251   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20252   if (p == 0)
20253     {
20254       clib_spinlock_unlock (vam->stat_segment_lockp);
20255       errmsg ("vector_rate not found?");
20256       return -99;
20257     }
20258
20259   vector_rate = *(f64 *) (p[0]);
20260   p = hash_get_mem (counter_vector_by_name, "input_rate");
20261   if (p == 0)
20262     {
20263       clib_spinlock_unlock (vam->stat_segment_lockp);
20264       errmsg ("input_rate not found?");
20265       return -99;
20266     }
20267   input_rate = *(f64 *) (p[0]);
20268
20269   clib_spinlock_unlock (vam->stat_segment_lockp);
20270
20271   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20272          vector_rate, input_rate);
20273   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20274          thread0_index1_packets, thread0_index1_bytes);
20275
20276   return 0;
20277 }
20278
20279 static int
20280 cmd_cmp (void *a1, void *a2)
20281 {
20282   u8 **c1 = a1;
20283   u8 **c2 = a2;
20284
20285   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20286 }
20287
20288 static int
20289 help (vat_main_t * vam)
20290 {
20291   u8 **cmds = 0;
20292   u8 *name = 0;
20293   hash_pair_t *p;
20294   unformat_input_t *i = vam->input;
20295   int j;
20296
20297   if (unformat (i, "%s", &name))
20298     {
20299       uword *hs;
20300
20301       vec_add1 (name, 0);
20302
20303       hs = hash_get_mem (vam->help_by_name, name);
20304       if (hs)
20305         print (vam->ofp, "usage: %s %s", name, hs[0]);
20306       else
20307         print (vam->ofp, "No such msg / command '%s'", name);
20308       vec_free (name);
20309       return 0;
20310     }
20311
20312   print (vam->ofp, "Help is available for the following:");
20313
20314     /* *INDENT-OFF* */
20315     hash_foreach_pair (p, vam->function_by_name,
20316     ({
20317       vec_add1 (cmds, (u8 *)(p->key));
20318     }));
20319     /* *INDENT-ON* */
20320
20321   vec_sort_with_function (cmds, cmd_cmp);
20322
20323   for (j = 0; j < vec_len (cmds); j++)
20324     print (vam->ofp, "%s", cmds[j]);
20325
20326   vec_free (cmds);
20327   return 0;
20328 }
20329
20330 static int
20331 set (vat_main_t * vam)
20332 {
20333   u8 *name = 0, *value = 0;
20334   unformat_input_t *i = vam->input;
20335
20336   if (unformat (i, "%s", &name))
20337     {
20338       /* The input buffer is a vector, not a string. */
20339       value = vec_dup (i->buffer);
20340       vec_delete (value, i->index, 0);
20341       /* Almost certainly has a trailing newline */
20342       if (value[vec_len (value) - 1] == '\n')
20343         value[vec_len (value) - 1] = 0;
20344       /* Make sure it's a proper string, one way or the other */
20345       vec_add1 (value, 0);
20346       (void) clib_macro_set_value (&vam->macro_main,
20347                                    (char *) name, (char *) value);
20348     }
20349   else
20350     errmsg ("usage: set <name> <value>");
20351
20352   vec_free (name);
20353   vec_free (value);
20354   return 0;
20355 }
20356
20357 static int
20358 unset (vat_main_t * vam)
20359 {
20360   u8 *name = 0;
20361
20362   if (unformat (vam->input, "%s", &name))
20363     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20364       errmsg ("unset: %s wasn't set", name);
20365   vec_free (name);
20366   return 0;
20367 }
20368
20369 typedef struct
20370 {
20371   u8 *name;
20372   u8 *value;
20373 } macro_sort_t;
20374
20375
20376 static int
20377 macro_sort_cmp (void *a1, void *a2)
20378 {
20379   macro_sort_t *s1 = a1;
20380   macro_sort_t *s2 = a2;
20381
20382   return strcmp ((char *) (s1->name), (char *) (s2->name));
20383 }
20384
20385 static int
20386 dump_macro_table (vat_main_t * vam)
20387 {
20388   macro_sort_t *sort_me = 0, *sm;
20389   int i;
20390   hash_pair_t *p;
20391
20392     /* *INDENT-OFF* */
20393     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20394     ({
20395       vec_add2 (sort_me, sm, 1);
20396       sm->name = (u8 *)(p->key);
20397       sm->value = (u8 *) (p->value[0]);
20398     }));
20399     /* *INDENT-ON* */
20400
20401   vec_sort_with_function (sort_me, macro_sort_cmp);
20402
20403   if (vec_len (sort_me))
20404     print (vam->ofp, "%-15s%s", "Name", "Value");
20405   else
20406     print (vam->ofp, "The macro table is empty...");
20407
20408   for (i = 0; i < vec_len (sort_me); i++)
20409     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20410   return 0;
20411 }
20412
20413 static int
20414 dump_node_table (vat_main_t * vam)
20415 {
20416   int i, j;
20417   vlib_node_t *node, *next_node;
20418
20419   if (vec_len (vam->graph_nodes) == 0)
20420     {
20421       print (vam->ofp, "Node table empty, issue get_node_graph...");
20422       return 0;
20423     }
20424
20425   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20426     {
20427       node = vam->graph_nodes[0][i];
20428       print (vam->ofp, "[%d] %s", i, node->name);
20429       for (j = 0; j < vec_len (node->next_nodes); j++)
20430         {
20431           if (node->next_nodes[j] != ~0)
20432             {
20433               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20434               print (vam->ofp, "  [%d] %s", j, next_node->name);
20435             }
20436         }
20437     }
20438   return 0;
20439 }
20440
20441 static int
20442 value_sort_cmp (void *a1, void *a2)
20443 {
20444   name_sort_t *n1 = a1;
20445   name_sort_t *n2 = a2;
20446
20447   if (n1->value < n2->value)
20448     return -1;
20449   if (n1->value > n2->value)
20450     return 1;
20451   return 0;
20452 }
20453
20454
20455 static int
20456 dump_msg_api_table (vat_main_t * vam)
20457 {
20458   api_main_t *am = vlibapi_get_main ();
20459   name_sort_t *nses = 0, *ns;
20460   hash_pair_t *hp;
20461   int i;
20462
20463   /* *INDENT-OFF* */
20464   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20465   ({
20466     vec_add2 (nses, ns, 1);
20467     ns->name = (u8 *)(hp->key);
20468     ns->value = (u32) hp->value[0];
20469   }));
20470   /* *INDENT-ON* */
20471
20472   vec_sort_with_function (nses, value_sort_cmp);
20473
20474   for (i = 0; i < vec_len (nses); i++)
20475     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20476   vec_free (nses);
20477   return 0;
20478 }
20479
20480 static int
20481 get_msg_id (vat_main_t * vam)
20482 {
20483   u8 *name_and_crc;
20484   u32 message_index;
20485
20486   if (unformat (vam->input, "%s", &name_and_crc))
20487     {
20488       message_index = vl_msg_api_get_msg_index (name_and_crc);
20489       if (message_index == ~0)
20490         {
20491           print (vam->ofp, " '%s' not found", name_and_crc);
20492           return 0;
20493         }
20494       print (vam->ofp, " '%s' has message index %d",
20495              name_and_crc, message_index);
20496       return 0;
20497     }
20498   errmsg ("name_and_crc required...");
20499   return 0;
20500 }
20501
20502 static int
20503 search_node_table (vat_main_t * vam)
20504 {
20505   unformat_input_t *line_input = vam->input;
20506   u8 *node_to_find;
20507   int j;
20508   vlib_node_t *node, *next_node;
20509   uword *p;
20510
20511   if (vam->graph_node_index_by_name == 0)
20512     {
20513       print (vam->ofp, "Node table empty, issue get_node_graph...");
20514       return 0;
20515     }
20516
20517   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20518     {
20519       if (unformat (line_input, "%s", &node_to_find))
20520         {
20521           vec_add1 (node_to_find, 0);
20522           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20523           if (p == 0)
20524             {
20525               print (vam->ofp, "%s not found...", node_to_find);
20526               goto out;
20527             }
20528           node = vam->graph_nodes[0][p[0]];
20529           print (vam->ofp, "[%d] %s", p[0], node->name);
20530           for (j = 0; j < vec_len (node->next_nodes); j++)
20531             {
20532               if (node->next_nodes[j] != ~0)
20533                 {
20534                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20535                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20536                 }
20537             }
20538         }
20539
20540       else
20541         {
20542           clib_warning ("parse error '%U'", format_unformat_error,
20543                         line_input);
20544           return -99;
20545         }
20546
20547     out:
20548       vec_free (node_to_find);
20549
20550     }
20551
20552   return 0;
20553 }
20554
20555
20556 static int
20557 script (vat_main_t * vam)
20558 {
20559 #if (VPP_API_TEST_BUILTIN==0)
20560   u8 *s = 0;
20561   char *save_current_file;
20562   unformat_input_t save_input;
20563   jmp_buf save_jump_buf;
20564   u32 save_line_number;
20565
20566   FILE *new_fp, *save_ifp;
20567
20568   if (unformat (vam->input, "%s", &s))
20569     {
20570       new_fp = fopen ((char *) s, "r");
20571       if (new_fp == 0)
20572         {
20573           errmsg ("Couldn't open script file %s", s);
20574           vec_free (s);
20575           return -99;
20576         }
20577     }
20578   else
20579     {
20580       errmsg ("Missing script name");
20581       return -99;
20582     }
20583
20584   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20585   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20586   save_ifp = vam->ifp;
20587   save_line_number = vam->input_line_number;
20588   save_current_file = (char *) vam->current_file;
20589
20590   vam->input_line_number = 0;
20591   vam->ifp = new_fp;
20592   vam->current_file = s;
20593   do_one_file (vam);
20594
20595   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20596   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20597   vam->ifp = save_ifp;
20598   vam->input_line_number = save_line_number;
20599   vam->current_file = (u8 *) save_current_file;
20600   vec_free (s);
20601
20602   return 0;
20603 #else
20604   clib_warning ("use the exec command...");
20605   return -99;
20606 #endif
20607 }
20608
20609 static int
20610 echo (vat_main_t * vam)
20611 {
20612   print (vam->ofp, "%v", vam->input->buffer);
20613   return 0;
20614 }
20615
20616 /* List of API message constructors, CLI names map to api_xxx */
20617 #define foreach_vpe_api_msg                                             \
20618 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20619 _(sw_interface_dump,"")                                                 \
20620 _(sw_interface_set_flags,                                               \
20621   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20622 _(sw_interface_add_del_address,                                         \
20623   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20624 _(sw_interface_set_rx_mode,                                             \
20625   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20626 _(sw_interface_set_rx_placement,                                        \
20627   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20628 _(sw_interface_rx_placement_dump,                                       \
20629   "[<intfc> | sw_if_index <id>]")                                         \
20630 _(sw_interface_set_table,                                               \
20631   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20632 _(sw_interface_set_mpls_enable,                                         \
20633   "<intfc> | sw_if_index [disable | dis]")                              \
20634 _(sw_interface_set_vpath,                                               \
20635   "<intfc> | sw_if_index <id> enable | disable")                        \
20636 _(sw_interface_set_vxlan_bypass,                                        \
20637   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20638 _(sw_interface_set_geneve_bypass,                                       \
20639   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20640 _(sw_interface_set_l2_xconnect,                                         \
20641   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20642   "enable | disable")                                                   \
20643 _(sw_interface_set_l2_bridge,                                           \
20644   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20645   "[shg <split-horizon-group>] [bvi]\n"                                 \
20646   "enable | disable")                                                   \
20647 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20648 _(bridge_domain_add_del,                                                \
20649   "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") \
20650 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20651 _(l2fib_add_del,                                                        \
20652   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20653 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20654 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20655 _(l2_flags,                                                             \
20656   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20657 _(bridge_flags,                                                         \
20658   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20659 _(tap_create_v2,                                                        \
20660   "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]") \
20661 _(tap_delete_v2,                                                        \
20662   "<vpp-if-name> | sw_if_index <id>")                                   \
20663 _(sw_interface_tap_v2_dump, "")                                         \
20664 _(virtio_pci_create,                                                    \
20665   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20666 _(virtio_pci_delete,                                                    \
20667   "<vpp-if-name> | sw_if_index <id>")                                   \
20668 _(sw_interface_virtio_pci_dump, "")                                     \
20669 _(bond_create,                                                          \
20670   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20671   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20672   "[id <if-id>]")                                                       \
20673 _(bond_delete,                                                          \
20674   "<vpp-if-name> | sw_if_index <id>")                                   \
20675 _(bond_add_member,                                                      \
20676   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20677 _(bond_detach_member,                                                   \
20678   "sw_if_index <n>")                                                    \
20679  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20680  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20681  _(sw_member_interface_dump,                                            \
20682   "<vpp-if-name> | sw_if_index <id>")                                   \
20683 _(ip_table_add_del,                                                     \
20684   "table <n> [ipv6] [add | del]\n")                                     \
20685 _(ip_route_add_del,                                                     \
20686   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20687   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20688   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20689   "[multipath] [count <n>] [del]")                                      \
20690 _(ip_mroute_add_del,                                                    \
20691   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20692   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20693 _(mpls_table_add_del,                                                   \
20694   "table <n> [add | del]\n")                                            \
20695 _(mpls_route_add_del,                                                   \
20696   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20697   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20698   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20699   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20700   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20701   "[count <n>] [del]")                                                  \
20702 _(mpls_ip_bind_unbind,                                                  \
20703   "<label> <addr/len>")                                                 \
20704 _(mpls_tunnel_add_del,                                                  \
20705   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20706   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20707   "[l2-only]  [out-label <n>]")                                         \
20708 _(sr_mpls_policy_add,                                                   \
20709   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20710 _(sr_mpls_policy_del,                                                   \
20711   "bsid <id>")                                                          \
20712 _(bier_table_add_del,                                                   \
20713   "<label> <sub-domain> <set> <bsl> [del]")                             \
20714 _(bier_route_add_del,                                                   \
20715   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20716   "[<intfc> | sw_if_index <id>]"                                        \
20717   "[weight <n>] [del] [multipath]")                                     \
20718 _(sw_interface_set_unnumbered,                                          \
20719   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20720 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20721 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20722   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20723   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20724   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20725 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20726 _(ip_table_flush, "table <n> [ipv6]")                                   \
20727 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20728 _(set_ip_flow_hash,                                                     \
20729   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20730 _(sw_interface_ip6_enable_disable,                                      \
20731   "<intfc> | sw_if_index <id> enable | disable")                        \
20732 _(l2_patch_add_del,                                                     \
20733   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20734   "enable | disable")                                                   \
20735 _(sr_localsid_add_del,                                                  \
20736   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20737   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20738 _(classify_add_del_table,                                               \
20739   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20740   " [del] [del-chain] mask <mask-value>\n"                              \
20741   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20742   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20743 _(classify_add_del_session,                                             \
20744   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20745   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20746   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20747   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20748 _(classify_set_interface_ip_table,                                      \
20749   "<intfc> | sw_if_index <nn> table <nn>")                              \
20750 _(classify_set_interface_l2_tables,                                     \
20751   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20752   "  [other-table <nn>]")                                               \
20753 _(get_node_index, "node <node-name")                                    \
20754 _(add_node_next, "node <node-name> next <next-node-name>")              \
20755 _(l2tpv3_create_tunnel,                                                 \
20756   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20757   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20758   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20759 _(l2tpv3_set_tunnel_cookies,                                            \
20760   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20761   "[new_remote_cookie <nn>]\n")                                         \
20762 _(l2tpv3_interface_enable_disable,                                      \
20763   "<intfc> | sw_if_index <nn> enable | disable")                        \
20764 _(l2tpv3_set_lookup_key,                                                \
20765   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20766 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20767 _(vxlan_offload_rx,                                                     \
20768   "hw { <interface name> | hw_if_index <nn>} "                          \
20769   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20770 _(vxlan_add_del_tunnel,                                                 \
20771   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20772   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20773   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20774 _(geneve_add_del_tunnel,                                                \
20775   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20776   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20777   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20778 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20779 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20780 _(gre_tunnel_add_del,                                                   \
20781   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20782   "[teb | erspan <session-id>] [del]")                                  \
20783 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20784 _(l2_fib_clear_table, "")                                               \
20785 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20786 _(l2_interface_vlan_tag_rewrite,                                        \
20787   "<intfc> | sw_if_index <nn> \n"                                       \
20788   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20789   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20790 _(create_vhost_user_if,                                                 \
20791         "socket <filename> [server] [renumber <dev_instance>] "         \
20792         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20793         "[mac <mac_address>] [packed]")                                 \
20794 _(modify_vhost_user_if,                                                 \
20795         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20796         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20797 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20798 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20799 _(show_version, "")                                                     \
20800 _(show_threads, "")                                                     \
20801 _(vxlan_gpe_add_del_tunnel,                                             \
20802   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20803   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20804   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20805   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20806 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20807 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20808 _(interface_name_renumber,                                              \
20809   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20810 _(input_acl_set_interface,                                              \
20811   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20812   "  [l2-table <nn>] [del]")                                            \
20813 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20814 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20815 _(ip_dump, "ipv4 | ipv6")                                               \
20816 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20817 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20818   "  spid_id <n> ")                                                     \
20819 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20820   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20821   "  integ_alg <alg> integ_key <hex>")                                  \
20822 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20823   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20824   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20825   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20826 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20827   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20828   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20829   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20830   "  [instance <n>]")     \
20831 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20832 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20833 _(delete_loopback,"sw_if_index <nn>")                                   \
20834 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20835 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20836 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20837 _(want_interface_events,  "enable|disable")                             \
20838 _(get_first_msg_id, "client <name>")                                    \
20839 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20840 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20841   "fib-id <nn> [ip4][ip6][default]")                                    \
20842 _(get_node_graph, " ")                                                  \
20843 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20844 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20845 _(ioam_disable, "")                                                     \
20846 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20847                             " sw_if_index <sw_if_index> p <priority> "  \
20848                             "w <weight>] [del]")                        \
20849 _(one_add_del_locator, "locator-set <locator_name> "                    \
20850                         "iface <intf> | sw_if_index <sw_if_index> "     \
20851                         "p <priority> w <weight> [del]")                \
20852 _(one_add_del_local_eid,"vni <vni> eid "                                \
20853                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20854                          "locator-set <locator_name> [del]"             \
20855                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20856 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20857 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20858 _(one_enable_disable, "enable|disable")                                 \
20859 _(one_map_register_enable_disable, "enable|disable")                    \
20860 _(one_map_register_fallback_threshold, "<value>")                       \
20861 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20862 _(one_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 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20868                           "<local-eid>")                                \
20869 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20870 _(one_use_petr, "ip-address> | disable")                                \
20871 _(one_map_request_mode, "src-dst|dst-only")                             \
20872 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20873 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20874 _(one_locator_set_dump, "[local | remote]")                             \
20875 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20876 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20877                        "[local] | [remote]")                            \
20878 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20879 _(one_ndp_bd_get, "")                                                   \
20880 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20881 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20882 _(one_l2_arp_bd_get, "")                                                \
20883 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20884 _(one_stats_enable_disable, "enable|disable")                           \
20885 _(show_one_stats_enable_disable, "")                                    \
20886 _(one_eid_table_vni_dump, "")                                           \
20887 _(one_eid_table_map_dump, "l2|l3")                                      \
20888 _(one_map_resolver_dump, "")                                            \
20889 _(one_map_server_dump, "")                                              \
20890 _(one_adjacencies_get, "vni <vni>")                                     \
20891 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20892 _(show_one_rloc_probe_state, "")                                        \
20893 _(show_one_map_register_state, "")                                      \
20894 _(show_one_status, "")                                                  \
20895 _(one_stats_dump, "")                                                   \
20896 _(one_stats_flush, "")                                                  \
20897 _(one_get_map_request_itr_rlocs, "")                                    \
20898 _(one_map_register_set_ttl, "<ttl>")                                    \
20899 _(one_set_transport_protocol, "udp|api")                                \
20900 _(one_get_transport_protocol, "")                                       \
20901 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20902 _(one_show_xtr_mode, "")                                                \
20903 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20904 _(one_show_pitr_mode, "")                                               \
20905 _(one_enable_disable_petr_mode, "enable|disable")                       \
20906 _(one_show_petr_mode, "")                                               \
20907 _(show_one_nsh_mapping, "")                                             \
20908 _(show_one_pitr, "")                                                    \
20909 _(show_one_use_petr, "")                                                \
20910 _(show_one_map_request_mode, "")                                        \
20911 _(show_one_map_register_ttl, "")                                        \
20912 _(show_one_map_register_fallback_threshold, "")                         \
20913 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20914                             " sw_if_index <sw_if_index> p <priority> "  \
20915                             "w <weight>] [del]")                        \
20916 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20917                         "iface <intf> | sw_if_index <sw_if_index> "     \
20918                         "p <priority> w <weight> [del]")                \
20919 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20920                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20921                          "locator-set <locator_name> [del]"             \
20922                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20923 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20924 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20925 _(lisp_enable_disable, "enable|disable")                                \
20926 _(lisp_map_register_enable_disable, "enable|disable")                   \
20927 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20928 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20929                                "[seid <seid>] "                         \
20930                                "rloc <locator> p <prio> "               \
20931                                "w <weight> [rloc <loc> ... ] "          \
20932                                "action <action> [del-all]")             \
20933 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20934                           "<local-eid>")                                \
20935 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20936 _(lisp_use_petr, "<ip-address> | disable")                              \
20937 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20938 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20939 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20940 _(lisp_locator_set_dump, "[local | remote]")                            \
20941 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20942 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20943                        "[local] | [remote]")                            \
20944 _(lisp_eid_table_vni_dump, "")                                          \
20945 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20946 _(lisp_map_resolver_dump, "")                                           \
20947 _(lisp_map_server_dump, "")                                             \
20948 _(lisp_adjacencies_get, "vni <vni>")                                    \
20949 _(gpe_fwd_entry_vnis_get, "")                                           \
20950 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20951 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20952                                 "[table <table-id>]")                   \
20953 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20954 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20955 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20956 _(gpe_get_encap_mode, "")                                               \
20957 _(lisp_gpe_add_del_iface, "up|down")                                    \
20958 _(lisp_gpe_enable_disable, "enable|disable")                            \
20959 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20960   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20961 _(show_lisp_rloc_probe_state, "")                                       \
20962 _(show_lisp_map_register_state, "")                                     \
20963 _(show_lisp_status, "")                                                 \
20964 _(lisp_get_map_request_itr_rlocs, "")                                   \
20965 _(show_lisp_pitr, "")                                                   \
20966 _(show_lisp_use_petr, "")                                               \
20967 _(show_lisp_map_request_mode, "")                                       \
20968 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20969 _(af_packet_delete, "name <host interface name>")                       \
20970 _(af_packet_dump, "")                                                   \
20971 _(policer_add_del, "name <policer name> <params> [del]")                \
20972 _(policer_dump, "[name <policer name>]")                                \
20973 _(policer_classify_set_interface,                                       \
20974   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20975   "  [l2-table <nn>] [del]")                                            \
20976 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20977 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20978 _(mpls_table_dump, "")                                                  \
20979 _(mpls_route_dump, "table-id <ID>")                                     \
20980 _(classify_table_ids, "")                                               \
20981 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20982 _(classify_table_info, "table_id <nn>")                                 \
20983 _(classify_session_dump, "table_id <nn>")                               \
20984 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20985     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20986     "[template_interval <nn>] [udp_checksum]")                          \
20987 _(ipfix_exporter_dump, "")                                              \
20988 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20989 _(ipfix_classify_stream_dump, "")                                       \
20990 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20991 _(ipfix_classify_table_dump, "")                                        \
20992 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20993 _(sw_interface_span_dump, "[l2]")                                           \
20994 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20995 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20996 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20997 _(pg_enable_disable, "[stream <id>] disable")                           \
20998 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
20999 _(ip_source_and_port_range_check_add_del,                               \
21000   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21001 _(ip_source_and_port_range_check_interface_add_del,                     \
21002   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21003   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21004 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21005 _(l2_interface_pbb_tag_rewrite,                                         \
21006   "<intfc> | sw_if_index <nn> \n"                                       \
21007   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21008   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21009 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21010 _(flow_classify_set_interface,                                          \
21011   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21012 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21013 _(ip_table_dump, "")                                                    \
21014 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21015 _(ip_mtable_dump, "")                                                   \
21016 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21017 _(feature_enable_disable, "arc_name <arc_name> "                        \
21018   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21019 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21020   "[enable | disable] ")                                                \
21021 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21022 "[disable]")                                                            \
21023 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21024   "mac <mac-address> [del]")                                            \
21025 _(l2_xconnect_dump, "")                                                 \
21026 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21027 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21028 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21029 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21030 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21031 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21032   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21033 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21034 _(sock_init_shm, "size <nnn>")                                          \
21035 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21036 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21037   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21038 _(session_rules_dump, "")                                               \
21039 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21040 _(output_acl_set_interface,                                             \
21041   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21042   "  [l2-table <nn>] [del]")                                            \
21043 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21044
21045 /* List of command functions, CLI names map directly to functions */
21046 #define foreach_cli_function                                    \
21047 _(comment, "usage: comment <ignore-rest-of-line>")              \
21048 _(dump_interface_table, "usage: dump_interface_table")          \
21049 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21050 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21051 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21052 _(dump_macro_table, "usage: dump_macro_table ")                 \
21053 _(dump_node_table, "usage: dump_node_table")                    \
21054 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21055 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21056 _(elog_disable, "usage: elog_disable")                          \
21057 _(elog_enable, "usage: elog_enable")                            \
21058 _(elog_save, "usage: elog_save <filename>")                     \
21059 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21060 _(echo, "usage: echo <message>")                                \
21061 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21062 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21063 _(help, "usage: help")                                          \
21064 _(q, "usage: quit")                                             \
21065 _(quit, "usage: quit")                                          \
21066 _(search_node_table, "usage: search_node_table <name>...")      \
21067 _(set, "usage: set <variable-name> <value>")                    \
21068 _(script, "usage: script <file-name>")                          \
21069 _(statseg, "usage: statseg")                                    \
21070 _(unset, "usage: unset <variable-name>")
21071
21072 #define _(N,n)                                  \
21073     static void vl_api_##n##_t_handler_uni      \
21074     (vl_api_##n##_t * mp)                       \
21075     {                                           \
21076         vat_main_t * vam = &vat_main;           \
21077         if (vam->json_output) {                 \
21078             vl_api_##n##_t_handler_json(mp);    \
21079         } else {                                \
21080             vl_api_##n##_t_handler(mp);         \
21081         }                                       \
21082     }
21083 foreach_vpe_api_reply_msg;
21084 #if VPP_API_TEST_BUILTIN == 0
21085 foreach_standalone_reply_msg;
21086 #endif
21087 #undef _
21088
21089 void
21090 vat_api_hookup (vat_main_t * vam)
21091 {
21092 #define _(N,n)                                                  \
21093     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21094                            vl_api_##n##_t_handler_uni,          \
21095                            vl_noop_handler,                     \
21096                            vl_api_##n##_t_endian,               \
21097                            vl_api_##n##_t_print,                \
21098                            sizeof(vl_api_##n##_t), 1);
21099   foreach_vpe_api_reply_msg;
21100 #if VPP_API_TEST_BUILTIN == 0
21101   foreach_standalone_reply_msg;
21102 #endif
21103 #undef _
21104
21105 #if (VPP_API_TEST_BUILTIN==0)
21106   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21107
21108   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21109
21110   vam->function_by_name = hash_create_string (0, sizeof (uword));
21111
21112   vam->help_by_name = hash_create_string (0, sizeof (uword));
21113 #endif
21114
21115   /* API messages we can send */
21116 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21117   foreach_vpe_api_msg;
21118 #undef _
21119
21120   /* Help strings */
21121 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21122   foreach_vpe_api_msg;
21123 #undef _
21124
21125   /* CLI functions */
21126 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21127   foreach_cli_function;
21128 #undef _
21129
21130   /* Help strings */
21131 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21132   foreach_cli_function;
21133 #undef _
21134 }
21135
21136 #if VPP_API_TEST_BUILTIN
21137 static clib_error_t *
21138 vat_api_hookup_shim (vlib_main_t * vm)
21139 {
21140   vat_api_hookup (&vat_main);
21141   return 0;
21142 }
21143
21144 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21145 #endif
21146
21147 /*
21148  * fd.io coding-style-patch-verification: ON
21149  *
21150  * Local Variables:
21151  * eval: (c-set-style "gnu")
21152  * End:
21153  */