bonding: add bond_create2 API to include gso option
[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_create_v2_reply_t_handler
1833   (vl_api_virtio_pci_create_v2_reply_t * 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->sw_if_index = ntohl (mp->sw_if_index);
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1850   (vl_api_virtio_pci_create_v2_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void
1867 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1868                                           mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   i32 retval = ntohl (mp->retval);
1872   if (vam->async_mode)
1873     {
1874       vam->async_errors += (retval < 0);
1875     }
1876   else
1877     {
1878       vam->retval = retval;
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_virtio_pci_delete_reply_t_handler_json
1884   (vl_api_virtio_pci_delete_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891
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_create_reply_t_handler (vl_api_bond_create_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->sw_if_index = ntohl (mp->sw_if_index);
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_create_reply_t_handler_json
1918   (vl_api_bond_create_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922
1923   vat_json_init_object (&node);
1924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1926
1927   vat_json_print (vam->ofp, &node);
1928   vat_json_free (&node);
1929
1930   vam->retval = ntohl (mp->retval);
1931   vam->result_ready = 1;
1932 }
1933
1934 static void
1935 vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1936 {
1937   vat_main_t *vam = &vat_main;
1938   i32 retval = ntohl (mp->retval);
1939
1940   if (vam->async_mode)
1941     {
1942       vam->async_errors += (retval < 0);
1943     }
1944   else
1945     {
1946       vam->retval = retval;
1947       vam->sw_if_index = ntohl (mp->sw_if_index);
1948       vam->result_ready = 1;
1949     }
1950 }
1951
1952 static void vl_api_bond_create2_reply_t_handler_json
1953   (vl_api_bond_create2_reply_t * mp)
1954 {
1955   vat_main_t *vam = &vat_main;
1956   vat_json_node_t node;
1957
1958   vat_json_init_object (&node);
1959   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1960   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1961
1962   vat_json_print (vam->ofp, &node);
1963   vat_json_free (&node);
1964
1965   vam->retval = ntohl (mp->retval);
1966   vam->result_ready = 1;
1967 }
1968
1969 static void
1970 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1971 {
1972   vat_main_t *vam = &vat_main;
1973   i32 retval = ntohl (mp->retval);
1974
1975   if (vam->async_mode)
1976     {
1977       vam->async_errors += (retval < 0);
1978     }
1979   else
1980     {
1981       vam->retval = retval;
1982       vam->result_ready = 1;
1983     }
1984 }
1985
1986 static void vl_api_bond_delete_reply_t_handler_json
1987   (vl_api_bond_delete_reply_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   vat_json_node_t node;
1991
1992   vat_json_init_object (&node);
1993   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1994
1995   vat_json_print (vam->ofp, &node);
1996   vat_json_free (&node);
1997
1998   vam->retval = ntohl (mp->retval);
1999   vam->result_ready = 1;
2000 }
2001
2002 static void
2003 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
2004 {
2005   vat_main_t *vam = &vat_main;
2006   i32 retval = ntohl (mp->retval);
2007
2008   if (vam->async_mode)
2009     {
2010       vam->async_errors += (retval < 0);
2011     }
2012   else
2013     {
2014       vam->retval = retval;
2015       vam->result_ready = 1;
2016     }
2017 }
2018
2019 static void vl_api_bond_add_member_reply_t_handler_json
2020   (vl_api_bond_add_member_reply_t * mp)
2021 {
2022   vat_main_t *vam = &vat_main;
2023   vat_json_node_t node;
2024
2025   vat_json_init_object (&node);
2026   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2027
2028   vat_json_print (vam->ofp, &node);
2029   vat_json_free (&node);
2030
2031   vam->retval = ntohl (mp->retval);
2032   vam->result_ready = 1;
2033 }
2034
2035 static void
2036 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2037                                            mp)
2038 {
2039   vat_main_t *vam = &vat_main;
2040   i32 retval = ntohl (mp->retval);
2041
2042   if (vam->async_mode)
2043     {
2044       vam->async_errors += (retval < 0);
2045     }
2046   else
2047     {
2048       vam->retval = retval;
2049       vam->result_ready = 1;
2050     }
2051 }
2052
2053 static void vl_api_bond_detach_member_reply_t_handler_json
2054   (vl_api_bond_detach_member_reply_t * mp)
2055 {
2056   vat_main_t *vam = &vat_main;
2057   vat_json_node_t node;
2058
2059   vat_json_init_object (&node);
2060   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2061
2062   vat_json_print (vam->ofp, &node);
2063   vat_json_free (&node);
2064
2065   vam->retval = ntohl (mp->retval);
2066   vam->result_ready = 1;
2067 }
2068
2069 static int
2070 api_sw_interface_set_bond_weight (vat_main_t * vam)
2071 {
2072   unformat_input_t *i = vam->input;
2073   vl_api_sw_interface_set_bond_weight_t *mp;
2074   u32 sw_if_index = ~0;
2075   u32 weight = 0;
2076   u8 weight_enter = 0;
2077   int ret;
2078
2079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2080     {
2081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2082         ;
2083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2084         ;
2085       else if (unformat (i, "weight %u", &weight))
2086         weight_enter = 1;
2087       else
2088         break;
2089     }
2090
2091   if (sw_if_index == ~0)
2092     {
2093       errmsg ("missing interface name or sw_if_index");
2094       return -99;
2095     }
2096   if (weight_enter == 0)
2097     {
2098       errmsg ("missing valid weight");
2099       return -99;
2100     }
2101
2102   /* Construct the API message */
2103   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2104   mp->sw_if_index = ntohl (sw_if_index);
2105   mp->weight = ntohl (weight);
2106
2107   S (mp);
2108   W (ret);
2109   return ret;
2110 }
2111
2112 static void vl_api_sw_bond_interface_details_t_handler
2113   (vl_api_sw_bond_interface_details_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116
2117   print (vam->ofp,
2118          "%-16s %-12d %-12U %-13U %-14u %-14u",
2119          mp->interface_name, ntohl (mp->sw_if_index),
2120          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2121          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2122 }
2123
2124 static void vl_api_sw_bond_interface_details_t_handler_json
2125   (vl_api_sw_bond_interface_details_t * mp)
2126 {
2127   vat_main_t *vam = &vat_main;
2128   vat_json_node_t *node = NULL;
2129
2130   if (VAT_JSON_ARRAY != vam->json_tree.type)
2131     {
2132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2133       vat_json_init_array (&vam->json_tree);
2134     }
2135   node = vat_json_array_add (&vam->json_tree);
2136
2137   vat_json_init_object (node);
2138   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2139   vat_json_object_add_string_copy (node, "interface_name",
2140                                    mp->interface_name);
2141   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2142   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2143   vat_json_object_add_uint (node, "active_members",
2144                             ntohl (mp->active_members));
2145   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2146 }
2147
2148 static int
2149 api_sw_bond_interface_dump (vat_main_t * vam)
2150 {
2151   unformat_input_t *i = vam->input;
2152   vl_api_sw_bond_interface_dump_t *mp;
2153   vl_api_control_ping_t *mp_ping;
2154   int ret;
2155   u32 sw_if_index = ~0;
2156
2157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2158     {
2159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2160         ;
2161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2162         ;
2163       else
2164         break;
2165     }
2166
2167   print (vam->ofp,
2168          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2169          "interface name", "sw_if_index", "mode", "load balance",
2170          "active members", "members");
2171
2172   /* Get list of bond interfaces */
2173   M (SW_BOND_INTERFACE_DUMP, mp);
2174   mp->sw_if_index = ntohl (sw_if_index);
2175   S (mp);
2176
2177   /* Use a control ping for synchronization */
2178   MPING (CONTROL_PING, mp_ping);
2179   S (mp_ping);
2180
2181   W (ret);
2182   return ret;
2183 }
2184
2185 static void vl_api_sw_member_interface_details_t_handler
2186   (vl_api_sw_member_interface_details_t * mp)
2187 {
2188   vat_main_t *vam = &vat_main;
2189
2190   print (vam->ofp,
2191          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2192          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2193          ntohl (mp->weight), mp->is_local_numa);
2194 }
2195
2196 static void vl_api_sw_member_interface_details_t_handler_json
2197   (vl_api_sw_member_interface_details_t * mp)
2198 {
2199   vat_main_t *vam = &vat_main;
2200   vat_json_node_t *node = NULL;
2201
2202   if (VAT_JSON_ARRAY != vam->json_tree.type)
2203     {
2204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2205       vat_json_init_array (&vam->json_tree);
2206     }
2207   node = vat_json_array_add (&vam->json_tree);
2208
2209   vat_json_init_object (node);
2210   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2211   vat_json_object_add_string_copy (node, "interface_name",
2212                                    mp->interface_name);
2213   vat_json_object_add_uint (node, "passive", mp->is_passive);
2214   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2215   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2216   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2217 }
2218
2219 static int
2220 api_sw_member_interface_dump (vat_main_t * vam)
2221 {
2222   unformat_input_t *i = vam->input;
2223   vl_api_sw_member_interface_dump_t *mp;
2224   vl_api_control_ping_t *mp_ping;
2225   u32 sw_if_index = ~0;
2226   u8 sw_if_index_set = 0;
2227   int ret;
2228
2229   /* Parse args required to build the message */
2230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2231     {
2232       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2233         sw_if_index_set = 1;
2234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2235         sw_if_index_set = 1;
2236       else
2237         break;
2238     }
2239
2240   if (sw_if_index_set == 0)
2241     {
2242       errmsg ("missing vpp interface name. ");
2243       return -99;
2244     }
2245
2246   print (vam->ofp,
2247          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2248          "member interface name", "sw_if_index", "passive", "long_timeout",
2249          "weight", "local numa");
2250
2251   /* Get list of bond interfaces */
2252   M (SW_MEMBER_INTERFACE_DUMP, mp);
2253   mp->sw_if_index = ntohl (sw_if_index);
2254   S (mp);
2255
2256   /* Use a control ping for synchronization */
2257   MPING (CONTROL_PING, mp_ping);
2258   S (mp_ping);
2259
2260   W (ret);
2261   return ret;
2262 }
2263
2264 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2265   (vl_api_mpls_tunnel_add_del_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->sw_if_index = ntohl (mp->sw_if_index);
2277       vam->result_ready = 1;
2278     }
2279   vam->regenerate_interface_table = 1;
2280 }
2281
2282 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2283   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2284 {
2285   vat_main_t *vam = &vat_main;
2286   vat_json_node_t node;
2287
2288   vat_json_init_object (&node);
2289   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2290   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2291                             ntohl (mp->sw_if_index));
2292
2293   vat_json_print (vam->ofp, &node);
2294   vat_json_free (&node);
2295
2296   vam->retval = ntohl (mp->retval);
2297   vam->result_ready = 1;
2298 }
2299
2300 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2301   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2302 {
2303   vat_main_t *vam = &vat_main;
2304   i32 retval = ntohl (mp->retval);
2305   if (vam->async_mode)
2306     {
2307       vam->async_errors += (retval < 0);
2308     }
2309   else
2310     {
2311       vam->retval = retval;
2312       vam->sw_if_index = ntohl (mp->sw_if_index);
2313       vam->result_ready = 1;
2314     }
2315 }
2316
2317 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2318   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2319 {
2320   vat_main_t *vam = &vat_main;
2321   vat_json_node_t node;
2322
2323   vat_json_init_object (&node);
2324   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2325   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2326
2327   vat_json_print (vam->ofp, &node);
2328   vat_json_free (&node);
2329
2330   vam->retval = ntohl (mp->retval);
2331   vam->result_ready = 1;
2332 }
2333
2334 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2335   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2336 {
2337   vat_main_t *vam = &vat_main;
2338   i32 retval = ntohl (mp->retval);
2339   if (vam->async_mode)
2340     {
2341       vam->async_errors += (retval < 0);
2342     }
2343   else
2344     {
2345       vam->retval = retval;
2346       vam->result_ready = 1;
2347     }
2348 }
2349
2350 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2351   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   vat_json_node_t node;
2355
2356   vat_json_init_object (&node);
2357   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2358   vat_json_object_add_uint (&node, "fwd_entry_index",
2359                             clib_net_to_host_u32 (mp->fwd_entry_index));
2360
2361   vat_json_print (vam->ofp, &node);
2362   vat_json_free (&node);
2363
2364   vam->retval = ntohl (mp->retval);
2365   vam->result_ready = 1;
2366 }
2367
2368 u8 *
2369 format_lisp_transport_protocol (u8 * s, va_list * args)
2370 {
2371   u32 proto = va_arg (*args, u32);
2372
2373   switch (proto)
2374     {
2375     case 1:
2376       return format (s, "udp");
2377     case 2:
2378       return format (s, "api");
2379     default:
2380       return 0;
2381     }
2382   return 0;
2383 }
2384
2385 static void vl_api_one_get_transport_protocol_reply_t_handler
2386   (vl_api_one_get_transport_protocol_reply_t * mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   i32 retval = ntohl (mp->retval);
2390   if (vam->async_mode)
2391     {
2392       vam->async_errors += (retval < 0);
2393     }
2394   else
2395     {
2396       u32 proto = mp->protocol;
2397       print (vam->ofp, "Transport protocol: %U",
2398              format_lisp_transport_protocol, proto);
2399       vam->retval = retval;
2400       vam->result_ready = 1;
2401     }
2402 }
2403
2404 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2405   (vl_api_one_get_transport_protocol_reply_t * mp)
2406 {
2407   vat_main_t *vam = &vat_main;
2408   vat_json_node_t node;
2409   u8 *s;
2410
2411   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2412   vec_add1 (s, 0);
2413
2414   vat_json_init_object (&node);
2415   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2416   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2417
2418   vec_free (s);
2419   vat_json_print (vam->ofp, &node);
2420   vat_json_free (&node);
2421
2422   vam->retval = ntohl (mp->retval);
2423   vam->result_ready = 1;
2424 }
2425
2426 static void vl_api_one_add_del_locator_set_reply_t_handler
2427   (vl_api_one_add_del_locator_set_reply_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   i32 retval = ntohl (mp->retval);
2431   if (vam->async_mode)
2432     {
2433       vam->async_errors += (retval < 0);
2434     }
2435   else
2436     {
2437       vam->retval = retval;
2438       vam->result_ready = 1;
2439     }
2440 }
2441
2442 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2443   (vl_api_one_add_del_locator_set_reply_t * mp)
2444 {
2445   vat_main_t *vam = &vat_main;
2446   vat_json_node_t node;
2447
2448   vat_json_init_object (&node);
2449   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2450   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2451
2452   vat_json_print (vam->ofp, &node);
2453   vat_json_free (&node);
2454
2455   vam->retval = ntohl (mp->retval);
2456   vam->result_ready = 1;
2457 }
2458
2459 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2460   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   i32 retval = ntohl (mp->retval);
2464   if (vam->async_mode)
2465     {
2466       vam->async_errors += (retval < 0);
2467     }
2468   else
2469     {
2470       vam->retval = retval;
2471       vam->sw_if_index = ntohl (mp->sw_if_index);
2472       vam->result_ready = 1;
2473     }
2474   vam->regenerate_interface_table = 1;
2475 }
2476
2477 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2478   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   vat_json_node_t node;
2482
2483   vat_json_init_object (&node);
2484   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2485   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2486
2487   vat_json_print (vam->ofp, &node);
2488   vat_json_free (&node);
2489
2490   vam->retval = ntohl (mp->retval);
2491   vam->result_ready = 1;
2492 }
2493
2494 static void vl_api_vxlan_offload_rx_reply_t_handler
2495   (vl_api_vxlan_offload_rx_reply_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   i32 retval = ntohl (mp->retval);
2499   if (vam->async_mode)
2500     {
2501       vam->async_errors += (retval < 0);
2502     }
2503   else
2504     {
2505       vam->retval = retval;
2506       vam->result_ready = 1;
2507     }
2508 }
2509
2510 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2511   (vl_api_vxlan_offload_rx_reply_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   vat_json_node_t node;
2515
2516   vat_json_init_object (&node);
2517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2518
2519   vat_json_print (vam->ofp, &node);
2520   vat_json_free (&node);
2521
2522   vam->retval = ntohl (mp->retval);
2523   vam->result_ready = 1;
2524 }
2525
2526 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2527   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2528 {
2529   vat_main_t *vam = &vat_main;
2530   i32 retval = ntohl (mp->retval);
2531   if (vam->async_mode)
2532     {
2533       vam->async_errors += (retval < 0);
2534     }
2535   else
2536     {
2537       vam->retval = retval;
2538       vam->sw_if_index = ntohl (mp->sw_if_index);
2539       vam->result_ready = 1;
2540     }
2541 }
2542
2543 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2544   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   vat_json_node_t node;
2548
2549   vat_json_init_object (&node);
2550   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2551   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2552
2553   vat_json_print (vam->ofp, &node);
2554   vat_json_free (&node);
2555
2556   vam->retval = ntohl (mp->retval);
2557   vam->result_ready = 1;
2558 }
2559
2560 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2561   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564   i32 retval = ntohl (mp->retval);
2565   if (vam->async_mode)
2566     {
2567       vam->async_errors += (retval < 0);
2568     }
2569   else
2570     {
2571       vam->retval = retval;
2572       vam->sw_if_index = ntohl (mp->sw_if_index);
2573       vam->result_ready = 1;
2574     }
2575   vam->regenerate_interface_table = 1;
2576 }
2577
2578 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2579   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2580 {
2581   vat_main_t *vam = &vat_main;
2582   vat_json_node_t node;
2583
2584   vat_json_init_object (&node);
2585   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2586   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2587
2588   vat_json_print (vam->ofp, &node);
2589   vat_json_free (&node);
2590
2591   vam->retval = ntohl (mp->retval);
2592   vam->result_ready = 1;
2593 }
2594
2595 static void vl_api_gre_tunnel_add_del_reply_t_handler
2596   (vl_api_gre_tunnel_add_del_reply_t * mp)
2597 {
2598   vat_main_t *vam = &vat_main;
2599   i32 retval = ntohl (mp->retval);
2600   if (vam->async_mode)
2601     {
2602       vam->async_errors += (retval < 0);
2603     }
2604   else
2605     {
2606       vam->retval = retval;
2607       vam->sw_if_index = ntohl (mp->sw_if_index);
2608       vam->result_ready = 1;
2609     }
2610 }
2611
2612 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2613   (vl_api_gre_tunnel_add_del_reply_t * mp)
2614 {
2615   vat_main_t *vam = &vat_main;
2616   vat_json_node_t node;
2617
2618   vat_json_init_object (&node);
2619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2620   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2621
2622   vat_json_print (vam->ofp, &node);
2623   vat_json_free (&node);
2624
2625   vam->retval = ntohl (mp->retval);
2626   vam->result_ready = 1;
2627 }
2628
2629 static void vl_api_create_vhost_user_if_reply_t_handler
2630   (vl_api_create_vhost_user_if_reply_t * mp)
2631 {
2632   vat_main_t *vam = &vat_main;
2633   i32 retval = ntohl (mp->retval);
2634   if (vam->async_mode)
2635     {
2636       vam->async_errors += (retval < 0);
2637     }
2638   else
2639     {
2640       vam->retval = retval;
2641       vam->sw_if_index = ntohl (mp->sw_if_index);
2642       vam->result_ready = 1;
2643     }
2644   vam->regenerate_interface_table = 1;
2645 }
2646
2647 static void vl_api_create_vhost_user_if_reply_t_handler_json
2648   (vl_api_create_vhost_user_if_reply_t * mp)
2649 {
2650   vat_main_t *vam = &vat_main;
2651   vat_json_node_t node;
2652
2653   vat_json_init_object (&node);
2654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2655   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2656
2657   vat_json_print (vam->ofp, &node);
2658   vat_json_free (&node);
2659
2660   vam->retval = ntohl (mp->retval);
2661   vam->result_ready = 1;
2662 }
2663
2664 static void vl_api_ip_address_details_t_handler
2665   (vl_api_ip_address_details_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   static ip_address_details_t empty_ip_address_details = { {0} };
2669   ip_address_details_t *address = NULL;
2670   ip_details_t *current_ip_details = NULL;
2671   ip_details_t *details = NULL;
2672
2673   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2674
2675   if (!details || vam->current_sw_if_index >= vec_len (details)
2676       || !details[vam->current_sw_if_index].present)
2677     {
2678       errmsg ("ip address details arrived but not stored");
2679       errmsg ("ip_dump should be called first");
2680       return;
2681     }
2682
2683   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2684
2685 #define addresses (current_ip_details->addr)
2686
2687   vec_validate_init_empty (addresses, vec_len (addresses),
2688                            empty_ip_address_details);
2689
2690   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2691
2692   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2693   address->prefix_length = mp->prefix.len;
2694 #undef addresses
2695 }
2696
2697 static void vl_api_ip_address_details_t_handler_json
2698   (vl_api_ip_address_details_t * mp)
2699 {
2700   vat_main_t *vam = &vat_main;
2701   vat_json_node_t *node = NULL;
2702
2703   if (VAT_JSON_ARRAY != vam->json_tree.type)
2704     {
2705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2706       vat_json_init_array (&vam->json_tree);
2707     }
2708   node = vat_json_array_add (&vam->json_tree);
2709
2710   vat_json_init_object (node);
2711   vat_json_object_add_prefix (node, &mp->prefix);
2712 }
2713
2714 static void
2715 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2716 {
2717   vat_main_t *vam = &vat_main;
2718   static ip_details_t empty_ip_details = { 0 };
2719   ip_details_t *ip = NULL;
2720   u32 sw_if_index = ~0;
2721
2722   sw_if_index = ntohl (mp->sw_if_index);
2723
2724   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2725                            sw_if_index, empty_ip_details);
2726
2727   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2728                          sw_if_index);
2729
2730   ip->present = 1;
2731 }
2732
2733 static void
2734 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737
2738   if (VAT_JSON_ARRAY != vam->json_tree.type)
2739     {
2740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2741       vat_json_init_array (&vam->json_tree);
2742     }
2743   vat_json_array_add_uint (&vam->json_tree,
2744                            clib_net_to_host_u32 (mp->sw_if_index));
2745 }
2746
2747 static void vl_api_get_first_msg_id_reply_t_handler
2748   (vl_api_get_first_msg_id_reply_t * mp)
2749 {
2750   vat_main_t *vam = &vat_main;
2751   i32 retval = ntohl (mp->retval);
2752
2753   if (vam->async_mode)
2754     {
2755       vam->async_errors += (retval < 0);
2756     }
2757   else
2758     {
2759       vam->retval = retval;
2760       vam->result_ready = 1;
2761     }
2762   if (retval >= 0)
2763     {
2764       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2765     }
2766 }
2767
2768 static void vl_api_get_first_msg_id_reply_t_handler_json
2769   (vl_api_get_first_msg_id_reply_t * mp)
2770 {
2771   vat_main_t *vam = &vat_main;
2772   vat_json_node_t node;
2773
2774   vat_json_init_object (&node);
2775   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2776   vat_json_object_add_uint (&node, "first_msg_id",
2777                             (uint) ntohs (mp->first_msg_id));
2778
2779   vat_json_print (vam->ofp, &node);
2780   vat_json_free (&node);
2781
2782   vam->retval = ntohl (mp->retval);
2783   vam->result_ready = 1;
2784 }
2785
2786 static void vl_api_get_node_graph_reply_t_handler
2787   (vl_api_get_node_graph_reply_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   i32 retval = ntohl (mp->retval);
2791   u8 *pvt_copy, *reply;
2792   void *oldheap;
2793   vlib_node_t *node;
2794   int i;
2795
2796   if (vam->async_mode)
2797     {
2798       vam->async_errors += (retval < 0);
2799     }
2800   else
2801     {
2802       vam->retval = retval;
2803       vam->result_ready = 1;
2804     }
2805
2806   /* "Should never happen..." */
2807   if (retval != 0)
2808     return;
2809
2810   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2811   pvt_copy = vec_dup (reply);
2812
2813   /* Toss the shared-memory original... */
2814   oldheap = vl_msg_push_heap ();
2815
2816   vec_free (reply);
2817
2818   vl_msg_pop_heap (oldheap);
2819
2820   if (vam->graph_nodes)
2821     {
2822       hash_free (vam->graph_node_index_by_name);
2823
2824       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2825         {
2826           node = vam->graph_nodes[0][i];
2827           vec_free (node->name);
2828           vec_free (node->next_nodes);
2829           vec_free (node);
2830         }
2831       vec_free (vam->graph_nodes[0]);
2832       vec_free (vam->graph_nodes);
2833     }
2834
2835   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2836   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2837   vec_free (pvt_copy);
2838
2839   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2840     {
2841       node = vam->graph_nodes[0][i];
2842       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2843     }
2844 }
2845
2846 static void vl_api_get_node_graph_reply_t_handler_json
2847   (vl_api_get_node_graph_reply_t * mp)
2848 {
2849   vat_main_t *vam = &vat_main;
2850   void *oldheap;
2851   vat_json_node_t node;
2852   u8 *reply;
2853
2854   /* $$$$ make this real? */
2855   vat_json_init_object (&node);
2856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2857   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2858
2859   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2860
2861   /* Toss the shared-memory original... */
2862   oldheap = vl_msg_push_heap ();
2863
2864   vec_free (reply);
2865
2866   vl_msg_pop_heap (oldheap);
2867
2868   vat_json_print (vam->ofp, &node);
2869   vat_json_free (&node);
2870
2871   vam->retval = ntohl (mp->retval);
2872   vam->result_ready = 1;
2873 }
2874
2875 static void
2876 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2877 {
2878   vat_main_t *vam = &vat_main;
2879   u8 *s = 0;
2880
2881   if (mp->local)
2882     {
2883       s = format (s, "%=16d%=16d%=16d",
2884                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2885     }
2886   else
2887     {
2888       s = format (s, "%=16U%=16d%=16d",
2889                   format_ip46_address,
2890                   mp->ip_address, mp->priority, mp->weight);
2891     }
2892
2893   print (vam->ofp, "%v", s);
2894   vec_free (s);
2895 }
2896
2897 static void
2898 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2899 {
2900   vat_main_t *vam = &vat_main;
2901   vat_json_node_t *node = NULL;
2902   struct in6_addr ip6;
2903   struct in_addr ip4;
2904
2905   if (VAT_JSON_ARRAY != vam->json_tree.type)
2906     {
2907       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2908       vat_json_init_array (&vam->json_tree);
2909     }
2910   node = vat_json_array_add (&vam->json_tree);
2911   vat_json_init_object (node);
2912
2913   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2914   vat_json_object_add_uint (node, "priority", mp->priority);
2915   vat_json_object_add_uint (node, "weight", mp->weight);
2916
2917   if (mp->local)
2918     vat_json_object_add_uint (node, "sw_if_index",
2919                               clib_net_to_host_u32 (mp->sw_if_index));
2920   else
2921     {
2922       if (mp->ip_address.af)
2923         {
2924           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2925           vat_json_object_add_ip6 (node, "address", ip6);
2926         }
2927       else
2928         {
2929           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2930           vat_json_object_add_ip4 (node, "address", ip4);
2931         }
2932     }
2933 }
2934
2935 static void
2936 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2937                                           mp)
2938 {
2939   vat_main_t *vam = &vat_main;
2940   u8 *ls_name = 0;
2941
2942   ls_name = format (0, "%s", mp->ls_name);
2943
2944   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2945          ls_name);
2946   vec_free (ls_name);
2947 }
2948
2949 static void
2950   vl_api_one_locator_set_details_t_handler_json
2951   (vl_api_one_locator_set_details_t * mp)
2952 {
2953   vat_main_t *vam = &vat_main;
2954   vat_json_node_t *node = 0;
2955   u8 *ls_name = 0;
2956
2957   ls_name = format (0, "%s", mp->ls_name);
2958   vec_add1 (ls_name, 0);
2959
2960   if (VAT_JSON_ARRAY != vam->json_tree.type)
2961     {
2962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2963       vat_json_init_array (&vam->json_tree);
2964     }
2965   node = vat_json_array_add (&vam->json_tree);
2966
2967   vat_json_init_object (node);
2968   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2969   vat_json_object_add_uint (node, "ls_index",
2970                             clib_net_to_host_u32 (mp->ls_index));
2971   vec_free (ls_name);
2972 }
2973
2974 typedef struct
2975 {
2976   u32 spi;
2977   u8 si;
2978 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2979
2980 uword
2981 unformat_nsh_address (unformat_input_t * input, va_list * args)
2982 {
2983   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2984   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2985 }
2986
2987 static u8 *
2988 format_nsh_address_vat (u8 * s, va_list * args)
2989 {
2990   nsh_t *a = va_arg (*args, nsh_t *);
2991   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2992 }
2993
2994 static u8 *
2995 format_lisp_flat_eid (u8 * s, va_list * args)
2996 {
2997   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2998
2999   switch (eid->type)
3000     {
3001     case EID_TYPE_API_PREFIX:
3002       if (eid->address.prefix.address.af)
3003         return format (s, "%U/%d", format_ip6_address,
3004                        eid->address.prefix.address.un.ip6,
3005                        eid->address.prefix.len);
3006       return format (s, "%U/%d", format_ip4_address,
3007                      eid->address.prefix.address.un.ip4,
3008                      eid->address.prefix.len);
3009     case EID_TYPE_API_MAC:
3010       return format (s, "%U", format_ethernet_address, eid->address.mac);
3011     case EID_TYPE_API_NSH:
3012       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
3013     }
3014   return 0;
3015 }
3016
3017 static u8 *
3018 format_lisp_eid_vat (u8 * s, va_list * args)
3019 {
3020   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
3021   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
3022   u8 is_src_dst = (u8) va_arg (*args, int);
3023
3024   if (is_src_dst)
3025     s = format (s, "%U|", format_lisp_flat_eid, seid);
3026
3027   s = format (s, "%U", format_lisp_flat_eid, deid);
3028
3029   return s;
3030 }
3031
3032 static void
3033 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3034 {
3035   vat_main_t *vam = &vat_main;
3036   u8 *s = 0, *eid = 0;
3037
3038   if (~0 == mp->locator_set_index)
3039     s = format (0, "action: %d", mp->action);
3040   else
3041     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3042
3043   eid = format (0, "%U", format_lisp_eid_vat,
3044                 &mp->deid, &mp->seid, mp->is_src_dst);
3045   vec_add1 (eid, 0);
3046
3047   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3048          clib_net_to_host_u32 (mp->vni),
3049          eid,
3050          mp->is_local ? "local" : "remote",
3051          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3052          clib_net_to_host_u16 (mp->key.id), mp->key.key);
3053
3054   vec_free (s);
3055   vec_free (eid);
3056 }
3057
3058 static void
3059 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3060                                              * mp)
3061 {
3062   vat_main_t *vam = &vat_main;
3063   vat_json_node_t *node = 0;
3064   u8 *eid = 0;
3065
3066   if (VAT_JSON_ARRAY != vam->json_tree.type)
3067     {
3068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3069       vat_json_init_array (&vam->json_tree);
3070     }
3071   node = vat_json_array_add (&vam->json_tree);
3072
3073   vat_json_init_object (node);
3074   if (~0 == mp->locator_set_index)
3075     vat_json_object_add_uint (node, "action", mp->action);
3076   else
3077     vat_json_object_add_uint (node, "locator_set_index",
3078                               clib_net_to_host_u32 (mp->locator_set_index));
3079
3080   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3081   if (mp->deid.type == 3)
3082     {
3083       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3084       vat_json_init_object (nsh_json);
3085       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3086       vat_json_object_add_uint (nsh_json, "spi",
3087                                 clib_net_to_host_u32 (nsh->spi));
3088       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3089     }
3090   else
3091     {
3092       eid = format (0, "%U", format_lisp_eid_vat,
3093                     &mp->deid, &mp->seid, mp->is_src_dst);
3094       vec_add1 (eid, 0);
3095       vat_json_object_add_string_copy (node, "eid", eid);
3096       vec_free (eid);
3097     }
3098   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3099   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3100   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3101
3102   if (mp->key.id)
3103     {
3104       vat_json_object_add_uint (node, "key_id",
3105                                 clib_net_to_host_u16 (mp->key.id));
3106       vat_json_object_add_string_copy (node, "key", mp->key.key);
3107     }
3108 }
3109
3110 static void
3111 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3112 {
3113   vat_main_t *vam = &vat_main;
3114   u8 *seid = 0, *deid = 0;
3115   ip46_address_t lloc, rloc;
3116
3117   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3118
3119   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3120
3121   vec_add1 (deid, 0);
3122   vec_add1 (seid, 0);
3123
3124   if (mp->lloc.af)
3125     {
3126       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3127       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3128     }
3129   else
3130     {
3131       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3132       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3133     }
3134
3135
3136   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3137          clib_net_to_host_u32 (mp->vni),
3138          seid, deid,
3139          format_ip46_address, lloc,
3140          format_ip46_address, rloc,
3141          clib_net_to_host_u32 (mp->pkt_count),
3142          clib_net_to_host_u32 (mp->bytes));
3143
3144   vec_free (deid);
3145   vec_free (seid);
3146 }
3147
3148 static void
3149 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3150 {
3151   struct in6_addr ip6;
3152   struct in_addr ip4;
3153   vat_main_t *vam = &vat_main;
3154   vat_json_node_t *node = 0;
3155   u8 *deid = 0, *seid = 0;
3156
3157   if (VAT_JSON_ARRAY != vam->json_tree.type)
3158     {
3159       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3160       vat_json_init_array (&vam->json_tree);
3161     }
3162   node = vat_json_array_add (&vam->json_tree);
3163
3164   vat_json_init_object (node);
3165   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3166
3167   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3168
3169   vec_add1 (deid, 0);
3170   vec_add1 (seid, 0);
3171
3172   vat_json_object_add_string_copy (node, "seid", seid);
3173   vat_json_object_add_string_copy (node, "deid", deid);
3174   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3175
3176   if (mp->lloc.af)
3177     {
3178       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3179       vat_json_object_add_ip6 (node, "lloc", ip6);
3180       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3181       vat_json_object_add_ip6 (node, "rloc", ip6);
3182
3183     }
3184   else
3185     {
3186       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3187       vat_json_object_add_ip4 (node, "lloc", ip4);
3188       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3189       vat_json_object_add_ip4 (node, "rloc", ip4);
3190     }
3191   vat_json_object_add_uint (node, "pkt_count",
3192                             clib_net_to_host_u32 (mp->pkt_count));
3193   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3194
3195   vec_free (deid);
3196   vec_free (seid);
3197 }
3198
3199 static void
3200   vl_api_one_eid_table_map_details_t_handler
3201   (vl_api_one_eid_table_map_details_t * mp)
3202 {
3203   vat_main_t *vam = &vat_main;
3204
3205   u8 *line = format (0, "%=10d%=10d",
3206                      clib_net_to_host_u32 (mp->vni),
3207                      clib_net_to_host_u32 (mp->dp_table));
3208   print (vam->ofp, "%v", line);
3209   vec_free (line);
3210 }
3211
3212 static void
3213   vl_api_one_eid_table_map_details_t_handler_json
3214   (vl_api_one_eid_table_map_details_t * mp)
3215 {
3216   vat_main_t *vam = &vat_main;
3217   vat_json_node_t *node = NULL;
3218
3219   if (VAT_JSON_ARRAY != vam->json_tree.type)
3220     {
3221       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3222       vat_json_init_array (&vam->json_tree);
3223     }
3224   node = vat_json_array_add (&vam->json_tree);
3225   vat_json_init_object (node);
3226   vat_json_object_add_uint (node, "dp_table",
3227                             clib_net_to_host_u32 (mp->dp_table));
3228   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3229 }
3230
3231 static void
3232   vl_api_one_eid_table_vni_details_t_handler
3233   (vl_api_one_eid_table_vni_details_t * mp)
3234 {
3235   vat_main_t *vam = &vat_main;
3236
3237   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3238   print (vam->ofp, "%v", line);
3239   vec_free (line);
3240 }
3241
3242 static void
3243   vl_api_one_eid_table_vni_details_t_handler_json
3244   (vl_api_one_eid_table_vni_details_t * mp)
3245 {
3246   vat_main_t *vam = &vat_main;
3247   vat_json_node_t *node = NULL;
3248
3249   if (VAT_JSON_ARRAY != vam->json_tree.type)
3250     {
3251       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3252       vat_json_init_array (&vam->json_tree);
3253     }
3254   node = vat_json_array_add (&vam->json_tree);
3255   vat_json_init_object (node);
3256   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3257 }
3258
3259 static void
3260   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3261   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   int retval = clib_net_to_host_u32 (mp->retval);
3265
3266   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3267   print (vam->ofp, "fallback threshold value: %d", mp->value);
3268
3269   vam->retval = retval;
3270   vam->result_ready = 1;
3271 }
3272
3273 static void
3274   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3275   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278   vat_json_node_t _node, *node = &_node;
3279   int retval = clib_net_to_host_u32 (mp->retval);
3280
3281   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3282   vat_json_init_object (node);
3283   vat_json_object_add_uint (node, "value", mp->value);
3284
3285   vat_json_print (vam->ofp, node);
3286   vat_json_free (node);
3287
3288   vam->retval = retval;
3289   vam->result_ready = 1;
3290 }
3291
3292 static void
3293   vl_api_show_one_map_register_state_reply_t_handler
3294   (vl_api_show_one_map_register_state_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3300
3301   vam->retval = retval;
3302   vam->result_ready = 1;
3303 }
3304
3305 static void
3306   vl_api_show_one_map_register_state_reply_t_handler_json
3307   (vl_api_show_one_map_register_state_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   vat_json_node_t _node, *node = &_node;
3311   int retval = clib_net_to_host_u32 (mp->retval);
3312
3313   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3314
3315   vat_json_init_object (node);
3316   vat_json_object_add_string_copy (node, "state", s);
3317
3318   vat_json_print (vam->ofp, node);
3319   vat_json_free (node);
3320
3321   vam->retval = retval;
3322   vam->result_ready = 1;
3323   vec_free (s);
3324 }
3325
3326 static void
3327   vl_api_show_one_rloc_probe_state_reply_t_handler
3328   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3329 {
3330   vat_main_t *vam = &vat_main;
3331   int retval = clib_net_to_host_u32 (mp->retval);
3332
3333   if (retval)
3334     goto end;
3335
3336   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3337 end:
3338   vam->retval = retval;
3339   vam->result_ready = 1;
3340 }
3341
3342 static void
3343   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3344   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3345 {
3346   vat_main_t *vam = &vat_main;
3347   vat_json_node_t _node, *node = &_node;
3348   int retval = clib_net_to_host_u32 (mp->retval);
3349
3350   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3351   vat_json_init_object (node);
3352   vat_json_object_add_string_copy (node, "state", s);
3353
3354   vat_json_print (vam->ofp, node);
3355   vat_json_free (node);
3356
3357   vam->retval = retval;
3358   vam->result_ready = 1;
3359   vec_free (s);
3360 }
3361
3362 static void
3363   vl_api_show_one_stats_enable_disable_reply_t_handler
3364   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3365 {
3366   vat_main_t *vam = &vat_main;
3367   int retval = clib_net_to_host_u32 (mp->retval);
3368
3369   if (retval)
3370     goto end;
3371
3372   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3373 end:
3374   vam->retval = retval;
3375   vam->result_ready = 1;
3376 }
3377
3378 static void
3379   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3380   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3381 {
3382   vat_main_t *vam = &vat_main;
3383   vat_json_node_t _node, *node = &_node;
3384   int retval = clib_net_to_host_u32 (mp->retval);
3385
3386   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3387   vat_json_init_object (node);
3388   vat_json_object_add_string_copy (node, "state", s);
3389
3390   vat_json_print (vam->ofp, node);
3391   vat_json_free (node);
3392
3393   vam->retval = retval;
3394   vam->result_ready = 1;
3395   vec_free (s);
3396 }
3397
3398 static void
3399 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3400 {
3401   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3402   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3403   e->vni = clib_net_to_host_u32 (e->vni);
3404 }
3405
3406 static void
3407   gpe_fwd_entries_get_reply_t_net_to_host
3408   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3409 {
3410   u32 i;
3411
3412   mp->count = clib_net_to_host_u32 (mp->count);
3413   for (i = 0; i < mp->count; i++)
3414     {
3415       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3416     }
3417 }
3418
3419 static u8 *
3420 format_gpe_encap_mode (u8 * s, va_list * args)
3421 {
3422   u32 mode = va_arg (*args, u32);
3423
3424   switch (mode)
3425     {
3426     case 0:
3427       return format (s, "lisp");
3428     case 1:
3429       return format (s, "vxlan");
3430     }
3431   return 0;
3432 }
3433
3434 static void
3435   vl_api_gpe_get_encap_mode_reply_t_handler
3436   (vl_api_gpe_get_encap_mode_reply_t * mp)
3437 {
3438   vat_main_t *vam = &vat_main;
3439
3440   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3441   vam->retval = ntohl (mp->retval);
3442   vam->result_ready = 1;
3443 }
3444
3445 static void
3446   vl_api_gpe_get_encap_mode_reply_t_handler_json
3447   (vl_api_gpe_get_encap_mode_reply_t * mp)
3448 {
3449   vat_main_t *vam = &vat_main;
3450   vat_json_node_t node;
3451
3452   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3453   vec_add1 (encap_mode, 0);
3454
3455   vat_json_init_object (&node);
3456   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3457
3458   vec_free (encap_mode);
3459   vat_json_print (vam->ofp, &node);
3460   vat_json_free (&node);
3461
3462   vam->retval = ntohl (mp->retval);
3463   vam->result_ready = 1;
3464 }
3465
3466 static void
3467   vl_api_gpe_fwd_entry_path_details_t_handler
3468   (vl_api_gpe_fwd_entry_path_details_t * mp)
3469 {
3470   vat_main_t *vam = &vat_main;
3471   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3472
3473   if (mp->lcl_loc.addr.af)
3474     format_ip_address_fcn = format_ip6_address;
3475   else
3476     format_ip_address_fcn = format_ip4_address;
3477
3478   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3479          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3480          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3481 }
3482
3483 static void
3484 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3485 {
3486   struct in6_addr ip6;
3487   struct in_addr ip4;
3488
3489   if (loc->addr.af)
3490     {
3491       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3492       vat_json_object_add_ip6 (n, "address", ip6);
3493     }
3494   else
3495     {
3496       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3497       vat_json_object_add_ip4 (n, "address", ip4);
3498     }
3499   vat_json_object_add_uint (n, "weight", loc->weight);
3500 }
3501
3502 static void
3503   vl_api_gpe_fwd_entry_path_details_t_handler_json
3504   (vl_api_gpe_fwd_entry_path_details_t * mp)
3505 {
3506   vat_main_t *vam = &vat_main;
3507   vat_json_node_t *node = NULL;
3508   vat_json_node_t *loc_node;
3509
3510   if (VAT_JSON_ARRAY != vam->json_tree.type)
3511     {
3512       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3513       vat_json_init_array (&vam->json_tree);
3514     }
3515   node = vat_json_array_add (&vam->json_tree);
3516   vat_json_init_object (node);
3517
3518   loc_node = vat_json_object_add (node, "local_locator");
3519   vat_json_init_object (loc_node);
3520   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3521
3522   loc_node = vat_json_object_add (node, "remote_locator");
3523   vat_json_init_object (loc_node);
3524   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3525 }
3526
3527 static void
3528   vl_api_gpe_fwd_entries_get_reply_t_handler
3529   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3530 {
3531   vat_main_t *vam = &vat_main;
3532   u32 i;
3533   int retval = clib_net_to_host_u32 (mp->retval);
3534   vl_api_gpe_fwd_entry_t *e;
3535
3536   if (retval)
3537     goto end;
3538
3539   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3540
3541   for (i = 0; i < mp->count; i++)
3542     {
3543       e = &mp->entries[i];
3544       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3545              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3546     }
3547
3548 end:
3549   vam->retval = retval;
3550   vam->result_ready = 1;
3551 }
3552
3553 static void
3554   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3555   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3556 {
3557   u8 *s = 0;
3558   vat_main_t *vam = &vat_main;
3559   vat_json_node_t *e = 0, root;
3560   u32 i;
3561   int retval = clib_net_to_host_u32 (mp->retval);
3562   vl_api_gpe_fwd_entry_t *fwd;
3563
3564   if (retval)
3565     goto end;
3566
3567   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3568   vat_json_init_array (&root);
3569
3570   for (i = 0; i < mp->count; i++)
3571     {
3572       e = vat_json_array_add (&root);
3573       fwd = &mp->entries[i];
3574
3575       vat_json_init_object (e);
3576       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3577       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3578       vat_json_object_add_int (e, "vni", fwd->vni);
3579       vat_json_object_add_int (e, "action", fwd->action);
3580
3581       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3582       vec_add1 (s, 0);
3583       vat_json_object_add_string_copy (e, "leid", s);
3584       vec_free (s);
3585
3586       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3587       vec_add1 (s, 0);
3588       vat_json_object_add_string_copy (e, "reid", s);
3589       vec_free (s);
3590     }
3591
3592   vat_json_print (vam->ofp, &root);
3593   vat_json_free (&root);
3594
3595 end:
3596   vam->retval = retval;
3597   vam->result_ready = 1;
3598 }
3599
3600 static void
3601   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3602   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3603 {
3604   vat_main_t *vam = &vat_main;
3605   u32 i, n;
3606   int retval = clib_net_to_host_u32 (mp->retval);
3607   vl_api_gpe_native_fwd_rpath_t *r;
3608
3609   if (retval)
3610     goto end;
3611
3612   n = clib_net_to_host_u32 (mp->count);
3613
3614   for (i = 0; i < n; i++)
3615     {
3616       r = &mp->entries[i];
3617       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3618              clib_net_to_host_u32 (r->fib_index),
3619              clib_net_to_host_u32 (r->nh_sw_if_index),
3620              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3621              r->nh_addr.un);
3622     }
3623
3624 end:
3625   vam->retval = retval;
3626   vam->result_ready = 1;
3627 }
3628
3629 static void
3630   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3631   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3632 {
3633   vat_main_t *vam = &vat_main;
3634   vat_json_node_t root, *e;
3635   u32 i, n;
3636   int retval = clib_net_to_host_u32 (mp->retval);
3637   vl_api_gpe_native_fwd_rpath_t *r;
3638   u8 *s;
3639
3640   if (retval)
3641     goto end;
3642
3643   n = clib_net_to_host_u32 (mp->count);
3644   vat_json_init_array (&root);
3645
3646   for (i = 0; i < n; i++)
3647     {
3648       e = vat_json_array_add (&root);
3649       vat_json_init_object (e);
3650       r = &mp->entries[i];
3651       s =
3652         format (0, "%U",
3653                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3654                 r->nh_addr.un);
3655       vec_add1 (s, 0);
3656       vat_json_object_add_string_copy (e, "ip4", s);
3657       vec_free (s);
3658
3659       vat_json_object_add_uint (e, "fib_index",
3660                                 clib_net_to_host_u32 (r->fib_index));
3661       vat_json_object_add_uint (e, "nh_sw_if_index",
3662                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3663     }
3664
3665   vat_json_print (vam->ofp, &root);
3666   vat_json_free (&root);
3667
3668 end:
3669   vam->retval = retval;
3670   vam->result_ready = 1;
3671 }
3672
3673 static void
3674   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3675   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3676 {
3677   vat_main_t *vam = &vat_main;
3678   u32 i, n;
3679   int retval = clib_net_to_host_u32 (mp->retval);
3680
3681   if (retval)
3682     goto end;
3683
3684   n = clib_net_to_host_u32 (mp->count);
3685
3686   for (i = 0; i < n; i++)
3687     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3688
3689 end:
3690   vam->retval = retval;
3691   vam->result_ready = 1;
3692 }
3693
3694 static void
3695   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3696   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3697 {
3698   vat_main_t *vam = &vat_main;
3699   vat_json_node_t root;
3700   u32 i, n;
3701   int retval = clib_net_to_host_u32 (mp->retval);
3702
3703   if (retval)
3704     goto end;
3705
3706   n = clib_net_to_host_u32 (mp->count);
3707   vat_json_init_array (&root);
3708
3709   for (i = 0; i < n; i++)
3710     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3711
3712   vat_json_print (vam->ofp, &root);
3713   vat_json_free (&root);
3714
3715 end:
3716   vam->retval = retval;
3717   vam->result_ready = 1;
3718 }
3719
3720 static void
3721   vl_api_one_ndp_entries_get_reply_t_handler
3722   (vl_api_one_ndp_entries_get_reply_t * mp)
3723 {
3724   vat_main_t *vam = &vat_main;
3725   u32 i, n;
3726   int retval = clib_net_to_host_u32 (mp->retval);
3727
3728   if (retval)
3729     goto end;
3730
3731   n = clib_net_to_host_u32 (mp->count);
3732
3733   for (i = 0; i < n; i++)
3734     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3735            format_ethernet_address, mp->entries[i].mac);
3736
3737 end:
3738   vam->retval = retval;
3739   vam->result_ready = 1;
3740 }
3741
3742 static void
3743   vl_api_one_ndp_entries_get_reply_t_handler_json
3744   (vl_api_one_ndp_entries_get_reply_t * mp)
3745 {
3746   u8 *s = 0;
3747   vat_main_t *vam = &vat_main;
3748   vat_json_node_t *e = 0, root;
3749   u32 i, n;
3750   int retval = clib_net_to_host_u32 (mp->retval);
3751   vl_api_one_ndp_entry_t *arp_entry;
3752
3753   if (retval)
3754     goto end;
3755
3756   n = clib_net_to_host_u32 (mp->count);
3757   vat_json_init_array (&root);
3758
3759   for (i = 0; i < n; i++)
3760     {
3761       e = vat_json_array_add (&root);
3762       arp_entry = &mp->entries[i];
3763
3764       vat_json_init_object (e);
3765       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3766       vec_add1 (s, 0);
3767
3768       vat_json_object_add_string_copy (e, "mac", s);
3769       vec_free (s);
3770
3771       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3772       vec_add1 (s, 0);
3773       vat_json_object_add_string_copy (e, "ip6", s);
3774       vec_free (s);
3775     }
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786   vl_api_one_l2_arp_entries_get_reply_t_handler
3787   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   u32 i, n;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3800            format_ethernet_address, mp->entries[i].mac);
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3809   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3810 {
3811   u8 *s = 0;
3812   vat_main_t *vam = &vat_main;
3813   vat_json_node_t *e = 0, root;
3814   u32 i, n;
3815   int retval = clib_net_to_host_u32 (mp->retval);
3816   vl_api_one_l2_arp_entry_t *arp_entry;
3817
3818   if (retval)
3819     goto end;
3820
3821   n = clib_net_to_host_u32 (mp->count);
3822   vat_json_init_array (&root);
3823
3824   for (i = 0; i < n; i++)
3825     {
3826       e = vat_json_array_add (&root);
3827       arp_entry = &mp->entries[i];
3828
3829       vat_json_init_object (e);
3830       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3831       vec_add1 (s, 0);
3832
3833       vat_json_object_add_string_copy (e, "mac", s);
3834       vec_free (s);
3835
3836       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip4", s);
3839       vec_free (s);
3840     }
3841
3842   vat_json_print (vam->ofp, &root);
3843   vat_json_free (&root);
3844
3845 end:
3846   vam->retval = retval;
3847   vam->result_ready = 1;
3848 }
3849
3850 static void
3851 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3852 {
3853   vat_main_t *vam = &vat_main;
3854   u32 i, n;
3855   int retval = clib_net_to_host_u32 (mp->retval);
3856
3857   if (retval)
3858     goto end;
3859
3860   n = clib_net_to_host_u32 (mp->count);
3861
3862   for (i = 0; i < n; i++)
3863     {
3864       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3865     }
3866
3867 end:
3868   vam->retval = retval;
3869   vam->result_ready = 1;
3870 }
3871
3872 static void
3873   vl_api_one_ndp_bd_get_reply_t_handler_json
3874   (vl_api_one_ndp_bd_get_reply_t * mp)
3875 {
3876   vat_main_t *vam = &vat_main;
3877   vat_json_node_t root;
3878   u32 i, n;
3879   int retval = clib_net_to_host_u32 (mp->retval);
3880
3881   if (retval)
3882     goto end;
3883
3884   n = clib_net_to_host_u32 (mp->count);
3885   vat_json_init_array (&root);
3886
3887   for (i = 0; i < n; i++)
3888     {
3889       vat_json_array_add_uint (&root,
3890                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3891     }
3892
3893   vat_json_print (vam->ofp, &root);
3894   vat_json_free (&root);
3895
3896 end:
3897   vam->retval = retval;
3898   vam->result_ready = 1;
3899 }
3900
3901 static void
3902   vl_api_one_l2_arp_bd_get_reply_t_handler
3903   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3904 {
3905   vat_main_t *vam = &vat_main;
3906   u32 i, n;
3907   int retval = clib_net_to_host_u32 (mp->retval);
3908
3909   if (retval)
3910     goto end;
3911
3912   n = clib_net_to_host_u32 (mp->count);
3913
3914   for (i = 0; i < n; i++)
3915     {
3916       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3917     }
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3926   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3927 {
3928   vat_main_t *vam = &vat_main;
3929   vat_json_node_t root;
3930   u32 i, n;
3931   int retval = clib_net_to_host_u32 (mp->retval);
3932
3933   if (retval)
3934     goto end;
3935
3936   n = clib_net_to_host_u32 (mp->count);
3937   vat_json_init_array (&root);
3938
3939   for (i = 0; i < n; i++)
3940     {
3941       vat_json_array_add_uint (&root,
3942                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3943     }
3944
3945   vat_json_print (vam->ofp, &root);
3946   vat_json_free (&root);
3947
3948 end:
3949   vam->retval = retval;
3950   vam->result_ready = 1;
3951 }
3952
3953 static void
3954   vl_api_one_adjacencies_get_reply_t_handler
3955   (vl_api_one_adjacencies_get_reply_t * mp)
3956 {
3957   vat_main_t *vam = &vat_main;
3958   u32 i, n;
3959   int retval = clib_net_to_host_u32 (mp->retval);
3960   vl_api_one_adjacency_t *a;
3961
3962   if (retval)
3963     goto end;
3964
3965   n = clib_net_to_host_u32 (mp->count);
3966
3967   for (i = 0; i < n; i++)
3968     {
3969       a = &mp->adjacencies[i];
3970       print (vam->ofp, "%U %40U",
3971              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3972     }
3973
3974 end:
3975   vam->retval = retval;
3976   vam->result_ready = 1;
3977 }
3978
3979 static void
3980   vl_api_one_adjacencies_get_reply_t_handler_json
3981   (vl_api_one_adjacencies_get_reply_t * mp)
3982 {
3983   u8 *s = 0;
3984   vat_main_t *vam = &vat_main;
3985   vat_json_node_t *e = 0, root;
3986   u32 i, n;
3987   int retval = clib_net_to_host_u32 (mp->retval);
3988   vl_api_one_adjacency_t *a;
3989
3990   if (retval)
3991     goto end;
3992
3993   n = clib_net_to_host_u32 (mp->count);
3994   vat_json_init_array (&root);
3995
3996   for (i = 0; i < n; i++)
3997     {
3998       e = vat_json_array_add (&root);
3999       a = &mp->adjacencies[i];
4000
4001       vat_json_init_object (e);
4002       s = format (0, "%U", format_lisp_flat_eid, a->leid);
4003       vec_add1 (s, 0);
4004       vat_json_object_add_string_copy (e, "leid", s);
4005       vec_free (s);
4006
4007       s = format (0, "%U", format_lisp_flat_eid, a->reid);
4008       vec_add1 (s, 0);
4009       vat_json_object_add_string_copy (e, "reid", s);
4010       vec_free (s);
4011     }
4012
4013   vat_json_print (vam->ofp, &root);
4014   vat_json_free (&root);
4015
4016 end:
4017   vam->retval = retval;
4018   vam->result_ready = 1;
4019 }
4020
4021 static void
4022 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4023 {
4024   vat_main_t *vam = &vat_main;
4025
4026   print (vam->ofp, "%=20U",
4027          mp->ip_address.af ? format_ip6_address : format_ip4_address,
4028          mp->ip_address.un);
4029 }
4030
4031 static void
4032   vl_api_one_map_server_details_t_handler_json
4033   (vl_api_one_map_server_details_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   vat_json_node_t *node = NULL;
4037   struct in6_addr ip6;
4038   struct in_addr ip4;
4039
4040   if (VAT_JSON_ARRAY != vam->json_tree.type)
4041     {
4042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4043       vat_json_init_array (&vam->json_tree);
4044     }
4045   node = vat_json_array_add (&vam->json_tree);
4046
4047   vat_json_init_object (node);
4048   if (mp->ip_address.af)
4049     {
4050       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4051       vat_json_object_add_ip6 (node, "map-server", ip6);
4052     }
4053   else
4054     {
4055       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4056       vat_json_object_add_ip4 (node, "map-server", ip4);
4057     }
4058 }
4059
4060 static void
4061 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4062                                            * mp)
4063 {
4064   vat_main_t *vam = &vat_main;
4065
4066   print (vam->ofp, "%=20U",
4067          mp->ip_address.af ? format_ip6_address : format_ip4_address,
4068          mp->ip_address.un);
4069 }
4070
4071 static void
4072   vl_api_one_map_resolver_details_t_handler_json
4073   (vl_api_one_map_resolver_details_t * mp)
4074 {
4075   vat_main_t *vam = &vat_main;
4076   vat_json_node_t *node = NULL;
4077   struct in6_addr ip6;
4078   struct in_addr ip4;
4079
4080   if (VAT_JSON_ARRAY != vam->json_tree.type)
4081     {
4082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4083       vat_json_init_array (&vam->json_tree);
4084     }
4085   node = vat_json_array_add (&vam->json_tree);
4086
4087   vat_json_init_object (node);
4088   if (mp->ip_address.af)
4089     {
4090       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4091       vat_json_object_add_ip6 (node, "map resolver", ip6);
4092     }
4093   else
4094     {
4095       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4096       vat_json_object_add_ip4 (node, "map resolver", ip4);
4097     }
4098 }
4099
4100 static void
4101 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   i32 retval = ntohl (mp->retval);
4105
4106   if (0 <= retval)
4107     {
4108       print (vam->ofp, "feature: %s\ngpe: %s",
4109              mp->feature_status ? "enabled" : "disabled",
4110              mp->gpe_status ? "enabled" : "disabled");
4111     }
4112
4113   vam->retval = retval;
4114   vam->result_ready = 1;
4115 }
4116
4117 static void
4118   vl_api_show_one_status_reply_t_handler_json
4119   (vl_api_show_one_status_reply_t * mp)
4120 {
4121   vat_main_t *vam = &vat_main;
4122   vat_json_node_t node;
4123   u8 *gpe_status = NULL;
4124   u8 *feature_status = NULL;
4125
4126   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4127   feature_status = format (0, "%s",
4128                            mp->feature_status ? "enabled" : "disabled");
4129   vec_add1 (gpe_status, 0);
4130   vec_add1 (feature_status, 0);
4131
4132   vat_json_init_object (&node);
4133   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4134   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4135
4136   vec_free (gpe_status);
4137   vec_free (feature_status);
4138
4139   vat_json_print (vam->ofp, &node);
4140   vat_json_free (&node);
4141
4142   vam->retval = ntohl (mp->retval);
4143   vam->result_ready = 1;
4144 }
4145
4146 static void
4147   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4148   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4149 {
4150   vat_main_t *vam = &vat_main;
4151   i32 retval = ntohl (mp->retval);
4152
4153   if (retval >= 0)
4154     {
4155       print (vam->ofp, "%=20s", mp->locator_set_name);
4156     }
4157
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4164   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4165 {
4166   vat_main_t *vam = &vat_main;
4167   vat_json_node_t *node = NULL;
4168
4169   if (VAT_JSON_ARRAY != vam->json_tree.type)
4170     {
4171       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4172       vat_json_init_array (&vam->json_tree);
4173     }
4174   node = vat_json_array_add (&vam->json_tree);
4175
4176   vat_json_init_object (node);
4177   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4178
4179   vat_json_print (vam->ofp, node);
4180   vat_json_free (node);
4181
4182   vam->retval = ntohl (mp->retval);
4183   vam->result_ready = 1;
4184 }
4185
4186 static u8 *
4187 format_lisp_map_request_mode (u8 * s, va_list * args)
4188 {
4189   u32 mode = va_arg (*args, u32);
4190
4191   switch (mode)
4192     {
4193     case 0:
4194       return format (0, "dst-only");
4195     case 1:
4196       return format (0, "src-dst");
4197     }
4198   return 0;
4199 }
4200
4201 static void
4202   vl_api_show_one_map_request_mode_reply_t_handler
4203   (vl_api_show_one_map_request_mode_reply_t * mp)
4204 {
4205   vat_main_t *vam = &vat_main;
4206   i32 retval = ntohl (mp->retval);
4207
4208   if (0 <= retval)
4209     {
4210       u32 mode = mp->mode;
4211       print (vam->ofp, "map_request_mode: %U",
4212              format_lisp_map_request_mode, mode);
4213     }
4214
4215   vam->retval = retval;
4216   vam->result_ready = 1;
4217 }
4218
4219 static void
4220   vl_api_show_one_map_request_mode_reply_t_handler_json
4221   (vl_api_show_one_map_request_mode_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   vat_json_node_t node;
4225   u8 *s = 0;
4226   u32 mode;
4227
4228   mode = mp->mode;
4229   s = format (0, "%U", format_lisp_map_request_mode, mode);
4230   vec_add1 (s, 0);
4231
4232   vat_json_init_object (&node);
4233   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4234   vat_json_print (vam->ofp, &node);
4235   vat_json_free (&node);
4236
4237   vec_free (s);
4238   vam->retval = ntohl (mp->retval);
4239   vam->result_ready = 1;
4240 }
4241
4242 static void
4243   vl_api_one_show_xtr_mode_reply_t_handler
4244   (vl_api_one_show_xtr_mode_reply_t * mp)
4245 {
4246   vat_main_t *vam = &vat_main;
4247   i32 retval = ntohl (mp->retval);
4248
4249   if (0 <= retval)
4250     {
4251       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4252     }
4253
4254   vam->retval = retval;
4255   vam->result_ready = 1;
4256 }
4257
4258 static void
4259   vl_api_one_show_xtr_mode_reply_t_handler_json
4260   (vl_api_one_show_xtr_mode_reply_t * mp)
4261 {
4262   vat_main_t *vam = &vat_main;
4263   vat_json_node_t node;
4264   u8 *status = 0;
4265
4266   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4267   vec_add1 (status, 0);
4268
4269   vat_json_init_object (&node);
4270   vat_json_object_add_string_copy (&node, "status", status);
4271
4272   vec_free (status);
4273
4274   vat_json_print (vam->ofp, &node);
4275   vat_json_free (&node);
4276
4277   vam->retval = ntohl (mp->retval);
4278   vam->result_ready = 1;
4279 }
4280
4281 static void
4282   vl_api_one_show_pitr_mode_reply_t_handler
4283   (vl_api_one_show_pitr_mode_reply_t * mp)
4284 {
4285   vat_main_t *vam = &vat_main;
4286   i32 retval = ntohl (mp->retval);
4287
4288   if (0 <= retval)
4289     {
4290       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4291     }
4292
4293   vam->retval = retval;
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_one_show_pitr_mode_reply_t_handler_json
4299   (vl_api_one_show_pitr_mode_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   vat_json_node_t node;
4303   u8 *status = 0;
4304
4305   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4306   vec_add1 (status, 0);
4307
4308   vat_json_init_object (&node);
4309   vat_json_object_add_string_copy (&node, "status", status);
4310
4311   vec_free (status);
4312
4313   vat_json_print (vam->ofp, &node);
4314   vat_json_free (&node);
4315
4316   vam->retval = ntohl (mp->retval);
4317   vam->result_ready = 1;
4318 }
4319
4320 static void
4321   vl_api_one_show_petr_mode_reply_t_handler
4322   (vl_api_one_show_petr_mode_reply_t * mp)
4323 {
4324   vat_main_t *vam = &vat_main;
4325   i32 retval = ntohl (mp->retval);
4326
4327   if (0 <= retval)
4328     {
4329       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4330     }
4331
4332   vam->retval = retval;
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_one_show_petr_mode_reply_t_handler_json
4338   (vl_api_one_show_petr_mode_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   vat_json_node_t node;
4342   u8 *status = 0;
4343
4344   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4345   vec_add1 (status, 0);
4346
4347   vat_json_init_object (&node);
4348   vat_json_object_add_string_copy (&node, "status", status);
4349
4350   vec_free (status);
4351
4352   vat_json_print (vam->ofp, &node);
4353   vat_json_free (&node);
4354
4355   vam->retval = ntohl (mp->retval);
4356   vam->result_ready = 1;
4357 }
4358
4359 static void
4360   vl_api_show_one_use_petr_reply_t_handler
4361   (vl_api_show_one_use_petr_reply_t * mp)
4362 {
4363   vat_main_t *vam = &vat_main;
4364   i32 retval = ntohl (mp->retval);
4365
4366   if (0 <= retval)
4367     {
4368       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4369       if (mp->status)
4370         {
4371           print (vam->ofp, "Proxy-ETR address; %U",
4372                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4373                  mp->ip_address.un);
4374         }
4375     }
4376
4377   vam->retval = retval;
4378   vam->result_ready = 1;
4379 }
4380
4381 static void
4382   vl_api_show_one_use_petr_reply_t_handler_json
4383   (vl_api_show_one_use_petr_reply_t * mp)
4384 {
4385   vat_main_t *vam = &vat_main;
4386   vat_json_node_t node;
4387   u8 *status = 0;
4388   struct in_addr ip4;
4389   struct in6_addr ip6;
4390
4391   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4392   vec_add1 (status, 0);
4393
4394   vat_json_init_object (&node);
4395   vat_json_object_add_string_copy (&node, "status", status);
4396   if (mp->status)
4397     {
4398       if (mp->ip_address.af)
4399         {
4400           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4401           vat_json_object_add_ip6 (&node, "address", ip6);
4402         }
4403       else
4404         {
4405           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4406           vat_json_object_add_ip4 (&node, "address", ip4);
4407         }
4408     }
4409
4410   vec_free (status);
4411
4412   vat_json_print (vam->ofp, &node);
4413   vat_json_free (&node);
4414
4415   vam->retval = ntohl (mp->retval);
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_show_one_nsh_mapping_reply_t_handler
4421   (vl_api_show_one_nsh_mapping_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   i32 retval = ntohl (mp->retval);
4425
4426   if (0 <= retval)
4427     {
4428       print (vam->ofp, "%-20s%-16s",
4429              mp->is_set ? "set" : "not-set",
4430              mp->is_set ? (char *) mp->locator_set_name : "");
4431     }
4432
4433   vam->retval = retval;
4434   vam->result_ready = 1;
4435 }
4436
4437 static void
4438   vl_api_show_one_nsh_mapping_reply_t_handler_json
4439   (vl_api_show_one_nsh_mapping_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   vat_json_node_t node;
4443   u8 *status = 0;
4444
4445   status = format (0, "%s", mp->is_set ? "yes" : "no");
4446   vec_add1 (status, 0);
4447
4448   vat_json_init_object (&node);
4449   vat_json_object_add_string_copy (&node, "is_set", status);
4450   if (mp->is_set)
4451     {
4452       vat_json_object_add_string_copy (&node, "locator_set",
4453                                        mp->locator_set_name);
4454     }
4455
4456   vec_free (status);
4457
4458   vat_json_print (vam->ofp, &node);
4459   vat_json_free (&node);
4460
4461   vam->retval = ntohl (mp->retval);
4462   vam->result_ready = 1;
4463 }
4464
4465 static void
4466   vl_api_show_one_map_register_ttl_reply_t_handler
4467   (vl_api_show_one_map_register_ttl_reply_t * mp)
4468 {
4469   vat_main_t *vam = &vat_main;
4470   i32 retval = ntohl (mp->retval);
4471
4472   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4473
4474   if (0 <= retval)
4475     {
4476       print (vam->ofp, "ttl: %u", mp->ttl);
4477     }
4478
4479   vam->retval = retval;
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484   vl_api_show_one_map_register_ttl_reply_t_handler_json
4485   (vl_api_show_one_map_register_ttl_reply_t * mp)
4486 {
4487   vat_main_t *vam = &vat_main;
4488   vat_json_node_t node;
4489
4490   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4491   vat_json_init_object (&node);
4492   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4493
4494   vat_json_print (vam->ofp, &node);
4495   vat_json_free (&node);
4496
4497   vam->retval = ntohl (mp->retval);
4498   vam->result_ready = 1;
4499 }
4500
4501 static void
4502 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4503 {
4504   vat_main_t *vam = &vat_main;
4505   i32 retval = ntohl (mp->retval);
4506
4507   if (0 <= retval)
4508     {
4509       print (vam->ofp, "%-20s%-16s",
4510              mp->status ? "enabled" : "disabled",
4511              mp->status ? (char *) mp->locator_set_name : "");
4512     }
4513
4514   vam->retval = retval;
4515   vam->result_ready = 1;
4516 }
4517
4518 static void
4519 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4520 {
4521   vat_main_t *vam = &vat_main;
4522   vat_json_node_t node;
4523   u8 *status = 0;
4524
4525   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4526   vec_add1 (status, 0);
4527
4528   vat_json_init_object (&node);
4529   vat_json_object_add_string_copy (&node, "status", status);
4530   if (mp->status)
4531     {
4532       vat_json_object_add_string_copy (&node, "locator_set",
4533                                        mp->locator_set_name);
4534     }
4535
4536   vec_free (status);
4537
4538   vat_json_print (vam->ofp, &node);
4539   vat_json_free (&node);
4540
4541   vam->retval = ntohl (mp->retval);
4542   vam->result_ready = 1;
4543 }
4544
4545 static u8 *
4546 format_policer_type (u8 * s, va_list * va)
4547 {
4548   u32 i = va_arg (*va, u32);
4549
4550   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4551     s = format (s, "1r2c");
4552   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4553     s = format (s, "1r3c");
4554   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4555     s = format (s, "2r3c-2698");
4556   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4557     s = format (s, "2r3c-4115");
4558   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4559     s = format (s, "2r3c-mef5cf1");
4560   else
4561     s = format (s, "ILLEGAL");
4562   return s;
4563 }
4564
4565 static u8 *
4566 format_policer_rate_type (u8 * s, va_list * va)
4567 {
4568   u32 i = va_arg (*va, u32);
4569
4570   if (i == SSE2_QOS_RATE_KBPS)
4571     s = format (s, "kbps");
4572   else if (i == SSE2_QOS_RATE_PPS)
4573     s = format (s, "pps");
4574   else
4575     s = format (s, "ILLEGAL");
4576   return s;
4577 }
4578
4579 static u8 *
4580 format_policer_round_type (u8 * s, va_list * va)
4581 {
4582   u32 i = va_arg (*va, u32);
4583
4584   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4585     s = format (s, "closest");
4586   else if (i == SSE2_QOS_ROUND_TO_UP)
4587     s = format (s, "up");
4588   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4589     s = format (s, "down");
4590   else
4591     s = format (s, "ILLEGAL");
4592   return s;
4593 }
4594
4595 static u8 *
4596 format_policer_action_type (u8 * s, va_list * va)
4597 {
4598   u32 i = va_arg (*va, u32);
4599
4600   if (i == SSE2_QOS_ACTION_DROP)
4601     s = format (s, "drop");
4602   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4603     s = format (s, "transmit");
4604   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4605     s = format (s, "mark-and-transmit");
4606   else
4607     s = format (s, "ILLEGAL");
4608   return s;
4609 }
4610
4611 static u8 *
4612 format_dscp (u8 * s, va_list * va)
4613 {
4614   u32 i = va_arg (*va, u32);
4615   char *t = 0;
4616
4617   switch (i)
4618     {
4619 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4620       foreach_vnet_dscp
4621 #undef _
4622     default:
4623       return format (s, "ILLEGAL");
4624     }
4625   s = format (s, "%s", t);
4626   return s;
4627 }
4628
4629 static void
4630 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4631 {
4632   vat_main_t *vam = &vat_main;
4633   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4634
4635   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4636     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4637   else
4638     conform_dscp_str = format (0, "");
4639
4640   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4641     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4642   else
4643     exceed_dscp_str = format (0, "");
4644
4645   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4646     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4647   else
4648     violate_dscp_str = format (0, "");
4649
4650   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4651          "rate type %U, round type %U, %s rate, %s color-aware, "
4652          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4653          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4654          "conform action %U%s, exceed action %U%s, violate action %U%s",
4655          mp->name,
4656          format_policer_type, mp->type,
4657          ntohl (mp->cir),
4658          ntohl (mp->eir),
4659          clib_net_to_host_u64 (mp->cb),
4660          clib_net_to_host_u64 (mp->eb),
4661          format_policer_rate_type, mp->rate_type,
4662          format_policer_round_type, mp->round_type,
4663          mp->single_rate ? "single" : "dual",
4664          mp->color_aware ? "is" : "not",
4665          ntohl (mp->cir_tokens_per_period),
4666          ntohl (mp->pir_tokens_per_period),
4667          ntohl (mp->scale),
4668          ntohl (mp->current_limit),
4669          ntohl (mp->current_bucket),
4670          ntohl (mp->extended_limit),
4671          ntohl (mp->extended_bucket),
4672          clib_net_to_host_u64 (mp->last_update_time),
4673          format_policer_action_type, mp->conform_action.type,
4674          conform_dscp_str,
4675          format_policer_action_type, mp->exceed_action.type,
4676          exceed_dscp_str,
4677          format_policer_action_type, mp->violate_action.type,
4678          violate_dscp_str);
4679
4680   vec_free (conform_dscp_str);
4681   vec_free (exceed_dscp_str);
4682   vec_free (violate_dscp_str);
4683 }
4684
4685 static void vl_api_policer_details_t_handler_json
4686   (vl_api_policer_details_t * mp)
4687 {
4688   vat_main_t *vam = &vat_main;
4689   vat_json_node_t *node;
4690   u8 *rate_type_str, *round_type_str, *type_str;
4691   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4692
4693   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4694   round_type_str =
4695     format (0, "%U", format_policer_round_type, mp->round_type);
4696   type_str = format (0, "%U", format_policer_type, mp->type);
4697   conform_action_str = format (0, "%U", format_policer_action_type,
4698                                mp->conform_action.type);
4699   exceed_action_str = format (0, "%U", format_policer_action_type,
4700                               mp->exceed_action.type);
4701   violate_action_str = format (0, "%U", format_policer_action_type,
4702                                mp->violate_action.type);
4703
4704   if (VAT_JSON_ARRAY != vam->json_tree.type)
4705     {
4706       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4707       vat_json_init_array (&vam->json_tree);
4708     }
4709   node = vat_json_array_add (&vam->json_tree);
4710
4711   vat_json_init_object (node);
4712   vat_json_object_add_string_copy (node, "name", mp->name);
4713   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4714   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4715   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4716   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4717   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4718   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4719   vat_json_object_add_string_copy (node, "type", type_str);
4720   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4721   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4722   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4723   vat_json_object_add_uint (node, "cir_tokens_per_period",
4724                             ntohl (mp->cir_tokens_per_period));
4725   vat_json_object_add_uint (node, "eir_tokens_per_period",
4726                             ntohl (mp->pir_tokens_per_period));
4727   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4728   vat_json_object_add_uint (node, "current_bucket",
4729                             ntohl (mp->current_bucket));
4730   vat_json_object_add_uint (node, "extended_limit",
4731                             ntohl (mp->extended_limit));
4732   vat_json_object_add_uint (node, "extended_bucket",
4733                             ntohl (mp->extended_bucket));
4734   vat_json_object_add_uint (node, "last_update_time",
4735                             ntohl (mp->last_update_time));
4736   vat_json_object_add_string_copy (node, "conform_action",
4737                                    conform_action_str);
4738   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4739     {
4740       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4741       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4742       vec_free (dscp_str);
4743     }
4744   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4745   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4746     {
4747       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4748       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4749       vec_free (dscp_str);
4750     }
4751   vat_json_object_add_string_copy (node, "violate_action",
4752                                    violate_action_str);
4753   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4754     {
4755       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4756       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4757       vec_free (dscp_str);
4758     }
4759
4760   vec_free (rate_type_str);
4761   vec_free (round_type_str);
4762   vec_free (type_str);
4763   vec_free (conform_action_str);
4764   vec_free (exceed_action_str);
4765   vec_free (violate_action_str);
4766 }
4767
4768 static void
4769 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4770                                            mp)
4771 {
4772   vat_main_t *vam = &vat_main;
4773   int i, count = ntohl (mp->count);
4774
4775   if (count > 0)
4776     print (vam->ofp, "classify table ids (%d) : ", count);
4777   for (i = 0; i < count; i++)
4778     {
4779       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4780       print (vam->ofp, (i < count - 1) ? "," : "");
4781     }
4782   vam->retval = ntohl (mp->retval);
4783   vam->result_ready = 1;
4784 }
4785
4786 static void
4787   vl_api_classify_table_ids_reply_t_handler_json
4788   (vl_api_classify_table_ids_reply_t * mp)
4789 {
4790   vat_main_t *vam = &vat_main;
4791   int i, count = ntohl (mp->count);
4792
4793   if (count > 0)
4794     {
4795       vat_json_node_t node;
4796
4797       vat_json_init_object (&node);
4798       for (i = 0; i < count; i++)
4799         {
4800           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4801         }
4802       vat_json_print (vam->ofp, &node);
4803       vat_json_free (&node);
4804     }
4805   vam->retval = ntohl (mp->retval);
4806   vam->result_ready = 1;
4807 }
4808
4809 static void
4810   vl_api_classify_table_by_interface_reply_t_handler
4811   (vl_api_classify_table_by_interface_reply_t * mp)
4812 {
4813   vat_main_t *vam = &vat_main;
4814   u32 table_id;
4815
4816   table_id = ntohl (mp->l2_table_id);
4817   if (table_id != ~0)
4818     print (vam->ofp, "l2 table id : %d", table_id);
4819   else
4820     print (vam->ofp, "l2 table id : No input ACL tables configured");
4821   table_id = ntohl (mp->ip4_table_id);
4822   if (table_id != ~0)
4823     print (vam->ofp, "ip4 table id : %d", table_id);
4824   else
4825     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4826   table_id = ntohl (mp->ip6_table_id);
4827   if (table_id != ~0)
4828     print (vam->ofp, "ip6 table id : %d", table_id);
4829   else
4830     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4831   vam->retval = ntohl (mp->retval);
4832   vam->result_ready = 1;
4833 }
4834
4835 static void
4836   vl_api_classify_table_by_interface_reply_t_handler_json
4837   (vl_api_classify_table_by_interface_reply_t * mp)
4838 {
4839   vat_main_t *vam = &vat_main;
4840   vat_json_node_t node;
4841
4842   vat_json_init_object (&node);
4843
4844   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4845   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4846   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4847
4848   vat_json_print (vam->ofp, &node);
4849   vat_json_free (&node);
4850
4851   vam->retval = ntohl (mp->retval);
4852   vam->result_ready = 1;
4853 }
4854
4855 static void vl_api_policer_add_del_reply_t_handler
4856   (vl_api_policer_add_del_reply_t * mp)
4857 {
4858   vat_main_t *vam = &vat_main;
4859   i32 retval = ntohl (mp->retval);
4860   if (vam->async_mode)
4861     {
4862       vam->async_errors += (retval < 0);
4863     }
4864   else
4865     {
4866       vam->retval = retval;
4867       vam->result_ready = 1;
4868       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4869         /*
4870          * Note: this is just barely thread-safe, depends on
4871          * the main thread spinning waiting for an answer...
4872          */
4873         errmsg ("policer index %d", ntohl (mp->policer_index));
4874     }
4875 }
4876
4877 static void vl_api_policer_add_del_reply_t_handler_json
4878   (vl_api_policer_add_del_reply_t * mp)
4879 {
4880   vat_main_t *vam = &vat_main;
4881   vat_json_node_t node;
4882
4883   vat_json_init_object (&node);
4884   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4885   vat_json_object_add_uint (&node, "policer_index",
4886                             ntohl (mp->policer_index));
4887
4888   vat_json_print (vam->ofp, &node);
4889   vat_json_free (&node);
4890
4891   vam->retval = ntohl (mp->retval);
4892   vam->result_ready = 1;
4893 }
4894
4895 /* Format hex dump. */
4896 u8 *
4897 format_hex_bytes (u8 * s, va_list * va)
4898 {
4899   u8 *bytes = va_arg (*va, u8 *);
4900   int n_bytes = va_arg (*va, int);
4901   uword i;
4902
4903   /* Print short or long form depending on byte count. */
4904   uword short_form = n_bytes <= 32;
4905   u32 indent = format_get_indent (s);
4906
4907   if (n_bytes == 0)
4908     return s;
4909
4910   for (i = 0; i < n_bytes; i++)
4911     {
4912       if (!short_form && (i % 32) == 0)
4913         s = format (s, "%08x: ", i);
4914       s = format (s, "%02x", bytes[i]);
4915       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4916         s = format (s, "\n%U", format_white_space, indent);
4917     }
4918
4919   return s;
4920 }
4921
4922 static void
4923 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4924                                             * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   i32 retval = ntohl (mp->retval);
4928   if (retval == 0)
4929     {
4930       print (vam->ofp, "classify table info :");
4931       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4932              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4933              ntohl (mp->miss_next_index));
4934       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4935              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4936              ntohl (mp->match_n_vectors));
4937       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4938              ntohl (mp->mask_length));
4939     }
4940   vam->retval = retval;
4941   vam->result_ready = 1;
4942 }
4943
4944 static void
4945   vl_api_classify_table_info_reply_t_handler_json
4946   (vl_api_classify_table_info_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   i32 retval = ntohl (mp->retval);
4952   if (retval == 0)
4953     {
4954       vat_json_init_object (&node);
4955
4956       vat_json_object_add_int (&node, "sessions",
4957                                ntohl (mp->active_sessions));
4958       vat_json_object_add_int (&node, "nexttbl",
4959                                ntohl (mp->next_table_index));
4960       vat_json_object_add_int (&node, "nextnode",
4961                                ntohl (mp->miss_next_index));
4962       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4963       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4964       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4965       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4966                       ntohl (mp->mask_length), 0);
4967       vat_json_object_add_string_copy (&node, "mask", s);
4968
4969       vat_json_print (vam->ofp, &node);
4970       vat_json_free (&node);
4971     }
4972   vam->retval = ntohl (mp->retval);
4973   vam->result_ready = 1;
4974 }
4975
4976 static void
4977 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4978                                            mp)
4979 {
4980   vat_main_t *vam = &vat_main;
4981
4982   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4983          ntohl (mp->hit_next_index), ntohl (mp->advance),
4984          ntohl (mp->opaque_index));
4985   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4986          ntohl (mp->match_length));
4987 }
4988
4989 static void
4990   vl_api_classify_session_details_t_handler_json
4991   (vl_api_classify_session_details_t * mp)
4992 {
4993   vat_main_t *vam = &vat_main;
4994   vat_json_node_t *node = NULL;
4995
4996   if (VAT_JSON_ARRAY != vam->json_tree.type)
4997     {
4998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4999       vat_json_init_array (&vam->json_tree);
5000     }
5001   node = vat_json_array_add (&vam->json_tree);
5002
5003   vat_json_init_object (node);
5004   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5005   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5006   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5007   u8 *s =
5008     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5009             0);
5010   vat_json_object_add_string_copy (node, "match", s);
5011 }
5012
5013 static void vl_api_pg_create_interface_reply_t_handler
5014   (vl_api_pg_create_interface_reply_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017
5018   vam->retval = ntohl (mp->retval);
5019   vam->result_ready = 1;
5020 }
5021
5022 static void vl_api_pg_create_interface_reply_t_handler_json
5023   (vl_api_pg_create_interface_reply_t * mp)
5024 {
5025   vat_main_t *vam = &vat_main;
5026   vat_json_node_t node;
5027
5028   i32 retval = ntohl (mp->retval);
5029   if (retval == 0)
5030     {
5031       vat_json_init_object (&node);
5032
5033       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5034
5035       vat_json_print (vam->ofp, &node);
5036       vat_json_free (&node);
5037     }
5038   vam->retval = ntohl (mp->retval);
5039   vam->result_ready = 1;
5040 }
5041
5042 static void vl_api_policer_classify_details_t_handler
5043   (vl_api_policer_classify_details_t * mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046
5047   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5048          ntohl (mp->table_index));
5049 }
5050
5051 static void vl_api_policer_classify_details_t_handler_json
5052   (vl_api_policer_classify_details_t * mp)
5053 {
5054   vat_main_t *vam = &vat_main;
5055   vat_json_node_t *node;
5056
5057   if (VAT_JSON_ARRAY != vam->json_tree.type)
5058     {
5059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5060       vat_json_init_array (&vam->json_tree);
5061     }
5062   node = vat_json_array_add (&vam->json_tree);
5063
5064   vat_json_init_object (node);
5065   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5066   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5067 }
5068
5069 static void vl_api_flow_classify_details_t_handler
5070   (vl_api_flow_classify_details_t * mp)
5071 {
5072   vat_main_t *vam = &vat_main;
5073
5074   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5075          ntohl (mp->table_index));
5076 }
5077
5078 static void vl_api_flow_classify_details_t_handler_json
5079   (vl_api_flow_classify_details_t * mp)
5080 {
5081   vat_main_t *vam = &vat_main;
5082   vat_json_node_t *node;
5083
5084   if (VAT_JSON_ARRAY != vam->json_tree.type)
5085     {
5086       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5087       vat_json_init_array (&vam->json_tree);
5088     }
5089   node = vat_json_array_add (&vam->json_tree);
5090
5091   vat_json_init_object (node);
5092   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5093   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5094 }
5095
5096 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5097 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5098 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5099 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5100 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5101 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5102 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5103 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5104 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5105 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5106
5107 /*
5108  * Generate boilerplate reply handlers, which
5109  * dig the return value out of the xxx_reply_t API message,
5110  * stick it into vam->retval, and set vam->result_ready
5111  *
5112  * Could also do this by pointing N message decode slots at
5113  * a single function, but that could break in subtle ways.
5114  */
5115
5116 #define foreach_standard_reply_retval_handler           \
5117 _(sw_interface_set_flags_reply)                         \
5118 _(sw_interface_add_del_address_reply)                   \
5119 _(sw_interface_set_rx_mode_reply)                       \
5120 _(sw_interface_set_rx_placement_reply)                  \
5121 _(sw_interface_set_table_reply)                         \
5122 _(sw_interface_set_mpls_enable_reply)                   \
5123 _(sw_interface_set_vpath_reply)                         \
5124 _(sw_interface_set_vxlan_bypass_reply)                  \
5125 _(sw_interface_set_geneve_bypass_reply)                 \
5126 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5127 _(sw_interface_set_l2_bridge_reply)                     \
5128 _(sw_interface_set_bond_weight_reply)                   \
5129 _(bridge_domain_add_del_reply)                          \
5130 _(sw_interface_set_l2_xconnect_reply)                   \
5131 _(l2fib_add_del_reply)                                  \
5132 _(l2fib_flush_int_reply)                                \
5133 _(l2fib_flush_bd_reply)                                 \
5134 _(ip_route_add_del_reply)                               \
5135 _(ip_table_add_del_reply)                               \
5136 _(ip_table_replace_begin_reply)                         \
5137 _(ip_table_flush_reply)                                 \
5138 _(ip_table_replace_end_reply)                           \
5139 _(ip_mroute_add_del_reply)                              \
5140 _(mpls_route_add_del_reply)                             \
5141 _(mpls_table_add_del_reply)                             \
5142 _(mpls_ip_bind_unbind_reply)                            \
5143 _(bier_route_add_del_reply)                             \
5144 _(bier_table_add_del_reply)                             \
5145 _(sw_interface_set_unnumbered_reply)                    \
5146 _(set_ip_flow_hash_reply)                               \
5147 _(sw_interface_ip6_enable_disable_reply)                \
5148 _(l2_patch_add_del_reply)                               \
5149 _(sr_mpls_policy_add_reply)                             \
5150 _(sr_mpls_policy_mod_reply)                             \
5151 _(sr_mpls_policy_del_reply)                             \
5152 _(sr_policy_add_reply)                                  \
5153 _(sr_policy_mod_reply)                                  \
5154 _(sr_policy_del_reply)                                  \
5155 _(sr_localsid_add_del_reply)                            \
5156 _(sr_steering_add_del_reply)                            \
5157 _(classify_add_del_session_reply)                       \
5158 _(classify_set_interface_ip_table_reply)                \
5159 _(classify_set_interface_l2_tables_reply)               \
5160 _(l2tpv3_set_tunnel_cookies_reply)                      \
5161 _(l2tpv3_interface_enable_disable_reply)                \
5162 _(l2tpv3_set_lookup_key_reply)                          \
5163 _(l2_fib_clear_table_reply)                             \
5164 _(l2_interface_efp_filter_reply)                        \
5165 _(l2_interface_vlan_tag_rewrite_reply)                  \
5166 _(modify_vhost_user_if_reply)                           \
5167 _(delete_vhost_user_if_reply)                           \
5168 _(want_l2_macs_events_reply)                            \
5169 _(input_acl_set_interface_reply)                        \
5170 _(ipsec_spd_add_del_reply)                              \
5171 _(ipsec_interface_add_del_spd_reply)                    \
5172 _(ipsec_spd_entry_add_del_reply)                        \
5173 _(ipsec_sad_entry_add_del_reply)                        \
5174 _(ipsec_tunnel_if_add_del_reply)                        \
5175 _(ipsec_tunnel_if_set_sa_reply)                         \
5176 _(delete_loopback_reply)                                \
5177 _(bd_ip_mac_add_del_reply)                              \
5178 _(bd_ip_mac_flush_reply)                                \
5179 _(want_interface_events_reply)                          \
5180 _(cop_interface_enable_disable_reply)                   \
5181 _(cop_whitelist_enable_disable_reply)                   \
5182 _(sw_interface_clear_stats_reply)                       \
5183 _(ioam_enable_reply)                                    \
5184 _(ioam_disable_reply)                                   \
5185 _(one_add_del_locator_reply)                            \
5186 _(one_add_del_local_eid_reply)                          \
5187 _(one_add_del_remote_mapping_reply)                     \
5188 _(one_add_del_adjacency_reply)                          \
5189 _(one_add_del_map_resolver_reply)                       \
5190 _(one_add_del_map_server_reply)                         \
5191 _(one_enable_disable_reply)                             \
5192 _(one_rloc_probe_enable_disable_reply)                  \
5193 _(one_map_register_enable_disable_reply)                \
5194 _(one_map_register_set_ttl_reply)                       \
5195 _(one_set_transport_protocol_reply)                     \
5196 _(one_map_register_fallback_threshold_reply)            \
5197 _(one_pitr_set_locator_set_reply)                       \
5198 _(one_map_request_mode_reply)                           \
5199 _(one_add_del_map_request_itr_rlocs_reply)              \
5200 _(one_eid_table_add_del_map_reply)                      \
5201 _(one_use_petr_reply)                                   \
5202 _(one_stats_enable_disable_reply)                       \
5203 _(one_add_del_l2_arp_entry_reply)                       \
5204 _(one_add_del_ndp_entry_reply)                          \
5205 _(one_stats_flush_reply)                                \
5206 _(one_enable_disable_xtr_mode_reply)                    \
5207 _(one_enable_disable_pitr_mode_reply)                   \
5208 _(one_enable_disable_petr_mode_reply)                   \
5209 _(gpe_enable_disable_reply)                             \
5210 _(gpe_set_encap_mode_reply)                             \
5211 _(gpe_add_del_iface_reply)                              \
5212 _(gpe_add_del_native_fwd_rpath_reply)                   \
5213 _(af_packet_delete_reply)                               \
5214 _(policer_classify_set_interface_reply)                 \
5215 _(set_ipfix_exporter_reply)                             \
5216 _(set_ipfix_classify_stream_reply)                      \
5217 _(ipfix_classify_table_add_del_reply)                   \
5218 _(flow_classify_set_interface_reply)                    \
5219 _(sw_interface_span_enable_disable_reply)               \
5220 _(pg_capture_reply)                                     \
5221 _(pg_enable_disable_reply)                              \
5222 _(pg_interface_enable_disable_coalesce_reply)           \
5223 _(ip_source_and_port_range_check_add_del_reply)         \
5224 _(ip_source_and_port_range_check_interface_add_del_reply)\
5225 _(delete_subif_reply)                                   \
5226 _(l2_interface_pbb_tag_rewrite_reply)                   \
5227 _(set_punt_reply)                                       \
5228 _(feature_enable_disable_reply)                         \
5229 _(feature_gso_enable_disable_reply)                     \
5230 _(sw_interface_tag_add_del_reply)                       \
5231 _(sw_interface_add_del_mac_address_reply)               \
5232 _(hw_interface_set_mtu_reply)                           \
5233 _(p2p_ethernet_add_reply)                               \
5234 _(p2p_ethernet_del_reply)                               \
5235 _(lldp_config_reply)                                    \
5236 _(sw_interface_set_lldp_reply)                          \
5237 _(tcp_configure_src_addresses_reply)                    \
5238 _(session_rule_add_del_reply)                           \
5239 _(ip_container_proxy_add_del_reply)                     \
5240 _(output_acl_set_interface_reply)                       \
5241 _(qos_record_enable_disable_reply)                      \
5242 _(flow_add_reply)
5243
5244 #define _(n)                                    \
5245     static void vl_api_##n##_t_handler          \
5246     (vl_api_##n##_t * mp)                       \
5247     {                                           \
5248         vat_main_t * vam = &vat_main;           \
5249         i32 retval = ntohl(mp->retval);         \
5250         if (vam->async_mode) {                  \
5251             vam->async_errors += (retval < 0);  \
5252         } else {                                \
5253             vam->retval = retval;               \
5254             vam->result_ready = 1;              \
5255         }                                       \
5256     }
5257 foreach_standard_reply_retval_handler;
5258 #undef _
5259
5260 #define _(n)                                    \
5261     static void vl_api_##n##_t_handler_json     \
5262     (vl_api_##n##_t * mp)                       \
5263     {                                           \
5264         vat_main_t * vam = &vat_main;           \
5265         vat_json_node_t node;                   \
5266         vat_json_init_object(&node);            \
5267         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5268         vat_json_print(vam->ofp, &node);        \
5269         vam->retval = ntohl(mp->retval);        \
5270         vam->result_ready = 1;                  \
5271     }
5272 foreach_standard_reply_retval_handler;
5273 #undef _
5274
5275 /*
5276  * Table of message reply handlers, must include boilerplate handlers
5277  * we just generated
5278  */
5279
5280 #define foreach_vpe_api_reply_msg                                       \
5281 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5282 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5283 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5284 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5285 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5286 _(CLI_REPLY, cli_reply)                                                 \
5287 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5288 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5289   sw_interface_add_del_address_reply)                                   \
5290 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5291 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5292 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5293 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5294 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5295 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5296 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5297 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5298 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5299 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5300   sw_interface_set_l2_xconnect_reply)                                   \
5301 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5302   sw_interface_set_l2_bridge_reply)                                     \
5303 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5304 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5305 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5306 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5307 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5308 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5309 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5310 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5311 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5312 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5313 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5314 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5315 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
5316 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5317 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5318 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5319 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
5320 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5321 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
5322 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
5323 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5324 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
5325 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
5326 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5327 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5328 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5329 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5330 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5331 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5332 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5333 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5334 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5335 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5336 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5337 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5338 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5339   sw_interface_set_unnumbered_reply)                                    \
5340 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5341 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5342 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5343 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5344   sw_interface_ip6_enable_disable_reply)                                \
5345 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5346 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5347 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5348 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5349 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5350 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5351 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5352 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5353 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5354 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5355 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5356 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5357 classify_set_interface_ip_table_reply)                                  \
5358 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5359   classify_set_interface_l2_tables_reply)                               \
5360 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5361 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5362 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5363 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5364 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5365   l2tpv3_interface_enable_disable_reply)                                \
5366 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5367 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5368 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5369 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5370 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5371 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5372 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5373 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5374 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5375 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5376 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5377 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5378 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5379 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5380 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5381 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5382 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5383 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5384 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5385 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5386 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5387 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5388 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5389 _(L2_MACS_EVENT, l2_macs_event)                                         \
5390 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5391 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5392 _(IP_DETAILS, ip_details)                                               \
5393 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5394 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5395 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5396 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5397 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5398 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5399 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5400 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5401 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5402 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5403 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5404 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5405 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5406 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5407 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5408 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5409 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5410 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5411 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5412 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5413 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5414 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5415 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5416 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5417 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5418 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5419 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5420 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5421   one_map_register_enable_disable_reply)                                \
5422 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5423 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5424 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5425 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5426   one_map_register_fallback_threshold_reply)                            \
5427 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5428   one_rloc_probe_enable_disable_reply)                                  \
5429 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5430 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5431 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5432 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5433 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5434 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5435 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5436 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5437 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5438 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5439 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5440 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5441 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5442 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5443 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5444 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5445   show_one_stats_enable_disable_reply)                                  \
5446 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5447 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5448 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5449 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5450 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5451 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5452 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5453 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5454   one_enable_disable_pitr_mode_reply)                                   \
5455 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5456   one_enable_disable_petr_mode_reply)                                   \
5457 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5458 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5459 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5460 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5461 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5462 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5463 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5464 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5465 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5466 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5467 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5468 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5469   gpe_add_del_native_fwd_rpath_reply)                                   \
5470 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5471   gpe_fwd_entry_path_details)                                           \
5472 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5473 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5474   one_add_del_map_request_itr_rlocs_reply)                              \
5475 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5476   one_get_map_request_itr_rlocs_reply)                                  \
5477 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5478 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5479 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5480 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5481 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5482 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5483   show_one_map_register_state_reply)                                    \
5484 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5485 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5486   show_one_map_register_fallback_threshold_reply)                       \
5487 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5488 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5489 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5490 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5491 _(POLICER_DETAILS, policer_details)                                     \
5492 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5493 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5494 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5495 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5496 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5497 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5498 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5499 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5500 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5501 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5502 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5503 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5504 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5505 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5506 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5507 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5508 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5509 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5510 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5511 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5512 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5513 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5514 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5515 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
5516 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5517  ip_source_and_port_range_check_add_del_reply)                          \
5518 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5519  ip_source_and_port_range_check_interface_add_del_reply)                \
5520 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5521 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5522 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5523 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5524 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5525 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5526 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5527 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5528 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5529 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5530 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5531 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5532 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5533 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5534 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5535 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5536 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5537 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5538 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5539 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5540 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5541 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5542 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
5543 _(FLOW_ADD_REPLY, flow_add_reply)   \
5544
5545 #define foreach_standalone_reply_msg                                    \
5546 _(SW_INTERFACE_EVENT, sw_interface_event)
5547
5548 typedef struct
5549 {
5550   u8 *name;
5551   u32 value;
5552 } name_sort_t;
5553
5554 #define STR_VTR_OP_CASE(op)     \
5555     case L2_VTR_ ## op:         \
5556         return "" # op;
5557
5558 static const char *
5559 str_vtr_op (u32 vtr_op)
5560 {
5561   switch (vtr_op)
5562     {
5563       STR_VTR_OP_CASE (DISABLED);
5564       STR_VTR_OP_CASE (PUSH_1);
5565       STR_VTR_OP_CASE (PUSH_2);
5566       STR_VTR_OP_CASE (POP_1);
5567       STR_VTR_OP_CASE (POP_2);
5568       STR_VTR_OP_CASE (TRANSLATE_1_1);
5569       STR_VTR_OP_CASE (TRANSLATE_1_2);
5570       STR_VTR_OP_CASE (TRANSLATE_2_1);
5571       STR_VTR_OP_CASE (TRANSLATE_2_2);
5572     }
5573
5574   return "UNKNOWN";
5575 }
5576
5577 static int
5578 dump_sub_interface_table (vat_main_t * vam)
5579 {
5580   const sw_interface_subif_t *sub = NULL;
5581
5582   if (vam->json_output)
5583     {
5584       clib_warning
5585         ("JSON output supported only for VPE API calls and dump_stats_table");
5586       return -99;
5587     }
5588
5589   print (vam->ofp,
5590          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5591          "Interface", "sw_if_index",
5592          "sub id", "dot1ad", "tags", "outer id",
5593          "inner id", "exact", "default", "outer any", "inner any");
5594
5595   vec_foreach (sub, vam->sw_if_subif_table)
5596   {
5597     print (vam->ofp,
5598            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5599            sub->interface_name,
5600            sub->sw_if_index,
5601            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5602            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5603            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5604            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5605     if (sub->vtr_op != L2_VTR_DISABLED)
5606       {
5607         print (vam->ofp,
5608                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5609                "tag1: %d tag2: %d ]",
5610                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5611                sub->vtr_tag1, sub->vtr_tag2);
5612       }
5613   }
5614
5615   return 0;
5616 }
5617
5618 static int
5619 name_sort_cmp (void *a1, void *a2)
5620 {
5621   name_sort_t *n1 = a1;
5622   name_sort_t *n2 = a2;
5623
5624   return strcmp ((char *) n1->name, (char *) n2->name);
5625 }
5626
5627 static int
5628 dump_interface_table (vat_main_t * vam)
5629 {
5630   hash_pair_t *p;
5631   name_sort_t *nses = 0, *ns;
5632
5633   if (vam->json_output)
5634     {
5635       clib_warning
5636         ("JSON output supported only for VPE API calls and dump_stats_table");
5637       return -99;
5638     }
5639
5640   /* *INDENT-OFF* */
5641   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5642   ({
5643     vec_add2 (nses, ns, 1);
5644     ns->name = (u8 *)(p->key);
5645     ns->value = (u32) p->value[0];
5646   }));
5647   /* *INDENT-ON* */
5648
5649   vec_sort_with_function (nses, name_sort_cmp);
5650
5651   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5652   vec_foreach (ns, nses)
5653   {
5654     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5655   }
5656   vec_free (nses);
5657   return 0;
5658 }
5659
5660 static int
5661 dump_ip_table (vat_main_t * vam, int is_ipv6)
5662 {
5663   const ip_details_t *det = NULL;
5664   const ip_address_details_t *address = NULL;
5665   u32 i = ~0;
5666
5667   print (vam->ofp, "%-12s", "sw_if_index");
5668
5669   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5670   {
5671     i++;
5672     if (!det->present)
5673       {
5674         continue;
5675       }
5676     print (vam->ofp, "%-12d", i);
5677     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5678     if (!det->addr)
5679       {
5680         continue;
5681       }
5682     vec_foreach (address, det->addr)
5683     {
5684       print (vam->ofp,
5685              "            %-30U%-13d",
5686              is_ipv6 ? format_ip6_address : format_ip4_address,
5687              address->ip, address->prefix_length);
5688     }
5689   }
5690
5691   return 0;
5692 }
5693
5694 static int
5695 dump_ipv4_table (vat_main_t * vam)
5696 {
5697   if (vam->json_output)
5698     {
5699       clib_warning
5700         ("JSON output supported only for VPE API calls and dump_stats_table");
5701       return -99;
5702     }
5703
5704   return dump_ip_table (vam, 0);
5705 }
5706
5707 static int
5708 dump_ipv6_table (vat_main_t * vam)
5709 {
5710   if (vam->json_output)
5711     {
5712       clib_warning
5713         ("JSON output supported only for VPE API calls and dump_stats_table");
5714       return -99;
5715     }
5716
5717   return dump_ip_table (vam, 1);
5718 }
5719
5720 /*
5721  * Pass CLI buffers directly in the CLI_INBAND API message,
5722  * instead of an additional shared memory area.
5723  */
5724 static int
5725 exec_inband (vat_main_t * vam)
5726 {
5727   vl_api_cli_inband_t *mp;
5728   unformat_input_t *i = vam->input;
5729   int ret;
5730
5731   if (vec_len (i->buffer) == 0)
5732     return -1;
5733
5734   if (vam->exec_mode == 0 && unformat (i, "mode"))
5735     {
5736       vam->exec_mode = 1;
5737       return 0;
5738     }
5739   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5740     {
5741       vam->exec_mode = 0;
5742       return 0;
5743     }
5744
5745   /*
5746    * In order for the CLI command to work, it
5747    * must be a vector ending in \n, not a C-string ending
5748    * in \n\0.
5749    */
5750   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5751   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5752
5753   S (mp);
5754   W (ret);
5755   /* json responses may or may not include a useful reply... */
5756   if (vec_len (vam->cmd_reply))
5757     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5758   return ret;
5759 }
5760
5761 int
5762 exec (vat_main_t * vam)
5763 {
5764   return exec_inband (vam);
5765 }
5766
5767 static int
5768 api_create_loopback (vat_main_t * vam)
5769 {
5770   unformat_input_t *i = vam->input;
5771   vl_api_create_loopback_t *mp;
5772   vl_api_create_loopback_instance_t *mp_lbi;
5773   u8 mac_address[6];
5774   u8 mac_set = 0;
5775   u8 is_specified = 0;
5776   u32 user_instance = 0;
5777   int ret;
5778
5779   clib_memset (mac_address, 0, sizeof (mac_address));
5780
5781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5782     {
5783       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5784         mac_set = 1;
5785       if (unformat (i, "instance %d", &user_instance))
5786         is_specified = 1;
5787       else
5788         break;
5789     }
5790
5791   if (is_specified)
5792     {
5793       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5794       mp_lbi->is_specified = is_specified;
5795       if (is_specified)
5796         mp_lbi->user_instance = htonl (user_instance);
5797       if (mac_set)
5798         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5799       S (mp_lbi);
5800     }
5801   else
5802     {
5803       /* Construct the API message */
5804       M (CREATE_LOOPBACK, mp);
5805       if (mac_set)
5806         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5807       S (mp);
5808     }
5809
5810   W (ret);
5811   return ret;
5812 }
5813
5814 static int
5815 api_delete_loopback (vat_main_t * vam)
5816 {
5817   unformat_input_t *i = vam->input;
5818   vl_api_delete_loopback_t *mp;
5819   u32 sw_if_index = ~0;
5820   int ret;
5821
5822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5823     {
5824       if (unformat (i, "sw_if_index %d", &sw_if_index))
5825         ;
5826       else
5827         break;
5828     }
5829
5830   if (sw_if_index == ~0)
5831     {
5832       errmsg ("missing sw_if_index");
5833       return -99;
5834     }
5835
5836   /* Construct the API message */
5837   M (DELETE_LOOPBACK, mp);
5838   mp->sw_if_index = ntohl (sw_if_index);
5839
5840   S (mp);
5841   W (ret);
5842   return ret;
5843 }
5844
5845 static int
5846 api_want_interface_events (vat_main_t * vam)
5847 {
5848   unformat_input_t *i = vam->input;
5849   vl_api_want_interface_events_t *mp;
5850   int enable = -1;
5851   int ret;
5852
5853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5854     {
5855       if (unformat (i, "enable"))
5856         enable = 1;
5857       else if (unformat (i, "disable"))
5858         enable = 0;
5859       else
5860         break;
5861     }
5862
5863   if (enable == -1)
5864     {
5865       errmsg ("missing enable|disable");
5866       return -99;
5867     }
5868
5869   M (WANT_INTERFACE_EVENTS, mp);
5870   mp->enable_disable = enable;
5871
5872   vam->interface_event_display = enable;
5873
5874   S (mp);
5875   W (ret);
5876   return ret;
5877 }
5878
5879
5880 /* Note: non-static, called once to set up the initial intfc table */
5881 int
5882 api_sw_interface_dump (vat_main_t * vam)
5883 {
5884   vl_api_sw_interface_dump_t *mp;
5885   vl_api_control_ping_t *mp_ping;
5886   hash_pair_t *p;
5887   name_sort_t *nses = 0, *ns;
5888   sw_interface_subif_t *sub = NULL;
5889   int ret;
5890
5891   /* Toss the old name table */
5892   /* *INDENT-OFF* */
5893   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5894   ({
5895     vec_add2 (nses, ns, 1);
5896     ns->name = (u8 *)(p->key);
5897     ns->value = (u32) p->value[0];
5898   }));
5899   /* *INDENT-ON* */
5900
5901   hash_free (vam->sw_if_index_by_interface_name);
5902
5903   vec_foreach (ns, nses) vec_free (ns->name);
5904
5905   vec_free (nses);
5906
5907   vec_foreach (sub, vam->sw_if_subif_table)
5908   {
5909     vec_free (sub->interface_name);
5910   }
5911   vec_free (vam->sw_if_subif_table);
5912
5913   /* recreate the interface name hash table */
5914   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5915
5916   /*
5917    * Ask for all interface names. Otherwise, the epic catalog of
5918    * name filters becomes ridiculously long, and vat ends up needing
5919    * to be taught about new interface types.
5920    */
5921   M (SW_INTERFACE_DUMP, mp);
5922   S (mp);
5923
5924   /* Use a control ping for synchronization */
5925   MPING (CONTROL_PING, mp_ping);
5926   S (mp_ping);
5927
5928   W (ret);
5929   return ret;
5930 }
5931
5932 static int
5933 api_sw_interface_set_flags (vat_main_t * vam)
5934 {
5935   unformat_input_t *i = vam->input;
5936   vl_api_sw_interface_set_flags_t *mp;
5937   u32 sw_if_index;
5938   u8 sw_if_index_set = 0;
5939   u8 admin_up = 0;
5940   int ret;
5941
5942   /* Parse args required to build the message */
5943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5944     {
5945       if (unformat (i, "admin-up"))
5946         admin_up = 1;
5947       else if (unformat (i, "admin-down"))
5948         admin_up = 0;
5949       else
5950         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5951         sw_if_index_set = 1;
5952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5953         sw_if_index_set = 1;
5954       else
5955         break;
5956     }
5957
5958   if (sw_if_index_set == 0)
5959     {
5960       errmsg ("missing interface name or sw_if_index");
5961       return -99;
5962     }
5963
5964   /* Construct the API message */
5965   M (SW_INTERFACE_SET_FLAGS, mp);
5966   mp->sw_if_index = ntohl (sw_if_index);
5967   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5968
5969   /* send it... */
5970   S (mp);
5971
5972   /* Wait for a reply, return the good/bad news... */
5973   W (ret);
5974   return ret;
5975 }
5976
5977 static int
5978 api_sw_interface_set_rx_mode (vat_main_t * vam)
5979 {
5980   unformat_input_t *i = vam->input;
5981   vl_api_sw_interface_set_rx_mode_t *mp;
5982   u32 sw_if_index;
5983   u8 sw_if_index_set = 0;
5984   int ret;
5985   u8 queue_id_valid = 0;
5986   u32 queue_id;
5987   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5988
5989   /* Parse args required to build the message */
5990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5991     {
5992       if (unformat (i, "queue %d", &queue_id))
5993         queue_id_valid = 1;
5994       else if (unformat (i, "polling"))
5995         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5996       else if (unformat (i, "interrupt"))
5997         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5998       else if (unformat (i, "adaptive"))
5999         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6000       else
6001         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6002         sw_if_index_set = 1;
6003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6004         sw_if_index_set = 1;
6005       else
6006         break;
6007     }
6008
6009   if (sw_if_index_set == 0)
6010     {
6011       errmsg ("missing interface name or sw_if_index");
6012       return -99;
6013     }
6014   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6015     {
6016       errmsg ("missing rx-mode");
6017       return -99;
6018     }
6019
6020   /* Construct the API message */
6021   M (SW_INTERFACE_SET_RX_MODE, mp);
6022   mp->sw_if_index = ntohl (sw_if_index);
6023   mp->mode = (vl_api_rx_mode_t) mode;
6024   mp->queue_id_valid = queue_id_valid;
6025   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6026
6027   /* send it... */
6028   S (mp);
6029
6030   /* Wait for a reply, return the good/bad news... */
6031   W (ret);
6032   return ret;
6033 }
6034
6035 static int
6036 api_sw_interface_set_rx_placement (vat_main_t * vam)
6037 {
6038   unformat_input_t *i = vam->input;
6039   vl_api_sw_interface_set_rx_placement_t *mp;
6040   u32 sw_if_index;
6041   u8 sw_if_index_set = 0;
6042   int ret;
6043   u8 is_main = 0;
6044   u32 queue_id, thread_index;
6045
6046   /* Parse args required to build the message */
6047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048     {
6049       if (unformat (i, "queue %d", &queue_id))
6050         ;
6051       else if (unformat (i, "main"))
6052         is_main = 1;
6053       else if (unformat (i, "worker %d", &thread_index))
6054         ;
6055       else
6056         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6057         sw_if_index_set = 1;
6058       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6059         sw_if_index_set = 1;
6060       else
6061         break;
6062     }
6063
6064   if (sw_if_index_set == 0)
6065     {
6066       errmsg ("missing interface name or sw_if_index");
6067       return -99;
6068     }
6069
6070   if (is_main)
6071     thread_index = 0;
6072   /* Construct the API message */
6073   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6074   mp->sw_if_index = ntohl (sw_if_index);
6075   mp->worker_id = ntohl (thread_index);
6076   mp->queue_id = ntohl (queue_id);
6077   mp->is_main = is_main;
6078
6079   /* send it... */
6080   S (mp);
6081   /* Wait for a reply, return the good/bad news... */
6082   W (ret);
6083   return ret;
6084 }
6085
6086 static void vl_api_sw_interface_rx_placement_details_t_handler
6087   (vl_api_sw_interface_rx_placement_details_t * mp)
6088 {
6089   vat_main_t *vam = &vat_main;
6090   u32 worker_id = ntohl (mp->worker_id);
6091
6092   print (vam->ofp,
6093          "\n%-11d %-11s %-6d %-5d %-9s",
6094          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6095          worker_id, ntohl (mp->queue_id),
6096          (mp->mode ==
6097           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6098 }
6099
6100 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6101   (vl_api_sw_interface_rx_placement_details_t * mp)
6102 {
6103   vat_main_t *vam = &vat_main;
6104   vat_json_node_t *node = NULL;
6105
6106   if (VAT_JSON_ARRAY != vam->json_tree.type)
6107     {
6108       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6109       vat_json_init_array (&vam->json_tree);
6110     }
6111   node = vat_json_array_add (&vam->json_tree);
6112
6113   vat_json_init_object (node);
6114   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6115   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6116   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6117   vat_json_object_add_uint (node, "mode", mp->mode);
6118 }
6119
6120 static int
6121 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6122 {
6123   unformat_input_t *i = vam->input;
6124   vl_api_sw_interface_rx_placement_dump_t *mp;
6125   vl_api_control_ping_t *mp_ping;
6126   int ret;
6127   u32 sw_if_index;
6128   u8 sw_if_index_set = 0;
6129
6130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6131     {
6132       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6133         sw_if_index_set++;
6134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6135         sw_if_index_set++;
6136       else
6137         break;
6138     }
6139
6140   print (vam->ofp,
6141          "\n%-11s %-11s %-6s %-5s %-4s",
6142          "sw_if_index", "main/worker", "thread", "queue", "mode");
6143
6144   /* Dump Interface rx placement */
6145   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6146
6147   if (sw_if_index_set)
6148     mp->sw_if_index = htonl (sw_if_index);
6149   else
6150     mp->sw_if_index = ~0;
6151
6152   S (mp);
6153
6154   /* Use a control ping for synchronization */
6155   MPING (CONTROL_PING, mp_ping);
6156   S (mp_ping);
6157
6158   W (ret);
6159   return ret;
6160 }
6161
6162 static int
6163 api_sw_interface_clear_stats (vat_main_t * vam)
6164 {
6165   unformat_input_t *i = vam->input;
6166   vl_api_sw_interface_clear_stats_t *mp;
6167   u32 sw_if_index;
6168   u8 sw_if_index_set = 0;
6169   int ret;
6170
6171   /* Parse args required to build the message */
6172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6173     {
6174       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6175         sw_if_index_set = 1;
6176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6177         sw_if_index_set = 1;
6178       else
6179         break;
6180     }
6181
6182   /* Construct the API message */
6183   M (SW_INTERFACE_CLEAR_STATS, mp);
6184
6185   if (sw_if_index_set == 1)
6186     mp->sw_if_index = ntohl (sw_if_index);
6187   else
6188     mp->sw_if_index = ~0;
6189
6190   /* send it... */
6191   S (mp);
6192
6193   /* Wait for a reply, return the good/bad news... */
6194   W (ret);
6195   return ret;
6196 }
6197
6198 static int
6199 api_sw_interface_add_del_address (vat_main_t * vam)
6200 {
6201   unformat_input_t *i = vam->input;
6202   vl_api_sw_interface_add_del_address_t *mp;
6203   u32 sw_if_index;
6204   u8 sw_if_index_set = 0;
6205   u8 is_add = 1, del_all = 0;
6206   u32 address_length = 0;
6207   u8 v4_address_set = 0;
6208   u8 v6_address_set = 0;
6209   ip4_address_t v4address;
6210   ip6_address_t v6address;
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, "del-all"))
6217         del_all = 1;
6218       else if (unformat (i, "del"))
6219         is_add = 0;
6220       else
6221         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6222         sw_if_index_set = 1;
6223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6224         sw_if_index_set = 1;
6225       else if (unformat (i, "%U/%d",
6226                          unformat_ip4_address, &v4address, &address_length))
6227         v4_address_set = 1;
6228       else if (unformat (i, "%U/%d",
6229                          unformat_ip6_address, &v6address, &address_length))
6230         v6_address_set = 1;
6231       else
6232         break;
6233     }
6234
6235   if (sw_if_index_set == 0)
6236     {
6237       errmsg ("missing interface name or sw_if_index");
6238       return -99;
6239     }
6240   if (v4_address_set && v6_address_set)
6241     {
6242       errmsg ("both v4 and v6 addresses set");
6243       return -99;
6244     }
6245   if (!v4_address_set && !v6_address_set && !del_all)
6246     {
6247       errmsg ("no addresses set");
6248       return -99;
6249     }
6250
6251   /* Construct the API message */
6252   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6253
6254   mp->sw_if_index = ntohl (sw_if_index);
6255   mp->is_add = is_add;
6256   mp->del_all = del_all;
6257   if (v6_address_set)
6258     {
6259       mp->prefix.address.af = ADDRESS_IP6;
6260       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6261     }
6262   else
6263     {
6264       mp->prefix.address.af = ADDRESS_IP4;
6265       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6266     }
6267   mp->prefix.len = address_length;
6268
6269   /* send it... */
6270   S (mp);
6271
6272   /* Wait for a reply, return good/bad news  */
6273   W (ret);
6274   return ret;
6275 }
6276
6277 static int
6278 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6279 {
6280   unformat_input_t *i = vam->input;
6281   vl_api_sw_interface_set_mpls_enable_t *mp;
6282   u32 sw_if_index;
6283   u8 sw_if_index_set = 0;
6284   u8 enable = 1;
6285   int ret;
6286
6287   /* Parse args required to build the message */
6288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6289     {
6290       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6291         sw_if_index_set = 1;
6292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6293         sw_if_index_set = 1;
6294       else if (unformat (i, "disable"))
6295         enable = 0;
6296       else if (unformat (i, "dis"))
6297         enable = 0;
6298       else
6299         break;
6300     }
6301
6302   if (sw_if_index_set == 0)
6303     {
6304       errmsg ("missing interface name or sw_if_index");
6305       return -99;
6306     }
6307
6308   /* Construct the API message */
6309   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6310
6311   mp->sw_if_index = ntohl (sw_if_index);
6312   mp->enable = enable;
6313
6314   /* send it... */
6315   S (mp);
6316
6317   /* Wait for a reply... */
6318   W (ret);
6319   return ret;
6320 }
6321
6322 static int
6323 api_sw_interface_set_table (vat_main_t * vam)
6324 {
6325   unformat_input_t *i = vam->input;
6326   vl_api_sw_interface_set_table_t *mp;
6327   u32 sw_if_index, vrf_id = 0;
6328   u8 sw_if_index_set = 0;
6329   u8 is_ipv6 = 0;
6330   int ret;
6331
6332   /* Parse args required to build the message */
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, "vrf %d", &vrf_id))
6340         ;
6341       else if (unformat (i, "ipv6"))
6342         is_ipv6 = 1;
6343       else
6344         break;
6345     }
6346
6347   if (sw_if_index_set == 0)
6348     {
6349       errmsg ("missing interface name or sw_if_index");
6350       return -99;
6351     }
6352
6353   /* Construct the API message */
6354   M (SW_INTERFACE_SET_TABLE, mp);
6355
6356   mp->sw_if_index = ntohl (sw_if_index);
6357   mp->is_ipv6 = is_ipv6;
6358   mp->vrf_id = ntohl (vrf_id);
6359
6360   /* send it... */
6361   S (mp);
6362
6363   /* Wait for a reply... */
6364   W (ret);
6365   return ret;
6366 }
6367
6368 static void vl_api_sw_interface_get_table_reply_t_handler
6369   (vl_api_sw_interface_get_table_reply_t * mp)
6370 {
6371   vat_main_t *vam = &vat_main;
6372
6373   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6374
6375   vam->retval = ntohl (mp->retval);
6376   vam->result_ready = 1;
6377
6378 }
6379
6380 static void vl_api_sw_interface_get_table_reply_t_handler_json
6381   (vl_api_sw_interface_get_table_reply_t * mp)
6382 {
6383   vat_main_t *vam = &vat_main;
6384   vat_json_node_t node;
6385
6386   vat_json_init_object (&node);
6387   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6388   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6389
6390   vat_json_print (vam->ofp, &node);
6391   vat_json_free (&node);
6392
6393   vam->retval = ntohl (mp->retval);
6394   vam->result_ready = 1;
6395 }
6396
6397 static int
6398 api_sw_interface_get_table (vat_main_t * vam)
6399 {
6400   unformat_input_t *i = vam->input;
6401   vl_api_sw_interface_get_table_t *mp;
6402   u32 sw_if_index;
6403   u8 sw_if_index_set = 0;
6404   u8 is_ipv6 = 0;
6405   int ret;
6406
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6410         sw_if_index_set = 1;
6411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6412         sw_if_index_set = 1;
6413       else if (unformat (i, "ipv6"))
6414         is_ipv6 = 1;
6415       else
6416         break;
6417     }
6418
6419   if (sw_if_index_set == 0)
6420     {
6421       errmsg ("missing interface name or sw_if_index");
6422       return -99;
6423     }
6424
6425   M (SW_INTERFACE_GET_TABLE, mp);
6426   mp->sw_if_index = htonl (sw_if_index);
6427   mp->is_ipv6 = is_ipv6;
6428
6429   S (mp);
6430   W (ret);
6431   return ret;
6432 }
6433
6434 static int
6435 api_sw_interface_set_vpath (vat_main_t * vam)
6436 {
6437   unformat_input_t *i = vam->input;
6438   vl_api_sw_interface_set_vpath_t *mp;
6439   u32 sw_if_index = 0;
6440   u8 sw_if_index_set = 0;
6441   u8 is_enable = 0;
6442   int ret;
6443
6444   /* Parse args required to build the message */
6445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6446     {
6447       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6448         sw_if_index_set = 1;
6449       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6450         sw_if_index_set = 1;
6451       else if (unformat (i, "enable"))
6452         is_enable = 1;
6453       else if (unformat (i, "disable"))
6454         is_enable = 0;
6455       else
6456         break;
6457     }
6458
6459   if (sw_if_index_set == 0)
6460     {
6461       errmsg ("missing interface name or sw_if_index");
6462       return -99;
6463     }
6464
6465   /* Construct the API message */
6466   M (SW_INTERFACE_SET_VPATH, mp);
6467
6468   mp->sw_if_index = ntohl (sw_if_index);
6469   mp->enable = is_enable;
6470
6471   /* send it... */
6472   S (mp);
6473
6474   /* Wait for a reply... */
6475   W (ret);
6476   return ret;
6477 }
6478
6479 static int
6480 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6481 {
6482   unformat_input_t *i = vam->input;
6483   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6484   u32 sw_if_index = 0;
6485   u8 sw_if_index_set = 0;
6486   u8 is_enable = 1;
6487   u8 is_ipv6 = 0;
6488   int ret;
6489
6490   /* Parse args required to build the message */
6491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6492     {
6493       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6494         sw_if_index_set = 1;
6495       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6496         sw_if_index_set = 1;
6497       else if (unformat (i, "enable"))
6498         is_enable = 1;
6499       else if (unformat (i, "disable"))
6500         is_enable = 0;
6501       else if (unformat (i, "ip4"))
6502         is_ipv6 = 0;
6503       else if (unformat (i, "ip6"))
6504         is_ipv6 = 1;
6505       else
6506         break;
6507     }
6508
6509   if (sw_if_index_set == 0)
6510     {
6511       errmsg ("missing interface name or sw_if_index");
6512       return -99;
6513     }
6514
6515   /* Construct the API message */
6516   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6517
6518   mp->sw_if_index = ntohl (sw_if_index);
6519   mp->enable = is_enable;
6520   mp->is_ipv6 = is_ipv6;
6521
6522   /* send it... */
6523   S (mp);
6524
6525   /* Wait for a reply... */
6526   W (ret);
6527   return ret;
6528 }
6529
6530 static int
6531 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6532 {
6533   unformat_input_t *i = vam->input;
6534   vl_api_sw_interface_set_geneve_bypass_t *mp;
6535   u32 sw_if_index = 0;
6536   u8 sw_if_index_set = 0;
6537   u8 is_enable = 1;
6538   u8 is_ipv6 = 0;
6539   int ret;
6540
6541   /* Parse args required to build the message */
6542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6543     {
6544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6545         sw_if_index_set = 1;
6546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6547         sw_if_index_set = 1;
6548       else if (unformat (i, "enable"))
6549         is_enable = 1;
6550       else if (unformat (i, "disable"))
6551         is_enable = 0;
6552       else if (unformat (i, "ip4"))
6553         is_ipv6 = 0;
6554       else if (unformat (i, "ip6"))
6555         is_ipv6 = 1;
6556       else
6557         break;
6558     }
6559
6560   if (sw_if_index_set == 0)
6561     {
6562       errmsg ("missing interface name or sw_if_index");
6563       return -99;
6564     }
6565
6566   /* Construct the API message */
6567   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6568
6569   mp->sw_if_index = ntohl (sw_if_index);
6570   mp->enable = is_enable;
6571   mp->is_ipv6 = is_ipv6;
6572
6573   /* send it... */
6574   S (mp);
6575
6576   /* Wait for a reply... */
6577   W (ret);
6578   return ret;
6579 }
6580
6581 static int
6582 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6583 {
6584   unformat_input_t *i = vam->input;
6585   vl_api_sw_interface_set_l2_xconnect_t *mp;
6586   u32 rx_sw_if_index;
6587   u8 rx_sw_if_index_set = 0;
6588   u32 tx_sw_if_index;
6589   u8 tx_sw_if_index_set = 0;
6590   u8 enable = 1;
6591   int ret;
6592
6593   /* Parse args required to build the message */
6594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6595     {
6596       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6597         rx_sw_if_index_set = 1;
6598       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6599         tx_sw_if_index_set = 1;
6600       else if (unformat (i, "rx"))
6601         {
6602           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6603             {
6604               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6605                             &rx_sw_if_index))
6606                 rx_sw_if_index_set = 1;
6607             }
6608           else
6609             break;
6610         }
6611       else if (unformat (i, "tx"))
6612         {
6613           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614             {
6615               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6616                             &tx_sw_if_index))
6617                 tx_sw_if_index_set = 1;
6618             }
6619           else
6620             break;
6621         }
6622       else if (unformat (i, "enable"))
6623         enable = 1;
6624       else if (unformat (i, "disable"))
6625         enable = 0;
6626       else
6627         break;
6628     }
6629
6630   if (rx_sw_if_index_set == 0)
6631     {
6632       errmsg ("missing rx interface name or rx_sw_if_index");
6633       return -99;
6634     }
6635
6636   if (enable && (tx_sw_if_index_set == 0))
6637     {
6638       errmsg ("missing tx interface name or tx_sw_if_index");
6639       return -99;
6640     }
6641
6642   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6643
6644   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6645   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6646   mp->enable = enable;
6647
6648   S (mp);
6649   W (ret);
6650   return ret;
6651 }
6652
6653 static int
6654 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6655 {
6656   unformat_input_t *i = vam->input;
6657   vl_api_sw_interface_set_l2_bridge_t *mp;
6658   vl_api_l2_port_type_t port_type;
6659   u32 rx_sw_if_index;
6660   u8 rx_sw_if_index_set = 0;
6661   u32 bd_id;
6662   u8 bd_id_set = 0;
6663   u32 shg = 0;
6664   u8 enable = 1;
6665   int ret;
6666
6667   port_type = L2_API_PORT_TYPE_NORMAL;
6668
6669   /* Parse args required to build the message */
6670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6671     {
6672       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6673         rx_sw_if_index_set = 1;
6674       else if (unformat (i, "bd_id %d", &bd_id))
6675         bd_id_set = 1;
6676       else
6677         if (unformat
6678             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6679         rx_sw_if_index_set = 1;
6680       else if (unformat (i, "shg %d", &shg))
6681         ;
6682       else if (unformat (i, "bvi"))
6683         port_type = L2_API_PORT_TYPE_BVI;
6684       else if (unformat (i, "uu-fwd"))
6685         port_type = L2_API_PORT_TYPE_UU_FWD;
6686       else if (unformat (i, "enable"))
6687         enable = 1;
6688       else if (unformat (i, "disable"))
6689         enable = 0;
6690       else
6691         break;
6692     }
6693
6694   if (rx_sw_if_index_set == 0)
6695     {
6696       errmsg ("missing rx interface name or sw_if_index");
6697       return -99;
6698     }
6699
6700   if (enable && (bd_id_set == 0))
6701     {
6702       errmsg ("missing bridge domain");
6703       return -99;
6704     }
6705
6706   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6707
6708   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6709   mp->bd_id = ntohl (bd_id);
6710   mp->shg = (u8) shg;
6711   mp->port_type = ntohl (port_type);
6712   mp->enable = enable;
6713
6714   S (mp);
6715   W (ret);
6716   return ret;
6717 }
6718
6719 static int
6720 api_bridge_domain_dump (vat_main_t * vam)
6721 {
6722   unformat_input_t *i = vam->input;
6723   vl_api_bridge_domain_dump_t *mp;
6724   vl_api_control_ping_t *mp_ping;
6725   u32 bd_id = ~0;
6726   int ret;
6727
6728   /* Parse args required to build the message */
6729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6730     {
6731       if (unformat (i, "bd_id %d", &bd_id))
6732         ;
6733       else
6734         break;
6735     }
6736
6737   M (BRIDGE_DOMAIN_DUMP, mp);
6738   mp->bd_id = ntohl (bd_id);
6739   S (mp);
6740
6741   /* Use a control ping for synchronization */
6742   MPING (CONTROL_PING, mp_ping);
6743   S (mp_ping);
6744
6745   W (ret);
6746   return ret;
6747 }
6748
6749 static int
6750 api_bridge_domain_add_del (vat_main_t * vam)
6751 {
6752   unformat_input_t *i = vam->input;
6753   vl_api_bridge_domain_add_del_t *mp;
6754   u32 bd_id = ~0;
6755   u8 is_add = 1;
6756   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6757   u8 *bd_tag = NULL;
6758   u32 mac_age = 0;
6759   int ret;
6760
6761   /* Parse args required to build the message */
6762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6763     {
6764       if (unformat (i, "bd_id %d", &bd_id))
6765         ;
6766       else if (unformat (i, "flood %d", &flood))
6767         ;
6768       else if (unformat (i, "uu-flood %d", &uu_flood))
6769         ;
6770       else if (unformat (i, "forward %d", &forward))
6771         ;
6772       else if (unformat (i, "learn %d", &learn))
6773         ;
6774       else if (unformat (i, "arp-term %d", &arp_term))
6775         ;
6776       else if (unformat (i, "mac-age %d", &mac_age))
6777         ;
6778       else if (unformat (i, "bd-tag %s", &bd_tag))
6779         ;
6780       else if (unformat (i, "del"))
6781         {
6782           is_add = 0;
6783           flood = uu_flood = forward = learn = 0;
6784         }
6785       else
6786         break;
6787     }
6788
6789   if (bd_id == ~0)
6790     {
6791       errmsg ("missing bridge domain");
6792       ret = -99;
6793       goto done;
6794     }
6795
6796   if (mac_age > 255)
6797     {
6798       errmsg ("mac age must be less than 256 ");
6799       ret = -99;
6800       goto done;
6801     }
6802
6803   if ((bd_tag) && (vec_len (bd_tag) > 63))
6804     {
6805       errmsg ("bd-tag cannot be longer than 63");
6806       ret = -99;
6807       goto done;
6808     }
6809
6810   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6811
6812   mp->bd_id = ntohl (bd_id);
6813   mp->flood = flood;
6814   mp->uu_flood = uu_flood;
6815   mp->forward = forward;
6816   mp->learn = learn;
6817   mp->arp_term = arp_term;
6818   mp->is_add = is_add;
6819   mp->mac_age = (u8) mac_age;
6820   if (bd_tag)
6821     {
6822       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6823       mp->bd_tag[vec_len (bd_tag)] = 0;
6824     }
6825   S (mp);
6826   W (ret);
6827
6828 done:
6829   vec_free (bd_tag);
6830   return ret;
6831 }
6832
6833 static int
6834 api_l2fib_flush_bd (vat_main_t * vam)
6835 {
6836   unformat_input_t *i = vam->input;
6837   vl_api_l2fib_flush_bd_t *mp;
6838   u32 bd_id = ~0;
6839   int ret;
6840
6841   /* Parse args required to build the message */
6842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6843     {
6844       if (unformat (i, "bd_id %d", &bd_id));
6845       else
6846         break;
6847     }
6848
6849   if (bd_id == ~0)
6850     {
6851       errmsg ("missing bridge domain");
6852       return -99;
6853     }
6854
6855   M (L2FIB_FLUSH_BD, mp);
6856
6857   mp->bd_id = htonl (bd_id);
6858
6859   S (mp);
6860   W (ret);
6861   return ret;
6862 }
6863
6864 static int
6865 api_l2fib_flush_int (vat_main_t * vam)
6866 {
6867   unformat_input_t *i = vam->input;
6868   vl_api_l2fib_flush_int_t *mp;
6869   u32 sw_if_index = ~0;
6870   int ret;
6871
6872   /* Parse args required to build the message */
6873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6874     {
6875       if (unformat (i, "sw_if_index %d", &sw_if_index));
6876       else
6877         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6878       else
6879         break;
6880     }
6881
6882   if (sw_if_index == ~0)
6883     {
6884       errmsg ("missing interface name or sw_if_index");
6885       return -99;
6886     }
6887
6888   M (L2FIB_FLUSH_INT, mp);
6889
6890   mp->sw_if_index = ntohl (sw_if_index);
6891
6892   S (mp);
6893   W (ret);
6894   return ret;
6895 }
6896
6897 static int
6898 api_l2fib_add_del (vat_main_t * vam)
6899 {
6900   unformat_input_t *i = vam->input;
6901   vl_api_l2fib_add_del_t *mp;
6902   f64 timeout;
6903   u8 mac[6] = { 0 };
6904   u8 mac_set = 0;
6905   u32 bd_id;
6906   u8 bd_id_set = 0;
6907   u32 sw_if_index = 0;
6908   u8 sw_if_index_set = 0;
6909   u8 is_add = 1;
6910   u8 static_mac = 0;
6911   u8 filter_mac = 0;
6912   u8 bvi_mac = 0;
6913   int count = 1;
6914   f64 before = 0;
6915   int j;
6916
6917   /* Parse args required to build the message */
6918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6919     {
6920       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6921         mac_set = 1;
6922       else if (unformat (i, "bd_id %d", &bd_id))
6923         bd_id_set = 1;
6924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6925         sw_if_index_set = 1;
6926       else if (unformat (i, "sw_if"))
6927         {
6928           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6929             {
6930               if (unformat
6931                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6932                 sw_if_index_set = 1;
6933             }
6934           else
6935             break;
6936         }
6937       else if (unformat (i, "static"))
6938         static_mac = 1;
6939       else if (unformat (i, "filter"))
6940         {
6941           filter_mac = 1;
6942           static_mac = 1;
6943         }
6944       else if (unformat (i, "bvi"))
6945         {
6946           bvi_mac = 1;
6947           static_mac = 1;
6948         }
6949       else if (unformat (i, "del"))
6950         is_add = 0;
6951       else if (unformat (i, "count %d", &count))
6952         ;
6953       else
6954         break;
6955     }
6956
6957   if (mac_set == 0)
6958     {
6959       errmsg ("missing mac address");
6960       return -99;
6961     }
6962
6963   if (bd_id_set == 0)
6964     {
6965       errmsg ("missing bridge domain");
6966       return -99;
6967     }
6968
6969   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6970     {
6971       errmsg ("missing interface name or sw_if_index");
6972       return -99;
6973     }
6974
6975   if (count > 1)
6976     {
6977       /* Turn on async mode */
6978       vam->async_mode = 1;
6979       vam->async_errors = 0;
6980       before = vat_time_now (vam);
6981     }
6982
6983   for (j = 0; j < count; j++)
6984     {
6985       M (L2FIB_ADD_DEL, mp);
6986
6987       clib_memcpy (mp->mac, mac, 6);
6988       mp->bd_id = ntohl (bd_id);
6989       mp->is_add = is_add;
6990       mp->sw_if_index = ntohl (sw_if_index);
6991
6992       if (is_add)
6993         {
6994           mp->static_mac = static_mac;
6995           mp->filter_mac = filter_mac;
6996           mp->bvi_mac = bvi_mac;
6997         }
6998       increment_mac_address (mac);
6999       /* send it... */
7000       S (mp);
7001     }
7002
7003   if (count > 1)
7004     {
7005       vl_api_control_ping_t *mp_ping;
7006       f64 after;
7007
7008       /* Shut off async mode */
7009       vam->async_mode = 0;
7010
7011       MPING (CONTROL_PING, mp_ping);
7012       S (mp_ping);
7013
7014       timeout = vat_time_now (vam) + 1.0;
7015       while (vat_time_now (vam) < timeout)
7016         if (vam->result_ready == 1)
7017           goto out;
7018       vam->retval = -99;
7019
7020     out:
7021       if (vam->retval == -99)
7022         errmsg ("timeout");
7023
7024       if (vam->async_errors > 0)
7025         {
7026           errmsg ("%d asynchronous errors", vam->async_errors);
7027           vam->retval = -98;
7028         }
7029       vam->async_errors = 0;
7030       after = vat_time_now (vam);
7031
7032       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7033              count, after - before, count / (after - before));
7034     }
7035   else
7036     {
7037       int ret;
7038
7039       /* Wait for a reply... */
7040       W (ret);
7041       return ret;
7042     }
7043   /* Return the good/bad news */
7044   return (vam->retval);
7045 }
7046
7047 static int
7048 api_bridge_domain_set_mac_age (vat_main_t * vam)
7049 {
7050   unformat_input_t *i = vam->input;
7051   vl_api_bridge_domain_set_mac_age_t *mp;
7052   u32 bd_id = ~0;
7053   u32 mac_age = 0;
7054   int ret;
7055
7056   /* Parse args required to build the message */
7057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058     {
7059       if (unformat (i, "bd_id %d", &bd_id));
7060       else if (unformat (i, "mac-age %d", &mac_age));
7061       else
7062         break;
7063     }
7064
7065   if (bd_id == ~0)
7066     {
7067       errmsg ("missing bridge domain");
7068       return -99;
7069     }
7070
7071   if (mac_age > 255)
7072     {
7073       errmsg ("mac age must be less than 256 ");
7074       return -99;
7075     }
7076
7077   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7078
7079   mp->bd_id = htonl (bd_id);
7080   mp->mac_age = (u8) mac_age;
7081
7082   S (mp);
7083   W (ret);
7084   return ret;
7085 }
7086
7087 static int
7088 api_l2_flags (vat_main_t * vam)
7089 {
7090   unformat_input_t *i = vam->input;
7091   vl_api_l2_flags_t *mp;
7092   u32 sw_if_index;
7093   u32 flags = 0;
7094   u8 sw_if_index_set = 0;
7095   u8 is_set = 0;
7096   int ret;
7097
7098   /* Parse args required to build the message */
7099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7100     {
7101       if (unformat (i, "sw_if_index %d", &sw_if_index))
7102         sw_if_index_set = 1;
7103       else if (unformat (i, "sw_if"))
7104         {
7105           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7106             {
7107               if (unformat
7108                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7109                 sw_if_index_set = 1;
7110             }
7111           else
7112             break;
7113         }
7114       else if (unformat (i, "learn"))
7115         flags |= L2_LEARN;
7116       else if (unformat (i, "forward"))
7117         flags |= L2_FWD;
7118       else if (unformat (i, "flood"))
7119         flags |= L2_FLOOD;
7120       else if (unformat (i, "uu-flood"))
7121         flags |= L2_UU_FLOOD;
7122       else if (unformat (i, "arp-term"))
7123         flags |= L2_ARP_TERM;
7124       else if (unformat (i, "off"))
7125         is_set = 0;
7126       else if (unformat (i, "disable"))
7127         is_set = 0;
7128       else
7129         break;
7130     }
7131
7132   if (sw_if_index_set == 0)
7133     {
7134       errmsg ("missing interface name or sw_if_index");
7135       return -99;
7136     }
7137
7138   M (L2_FLAGS, mp);
7139
7140   mp->sw_if_index = ntohl (sw_if_index);
7141   mp->feature_bitmap = ntohl (flags);
7142   mp->is_set = is_set;
7143
7144   S (mp);
7145   W (ret);
7146   return ret;
7147 }
7148
7149 static int
7150 api_bridge_flags (vat_main_t * vam)
7151 {
7152   unformat_input_t *i = vam->input;
7153   vl_api_bridge_flags_t *mp;
7154   u32 bd_id;
7155   u8 bd_id_set = 0;
7156   u8 is_set = 1;
7157   bd_flags_t flags = 0;
7158   int ret;
7159
7160   /* Parse args required to build the message */
7161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7162     {
7163       if (unformat (i, "bd_id %d", &bd_id))
7164         bd_id_set = 1;
7165       else if (unformat (i, "learn"))
7166         flags |= BRIDGE_API_FLAG_LEARN;
7167       else if (unformat (i, "forward"))
7168         flags |= BRIDGE_API_FLAG_FWD;
7169       else if (unformat (i, "flood"))
7170         flags |= BRIDGE_API_FLAG_FLOOD;
7171       else if (unformat (i, "uu-flood"))
7172         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7173       else if (unformat (i, "arp-term"))
7174         flags |= BRIDGE_API_FLAG_ARP_TERM;
7175       else if (unformat (i, "off"))
7176         is_set = 0;
7177       else if (unformat (i, "disable"))
7178         is_set = 0;
7179       else
7180         break;
7181     }
7182
7183   if (bd_id_set == 0)
7184     {
7185       errmsg ("missing bridge domain");
7186       return -99;
7187     }
7188
7189   M (BRIDGE_FLAGS, mp);
7190
7191   mp->bd_id = ntohl (bd_id);
7192   mp->flags = ntohl (flags);
7193   mp->is_set = is_set;
7194
7195   S (mp);
7196   W (ret);
7197   return ret;
7198 }
7199
7200 static int
7201 api_bd_ip_mac_add_del (vat_main_t * vam)
7202 {
7203   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7204   vl_api_mac_address_t mac = { 0 };
7205   unformat_input_t *i = vam->input;
7206   vl_api_bd_ip_mac_add_del_t *mp;
7207   u32 bd_id;
7208   u8 is_add = 1;
7209   u8 bd_id_set = 0;
7210   u8 ip_set = 0;
7211   u8 mac_set = 0;
7212   int ret;
7213
7214
7215   /* Parse args required to build the message */
7216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7217     {
7218       if (unformat (i, "bd_id %d", &bd_id))
7219         {
7220           bd_id_set++;
7221         }
7222       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7223         {
7224           ip_set++;
7225         }
7226       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7227         {
7228           mac_set++;
7229         }
7230       else if (unformat (i, "del"))
7231         is_add = 0;
7232       else
7233         break;
7234     }
7235
7236   if (bd_id_set == 0)
7237     {
7238       errmsg ("missing bridge domain");
7239       return -99;
7240     }
7241   else if (ip_set == 0)
7242     {
7243       errmsg ("missing IP address");
7244       return -99;
7245     }
7246   else if (mac_set == 0)
7247     {
7248       errmsg ("missing MAC address");
7249       return -99;
7250     }
7251
7252   M (BD_IP_MAC_ADD_DEL, mp);
7253
7254   mp->entry.bd_id = ntohl (bd_id);
7255   mp->is_add = is_add;
7256
7257   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7258   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7259
7260   S (mp);
7261   W (ret);
7262   return ret;
7263 }
7264
7265 static int
7266 api_bd_ip_mac_flush (vat_main_t * vam)
7267 {
7268   unformat_input_t *i = vam->input;
7269   vl_api_bd_ip_mac_flush_t *mp;
7270   u32 bd_id;
7271   u8 bd_id_set = 0;
7272   int ret;
7273
7274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7275     {
7276       if (unformat (i, "bd_id %d", &bd_id))
7277         {
7278           bd_id_set++;
7279         }
7280       else
7281         break;
7282     }
7283
7284   if (bd_id_set == 0)
7285     {
7286       errmsg ("missing bridge domain");
7287       return -99;
7288     }
7289
7290   M (BD_IP_MAC_FLUSH, mp);
7291
7292   mp->bd_id = ntohl (bd_id);
7293
7294   S (mp);
7295   W (ret);
7296   return ret;
7297 }
7298
7299 static void vl_api_bd_ip_mac_details_t_handler
7300   (vl_api_bd_ip_mac_details_t * mp)
7301 {
7302   vat_main_t *vam = &vat_main;
7303
7304   print (vam->ofp,
7305          "\n%-5d %U %U",
7306          ntohl (mp->entry.bd_id),
7307          format_vl_api_mac_address, mp->entry.mac,
7308          format_vl_api_address, &mp->entry.ip);
7309 }
7310
7311 static void vl_api_bd_ip_mac_details_t_handler_json
7312   (vl_api_bd_ip_mac_details_t * mp)
7313 {
7314   vat_main_t *vam = &vat_main;
7315   vat_json_node_t *node = NULL;
7316
7317   if (VAT_JSON_ARRAY != vam->json_tree.type)
7318     {
7319       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7320       vat_json_init_array (&vam->json_tree);
7321     }
7322   node = vat_json_array_add (&vam->json_tree);
7323
7324   vat_json_init_object (node);
7325   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7326   vat_json_object_add_string_copy (node, "mac_address",
7327                                    format (0, "%U", format_vl_api_mac_address,
7328                                            &mp->entry.mac));
7329   u8 *ip = 0;
7330
7331   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7332   vat_json_object_add_string_copy (node, "ip_address", ip);
7333   vec_free (ip);
7334 }
7335
7336 static int
7337 api_bd_ip_mac_dump (vat_main_t * vam)
7338 {
7339   unformat_input_t *i = vam->input;
7340   vl_api_bd_ip_mac_dump_t *mp;
7341   vl_api_control_ping_t *mp_ping;
7342   int ret;
7343   u32 bd_id;
7344   u8 bd_id_set = 0;
7345
7346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7347     {
7348       if (unformat (i, "bd_id %d", &bd_id))
7349         {
7350           bd_id_set++;
7351         }
7352       else
7353         break;
7354     }
7355
7356   print (vam->ofp,
7357          "\n%-5s %-7s %-20s %-30s",
7358          "bd_id", "is_ipv6", "mac_address", "ip_address");
7359
7360   /* Dump Bridge Domain Ip to Mac entries */
7361   M (BD_IP_MAC_DUMP, mp);
7362
7363   if (bd_id_set)
7364     mp->bd_id = htonl (bd_id);
7365   else
7366     mp->bd_id = ~0;
7367
7368   S (mp);
7369
7370   /* Use a control ping for synchronization */
7371   MPING (CONTROL_PING, mp_ping);
7372   S (mp_ping);
7373
7374   W (ret);
7375   return ret;
7376 }
7377
7378 static int
7379 api_tap_create_v2 (vat_main_t * vam)
7380 {
7381   unformat_input_t *i = vam->input;
7382   vl_api_tap_create_v2_t *mp;
7383   u8 mac_address[6];
7384   u8 random_mac = 1;
7385   u32 id = ~0;
7386   u32 num_rx_queues = 0;
7387   u8 *host_if_name = 0;
7388   u8 host_if_name_set = 0;
7389   u8 *host_ns = 0;
7390   u8 host_ns_set = 0;
7391   u8 host_mac_addr[6];
7392   u8 host_mac_addr_set = 0;
7393   u8 *host_bridge = 0;
7394   u8 host_bridge_set = 0;
7395   u8 host_ip4_prefix_set = 0;
7396   u8 host_ip6_prefix_set = 0;
7397   ip4_address_t host_ip4_addr;
7398   ip4_address_t host_ip4_gw;
7399   u8 host_ip4_gw_set = 0;
7400   u32 host_ip4_prefix_len = 0;
7401   ip6_address_t host_ip6_addr;
7402   ip6_address_t host_ip6_gw;
7403   u8 host_ip6_gw_set = 0;
7404   u32 host_ip6_prefix_len = 0;
7405   u32 host_mtu_size = 0;
7406   u8 host_mtu_set = 0;
7407   u32 tap_flags = 0;
7408   int ret;
7409   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7410
7411   clib_memset (mac_address, 0, sizeof (mac_address));
7412
7413   /* Parse args required to build the message */
7414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7415     {
7416       if (unformat (i, "id %u", &id))
7417         ;
7418       else
7419         if (unformat
7420             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7421         random_mac = 0;
7422       else if (unformat (i, "host-if-name %s", &host_if_name))
7423         host_if_name_set = 1;
7424       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7425         ;
7426       else if (unformat (i, "host-ns %s", &host_ns))
7427         host_ns_set = 1;
7428       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7429                          host_mac_addr))
7430         host_mac_addr_set = 1;
7431       else if (unformat (i, "host-bridge %s", &host_bridge))
7432         host_bridge_set = 1;
7433       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7434                          &host_ip4_addr, &host_ip4_prefix_len))
7435         host_ip4_prefix_set = 1;
7436       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7437                          &host_ip6_addr, &host_ip6_prefix_len))
7438         host_ip6_prefix_set = 1;
7439       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7440                          &host_ip4_gw))
7441         host_ip4_gw_set = 1;
7442       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7443                          &host_ip6_gw))
7444         host_ip6_gw_set = 1;
7445       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7446         ;
7447       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7448         ;
7449       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7450         host_mtu_set = 1;
7451       else if (unformat (i, "no-gso"))
7452         tap_flags &= ~TAP_API_FLAG_GSO;
7453       else if (unformat (i, "gso"))
7454         tap_flags |= TAP_API_FLAG_GSO;
7455       else if (unformat (i, "csum-offload"))
7456         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7457       else if (unformat (i, "persist"))
7458         tap_flags |= TAP_API_FLAG_PERSIST;
7459       else if (unformat (i, "attach"))
7460         tap_flags |= TAP_API_FLAG_ATTACH;
7461       else if (unformat (i, "tun"))
7462         tap_flags |= TAP_API_FLAG_TUN;
7463       else if (unformat (i, "gro-coalesce"))
7464         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7465       else if (unformat (i, "packed"))
7466         tap_flags |= TAP_API_FLAG_PACKED;
7467       else if (unformat (i, "in-order"))
7468         tap_flags |= TAP_API_FLAG_IN_ORDER;
7469       else
7470         break;
7471     }
7472
7473   if (vec_len (host_if_name) > 63)
7474     {
7475       errmsg ("tap name too long. ");
7476       return -99;
7477     }
7478   if (vec_len (host_ns) > 63)
7479     {
7480       errmsg ("host name space too long. ");
7481       return -99;
7482     }
7483   if (vec_len (host_bridge) > 63)
7484     {
7485       errmsg ("host bridge name too long. ");
7486       return -99;
7487     }
7488   if (host_ip4_prefix_len > 32)
7489     {
7490       errmsg ("host ip4 prefix length not valid. ");
7491       return -99;
7492     }
7493   if (host_ip6_prefix_len > 128)
7494     {
7495       errmsg ("host ip6 prefix length not valid. ");
7496       return -99;
7497     }
7498   if (!is_pow2 (rx_ring_sz))
7499     {
7500       errmsg ("rx ring size must be power of 2. ");
7501       return -99;
7502     }
7503   if (rx_ring_sz > 32768)
7504     {
7505       errmsg ("rx ring size must be 32768 or lower. ");
7506       return -99;
7507     }
7508   if (!is_pow2 (tx_ring_sz))
7509     {
7510       errmsg ("tx ring size must be power of 2. ");
7511       return -99;
7512     }
7513   if (tx_ring_sz > 32768)
7514     {
7515       errmsg ("tx ring size must be 32768 or lower. ");
7516       return -99;
7517     }
7518   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7519     {
7520       errmsg ("host MTU size must be in between 64 and 65355. ");
7521       return -99;
7522     }
7523
7524   /* Construct the API message */
7525   M (TAP_CREATE_V2, mp);
7526
7527   mp->id = ntohl (id);
7528   mp->use_random_mac = random_mac;
7529   mp->num_rx_queues = (u8) num_rx_queues;
7530   mp->tx_ring_sz = ntohs (tx_ring_sz);
7531   mp->rx_ring_sz = ntohs (rx_ring_sz);
7532   mp->host_mtu_set = host_mtu_set;
7533   mp->host_mtu_size = ntohl (host_mtu_size);
7534   mp->host_mac_addr_set = host_mac_addr_set;
7535   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7536   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7537   mp->host_ip4_gw_set = host_ip4_gw_set;
7538   mp->host_ip6_gw_set = host_ip6_gw_set;
7539   mp->tap_flags = ntohl (tap_flags);
7540   mp->host_namespace_set = host_ns_set;
7541   mp->host_if_name_set = host_if_name_set;
7542   mp->host_bridge_set = host_bridge_set;
7543
7544   if (random_mac == 0)
7545     clib_memcpy (mp->mac_address, mac_address, 6);
7546   if (host_mac_addr_set)
7547     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7548   if (host_if_name_set)
7549     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7550   if (host_ns_set)
7551     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7552   if (host_bridge_set)
7553     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7554   if (host_ip4_prefix_set)
7555     {
7556       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7557       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7558     }
7559   if (host_ip6_prefix_set)
7560     {
7561       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7562       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7563     }
7564   if (host_ip4_gw_set)
7565     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7566   if (host_ip6_gw_set)
7567     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7568
7569   vec_free (host_ns);
7570   vec_free (host_if_name);
7571   vec_free (host_bridge);
7572
7573   /* send it... */
7574   S (mp);
7575
7576   /* Wait for a reply... */
7577   W (ret);
7578   return ret;
7579 }
7580
7581 static int
7582 api_tap_delete_v2 (vat_main_t * vam)
7583 {
7584   unformat_input_t *i = vam->input;
7585   vl_api_tap_delete_v2_t *mp;
7586   u32 sw_if_index = ~0;
7587   u8 sw_if_index_set = 0;
7588   int ret;
7589
7590   /* Parse args required to build the message */
7591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7592     {
7593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7594         sw_if_index_set = 1;
7595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7596         sw_if_index_set = 1;
7597       else
7598         break;
7599     }
7600
7601   if (sw_if_index_set == 0)
7602     {
7603       errmsg ("missing vpp interface name. ");
7604       return -99;
7605     }
7606
7607   /* Construct the API message */
7608   M (TAP_DELETE_V2, mp);
7609
7610   mp->sw_if_index = ntohl (sw_if_index);
7611
7612   /* send it... */
7613   S (mp);
7614
7615   /* Wait for a reply... */
7616   W (ret);
7617   return ret;
7618 }
7619
7620 uword
7621 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7622 {
7623   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7624   u32 x[4];
7625
7626   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7627     return 0;
7628
7629   addr->domain = x[0];
7630   addr->bus = x[1];
7631   addr->slot = x[2];
7632   addr->function = x[3];
7633
7634   return 1;
7635 }
7636
7637 static int
7638 api_virtio_pci_create_v2 (vat_main_t * vam)
7639 {
7640   unformat_input_t *i = vam->input;
7641   vl_api_virtio_pci_create_v2_t *mp;
7642   u8 mac_address[6];
7643   u8 random_mac = 1;
7644   u32 pci_addr = 0;
7645   u64 features = (u64) ~ (0ULL);
7646   u32 virtio_flags = 0;
7647   int ret;
7648
7649   clib_memset (mac_address, 0, sizeof (mac_address));
7650
7651   /* Parse args required to build the message */
7652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7653     {
7654       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7655         {
7656           random_mac = 0;
7657         }
7658       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7659         ;
7660       else if (unformat (i, "features 0x%llx", &features))
7661         ;
7662       else if (unformat (i, "gso-enabled"))
7663         virtio_flags |= VIRTIO_API_FLAG_GSO;
7664       else if (unformat (i, "csum-offload-enabled"))
7665         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
7666       else if (unformat (i, "gro-coalesce"))
7667         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
7668       else if (unformat (i, "packed"))
7669         virtio_flags |= VIRTIO_API_FLAG_PACKED;
7670       else if (unformat (i, "in-order"))
7671         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
7672       else
7673         break;
7674     }
7675
7676   if (pci_addr == 0)
7677     {
7678       errmsg ("pci address must be non zero. ");
7679       return -99;
7680     }
7681
7682   /* Construct the API message */
7683   M (VIRTIO_PCI_CREATE_V2, mp);
7684
7685   mp->use_random_mac = random_mac;
7686
7687   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7688   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7689   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7690   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7691
7692   mp->features = clib_host_to_net_u64 (features);
7693   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
7694
7695   if (random_mac == 0)
7696     clib_memcpy (mp->mac_address, mac_address, 6);
7697
7698   /* send it... */
7699   S (mp);
7700
7701   /* Wait for a reply... */
7702   W (ret);
7703   return ret;
7704 }
7705
7706 static int
7707 api_virtio_pci_delete (vat_main_t * vam)
7708 {
7709   unformat_input_t *i = vam->input;
7710   vl_api_virtio_pci_delete_t *mp;
7711   u32 sw_if_index = ~0;
7712   u8 sw_if_index_set = 0;
7713   int ret;
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7719         sw_if_index_set = 1;
7720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7721         sw_if_index_set = 1;
7722       else
7723         break;
7724     }
7725
7726   if (sw_if_index_set == 0)
7727     {
7728       errmsg ("missing vpp interface name. ");
7729       return -99;
7730     }
7731
7732   /* Construct the API message */
7733   M (VIRTIO_PCI_DELETE, mp);
7734
7735   mp->sw_if_index = htonl (sw_if_index);
7736
7737   /* send it... */
7738   S (mp);
7739
7740   /* Wait for a reply... */
7741   W (ret);
7742   return ret;
7743 }
7744
7745 static int
7746 api_bond_create (vat_main_t * vam)
7747 {
7748   unformat_input_t *i = vam->input;
7749   vl_api_bond_create_t *mp;
7750   u8 mac_address[6];
7751   u8 custom_mac = 0;
7752   int ret;
7753   u8 mode;
7754   u8 lb;
7755   u8 mode_is_set = 0;
7756   u32 id = ~0;
7757   u8 numa_only = 0;
7758
7759   clib_memset (mac_address, 0, sizeof (mac_address));
7760   lb = BOND_LB_L2;
7761
7762   /* Parse args required to build the message */
7763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7764     {
7765       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7766         mode_is_set = 1;
7767       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7768                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7769         ;
7770       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7771                          mac_address))
7772         custom_mac = 1;
7773       else if (unformat (i, "numa-only"))
7774         numa_only = 1;
7775       else if (unformat (i, "id %u", &id))
7776         ;
7777       else
7778         break;
7779     }
7780
7781   if (mode_is_set == 0)
7782     {
7783       errmsg ("Missing bond mode. ");
7784       return -99;
7785     }
7786
7787   /* Construct the API message */
7788   M (BOND_CREATE, mp);
7789
7790   mp->use_custom_mac = custom_mac;
7791
7792   mp->mode = htonl (mode);
7793   mp->lb = htonl (lb);
7794   mp->id = htonl (id);
7795   mp->numa_only = numa_only;
7796
7797   if (custom_mac)
7798     clib_memcpy (mp->mac_address, mac_address, 6);
7799
7800   /* send it... */
7801   S (mp);
7802
7803   /* Wait for a reply... */
7804   W (ret);
7805   return ret;
7806 }
7807
7808 static int
7809 api_bond_create2 (vat_main_t * vam)
7810 {
7811   unformat_input_t *i = vam->input;
7812   vl_api_bond_create2_t *mp;
7813   u8 mac_address[6];
7814   u8 custom_mac = 0;
7815   int ret;
7816   u8 mode;
7817   u8 lb;
7818   u8 mode_is_set = 0;
7819   u32 id = ~0;
7820   u8 numa_only = 0;
7821   u8 gso = 0;
7822
7823   clib_memset (mac_address, 0, sizeof (mac_address));
7824   lb = BOND_LB_L2;
7825
7826   /* Parse args required to build the message */
7827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7828     {
7829       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7830         mode_is_set = 1;
7831       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7832                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7833         ;
7834       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7835                          mac_address))
7836         custom_mac = 1;
7837       else if (unformat (i, "numa-only"))
7838         numa_only = 1;
7839       else if (unformat (i, "gso"))
7840         gso = 1;
7841       else if (unformat (i, "id %u", &id))
7842         ;
7843       else
7844         break;
7845     }
7846
7847   if (mode_is_set == 0)
7848     {
7849       errmsg ("Missing bond mode. ");
7850       return -99;
7851     }
7852
7853   /* Construct the API message */
7854   M (BOND_CREATE2, mp);
7855
7856   mp->use_custom_mac = custom_mac;
7857
7858   mp->mode = htonl (mode);
7859   mp->lb = htonl (lb);
7860   mp->id = htonl (id);
7861   mp->numa_only = numa_only;
7862   mp->enable_gso = gso;
7863
7864   if (custom_mac)
7865     clib_memcpy (mp->mac_address, mac_address, 6);
7866
7867   /* send it... */
7868   S (mp);
7869
7870   /* Wait for a reply... */
7871   W (ret);
7872   return ret;
7873 }
7874
7875 static int
7876 api_bond_delete (vat_main_t * vam)
7877 {
7878   unformat_input_t *i = vam->input;
7879   vl_api_bond_delete_t *mp;
7880   u32 sw_if_index = ~0;
7881   u8 sw_if_index_set = 0;
7882   int ret;
7883
7884   /* Parse args required to build the message */
7885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7886     {
7887       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7888         sw_if_index_set = 1;
7889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7890         sw_if_index_set = 1;
7891       else
7892         break;
7893     }
7894
7895   if (sw_if_index_set == 0)
7896     {
7897       errmsg ("missing vpp interface name. ");
7898       return -99;
7899     }
7900
7901   /* Construct the API message */
7902   M (BOND_DELETE, mp);
7903
7904   mp->sw_if_index = ntohl (sw_if_index);
7905
7906   /* send it... */
7907   S (mp);
7908
7909   /* Wait for a reply... */
7910   W (ret);
7911   return ret;
7912 }
7913
7914 static int
7915 api_bond_add_member (vat_main_t * vam)
7916 {
7917   unformat_input_t *i = vam->input;
7918   vl_api_bond_add_member_t *mp;
7919   u32 bond_sw_if_index;
7920   int ret;
7921   u8 is_passive;
7922   u8 is_long_timeout;
7923   u32 bond_sw_if_index_is_set = 0;
7924   u32 sw_if_index;
7925   u8 sw_if_index_is_set = 0;
7926
7927   /* Parse args required to build the message */
7928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7929     {
7930       if (unformat (i, "sw_if_index %d", &sw_if_index))
7931         sw_if_index_is_set = 1;
7932       else if (unformat (i, "bond %u", &bond_sw_if_index))
7933         bond_sw_if_index_is_set = 1;
7934       else if (unformat (i, "passive %d", &is_passive))
7935         ;
7936       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7937         ;
7938       else
7939         break;
7940     }
7941
7942   if (bond_sw_if_index_is_set == 0)
7943     {
7944       errmsg ("Missing bond sw_if_index. ");
7945       return -99;
7946     }
7947   if (sw_if_index_is_set == 0)
7948     {
7949       errmsg ("Missing member sw_if_index. ");
7950       return -99;
7951     }
7952
7953   /* Construct the API message */
7954   M (BOND_ADD_MEMBER, mp);
7955
7956   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7957   mp->sw_if_index = ntohl (sw_if_index);
7958   mp->is_long_timeout = is_long_timeout;
7959   mp->is_passive = is_passive;
7960
7961   /* send it... */
7962   S (mp);
7963
7964   /* Wait for a reply... */
7965   W (ret);
7966   return ret;
7967 }
7968
7969 static int
7970 api_bond_detach_member (vat_main_t * vam)
7971 {
7972   unformat_input_t *i = vam->input;
7973   vl_api_bond_detach_member_t *mp;
7974   u32 sw_if_index = ~0;
7975   u8 sw_if_index_set = 0;
7976   int ret;
7977
7978   /* Parse args required to build the message */
7979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7980     {
7981       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7982         sw_if_index_set = 1;
7983       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7984         sw_if_index_set = 1;
7985       else
7986         break;
7987     }
7988
7989   if (sw_if_index_set == 0)
7990     {
7991       errmsg ("missing vpp interface name. ");
7992       return -99;
7993     }
7994
7995   /* Construct the API message */
7996   M (BOND_DETACH_MEMBER, mp);
7997
7998   mp->sw_if_index = ntohl (sw_if_index);
7999
8000   /* send it... */
8001   S (mp);
8002
8003   /* Wait for a reply... */
8004   W (ret);
8005   return ret;
8006 }
8007
8008 static int
8009 api_ip_table_add_del (vat_main_t * vam)
8010 {
8011   unformat_input_t *i = vam->input;
8012   vl_api_ip_table_add_del_t *mp;
8013   u32 table_id = ~0;
8014   u8 is_ipv6 = 0;
8015   u8 is_add = 1;
8016   int ret = 0;
8017
8018   /* Parse args required to build the message */
8019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8020     {
8021       if (unformat (i, "ipv6"))
8022         is_ipv6 = 1;
8023       else if (unformat (i, "del"))
8024         is_add = 0;
8025       else if (unformat (i, "add"))
8026         is_add = 1;
8027       else if (unformat (i, "table %d", &table_id))
8028         ;
8029       else
8030         {
8031           clib_warning ("parse error '%U'", format_unformat_error, i);
8032           return -99;
8033         }
8034     }
8035
8036   if (~0 == table_id)
8037     {
8038       errmsg ("missing table-ID");
8039       return -99;
8040     }
8041
8042   /* Construct the API message */
8043   M (IP_TABLE_ADD_DEL, mp);
8044
8045   mp->table.table_id = ntohl (table_id);
8046   mp->table.is_ip6 = is_ipv6;
8047   mp->is_add = is_add;
8048
8049   /* send it... */
8050   S (mp);
8051
8052   /* Wait for a reply... */
8053   W (ret);
8054
8055   return ret;
8056 }
8057
8058 uword
8059 unformat_fib_path (unformat_input_t * input, va_list * args)
8060 {
8061   vat_main_t *vam = va_arg (*args, vat_main_t *);
8062   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8063   u32 weight, preference;
8064   mpls_label_t out_label;
8065
8066   clib_memset (path, 0, sizeof (*path));
8067   path->weight = 1;
8068   path->sw_if_index = ~0;
8069   path->rpf_id = ~0;
8070   path->n_labels = 0;
8071
8072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8073     {
8074       if (unformat (input, "%U %U",
8075                     unformat_vl_api_ip4_address,
8076                     &path->nh.address.ip4,
8077                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8078         {
8079           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8080         }
8081       else if (unformat (input, "%U %U",
8082                          unformat_vl_api_ip6_address,
8083                          &path->nh.address.ip6,
8084                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8085         {
8086           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8087         }
8088       else if (unformat (input, "weight %u", &weight))
8089         {
8090           path->weight = weight;
8091         }
8092       else if (unformat (input, "preference %u", &preference))
8093         {
8094           path->preference = preference;
8095         }
8096       else if (unformat (input, "%U next-hop-table %d",
8097                          unformat_vl_api_ip4_address,
8098                          &path->nh.address.ip4, &path->table_id))
8099         {
8100           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8101         }
8102       else if (unformat (input, "%U next-hop-table %d",
8103                          unformat_vl_api_ip6_address,
8104                          &path->nh.address.ip6, &path->table_id))
8105         {
8106           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8107         }
8108       else if (unformat (input, "%U",
8109                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8110         {
8111           /*
8112            * the recursive next-hops are by default in the default table
8113            */
8114           path->table_id = 0;
8115           path->sw_if_index = ~0;
8116           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8117         }
8118       else if (unformat (input, "%U",
8119                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8120         {
8121           /*
8122            * the recursive next-hops are by default in the default table
8123            */
8124           path->table_id = 0;
8125           path->sw_if_index = ~0;
8126           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8127         }
8128       else if (unformat (input, "resolve-via-host"))
8129         {
8130           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8131         }
8132       else if (unformat (input, "resolve-via-attached"))
8133         {
8134           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8135         }
8136       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8137         {
8138           path->type = FIB_API_PATH_TYPE_LOCAL;
8139           path->sw_if_index = ~0;
8140           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8141         }
8142       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8143         {
8144           path->type = FIB_API_PATH_TYPE_LOCAL;
8145           path->sw_if_index = ~0;
8146           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8147         }
8148       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8149         ;
8150       else if (unformat (input, "via-label %d", &path->nh.via_label))
8151         {
8152           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8153           path->sw_if_index = ~0;
8154         }
8155       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8156         {
8157           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8158           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8159         }
8160       else if (unformat (input, "local"))
8161         {
8162           path->type = FIB_API_PATH_TYPE_LOCAL;
8163         }
8164       else if (unformat (input, "out-labels"))
8165         {
8166           while (unformat (input, "%d", &out_label))
8167             {
8168               path->label_stack[path->n_labels].label = out_label;
8169               path->label_stack[path->n_labels].is_uniform = 0;
8170               path->label_stack[path->n_labels].ttl = 64;
8171               path->n_labels++;
8172             }
8173         }
8174       else if (unformat (input, "via"))
8175         {
8176           /* new path, back up and return */
8177           unformat_put_input (input);
8178           unformat_put_input (input);
8179           unformat_put_input (input);
8180           unformat_put_input (input);
8181           break;
8182         }
8183       else
8184         {
8185           return (0);
8186         }
8187     }
8188
8189   path->proto = ntohl (path->proto);
8190   path->type = ntohl (path->type);
8191   path->flags = ntohl (path->flags);
8192   path->table_id = ntohl (path->table_id);
8193   path->sw_if_index = ntohl (path->sw_if_index);
8194
8195   return (1);
8196 }
8197
8198 static int
8199 api_ip_route_add_del (vat_main_t * vam)
8200 {
8201   unformat_input_t *i = vam->input;
8202   vl_api_ip_route_add_del_t *mp;
8203   u32 vrf_id = 0;
8204   u8 is_add = 1;
8205   u8 is_multipath = 0;
8206   u8 prefix_set = 0;
8207   u8 path_count = 0;
8208   vl_api_prefix_t pfx = { };
8209   vl_api_fib_path_t paths[8];
8210   int count = 1;
8211   int j;
8212   f64 before = 0;
8213   u32 random_add_del = 0;
8214   u32 *random_vector = 0;
8215   u32 random_seed = 0xdeaddabe;
8216
8217   /* Parse args required to build the message */
8218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8219     {
8220       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8221         prefix_set = 1;
8222       else if (unformat (i, "del"))
8223         is_add = 0;
8224       else if (unformat (i, "add"))
8225         is_add = 1;
8226       else if (unformat (i, "vrf %d", &vrf_id))
8227         ;
8228       else if (unformat (i, "count %d", &count))
8229         ;
8230       else if (unformat (i, "random"))
8231         random_add_del = 1;
8232       else if (unformat (i, "multipath"))
8233         is_multipath = 1;
8234       else if (unformat (i, "seed %d", &random_seed))
8235         ;
8236       else
8237         if (unformat
8238             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8239         {
8240           path_count++;
8241           if (8 == path_count)
8242             {
8243               errmsg ("max 8 paths");
8244               return -99;
8245             }
8246         }
8247       else
8248         {
8249           clib_warning ("parse error '%U'", format_unformat_error, i);
8250           return -99;
8251         }
8252     }
8253
8254   if (!path_count)
8255     {
8256       errmsg ("specify a path; via ...");
8257       return -99;
8258     }
8259   if (prefix_set == 0)
8260     {
8261       errmsg ("missing prefix");
8262       return -99;
8263     }
8264
8265   /* Generate a pile of unique, random routes */
8266   if (random_add_del)
8267     {
8268       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8269       u32 this_random_address;
8270       uword *random_hash;
8271
8272       random_hash = hash_create (count, sizeof (uword));
8273
8274       hash_set (random_hash, i->as_u32, 1);
8275       for (j = 0; j <= count; j++)
8276         {
8277           do
8278             {
8279               this_random_address = random_u32 (&random_seed);
8280               this_random_address =
8281                 clib_host_to_net_u32 (this_random_address);
8282             }
8283           while (hash_get (random_hash, this_random_address));
8284           vec_add1 (random_vector, this_random_address);
8285           hash_set (random_hash, this_random_address, 1);
8286         }
8287       hash_free (random_hash);
8288       set_ip4_address (&pfx.address, random_vector[0]);
8289     }
8290
8291   if (count > 1)
8292     {
8293       /* Turn on async mode */
8294       vam->async_mode = 1;
8295       vam->async_errors = 0;
8296       before = vat_time_now (vam);
8297     }
8298
8299   for (j = 0; j < count; j++)
8300     {
8301       /* Construct the API message */
8302       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8303
8304       mp->is_add = is_add;
8305       mp->is_multipath = is_multipath;
8306
8307       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8308       mp->route.table_id = ntohl (vrf_id);
8309       mp->route.n_paths = path_count;
8310
8311       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8312
8313       if (random_add_del)
8314         set_ip4_address (&pfx.address, random_vector[j + 1]);
8315       else
8316         increment_address (&pfx.address);
8317       /* send it... */
8318       S (mp);
8319       /* If we receive SIGTERM, stop now... */
8320       if (vam->do_exit)
8321         break;
8322     }
8323
8324   /* When testing multiple add/del ops, use a control-ping to sync */
8325   if (count > 1)
8326     {
8327       vl_api_control_ping_t *mp_ping;
8328       f64 after;
8329       f64 timeout;
8330
8331       /* Shut off async mode */
8332       vam->async_mode = 0;
8333
8334       MPING (CONTROL_PING, mp_ping);
8335       S (mp_ping);
8336
8337       timeout = vat_time_now (vam) + 1.0;
8338       while (vat_time_now (vam) < timeout)
8339         if (vam->result_ready == 1)
8340           goto out;
8341       vam->retval = -99;
8342
8343     out:
8344       if (vam->retval == -99)
8345         errmsg ("timeout");
8346
8347       if (vam->async_errors > 0)
8348         {
8349           errmsg ("%d asynchronous errors", vam->async_errors);
8350           vam->retval = -98;
8351         }
8352       vam->async_errors = 0;
8353       after = vat_time_now (vam);
8354
8355       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8356       if (j > 0)
8357         count = j;
8358
8359       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8360              count, after - before, count / (after - before));
8361     }
8362   else
8363     {
8364       int ret;
8365
8366       /* Wait for a reply... */
8367       W (ret);
8368       return ret;
8369     }
8370
8371   /* Return the good/bad news */
8372   return (vam->retval);
8373 }
8374
8375 static int
8376 api_ip_mroute_add_del (vat_main_t * vam)
8377 {
8378   unformat_input_t *i = vam->input;
8379   u8 path_set = 0, prefix_set = 0, is_add = 1;
8380   vl_api_ip_mroute_add_del_t *mp;
8381   mfib_entry_flags_t eflags = 0;
8382   vl_api_mfib_path_t path;
8383   vl_api_mprefix_t pfx = { };
8384   u32 vrf_id = 0;
8385   int ret;
8386
8387   /* Parse args required to build the message */
8388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8389     {
8390       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8391         {
8392           prefix_set = 1;
8393           pfx.grp_address_length = htons (pfx.grp_address_length);
8394         }
8395       else if (unformat (i, "del"))
8396         is_add = 0;
8397       else if (unformat (i, "add"))
8398         is_add = 1;
8399       else if (unformat (i, "vrf %d", &vrf_id))
8400         ;
8401       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8402         path.itf_flags = htonl (path.itf_flags);
8403       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8404         ;
8405       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8406         path_set = 1;
8407       else
8408         {
8409           clib_warning ("parse error '%U'", format_unformat_error, i);
8410           return -99;
8411         }
8412     }
8413
8414   if (prefix_set == 0)
8415     {
8416       errmsg ("missing addresses\n");
8417       return -99;
8418     }
8419   if (path_set == 0)
8420     {
8421       errmsg ("missing path\n");
8422       return -99;
8423     }
8424
8425   /* Construct the API message */
8426   M (IP_MROUTE_ADD_DEL, mp);
8427
8428   mp->is_add = is_add;
8429   mp->is_multipath = 1;
8430
8431   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8432   mp->route.table_id = htonl (vrf_id);
8433   mp->route.n_paths = 1;
8434   mp->route.entry_flags = htonl (eflags);
8435
8436   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8437
8438   /* send it... */
8439   S (mp);
8440   /* Wait for a reply... */
8441   W (ret);
8442   return ret;
8443 }
8444
8445 static int
8446 api_mpls_table_add_del (vat_main_t * vam)
8447 {
8448   unformat_input_t *i = vam->input;
8449   vl_api_mpls_table_add_del_t *mp;
8450   u32 table_id = ~0;
8451   u8 is_add = 1;
8452   int ret = 0;
8453
8454   /* Parse args required to build the message */
8455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8456     {
8457       if (unformat (i, "table %d", &table_id))
8458         ;
8459       else if (unformat (i, "del"))
8460         is_add = 0;
8461       else if (unformat (i, "add"))
8462         is_add = 1;
8463       else
8464         {
8465           clib_warning ("parse error '%U'", format_unformat_error, i);
8466           return -99;
8467         }
8468     }
8469
8470   if (~0 == table_id)
8471     {
8472       errmsg ("missing table-ID");
8473       return -99;
8474     }
8475
8476   /* Construct the API message */
8477   M (MPLS_TABLE_ADD_DEL, mp);
8478
8479   mp->mt_table.mt_table_id = ntohl (table_id);
8480   mp->mt_is_add = is_add;
8481
8482   /* send it... */
8483   S (mp);
8484
8485   /* Wait for a reply... */
8486   W (ret);
8487
8488   return ret;
8489 }
8490
8491 static int
8492 api_mpls_route_add_del (vat_main_t * vam)
8493 {
8494   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8495   mpls_label_t local_label = MPLS_LABEL_INVALID;
8496   unformat_input_t *i = vam->input;
8497   vl_api_mpls_route_add_del_t *mp;
8498   vl_api_fib_path_t paths[8];
8499   int count = 1, j;
8500   f64 before = 0;
8501
8502   /* Parse args required to build the message */
8503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8504     {
8505       if (unformat (i, "%d", &local_label))
8506         ;
8507       else if (unformat (i, "eos"))
8508         is_eos = 1;
8509       else if (unformat (i, "non-eos"))
8510         is_eos = 0;
8511       else if (unformat (i, "del"))
8512         is_add = 0;
8513       else if (unformat (i, "add"))
8514         is_add = 1;
8515       else if (unformat (i, "multipath"))
8516         is_multipath = 1;
8517       else if (unformat (i, "count %d", &count))
8518         ;
8519       else
8520         if (unformat
8521             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8522         {
8523           path_count++;
8524           if (8 == path_count)
8525             {
8526               errmsg ("max 8 paths");
8527               return -99;
8528             }
8529         }
8530       else
8531         {
8532           clib_warning ("parse error '%U'", format_unformat_error, i);
8533           return -99;
8534         }
8535     }
8536
8537   if (!path_count)
8538     {
8539       errmsg ("specify a path; via ...");
8540       return -99;
8541     }
8542
8543   if (MPLS_LABEL_INVALID == local_label)
8544     {
8545       errmsg ("missing label");
8546       return -99;
8547     }
8548
8549   if (count > 1)
8550     {
8551       /* Turn on async mode */
8552       vam->async_mode = 1;
8553       vam->async_errors = 0;
8554       before = vat_time_now (vam);
8555     }
8556
8557   for (j = 0; j < count; j++)
8558     {
8559       /* Construct the API message */
8560       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8561
8562       mp->mr_is_add = is_add;
8563       mp->mr_is_multipath = is_multipath;
8564
8565       mp->mr_route.mr_label = local_label;
8566       mp->mr_route.mr_eos = is_eos;
8567       mp->mr_route.mr_table_id = 0;
8568       mp->mr_route.mr_n_paths = path_count;
8569
8570       clib_memcpy (&mp->mr_route.mr_paths, paths,
8571                    sizeof (paths[0]) * path_count);
8572
8573       local_label++;
8574
8575       /* send it... */
8576       S (mp);
8577       /* If we receive SIGTERM, stop now... */
8578       if (vam->do_exit)
8579         break;
8580     }
8581
8582   /* When testing multiple add/del ops, use a control-ping to sync */
8583   if (count > 1)
8584     {
8585       vl_api_control_ping_t *mp_ping;
8586       f64 after;
8587       f64 timeout;
8588
8589       /* Shut off async mode */
8590       vam->async_mode = 0;
8591
8592       MPING (CONTROL_PING, mp_ping);
8593       S (mp_ping);
8594
8595       timeout = vat_time_now (vam) + 1.0;
8596       while (vat_time_now (vam) < timeout)
8597         if (vam->result_ready == 1)
8598           goto out;
8599       vam->retval = -99;
8600
8601     out:
8602       if (vam->retval == -99)
8603         errmsg ("timeout");
8604
8605       if (vam->async_errors > 0)
8606         {
8607           errmsg ("%d asynchronous errors", vam->async_errors);
8608           vam->retval = -98;
8609         }
8610       vam->async_errors = 0;
8611       after = vat_time_now (vam);
8612
8613       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8614       if (j > 0)
8615         count = j;
8616
8617       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8618              count, after - before, count / (after - before));
8619     }
8620   else
8621     {
8622       int ret;
8623
8624       /* Wait for a reply... */
8625       W (ret);
8626       return ret;
8627     }
8628
8629   /* Return the good/bad news */
8630   return (vam->retval);
8631   return (0);
8632 }
8633
8634 static int
8635 api_mpls_ip_bind_unbind (vat_main_t * vam)
8636 {
8637   unformat_input_t *i = vam->input;
8638   vl_api_mpls_ip_bind_unbind_t *mp;
8639   u32 ip_table_id = 0;
8640   u8 is_bind = 1;
8641   vl_api_prefix_t pfx;
8642   u8 prefix_set = 0;
8643   mpls_label_t local_label = MPLS_LABEL_INVALID;
8644   int ret;
8645
8646   /* Parse args required to build the message */
8647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8648     {
8649       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8650         prefix_set = 1;
8651       else if (unformat (i, "%d", &local_label))
8652         ;
8653       else if (unformat (i, "table-id %d", &ip_table_id))
8654         ;
8655       else if (unformat (i, "unbind"))
8656         is_bind = 0;
8657       else if (unformat (i, "bind"))
8658         is_bind = 1;
8659       else
8660         {
8661           clib_warning ("parse error '%U'", format_unformat_error, i);
8662           return -99;
8663         }
8664     }
8665
8666   if (!prefix_set)
8667     {
8668       errmsg ("IP prefix not set");
8669       return -99;
8670     }
8671
8672   if (MPLS_LABEL_INVALID == local_label)
8673     {
8674       errmsg ("missing label");
8675       return -99;
8676     }
8677
8678   /* Construct the API message */
8679   M (MPLS_IP_BIND_UNBIND, mp);
8680
8681   mp->mb_is_bind = is_bind;
8682   mp->mb_ip_table_id = ntohl (ip_table_id);
8683   mp->mb_mpls_table_id = 0;
8684   mp->mb_label = ntohl (local_label);
8685   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8686
8687   /* send it... */
8688   S (mp);
8689
8690   /* Wait for a reply... */
8691   W (ret);
8692   return ret;
8693   return (0);
8694 }
8695
8696 static int
8697 api_sr_mpls_policy_add (vat_main_t * vam)
8698 {
8699   unformat_input_t *i = vam->input;
8700   vl_api_sr_mpls_policy_add_t *mp;
8701   u32 bsid = 0;
8702   u32 weight = 1;
8703   u8 type = 0;
8704   u8 n_segments = 0;
8705   u32 sid;
8706   u32 *segments = NULL;
8707   int ret;
8708
8709   /* Parse args required to build the message */
8710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8711     {
8712       if (unformat (i, "bsid %d", &bsid))
8713         ;
8714       else if (unformat (i, "weight %d", &weight))
8715         ;
8716       else if (unformat (i, "spray"))
8717         type = 1;
8718       else if (unformat (i, "next %d", &sid))
8719         {
8720           n_segments += 1;
8721           vec_add1 (segments, htonl (sid));
8722         }
8723       else
8724         {
8725           clib_warning ("parse error '%U'", format_unformat_error, i);
8726           return -99;
8727         }
8728     }
8729
8730   if (bsid == 0)
8731     {
8732       errmsg ("bsid not set");
8733       return -99;
8734     }
8735
8736   if (n_segments == 0)
8737     {
8738       errmsg ("no sid in segment stack");
8739       return -99;
8740     }
8741
8742   /* Construct the API message */
8743   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8744
8745   mp->bsid = htonl (bsid);
8746   mp->weight = htonl (weight);
8747   mp->is_spray = type;
8748   mp->n_segments = n_segments;
8749   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8750   vec_free (segments);
8751
8752   /* send it... */
8753   S (mp);
8754
8755   /* Wait for a reply... */
8756   W (ret);
8757   return ret;
8758 }
8759
8760 static int
8761 api_sr_mpls_policy_del (vat_main_t * vam)
8762 {
8763   unformat_input_t *i = vam->input;
8764   vl_api_sr_mpls_policy_del_t *mp;
8765   u32 bsid = 0;
8766   int ret;
8767
8768   /* Parse args required to build the message */
8769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8770     {
8771       if (unformat (i, "bsid %d", &bsid))
8772         ;
8773       else
8774         {
8775           clib_warning ("parse error '%U'", format_unformat_error, i);
8776           return -99;
8777         }
8778     }
8779
8780   if (bsid == 0)
8781     {
8782       errmsg ("bsid not set");
8783       return -99;
8784     }
8785
8786   /* Construct the API message */
8787   M (SR_MPLS_POLICY_DEL, mp);
8788
8789   mp->bsid = htonl (bsid);
8790
8791   /* send it... */
8792   S (mp);
8793
8794   /* Wait for a reply... */
8795   W (ret);
8796   return ret;
8797 }
8798
8799 static int
8800 api_bier_table_add_del (vat_main_t * vam)
8801 {
8802   unformat_input_t *i = vam->input;
8803   vl_api_bier_table_add_del_t *mp;
8804   u8 is_add = 1;
8805   u32 set = 0, sub_domain = 0, hdr_len = 3;
8806   mpls_label_t local_label = MPLS_LABEL_INVALID;
8807   int ret;
8808
8809   /* Parse args required to build the message */
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "sub-domain %d", &sub_domain))
8813         ;
8814       else if (unformat (i, "set %d", &set))
8815         ;
8816       else if (unformat (i, "label %d", &local_label))
8817         ;
8818       else if (unformat (i, "hdr-len %d", &hdr_len))
8819         ;
8820       else if (unformat (i, "add"))
8821         is_add = 1;
8822       else if (unformat (i, "del"))
8823         is_add = 0;
8824       else
8825         {
8826           clib_warning ("parse error '%U'", format_unformat_error, i);
8827           return -99;
8828         }
8829     }
8830
8831   if (MPLS_LABEL_INVALID == local_label)
8832     {
8833       errmsg ("missing label\n");
8834       return -99;
8835     }
8836
8837   /* Construct the API message */
8838   M (BIER_TABLE_ADD_DEL, mp);
8839
8840   mp->bt_is_add = is_add;
8841   mp->bt_label = ntohl (local_label);
8842   mp->bt_tbl_id.bt_set = set;
8843   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8844   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8845
8846   /* send it... */
8847   S (mp);
8848
8849   /* Wait for a reply... */
8850   W (ret);
8851
8852   return (ret);
8853 }
8854
8855 static int
8856 api_bier_route_add_del (vat_main_t * vam)
8857 {
8858   unformat_input_t *i = vam->input;
8859   vl_api_bier_route_add_del_t *mp;
8860   u8 is_add = 1;
8861   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8862   ip4_address_t v4_next_hop_address;
8863   ip6_address_t v6_next_hop_address;
8864   u8 next_hop_set = 0;
8865   u8 next_hop_proto_is_ip4 = 1;
8866   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8867   int ret;
8868
8869   /* Parse args required to build the message */
8870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8871     {
8872       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8873         {
8874           next_hop_proto_is_ip4 = 1;
8875           next_hop_set = 1;
8876         }
8877       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8878         {
8879           next_hop_proto_is_ip4 = 0;
8880           next_hop_set = 1;
8881         }
8882       if (unformat (i, "sub-domain %d", &sub_domain))
8883         ;
8884       else if (unformat (i, "set %d", &set))
8885         ;
8886       else if (unformat (i, "hdr-len %d", &hdr_len))
8887         ;
8888       else if (unformat (i, "bp %d", &bp))
8889         ;
8890       else if (unformat (i, "add"))
8891         is_add = 1;
8892       else if (unformat (i, "del"))
8893         is_add = 0;
8894       else if (unformat (i, "out-label %d", &next_hop_out_label))
8895         ;
8896       else
8897         {
8898           clib_warning ("parse error '%U'", format_unformat_error, i);
8899           return -99;
8900         }
8901     }
8902
8903   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8904     {
8905       errmsg ("next hop / label set\n");
8906       return -99;
8907     }
8908   if (0 == bp)
8909     {
8910       errmsg ("bit=position not set\n");
8911       return -99;
8912     }
8913
8914   /* Construct the API message */
8915   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8916
8917   mp->br_is_add = is_add;
8918   mp->br_route.br_tbl_id.bt_set = set;
8919   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8920   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8921   mp->br_route.br_bp = ntohs (bp);
8922   mp->br_route.br_n_paths = 1;
8923   mp->br_route.br_paths[0].n_labels = 1;
8924   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8925   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8926                                     FIB_API_PATH_NH_PROTO_IP4 :
8927                                     FIB_API_PATH_NH_PROTO_IP6);
8928
8929   if (next_hop_proto_is_ip4)
8930     {
8931       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8932                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8933     }
8934   else
8935     {
8936       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8937                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8938     }
8939
8940   /* send it... */
8941   S (mp);
8942
8943   /* Wait for a reply... */
8944   W (ret);
8945
8946   return (ret);
8947 }
8948
8949 static int
8950 api_mpls_tunnel_add_del (vat_main_t * vam)
8951 {
8952   unformat_input_t *i = vam->input;
8953   vl_api_mpls_tunnel_add_del_t *mp;
8954
8955   vl_api_fib_path_t paths[8];
8956   u32 sw_if_index = ~0;
8957   u8 path_count = 0;
8958   u8 l2_only = 0;
8959   u8 is_add = 1;
8960   int ret;
8961
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "add"))
8965         is_add = 1;
8966       else
8967         if (unformat
8968             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8969         is_add = 0;
8970       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8971         is_add = 0;
8972       else if (unformat (i, "l2-only"))
8973         l2_only = 1;
8974       else
8975         if (unformat
8976             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8977         {
8978           path_count++;
8979           if (8 == path_count)
8980             {
8981               errmsg ("max 8 paths");
8982               return -99;
8983             }
8984         }
8985       else
8986         {
8987           clib_warning ("parse error '%U'", format_unformat_error, i);
8988           return -99;
8989         }
8990     }
8991
8992   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8993
8994   mp->mt_is_add = is_add;
8995   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8996   mp->mt_tunnel.mt_l2_only = l2_only;
8997   mp->mt_tunnel.mt_is_multicast = 0;
8998   mp->mt_tunnel.mt_n_paths = path_count;
8999
9000   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9001                sizeof (paths[0]) * path_count);
9002
9003   S (mp);
9004   W (ret);
9005   return ret;
9006 }
9007
9008 static int
9009 api_sw_interface_set_unnumbered (vat_main_t * vam)
9010 {
9011   unformat_input_t *i = vam->input;
9012   vl_api_sw_interface_set_unnumbered_t *mp;
9013   u32 sw_if_index;
9014   u32 unnum_sw_index = ~0;
9015   u8 is_add = 1;
9016   u8 sw_if_index_set = 0;
9017   int ret;
9018
9019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9020     {
9021       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9022         sw_if_index_set = 1;
9023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9024         sw_if_index_set = 1;
9025       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9026         ;
9027       else if (unformat (i, "del"))
9028         is_add = 0;
9029       else
9030         {
9031           clib_warning ("parse error '%U'", format_unformat_error, i);
9032           return -99;
9033         }
9034     }
9035
9036   if (sw_if_index_set == 0)
9037     {
9038       errmsg ("missing interface name or sw_if_index");
9039       return -99;
9040     }
9041
9042   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9043
9044   mp->sw_if_index = ntohl (sw_if_index);
9045   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9046   mp->is_add = is_add;
9047
9048   S (mp);
9049   W (ret);
9050   return ret;
9051 }
9052
9053
9054 static int
9055 api_create_vlan_subif (vat_main_t * vam)
9056 {
9057   unformat_input_t *i = vam->input;
9058   vl_api_create_vlan_subif_t *mp;
9059   u32 sw_if_index;
9060   u8 sw_if_index_set = 0;
9061   u32 vlan_id;
9062   u8 vlan_id_set = 0;
9063   int ret;
9064
9065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9066     {
9067       if (unformat (i, "sw_if_index %d", &sw_if_index))
9068         sw_if_index_set = 1;
9069       else
9070         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9071         sw_if_index_set = 1;
9072       else if (unformat (i, "vlan %d", &vlan_id))
9073         vlan_id_set = 1;
9074       else
9075         {
9076           clib_warning ("parse error '%U'", format_unformat_error, i);
9077           return -99;
9078         }
9079     }
9080
9081   if (sw_if_index_set == 0)
9082     {
9083       errmsg ("missing interface name or sw_if_index");
9084       return -99;
9085     }
9086
9087   if (vlan_id_set == 0)
9088     {
9089       errmsg ("missing vlan_id");
9090       return -99;
9091     }
9092   M (CREATE_VLAN_SUBIF, mp);
9093
9094   mp->sw_if_index = ntohl (sw_if_index);
9095   mp->vlan_id = ntohl (vlan_id);
9096
9097   S (mp);
9098   W (ret);
9099   return ret;
9100 }
9101
9102 #define foreach_create_subif_bit                \
9103 _(no_tags)                                      \
9104 _(one_tag)                                      \
9105 _(two_tags)                                     \
9106 _(dot1ad)                                       \
9107 _(exact_match)                                  \
9108 _(default_sub)                                  \
9109 _(outer_vlan_id_any)                            \
9110 _(inner_vlan_id_any)
9111
9112 #define foreach_create_subif_flag               \
9113 _(0, "no_tags")                                 \
9114 _(1, "one_tag")                                 \
9115 _(2, "two_tags")                                \
9116 _(3, "dot1ad")                                  \
9117 _(4, "exact_match")                             \
9118 _(5, "default_sub")                             \
9119 _(6, "outer_vlan_id_any")                       \
9120 _(7, "inner_vlan_id_any")
9121
9122 static int
9123 api_create_subif (vat_main_t * vam)
9124 {
9125   unformat_input_t *i = vam->input;
9126   vl_api_create_subif_t *mp;
9127   u32 sw_if_index;
9128   u8 sw_if_index_set = 0;
9129   u32 sub_id;
9130   u8 sub_id_set = 0;
9131   u32 __attribute__ ((unused)) no_tags = 0;
9132   u32 __attribute__ ((unused)) one_tag = 0;
9133   u32 __attribute__ ((unused)) two_tags = 0;
9134   u32 __attribute__ ((unused)) dot1ad = 0;
9135   u32 __attribute__ ((unused)) exact_match = 0;
9136   u32 __attribute__ ((unused)) default_sub = 0;
9137   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9138   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9139   u32 tmp;
9140   u16 outer_vlan_id = 0;
9141   u16 inner_vlan_id = 0;
9142   int ret;
9143
9144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9145     {
9146       if (unformat (i, "sw_if_index %d", &sw_if_index))
9147         sw_if_index_set = 1;
9148       else
9149         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9150         sw_if_index_set = 1;
9151       else if (unformat (i, "sub_id %d", &sub_id))
9152         sub_id_set = 1;
9153       else if (unformat (i, "outer_vlan_id %d", &tmp))
9154         outer_vlan_id = tmp;
9155       else if (unformat (i, "inner_vlan_id %d", &tmp))
9156         inner_vlan_id = tmp;
9157
9158 #define _(a) else if (unformat (i, #a)) a = 1 ;
9159       foreach_create_subif_bit
9160 #undef _
9161         else
9162         {
9163           clib_warning ("parse error '%U'", format_unformat_error, i);
9164           return -99;
9165         }
9166     }
9167
9168   if (sw_if_index_set == 0)
9169     {
9170       errmsg ("missing interface name or sw_if_index");
9171       return -99;
9172     }
9173
9174   if (sub_id_set == 0)
9175     {
9176       errmsg ("missing sub_id");
9177       return -99;
9178     }
9179   M (CREATE_SUBIF, mp);
9180
9181   mp->sw_if_index = ntohl (sw_if_index);
9182   mp->sub_id = ntohl (sub_id);
9183
9184 #define _(a,b) mp->sub_if_flags |= (1 << a);
9185   foreach_create_subif_flag;
9186 #undef _
9187
9188   mp->outer_vlan_id = ntohs (outer_vlan_id);
9189   mp->inner_vlan_id = ntohs (inner_vlan_id);
9190
9191   S (mp);
9192   W (ret);
9193   return ret;
9194 }
9195
9196 static int
9197 api_ip_table_replace_begin (vat_main_t * vam)
9198 {
9199   unformat_input_t *i = vam->input;
9200   vl_api_ip_table_replace_begin_t *mp;
9201   u32 table_id = 0;
9202   u8 is_ipv6 = 0;
9203
9204   int ret;
9205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9206     {
9207       if (unformat (i, "table %d", &table_id))
9208         ;
9209       else if (unformat (i, "ipv6"))
9210         is_ipv6 = 1;
9211       else
9212         {
9213           clib_warning ("parse error '%U'", format_unformat_error, i);
9214           return -99;
9215         }
9216     }
9217
9218   M (IP_TABLE_REPLACE_BEGIN, mp);
9219
9220   mp->table.table_id = ntohl (table_id);
9221   mp->table.is_ip6 = is_ipv6;
9222
9223   S (mp);
9224   W (ret);
9225   return ret;
9226 }
9227
9228 static int
9229 api_ip_table_flush (vat_main_t * vam)
9230 {
9231   unformat_input_t *i = vam->input;
9232   vl_api_ip_table_flush_t *mp;
9233   u32 table_id = 0;
9234   u8 is_ipv6 = 0;
9235
9236   int ret;
9237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9238     {
9239       if (unformat (i, "table %d", &table_id))
9240         ;
9241       else if (unformat (i, "ipv6"))
9242         is_ipv6 = 1;
9243       else
9244         {
9245           clib_warning ("parse error '%U'", format_unformat_error, i);
9246           return -99;
9247         }
9248     }
9249
9250   M (IP_TABLE_FLUSH, mp);
9251
9252   mp->table.table_id = ntohl (table_id);
9253   mp->table.is_ip6 = is_ipv6;
9254
9255   S (mp);
9256   W (ret);
9257   return ret;
9258 }
9259
9260 static int
9261 api_ip_table_replace_end (vat_main_t * vam)
9262 {
9263   unformat_input_t *i = vam->input;
9264   vl_api_ip_table_replace_end_t *mp;
9265   u32 table_id = 0;
9266   u8 is_ipv6 = 0;
9267
9268   int ret;
9269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9270     {
9271       if (unformat (i, "table %d", &table_id))
9272         ;
9273       else if (unformat (i, "ipv6"))
9274         is_ipv6 = 1;
9275       else
9276         {
9277           clib_warning ("parse error '%U'", format_unformat_error, i);
9278           return -99;
9279         }
9280     }
9281
9282   M (IP_TABLE_REPLACE_END, mp);
9283
9284   mp->table.table_id = ntohl (table_id);
9285   mp->table.is_ip6 = is_ipv6;
9286
9287   S (mp);
9288   W (ret);
9289   return ret;
9290 }
9291
9292 static int
9293 api_set_ip_flow_hash (vat_main_t * vam)
9294 {
9295   unformat_input_t *i = vam->input;
9296   vl_api_set_ip_flow_hash_t *mp;
9297   u32 vrf_id = 0;
9298   u8 is_ipv6 = 0;
9299   u8 vrf_id_set = 0;
9300   u8 src = 0;
9301   u8 dst = 0;
9302   u8 sport = 0;
9303   u8 dport = 0;
9304   u8 proto = 0;
9305   u8 reverse = 0;
9306   int ret;
9307
9308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9309     {
9310       if (unformat (i, "vrf %d", &vrf_id))
9311         vrf_id_set = 1;
9312       else if (unformat (i, "ipv6"))
9313         is_ipv6 = 1;
9314       else if (unformat (i, "src"))
9315         src = 1;
9316       else if (unformat (i, "dst"))
9317         dst = 1;
9318       else if (unformat (i, "sport"))
9319         sport = 1;
9320       else if (unformat (i, "dport"))
9321         dport = 1;
9322       else if (unformat (i, "proto"))
9323         proto = 1;
9324       else if (unformat (i, "reverse"))
9325         reverse = 1;
9326
9327       else
9328         {
9329           clib_warning ("parse error '%U'", format_unformat_error, i);
9330           return -99;
9331         }
9332     }
9333
9334   if (vrf_id_set == 0)
9335     {
9336       errmsg ("missing vrf id");
9337       return -99;
9338     }
9339
9340   M (SET_IP_FLOW_HASH, mp);
9341   mp->src = src;
9342   mp->dst = dst;
9343   mp->sport = sport;
9344   mp->dport = dport;
9345   mp->proto = proto;
9346   mp->reverse = reverse;
9347   mp->vrf_id = ntohl (vrf_id);
9348   mp->is_ipv6 = is_ipv6;
9349
9350   S (mp);
9351   W (ret);
9352   return ret;
9353 }
9354
9355 static int
9356 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9357 {
9358   unformat_input_t *i = vam->input;
9359   vl_api_sw_interface_ip6_enable_disable_t *mp;
9360   u32 sw_if_index;
9361   u8 sw_if_index_set = 0;
9362   u8 enable = 0;
9363   int ret;
9364
9365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9366     {
9367       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9368         sw_if_index_set = 1;
9369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9370         sw_if_index_set = 1;
9371       else if (unformat (i, "enable"))
9372         enable = 1;
9373       else if (unformat (i, "disable"))
9374         enable = 0;
9375       else
9376         {
9377           clib_warning ("parse error '%U'", format_unformat_error, i);
9378           return -99;
9379         }
9380     }
9381
9382   if (sw_if_index_set == 0)
9383     {
9384       errmsg ("missing interface name or sw_if_index");
9385       return -99;
9386     }
9387
9388   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9389
9390   mp->sw_if_index = ntohl (sw_if_index);
9391   mp->enable = enable;
9392
9393   S (mp);
9394   W (ret);
9395   return ret;
9396 }
9397
9398
9399 static int
9400 api_l2_patch_add_del (vat_main_t * vam)
9401 {
9402   unformat_input_t *i = vam->input;
9403   vl_api_l2_patch_add_del_t *mp;
9404   u32 rx_sw_if_index;
9405   u8 rx_sw_if_index_set = 0;
9406   u32 tx_sw_if_index;
9407   u8 tx_sw_if_index_set = 0;
9408   u8 is_add = 1;
9409   int ret;
9410
9411   /* Parse args required to build the message */
9412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9413     {
9414       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9415         rx_sw_if_index_set = 1;
9416       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9417         tx_sw_if_index_set = 1;
9418       else if (unformat (i, "rx"))
9419         {
9420           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9421             {
9422               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9423                             &rx_sw_if_index))
9424                 rx_sw_if_index_set = 1;
9425             }
9426           else
9427             break;
9428         }
9429       else if (unformat (i, "tx"))
9430         {
9431           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9432             {
9433               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9434                             &tx_sw_if_index))
9435                 tx_sw_if_index_set = 1;
9436             }
9437           else
9438             break;
9439         }
9440       else if (unformat (i, "del"))
9441         is_add = 0;
9442       else
9443         break;
9444     }
9445
9446   if (rx_sw_if_index_set == 0)
9447     {
9448       errmsg ("missing rx interface name or rx_sw_if_index");
9449       return -99;
9450     }
9451
9452   if (tx_sw_if_index_set == 0)
9453     {
9454       errmsg ("missing tx interface name or tx_sw_if_index");
9455       return -99;
9456     }
9457
9458   M (L2_PATCH_ADD_DEL, mp);
9459
9460   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9461   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9462   mp->is_add = is_add;
9463
9464   S (mp);
9465   W (ret);
9466   return ret;
9467 }
9468
9469 u8 is_del;
9470 u8 localsid_addr[16];
9471 u8 end_psp;
9472 u8 behavior;
9473 u32 sw_if_index;
9474 u32 vlan_index;
9475 u32 fib_table;
9476 u8 nh_addr[16];
9477
9478 static int
9479 api_sr_localsid_add_del (vat_main_t * vam)
9480 {
9481   unformat_input_t *i = vam->input;
9482   vl_api_sr_localsid_add_del_t *mp;
9483
9484   u8 is_del;
9485   ip6_address_t localsid;
9486   u8 end_psp = 0;
9487   u8 behavior = ~0;
9488   u32 sw_if_index;
9489   u32 fib_table = ~(u32) 0;
9490   ip46_address_t nh_addr;
9491   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9492
9493   bool nexthop_set = 0;
9494
9495   int ret;
9496
9497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9498     {
9499       if (unformat (i, "del"))
9500         is_del = 1;
9501       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9502       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9503         nexthop_set = 1;
9504       else if (unformat (i, "behavior %u", &behavior));
9505       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9506       else if (unformat (i, "fib-table %u", &fib_table));
9507       else if (unformat (i, "end.psp %u", &behavior));
9508       else
9509         break;
9510     }
9511
9512   M (SR_LOCALSID_ADD_DEL, mp);
9513
9514   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9515
9516   if (nexthop_set)
9517     {
9518       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9519     }
9520   mp->behavior = behavior;
9521   mp->sw_if_index = ntohl (sw_if_index);
9522   mp->fib_table = ntohl (fib_table);
9523   mp->end_psp = end_psp;
9524   mp->is_del = is_del;
9525
9526   S (mp);
9527   W (ret);
9528   return ret;
9529 }
9530
9531 static int
9532 api_ioam_enable (vat_main_t * vam)
9533 {
9534   unformat_input_t *input = vam->input;
9535   vl_api_ioam_enable_t *mp;
9536   u32 id = 0;
9537   int has_trace_option = 0;
9538   int has_pot_option = 0;
9539   int has_seqno_option = 0;
9540   int has_analyse_option = 0;
9541   int ret;
9542
9543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9544     {
9545       if (unformat (input, "trace"))
9546         has_trace_option = 1;
9547       else if (unformat (input, "pot"))
9548         has_pot_option = 1;
9549       else if (unformat (input, "seqno"))
9550         has_seqno_option = 1;
9551       else if (unformat (input, "analyse"))
9552         has_analyse_option = 1;
9553       else
9554         break;
9555     }
9556   M (IOAM_ENABLE, mp);
9557   mp->id = htons (id);
9558   mp->seqno = has_seqno_option;
9559   mp->analyse = has_analyse_option;
9560   mp->pot_enable = has_pot_option;
9561   mp->trace_enable = has_trace_option;
9562
9563   S (mp);
9564   W (ret);
9565   return ret;
9566 }
9567
9568
9569 static int
9570 api_ioam_disable (vat_main_t * vam)
9571 {
9572   vl_api_ioam_disable_t *mp;
9573   int ret;
9574
9575   M (IOAM_DISABLE, mp);
9576   S (mp);
9577   W (ret);
9578   return ret;
9579 }
9580
9581 #define foreach_tcp_proto_field                 \
9582 _(src_port)                                     \
9583 _(dst_port)
9584
9585 #define foreach_udp_proto_field                 \
9586 _(src_port)                                     \
9587 _(dst_port)
9588
9589 #define foreach_ip4_proto_field                 \
9590 _(src_address)                                  \
9591 _(dst_address)                                  \
9592 _(tos)                                          \
9593 _(length)                                       \
9594 _(fragment_id)                                  \
9595 _(ttl)                                          \
9596 _(protocol)                                     \
9597 _(checksum)
9598
9599 typedef struct
9600 {
9601   u16 src_port, dst_port;
9602 } tcpudp_header_t;
9603
9604 #if VPP_API_TEST_BUILTIN == 0
9605 uword
9606 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9607 {
9608   u8 **maskp = va_arg (*args, u8 **);
9609   u8 *mask = 0;
9610   u8 found_something = 0;
9611   tcp_header_t *tcp;
9612
9613 #define _(a) u8 a=0;
9614   foreach_tcp_proto_field;
9615 #undef _
9616
9617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9618     {
9619       if (0);
9620 #define _(a) else if (unformat (input, #a)) a=1;
9621       foreach_tcp_proto_field
9622 #undef _
9623         else
9624         break;
9625     }
9626
9627 #define _(a) found_something += a;
9628   foreach_tcp_proto_field;
9629 #undef _
9630
9631   if (found_something == 0)
9632     return 0;
9633
9634   vec_validate (mask, sizeof (*tcp) - 1);
9635
9636   tcp = (tcp_header_t *) mask;
9637
9638 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9639   foreach_tcp_proto_field;
9640 #undef _
9641
9642   *maskp = mask;
9643   return 1;
9644 }
9645
9646 uword
9647 unformat_udp_mask (unformat_input_t * input, va_list * args)
9648 {
9649   u8 **maskp = va_arg (*args, u8 **);
9650   u8 *mask = 0;
9651   u8 found_something = 0;
9652   udp_header_t *udp;
9653
9654 #define _(a) u8 a=0;
9655   foreach_udp_proto_field;
9656 #undef _
9657
9658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9659     {
9660       if (0);
9661 #define _(a) else if (unformat (input, #a)) a=1;
9662       foreach_udp_proto_field
9663 #undef _
9664         else
9665         break;
9666     }
9667
9668 #define _(a) found_something += a;
9669   foreach_udp_proto_field;
9670 #undef _
9671
9672   if (found_something == 0)
9673     return 0;
9674
9675   vec_validate (mask, sizeof (*udp) - 1);
9676
9677   udp = (udp_header_t *) mask;
9678
9679 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9680   foreach_udp_proto_field;
9681 #undef _
9682
9683   *maskp = mask;
9684   return 1;
9685 }
9686
9687 uword
9688 unformat_l4_mask (unformat_input_t * input, va_list * args)
9689 {
9690   u8 **maskp = va_arg (*args, u8 **);
9691   u16 src_port = 0, dst_port = 0;
9692   tcpudp_header_t *tcpudp;
9693
9694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9695     {
9696       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9697         return 1;
9698       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9699         return 1;
9700       else if (unformat (input, "src_port"))
9701         src_port = 0xFFFF;
9702       else if (unformat (input, "dst_port"))
9703         dst_port = 0xFFFF;
9704       else
9705         return 0;
9706     }
9707
9708   if (!src_port && !dst_port)
9709     return 0;
9710
9711   u8 *mask = 0;
9712   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9713
9714   tcpudp = (tcpudp_header_t *) mask;
9715   tcpudp->src_port = src_port;
9716   tcpudp->dst_port = dst_port;
9717
9718   *maskp = mask;
9719
9720   return 1;
9721 }
9722
9723 uword
9724 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9725 {
9726   u8 **maskp = va_arg (*args, u8 **);
9727   u8 *mask = 0;
9728   u8 found_something = 0;
9729   ip4_header_t *ip;
9730
9731 #define _(a) u8 a=0;
9732   foreach_ip4_proto_field;
9733 #undef _
9734   u8 version = 0;
9735   u8 hdr_length = 0;
9736
9737
9738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9739     {
9740       if (unformat (input, "version"))
9741         version = 1;
9742       else if (unformat (input, "hdr_length"))
9743         hdr_length = 1;
9744       else if (unformat (input, "src"))
9745         src_address = 1;
9746       else if (unformat (input, "dst"))
9747         dst_address = 1;
9748       else if (unformat (input, "proto"))
9749         protocol = 1;
9750
9751 #define _(a) else if (unformat (input, #a)) a=1;
9752       foreach_ip4_proto_field
9753 #undef _
9754         else
9755         break;
9756     }
9757
9758 #define _(a) found_something += a;
9759   foreach_ip4_proto_field;
9760 #undef _
9761
9762   if (found_something == 0)
9763     return 0;
9764
9765   vec_validate (mask, sizeof (*ip) - 1);
9766
9767   ip = (ip4_header_t *) mask;
9768
9769 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9770   foreach_ip4_proto_field;
9771 #undef _
9772
9773   ip->ip_version_and_header_length = 0;
9774
9775   if (version)
9776     ip->ip_version_and_header_length |= 0xF0;
9777
9778   if (hdr_length)
9779     ip->ip_version_and_header_length |= 0x0F;
9780
9781   *maskp = mask;
9782   return 1;
9783 }
9784
9785 #define foreach_ip6_proto_field                 \
9786 _(src_address)                                  \
9787 _(dst_address)                                  \
9788 _(payload_length)                               \
9789 _(hop_limit)                                    \
9790 _(protocol)
9791
9792 uword
9793 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9794 {
9795   u8 **maskp = va_arg (*args, u8 **);
9796   u8 *mask = 0;
9797   u8 found_something = 0;
9798   ip6_header_t *ip;
9799   u32 ip_version_traffic_class_and_flow_label;
9800
9801 #define _(a) u8 a=0;
9802   foreach_ip6_proto_field;
9803 #undef _
9804   u8 version = 0;
9805   u8 traffic_class = 0;
9806   u8 flow_label = 0;
9807
9808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9809     {
9810       if (unformat (input, "version"))
9811         version = 1;
9812       else if (unformat (input, "traffic-class"))
9813         traffic_class = 1;
9814       else if (unformat (input, "flow-label"))
9815         flow_label = 1;
9816       else if (unformat (input, "src"))
9817         src_address = 1;
9818       else if (unformat (input, "dst"))
9819         dst_address = 1;
9820       else if (unformat (input, "proto"))
9821         protocol = 1;
9822
9823 #define _(a) else if (unformat (input, #a)) a=1;
9824       foreach_ip6_proto_field
9825 #undef _
9826         else
9827         break;
9828     }
9829
9830 #define _(a) found_something += a;
9831   foreach_ip6_proto_field;
9832 #undef _
9833
9834   if (found_something == 0)
9835     return 0;
9836
9837   vec_validate (mask, sizeof (*ip) - 1);
9838
9839   ip = (ip6_header_t *) mask;
9840
9841 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9842   foreach_ip6_proto_field;
9843 #undef _
9844
9845   ip_version_traffic_class_and_flow_label = 0;
9846
9847   if (version)
9848     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9849
9850   if (traffic_class)
9851     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9852
9853   if (flow_label)
9854     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9855
9856   ip->ip_version_traffic_class_and_flow_label =
9857     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9858
9859   *maskp = mask;
9860   return 1;
9861 }
9862
9863 uword
9864 unformat_l3_mask (unformat_input_t * input, va_list * args)
9865 {
9866   u8 **maskp = va_arg (*args, u8 **);
9867
9868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9869     {
9870       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9871         return 1;
9872       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9873         return 1;
9874       else
9875         break;
9876     }
9877   return 0;
9878 }
9879
9880 uword
9881 unformat_l2_mask (unformat_input_t * input, va_list * args)
9882 {
9883   u8 **maskp = va_arg (*args, u8 **);
9884   u8 *mask = 0;
9885   u8 src = 0;
9886   u8 dst = 0;
9887   u8 proto = 0;
9888   u8 tag1 = 0;
9889   u8 tag2 = 0;
9890   u8 ignore_tag1 = 0;
9891   u8 ignore_tag2 = 0;
9892   u8 cos1 = 0;
9893   u8 cos2 = 0;
9894   u8 dot1q = 0;
9895   u8 dot1ad = 0;
9896   int len = 14;
9897
9898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9899     {
9900       if (unformat (input, "src"))
9901         src = 1;
9902       else if (unformat (input, "dst"))
9903         dst = 1;
9904       else if (unformat (input, "proto"))
9905         proto = 1;
9906       else if (unformat (input, "tag1"))
9907         tag1 = 1;
9908       else if (unformat (input, "tag2"))
9909         tag2 = 1;
9910       else if (unformat (input, "ignore-tag1"))
9911         ignore_tag1 = 1;
9912       else if (unformat (input, "ignore-tag2"))
9913         ignore_tag2 = 1;
9914       else if (unformat (input, "cos1"))
9915         cos1 = 1;
9916       else if (unformat (input, "cos2"))
9917         cos2 = 1;
9918       else if (unformat (input, "dot1q"))
9919         dot1q = 1;
9920       else if (unformat (input, "dot1ad"))
9921         dot1ad = 1;
9922       else
9923         break;
9924     }
9925   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9926        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9927     return 0;
9928
9929   if (tag1 || ignore_tag1 || cos1 || dot1q)
9930     len = 18;
9931   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9932     len = 22;
9933
9934   vec_validate (mask, len - 1);
9935
9936   if (dst)
9937     clib_memset (mask, 0xff, 6);
9938
9939   if (src)
9940     clib_memset (mask + 6, 0xff, 6);
9941
9942   if (tag2 || dot1ad)
9943     {
9944       /* inner vlan tag */
9945       if (tag2)
9946         {
9947           mask[19] = 0xff;
9948           mask[18] = 0x0f;
9949         }
9950       if (cos2)
9951         mask[18] |= 0xe0;
9952       if (proto)
9953         mask[21] = mask[20] = 0xff;
9954       if (tag1)
9955         {
9956           mask[15] = 0xff;
9957           mask[14] = 0x0f;
9958         }
9959       if (cos1)
9960         mask[14] |= 0xe0;
9961       *maskp = mask;
9962       return 1;
9963     }
9964   if (tag1 | dot1q)
9965     {
9966       if (tag1)
9967         {
9968           mask[15] = 0xff;
9969           mask[14] = 0x0f;
9970         }
9971       if (cos1)
9972         mask[14] |= 0xe0;
9973       if (proto)
9974         mask[16] = mask[17] = 0xff;
9975
9976       *maskp = mask;
9977       return 1;
9978     }
9979   if (cos2)
9980     mask[18] |= 0xe0;
9981   if (cos1)
9982     mask[14] |= 0xe0;
9983   if (proto)
9984     mask[12] = mask[13] = 0xff;
9985
9986   *maskp = mask;
9987   return 1;
9988 }
9989
9990 uword
9991 unformat_classify_mask (unformat_input_t * input, va_list * args)
9992 {
9993   u8 **maskp = va_arg (*args, u8 **);
9994   u32 *skipp = va_arg (*args, u32 *);
9995   u32 *matchp = va_arg (*args, u32 *);
9996   u32 match;
9997   u8 *mask = 0;
9998   u8 *l2 = 0;
9999   u8 *l3 = 0;
10000   u8 *l4 = 0;
10001   int i;
10002
10003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10004     {
10005       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10006         ;
10007       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10008         ;
10009       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10010         ;
10011       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10012         ;
10013       else
10014         break;
10015     }
10016
10017   if (l4 && !l3)
10018     {
10019       vec_free (mask);
10020       vec_free (l2);
10021       vec_free (l4);
10022       return 0;
10023     }
10024
10025   if (mask || l2 || l3 || l4)
10026     {
10027       if (l2 || l3 || l4)
10028         {
10029           /* "With a free Ethernet header in every package" */
10030           if (l2 == 0)
10031             vec_validate (l2, 13);
10032           mask = l2;
10033           if (vec_len (l3))
10034             {
10035               vec_append (mask, l3);
10036               vec_free (l3);
10037             }
10038           if (vec_len (l4))
10039             {
10040               vec_append (mask, l4);
10041               vec_free (l4);
10042             }
10043         }
10044
10045       /* Scan forward looking for the first significant mask octet */
10046       for (i = 0; i < vec_len (mask); i++)
10047         if (mask[i])
10048           break;
10049
10050       /* compute (skip, match) params */
10051       *skipp = i / sizeof (u32x4);
10052       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10053
10054       /* Pad mask to an even multiple of the vector size */
10055       while (vec_len (mask) % sizeof (u32x4))
10056         vec_add1 (mask, 0);
10057
10058       match = vec_len (mask) / sizeof (u32x4);
10059
10060       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10061         {
10062           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10063           if (*tmp || *(tmp + 1))
10064             break;
10065           match--;
10066         }
10067       if (match == 0)
10068         clib_warning ("BUG: match 0");
10069
10070       _vec_len (mask) = match * sizeof (u32x4);
10071
10072       *matchp = match;
10073       *maskp = mask;
10074
10075       return 1;
10076     }
10077
10078   return 0;
10079 }
10080 #endif /* VPP_API_TEST_BUILTIN */
10081
10082 #define foreach_l2_next                         \
10083 _(drop, DROP)                                   \
10084 _(ethernet, ETHERNET_INPUT)                     \
10085 _(ip4, IP4_INPUT)                               \
10086 _(ip6, IP6_INPUT)
10087
10088 uword
10089 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10090 {
10091   u32 *miss_next_indexp = va_arg (*args, u32 *);
10092   u32 next_index = 0;
10093   u32 tmp;
10094
10095 #define _(n,N) \
10096   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10097   foreach_l2_next;
10098 #undef _
10099
10100   if (unformat (input, "%d", &tmp))
10101     {
10102       next_index = tmp;
10103       goto out;
10104     }
10105
10106   return 0;
10107
10108 out:
10109   *miss_next_indexp = next_index;
10110   return 1;
10111 }
10112
10113 #define foreach_ip_next                         \
10114 _(drop, DROP)                                   \
10115 _(local, LOCAL)                                 \
10116 _(rewrite, REWRITE)
10117
10118 uword
10119 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10120 {
10121   u32 *miss_next_indexp = va_arg (*args, u32 *);
10122   u32 next_index = 0;
10123   u32 tmp;
10124
10125 #define _(n,N) \
10126   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10127   foreach_ip_next;
10128 #undef _
10129
10130   if (unformat (input, "%d", &tmp))
10131     {
10132       next_index = tmp;
10133       goto out;
10134     }
10135
10136   return 0;
10137
10138 out:
10139   *miss_next_indexp = next_index;
10140   return 1;
10141 }
10142
10143 #define foreach_acl_next                        \
10144 _(deny, DENY)
10145
10146 uword
10147 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10148 {
10149   u32 *miss_next_indexp = va_arg (*args, u32 *);
10150   u32 next_index = 0;
10151   u32 tmp;
10152
10153 #define _(n,N) \
10154   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10155   foreach_acl_next;
10156 #undef _
10157
10158   if (unformat (input, "permit"))
10159     {
10160       next_index = ~0;
10161       goto out;
10162     }
10163   else if (unformat (input, "%d", &tmp))
10164     {
10165       next_index = tmp;
10166       goto out;
10167     }
10168
10169   return 0;
10170
10171 out:
10172   *miss_next_indexp = next_index;
10173   return 1;
10174 }
10175
10176 uword
10177 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10178 {
10179   u32 *r = va_arg (*args, u32 *);
10180
10181   if (unformat (input, "conform-color"))
10182     *r = POLICE_CONFORM;
10183   else if (unformat (input, "exceed-color"))
10184     *r = POLICE_EXCEED;
10185   else
10186     return 0;
10187
10188   return 1;
10189 }
10190
10191 static int
10192 api_classify_add_del_table (vat_main_t * vam)
10193 {
10194   unformat_input_t *i = vam->input;
10195   vl_api_classify_add_del_table_t *mp;
10196
10197   u32 nbuckets = 2;
10198   u32 skip = ~0;
10199   u32 match = ~0;
10200   int is_add = 1;
10201   int del_chain = 0;
10202   u32 table_index = ~0;
10203   u32 next_table_index = ~0;
10204   u32 miss_next_index = ~0;
10205   u32 memory_size = 32 << 20;
10206   u8 *mask = 0;
10207   u32 current_data_flag = 0;
10208   int current_data_offset = 0;
10209   int ret;
10210
10211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10212     {
10213       if (unformat (i, "del"))
10214         is_add = 0;
10215       else if (unformat (i, "del-chain"))
10216         {
10217           is_add = 0;
10218           del_chain = 1;
10219         }
10220       else if (unformat (i, "buckets %d", &nbuckets))
10221         ;
10222       else if (unformat (i, "memory_size %d", &memory_size))
10223         ;
10224       else if (unformat (i, "skip %d", &skip))
10225         ;
10226       else if (unformat (i, "match %d", &match))
10227         ;
10228       else if (unformat (i, "table %d", &table_index))
10229         ;
10230       else if (unformat (i, "mask %U", unformat_classify_mask,
10231                          &mask, &skip, &match))
10232         ;
10233       else if (unformat (i, "next-table %d", &next_table_index))
10234         ;
10235       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10236                          &miss_next_index))
10237         ;
10238       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10239                          &miss_next_index))
10240         ;
10241       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10242                          &miss_next_index))
10243         ;
10244       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10245         ;
10246       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10247         ;
10248       else
10249         break;
10250     }
10251
10252   if (is_add && mask == 0)
10253     {
10254       errmsg ("Mask required");
10255       return -99;
10256     }
10257
10258   if (is_add && skip == ~0)
10259     {
10260       errmsg ("skip count required");
10261       return -99;
10262     }
10263
10264   if (is_add && match == ~0)
10265     {
10266       errmsg ("match count required");
10267       return -99;
10268     }
10269
10270   if (!is_add && table_index == ~0)
10271     {
10272       errmsg ("table index required for delete");
10273       return -99;
10274     }
10275
10276   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10277
10278   mp->is_add = is_add;
10279   mp->del_chain = del_chain;
10280   mp->table_index = ntohl (table_index);
10281   mp->nbuckets = ntohl (nbuckets);
10282   mp->memory_size = ntohl (memory_size);
10283   mp->skip_n_vectors = ntohl (skip);
10284   mp->match_n_vectors = ntohl (match);
10285   mp->next_table_index = ntohl (next_table_index);
10286   mp->miss_next_index = ntohl (miss_next_index);
10287   mp->current_data_flag = ntohl (current_data_flag);
10288   mp->current_data_offset = ntohl (current_data_offset);
10289   mp->mask_len = ntohl (vec_len (mask));
10290   clib_memcpy (mp->mask, mask, vec_len (mask));
10291
10292   vec_free (mask);
10293
10294   S (mp);
10295   W (ret);
10296   return ret;
10297 }
10298
10299 #if VPP_API_TEST_BUILTIN == 0
10300 uword
10301 unformat_l4_match (unformat_input_t * input, va_list * args)
10302 {
10303   u8 **matchp = va_arg (*args, u8 **);
10304
10305   u8 *proto_header = 0;
10306   int src_port = 0;
10307   int dst_port = 0;
10308
10309   tcpudp_header_t h;
10310
10311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10312     {
10313       if (unformat (input, "src_port %d", &src_port))
10314         ;
10315       else if (unformat (input, "dst_port %d", &dst_port))
10316         ;
10317       else
10318         return 0;
10319     }
10320
10321   h.src_port = clib_host_to_net_u16 (src_port);
10322   h.dst_port = clib_host_to_net_u16 (dst_port);
10323   vec_validate (proto_header, sizeof (h) - 1);
10324   memcpy (proto_header, &h, sizeof (h));
10325
10326   *matchp = proto_header;
10327
10328   return 1;
10329 }
10330
10331 uword
10332 unformat_ip4_match (unformat_input_t * input, va_list * args)
10333 {
10334   u8 **matchp = va_arg (*args, u8 **);
10335   u8 *match = 0;
10336   ip4_header_t *ip;
10337   int version = 0;
10338   u32 version_val;
10339   int hdr_length = 0;
10340   u32 hdr_length_val;
10341   int src = 0, dst = 0;
10342   ip4_address_t src_val, dst_val;
10343   int proto = 0;
10344   u32 proto_val;
10345   int tos = 0;
10346   u32 tos_val;
10347   int length = 0;
10348   u32 length_val;
10349   int fragment_id = 0;
10350   u32 fragment_id_val;
10351   int ttl = 0;
10352   int ttl_val;
10353   int checksum = 0;
10354   u32 checksum_val;
10355
10356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10357     {
10358       if (unformat (input, "version %d", &version_val))
10359         version = 1;
10360       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10361         hdr_length = 1;
10362       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10363         src = 1;
10364       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10365         dst = 1;
10366       else if (unformat (input, "proto %d", &proto_val))
10367         proto = 1;
10368       else if (unformat (input, "tos %d", &tos_val))
10369         tos = 1;
10370       else if (unformat (input, "length %d", &length_val))
10371         length = 1;
10372       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10373         fragment_id = 1;
10374       else if (unformat (input, "ttl %d", &ttl_val))
10375         ttl = 1;
10376       else if (unformat (input, "checksum %d", &checksum_val))
10377         checksum = 1;
10378       else
10379         break;
10380     }
10381
10382   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10383       + ttl + checksum == 0)
10384     return 0;
10385
10386   /*
10387    * Aligned because we use the real comparison functions
10388    */
10389   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10390
10391   ip = (ip4_header_t *) match;
10392
10393   /* These are realistically matched in practice */
10394   if (src)
10395     ip->src_address.as_u32 = src_val.as_u32;
10396
10397   if (dst)
10398     ip->dst_address.as_u32 = dst_val.as_u32;
10399
10400   if (proto)
10401     ip->protocol = proto_val;
10402
10403
10404   /* These are not, but they're included for completeness */
10405   if (version)
10406     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10407
10408   if (hdr_length)
10409     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10410
10411   if (tos)
10412     ip->tos = tos_val;
10413
10414   if (length)
10415     ip->length = clib_host_to_net_u16 (length_val);
10416
10417   if (ttl)
10418     ip->ttl = ttl_val;
10419
10420   if (checksum)
10421     ip->checksum = clib_host_to_net_u16 (checksum_val);
10422
10423   *matchp = match;
10424   return 1;
10425 }
10426
10427 uword
10428 unformat_ip6_match (unformat_input_t * input, va_list * args)
10429 {
10430   u8 **matchp = va_arg (*args, u8 **);
10431   u8 *match = 0;
10432   ip6_header_t *ip;
10433   int version = 0;
10434   u32 version_val;
10435   u8 traffic_class = 0;
10436   u32 traffic_class_val = 0;
10437   u8 flow_label = 0;
10438   u8 flow_label_val;
10439   int src = 0, dst = 0;
10440   ip6_address_t src_val, dst_val;
10441   int proto = 0;
10442   u32 proto_val;
10443   int payload_length = 0;
10444   u32 payload_length_val;
10445   int hop_limit = 0;
10446   int hop_limit_val;
10447   u32 ip_version_traffic_class_and_flow_label;
10448
10449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10450     {
10451       if (unformat (input, "version %d", &version_val))
10452         version = 1;
10453       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10454         traffic_class = 1;
10455       else if (unformat (input, "flow_label %d", &flow_label_val))
10456         flow_label = 1;
10457       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10458         src = 1;
10459       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10460         dst = 1;
10461       else if (unformat (input, "proto %d", &proto_val))
10462         proto = 1;
10463       else if (unformat (input, "payload_length %d", &payload_length_val))
10464         payload_length = 1;
10465       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10466         hop_limit = 1;
10467       else
10468         break;
10469     }
10470
10471   if (version + traffic_class + flow_label + src + dst + proto +
10472       payload_length + hop_limit == 0)
10473     return 0;
10474
10475   /*
10476    * Aligned because we use the real comparison functions
10477    */
10478   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10479
10480   ip = (ip6_header_t *) match;
10481
10482   if (src)
10483     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10484
10485   if (dst)
10486     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10487
10488   if (proto)
10489     ip->protocol = proto_val;
10490
10491   ip_version_traffic_class_and_flow_label = 0;
10492
10493   if (version)
10494     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10495
10496   if (traffic_class)
10497     ip_version_traffic_class_and_flow_label |=
10498       (traffic_class_val & 0xFF) << 20;
10499
10500   if (flow_label)
10501     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10502
10503   ip->ip_version_traffic_class_and_flow_label =
10504     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10505
10506   if (payload_length)
10507     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10508
10509   if (hop_limit)
10510     ip->hop_limit = hop_limit_val;
10511
10512   *matchp = match;
10513   return 1;
10514 }
10515
10516 uword
10517 unformat_l3_match (unformat_input_t * input, va_list * args)
10518 {
10519   u8 **matchp = va_arg (*args, u8 **);
10520
10521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10522     {
10523       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10524         return 1;
10525       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10526         return 1;
10527       else
10528         break;
10529     }
10530   return 0;
10531 }
10532
10533 uword
10534 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10535 {
10536   u8 *tagp = va_arg (*args, u8 *);
10537   u32 tag;
10538
10539   if (unformat (input, "%d", &tag))
10540     {
10541       tagp[0] = (tag >> 8) & 0x0F;
10542       tagp[1] = tag & 0xFF;
10543       return 1;
10544     }
10545
10546   return 0;
10547 }
10548
10549 uword
10550 unformat_l2_match (unformat_input_t * input, va_list * args)
10551 {
10552   u8 **matchp = va_arg (*args, u8 **);
10553   u8 *match = 0;
10554   u8 src = 0;
10555   u8 src_val[6];
10556   u8 dst = 0;
10557   u8 dst_val[6];
10558   u8 proto = 0;
10559   u16 proto_val;
10560   u8 tag1 = 0;
10561   u8 tag1_val[2];
10562   u8 tag2 = 0;
10563   u8 tag2_val[2];
10564   int len = 14;
10565   u8 ignore_tag1 = 0;
10566   u8 ignore_tag2 = 0;
10567   u8 cos1 = 0;
10568   u8 cos2 = 0;
10569   u32 cos1_val = 0;
10570   u32 cos2_val = 0;
10571
10572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10573     {
10574       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10575         src = 1;
10576       else
10577         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10578         dst = 1;
10579       else if (unformat (input, "proto %U",
10580                          unformat_ethernet_type_host_byte_order, &proto_val))
10581         proto = 1;
10582       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10583         tag1 = 1;
10584       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10585         tag2 = 1;
10586       else if (unformat (input, "ignore-tag1"))
10587         ignore_tag1 = 1;
10588       else if (unformat (input, "ignore-tag2"))
10589         ignore_tag2 = 1;
10590       else if (unformat (input, "cos1 %d", &cos1_val))
10591         cos1 = 1;
10592       else if (unformat (input, "cos2 %d", &cos2_val))
10593         cos2 = 1;
10594       else
10595         break;
10596     }
10597   if ((src + dst + proto + tag1 + tag2 +
10598        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10599     return 0;
10600
10601   if (tag1 || ignore_tag1 || cos1)
10602     len = 18;
10603   if (tag2 || ignore_tag2 || cos2)
10604     len = 22;
10605
10606   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10607
10608   if (dst)
10609     clib_memcpy (match, dst_val, 6);
10610
10611   if (src)
10612     clib_memcpy (match + 6, src_val, 6);
10613
10614   if (tag2)
10615     {
10616       /* inner vlan tag */
10617       match[19] = tag2_val[1];
10618       match[18] = tag2_val[0];
10619       if (cos2)
10620         match[18] |= (cos2_val & 0x7) << 5;
10621       if (proto)
10622         {
10623           match[21] = proto_val & 0xff;
10624           match[20] = proto_val >> 8;
10625         }
10626       if (tag1)
10627         {
10628           match[15] = tag1_val[1];
10629           match[14] = tag1_val[0];
10630         }
10631       if (cos1)
10632         match[14] |= (cos1_val & 0x7) << 5;
10633       *matchp = match;
10634       return 1;
10635     }
10636   if (tag1)
10637     {
10638       match[15] = tag1_val[1];
10639       match[14] = tag1_val[0];
10640       if (proto)
10641         {
10642           match[17] = proto_val & 0xff;
10643           match[16] = proto_val >> 8;
10644         }
10645       if (cos1)
10646         match[14] |= (cos1_val & 0x7) << 5;
10647
10648       *matchp = match;
10649       return 1;
10650     }
10651   if (cos2)
10652     match[18] |= (cos2_val & 0x7) << 5;
10653   if (cos1)
10654     match[14] |= (cos1_val & 0x7) << 5;
10655   if (proto)
10656     {
10657       match[13] = proto_val & 0xff;
10658       match[12] = proto_val >> 8;
10659     }
10660
10661   *matchp = match;
10662   return 1;
10663 }
10664
10665 uword
10666 unformat_qos_source (unformat_input_t * input, va_list * args)
10667 {
10668   int *qs = va_arg (*args, int *);
10669
10670   if (unformat (input, "ip"))
10671     *qs = QOS_SOURCE_IP;
10672   else if (unformat (input, "mpls"))
10673     *qs = QOS_SOURCE_MPLS;
10674   else if (unformat (input, "ext"))
10675     *qs = QOS_SOURCE_EXT;
10676   else if (unformat (input, "vlan"))
10677     *qs = QOS_SOURCE_VLAN;
10678   else
10679     return 0;
10680
10681   return 1;
10682 }
10683 #endif
10684
10685 uword
10686 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10687 {
10688   u8 **matchp = va_arg (*args, u8 **);
10689   u32 skip_n_vectors = va_arg (*args, u32);
10690   u32 match_n_vectors = va_arg (*args, u32);
10691
10692   u8 *match = 0;
10693   u8 *l2 = 0;
10694   u8 *l3 = 0;
10695   u8 *l4 = 0;
10696
10697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10698     {
10699       if (unformat (input, "hex %U", unformat_hex_string, &match))
10700         ;
10701       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10702         ;
10703       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10704         ;
10705       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10706         ;
10707       else
10708         break;
10709     }
10710
10711   if (l4 && !l3)
10712     {
10713       vec_free (match);
10714       vec_free (l2);
10715       vec_free (l4);
10716       return 0;
10717     }
10718
10719   if (match || l2 || l3 || l4)
10720     {
10721       if (l2 || l3 || l4)
10722         {
10723           /* "Win a free Ethernet header in every packet" */
10724           if (l2 == 0)
10725             vec_validate_aligned (l2, 13, sizeof (u32x4));
10726           match = l2;
10727           if (vec_len (l3))
10728             {
10729               vec_append_aligned (match, l3, sizeof (u32x4));
10730               vec_free (l3);
10731             }
10732           if (vec_len (l4))
10733             {
10734               vec_append_aligned (match, l4, sizeof (u32x4));
10735               vec_free (l4);
10736             }
10737         }
10738
10739       /* Make sure the vector is big enough even if key is all 0's */
10740       vec_validate_aligned
10741         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10742          sizeof (u32x4));
10743
10744       /* Set size, include skipped vectors */
10745       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10746
10747       *matchp = match;
10748
10749       return 1;
10750     }
10751
10752   return 0;
10753 }
10754
10755 static int
10756 api_classify_add_del_session (vat_main_t * vam)
10757 {
10758   unformat_input_t *i = vam->input;
10759   vl_api_classify_add_del_session_t *mp;
10760   int is_add = 1;
10761   u32 table_index = ~0;
10762   u32 hit_next_index = ~0;
10763   u32 opaque_index = ~0;
10764   u8 *match = 0;
10765   i32 advance = 0;
10766   u32 skip_n_vectors = 0;
10767   u32 match_n_vectors = 0;
10768   u32 action = 0;
10769   u32 metadata = 0;
10770   int ret;
10771
10772   /*
10773    * Warning: you have to supply skip_n and match_n
10774    * because the API client cant simply look at the classify
10775    * table object.
10776    */
10777
10778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10779     {
10780       if (unformat (i, "del"))
10781         is_add = 0;
10782       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10783                          &hit_next_index))
10784         ;
10785       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10786                          &hit_next_index))
10787         ;
10788       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10789                          &hit_next_index))
10790         ;
10791       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10792         ;
10793       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10794         ;
10795       else if (unformat (i, "opaque-index %d", &opaque_index))
10796         ;
10797       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10798         ;
10799       else if (unformat (i, "match_n %d", &match_n_vectors))
10800         ;
10801       else if (unformat (i, "match %U", api_unformat_classify_match,
10802                          &match, skip_n_vectors, match_n_vectors))
10803         ;
10804       else if (unformat (i, "advance %d", &advance))
10805         ;
10806       else if (unformat (i, "table-index %d", &table_index))
10807         ;
10808       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10809         action = 1;
10810       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10811         action = 2;
10812       else if (unformat (i, "action %d", &action))
10813         ;
10814       else if (unformat (i, "metadata %d", &metadata))
10815         ;
10816       else
10817         break;
10818     }
10819
10820   if (table_index == ~0)
10821     {
10822       errmsg ("Table index required");
10823       return -99;
10824     }
10825
10826   if (is_add && match == 0)
10827     {
10828       errmsg ("Match value required");
10829       return -99;
10830     }
10831
10832   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10833
10834   mp->is_add = is_add;
10835   mp->table_index = ntohl (table_index);
10836   mp->hit_next_index = ntohl (hit_next_index);
10837   mp->opaque_index = ntohl (opaque_index);
10838   mp->advance = ntohl (advance);
10839   mp->action = action;
10840   mp->metadata = ntohl (metadata);
10841   mp->match_len = ntohl (vec_len (match));
10842   clib_memcpy (mp->match, match, vec_len (match));
10843   vec_free (match);
10844
10845   S (mp);
10846   W (ret);
10847   return ret;
10848 }
10849
10850 static int
10851 api_classify_set_interface_ip_table (vat_main_t * vam)
10852 {
10853   unformat_input_t *i = vam->input;
10854   vl_api_classify_set_interface_ip_table_t *mp;
10855   u32 sw_if_index;
10856   int sw_if_index_set;
10857   u32 table_index = ~0;
10858   u8 is_ipv6 = 0;
10859   int ret;
10860
10861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10862     {
10863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10864         sw_if_index_set = 1;
10865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10866         sw_if_index_set = 1;
10867       else if (unformat (i, "table %d", &table_index))
10868         ;
10869       else
10870         {
10871           clib_warning ("parse error '%U'", format_unformat_error, i);
10872           return -99;
10873         }
10874     }
10875
10876   if (sw_if_index_set == 0)
10877     {
10878       errmsg ("missing interface name or sw_if_index");
10879       return -99;
10880     }
10881
10882
10883   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10884
10885   mp->sw_if_index = ntohl (sw_if_index);
10886   mp->table_index = ntohl (table_index);
10887   mp->is_ipv6 = is_ipv6;
10888
10889   S (mp);
10890   W (ret);
10891   return ret;
10892 }
10893
10894 static int
10895 api_classify_set_interface_l2_tables (vat_main_t * vam)
10896 {
10897   unformat_input_t *i = vam->input;
10898   vl_api_classify_set_interface_l2_tables_t *mp;
10899   u32 sw_if_index;
10900   int sw_if_index_set;
10901   u32 ip4_table_index = ~0;
10902   u32 ip6_table_index = ~0;
10903   u32 other_table_index = ~0;
10904   u32 is_input = 1;
10905   int ret;
10906
10907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10908     {
10909       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10910         sw_if_index_set = 1;
10911       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10912         sw_if_index_set = 1;
10913       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10914         ;
10915       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10916         ;
10917       else if (unformat (i, "other-table %d", &other_table_index))
10918         ;
10919       else if (unformat (i, "is-input %d", &is_input))
10920         ;
10921       else
10922         {
10923           clib_warning ("parse error '%U'", format_unformat_error, i);
10924           return -99;
10925         }
10926     }
10927
10928   if (sw_if_index_set == 0)
10929     {
10930       errmsg ("missing interface name or sw_if_index");
10931       return -99;
10932     }
10933
10934
10935   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10936
10937   mp->sw_if_index = ntohl (sw_if_index);
10938   mp->ip4_table_index = ntohl (ip4_table_index);
10939   mp->ip6_table_index = ntohl (ip6_table_index);
10940   mp->other_table_index = ntohl (other_table_index);
10941   mp->is_input = (u8) is_input;
10942
10943   S (mp);
10944   W (ret);
10945   return ret;
10946 }
10947
10948 static int
10949 api_set_ipfix_exporter (vat_main_t * vam)
10950 {
10951   unformat_input_t *i = vam->input;
10952   vl_api_set_ipfix_exporter_t *mp;
10953   ip4_address_t collector_address;
10954   u8 collector_address_set = 0;
10955   u32 collector_port = ~0;
10956   ip4_address_t src_address;
10957   u8 src_address_set = 0;
10958   u32 vrf_id = ~0;
10959   u32 path_mtu = ~0;
10960   u32 template_interval = ~0;
10961   u8 udp_checksum = 0;
10962   int ret;
10963
10964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10965     {
10966       if (unformat (i, "collector_address %U", unformat_ip4_address,
10967                     &collector_address))
10968         collector_address_set = 1;
10969       else if (unformat (i, "collector_port %d", &collector_port))
10970         ;
10971       else if (unformat (i, "src_address %U", unformat_ip4_address,
10972                          &src_address))
10973         src_address_set = 1;
10974       else if (unformat (i, "vrf_id %d", &vrf_id))
10975         ;
10976       else if (unformat (i, "path_mtu %d", &path_mtu))
10977         ;
10978       else if (unformat (i, "template_interval %d", &template_interval))
10979         ;
10980       else if (unformat (i, "udp_checksum"))
10981         udp_checksum = 1;
10982       else
10983         break;
10984     }
10985
10986   if (collector_address_set == 0)
10987     {
10988       errmsg ("collector_address required");
10989       return -99;
10990     }
10991
10992   if (src_address_set == 0)
10993     {
10994       errmsg ("src_address required");
10995       return -99;
10996     }
10997
10998   M (SET_IPFIX_EXPORTER, mp);
10999
11000   memcpy (mp->collector_address.un.ip4, collector_address.data,
11001           sizeof (collector_address.data));
11002   mp->collector_port = htons ((u16) collector_port);
11003   memcpy (mp->src_address.un.ip4, src_address.data,
11004           sizeof (src_address.data));
11005   mp->vrf_id = htonl (vrf_id);
11006   mp->path_mtu = htonl (path_mtu);
11007   mp->template_interval = htonl (template_interval);
11008   mp->udp_checksum = udp_checksum;
11009
11010   S (mp);
11011   W (ret);
11012   return ret;
11013 }
11014
11015 static int
11016 api_set_ipfix_classify_stream (vat_main_t * vam)
11017 {
11018   unformat_input_t *i = vam->input;
11019   vl_api_set_ipfix_classify_stream_t *mp;
11020   u32 domain_id = 0;
11021   u32 src_port = UDP_DST_PORT_ipfix;
11022   int ret;
11023
11024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11025     {
11026       if (unformat (i, "domain %d", &domain_id))
11027         ;
11028       else if (unformat (i, "src_port %d", &src_port))
11029         ;
11030       else
11031         {
11032           errmsg ("unknown input `%U'", format_unformat_error, i);
11033           return -99;
11034         }
11035     }
11036
11037   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11038
11039   mp->domain_id = htonl (domain_id);
11040   mp->src_port = htons ((u16) src_port);
11041
11042   S (mp);
11043   W (ret);
11044   return ret;
11045 }
11046
11047 static int
11048 api_ipfix_classify_table_add_del (vat_main_t * vam)
11049 {
11050   unformat_input_t *i = vam->input;
11051   vl_api_ipfix_classify_table_add_del_t *mp;
11052   int is_add = -1;
11053   u32 classify_table_index = ~0;
11054   u8 ip_version = 0;
11055   u8 transport_protocol = 255;
11056   int ret;
11057
11058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11059     {
11060       if (unformat (i, "add"))
11061         is_add = 1;
11062       else if (unformat (i, "del"))
11063         is_add = 0;
11064       else if (unformat (i, "table %d", &classify_table_index))
11065         ;
11066       else if (unformat (i, "ip4"))
11067         ip_version = 4;
11068       else if (unformat (i, "ip6"))
11069         ip_version = 6;
11070       else if (unformat (i, "tcp"))
11071         transport_protocol = 6;
11072       else if (unformat (i, "udp"))
11073         transport_protocol = 17;
11074       else
11075         {
11076           errmsg ("unknown input `%U'", format_unformat_error, i);
11077           return -99;
11078         }
11079     }
11080
11081   if (is_add == -1)
11082     {
11083       errmsg ("expecting: add|del");
11084       return -99;
11085     }
11086   if (classify_table_index == ~0)
11087     {
11088       errmsg ("classifier table not specified");
11089       return -99;
11090     }
11091   if (ip_version == 0)
11092     {
11093       errmsg ("IP version not specified");
11094       return -99;
11095     }
11096
11097   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11098
11099   mp->is_add = is_add;
11100   mp->table_id = htonl (classify_table_index);
11101   mp->ip_version = ip_version;
11102   mp->transport_protocol = transport_protocol;
11103
11104   S (mp);
11105   W (ret);
11106   return ret;
11107 }
11108
11109 static int
11110 api_get_node_index (vat_main_t * vam)
11111 {
11112   unformat_input_t *i = vam->input;
11113   vl_api_get_node_index_t *mp;
11114   u8 *name = 0;
11115   int ret;
11116
11117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11118     {
11119       if (unformat (i, "node %s", &name))
11120         ;
11121       else
11122         break;
11123     }
11124   if (name == 0)
11125     {
11126       errmsg ("node name required");
11127       return -99;
11128     }
11129   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11130     {
11131       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11132       return -99;
11133     }
11134
11135   M (GET_NODE_INDEX, mp);
11136   clib_memcpy (mp->node_name, name, vec_len (name));
11137   vec_free (name);
11138
11139   S (mp);
11140   W (ret);
11141   return ret;
11142 }
11143
11144 static int
11145 api_get_next_index (vat_main_t * vam)
11146 {
11147   unformat_input_t *i = vam->input;
11148   vl_api_get_next_index_t *mp;
11149   u8 *node_name = 0, *next_node_name = 0;
11150   int ret;
11151
11152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11153     {
11154       if (unformat (i, "node-name %s", &node_name))
11155         ;
11156       else if (unformat (i, "next-node-name %s", &next_node_name))
11157         break;
11158     }
11159
11160   if (node_name == 0)
11161     {
11162       errmsg ("node name required");
11163       return -99;
11164     }
11165   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11166     {
11167       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11168       return -99;
11169     }
11170
11171   if (next_node_name == 0)
11172     {
11173       errmsg ("next node name required");
11174       return -99;
11175     }
11176   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11177     {
11178       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11179       return -99;
11180     }
11181
11182   M (GET_NEXT_INDEX, mp);
11183   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11184   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11185   vec_free (node_name);
11186   vec_free (next_node_name);
11187
11188   S (mp);
11189   W (ret);
11190   return ret;
11191 }
11192
11193 static int
11194 api_add_node_next (vat_main_t * vam)
11195 {
11196   unformat_input_t *i = vam->input;
11197   vl_api_add_node_next_t *mp;
11198   u8 *name = 0;
11199   u8 *next = 0;
11200   int ret;
11201
11202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11203     {
11204       if (unformat (i, "node %s", &name))
11205         ;
11206       else if (unformat (i, "next %s", &next))
11207         ;
11208       else
11209         break;
11210     }
11211   if (name == 0)
11212     {
11213       errmsg ("node name required");
11214       return -99;
11215     }
11216   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11217     {
11218       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11219       return -99;
11220     }
11221   if (next == 0)
11222     {
11223       errmsg ("next node required");
11224       return -99;
11225     }
11226   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11227     {
11228       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11229       return -99;
11230     }
11231
11232   M (ADD_NODE_NEXT, mp);
11233   clib_memcpy (mp->node_name, name, vec_len (name));
11234   clib_memcpy (mp->next_name, next, vec_len (next));
11235   vec_free (name);
11236   vec_free (next);
11237
11238   S (mp);
11239   W (ret);
11240   return ret;
11241 }
11242
11243 static int
11244 api_l2tpv3_create_tunnel (vat_main_t * vam)
11245 {
11246   unformat_input_t *i = vam->input;
11247   ip6_address_t client_address, our_address;
11248   int client_address_set = 0;
11249   int our_address_set = 0;
11250   u32 local_session_id = 0;
11251   u32 remote_session_id = 0;
11252   u64 local_cookie = 0;
11253   u64 remote_cookie = 0;
11254   u8 l2_sublayer_present = 0;
11255   vl_api_l2tpv3_create_tunnel_t *mp;
11256   int ret;
11257
11258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11259     {
11260       if (unformat (i, "client_address %U", unformat_ip6_address,
11261                     &client_address))
11262         client_address_set = 1;
11263       else if (unformat (i, "our_address %U", unformat_ip6_address,
11264                          &our_address))
11265         our_address_set = 1;
11266       else if (unformat (i, "local_session_id %d", &local_session_id))
11267         ;
11268       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11269         ;
11270       else if (unformat (i, "local_cookie %lld", &local_cookie))
11271         ;
11272       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11273         ;
11274       else if (unformat (i, "l2-sublayer-present"))
11275         l2_sublayer_present = 1;
11276       else
11277         break;
11278     }
11279
11280   if (client_address_set == 0)
11281     {
11282       errmsg ("client_address required");
11283       return -99;
11284     }
11285
11286   if (our_address_set == 0)
11287     {
11288       errmsg ("our_address required");
11289       return -99;
11290     }
11291
11292   M (L2TPV3_CREATE_TUNNEL, mp);
11293
11294   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11295                sizeof (ip6_address_t));
11296
11297   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11298                sizeof (ip6_address_t));
11299
11300   mp->local_session_id = ntohl (local_session_id);
11301   mp->remote_session_id = ntohl (remote_session_id);
11302   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11303   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11304   mp->l2_sublayer_present = l2_sublayer_present;
11305
11306   S (mp);
11307   W (ret);
11308   return ret;
11309 }
11310
11311 static int
11312 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11313 {
11314   unformat_input_t *i = vam->input;
11315   u32 sw_if_index;
11316   u8 sw_if_index_set = 0;
11317   u64 new_local_cookie = 0;
11318   u64 new_remote_cookie = 0;
11319   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11320   int ret;
11321
11322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11323     {
11324       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11325         sw_if_index_set = 1;
11326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11327         sw_if_index_set = 1;
11328       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11329         ;
11330       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11331         ;
11332       else
11333         break;
11334     }
11335
11336   if (sw_if_index_set == 0)
11337     {
11338       errmsg ("missing interface name or sw_if_index");
11339       return -99;
11340     }
11341
11342   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11343
11344   mp->sw_if_index = ntohl (sw_if_index);
11345   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11346   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11347
11348   S (mp);
11349   W (ret);
11350   return ret;
11351 }
11352
11353 static int
11354 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11355 {
11356   unformat_input_t *i = vam->input;
11357   vl_api_l2tpv3_interface_enable_disable_t *mp;
11358   u32 sw_if_index;
11359   u8 sw_if_index_set = 0;
11360   u8 enable_disable = 1;
11361   int ret;
11362
11363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11364     {
11365       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11366         sw_if_index_set = 1;
11367       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11368         sw_if_index_set = 1;
11369       else if (unformat (i, "enable"))
11370         enable_disable = 1;
11371       else if (unformat (i, "disable"))
11372         enable_disable = 0;
11373       else
11374         break;
11375     }
11376
11377   if (sw_if_index_set == 0)
11378     {
11379       errmsg ("missing interface name or sw_if_index");
11380       return -99;
11381     }
11382
11383   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11384
11385   mp->sw_if_index = ntohl (sw_if_index);
11386   mp->enable_disable = enable_disable;
11387
11388   S (mp);
11389   W (ret);
11390   return ret;
11391 }
11392
11393 static int
11394 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11395 {
11396   unformat_input_t *i = vam->input;
11397   vl_api_l2tpv3_set_lookup_key_t *mp;
11398   u8 key = ~0;
11399   int ret;
11400
11401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11402     {
11403       if (unformat (i, "lookup_v6_src"))
11404         key = L2T_LOOKUP_SRC_ADDRESS;
11405       else if (unformat (i, "lookup_v6_dst"))
11406         key = L2T_LOOKUP_DST_ADDRESS;
11407       else if (unformat (i, "lookup_session_id"))
11408         key = L2T_LOOKUP_SESSION_ID;
11409       else
11410         break;
11411     }
11412
11413   if (key == (u8) ~ 0)
11414     {
11415       errmsg ("l2tp session lookup key unset");
11416       return -99;
11417     }
11418
11419   M (L2TPV3_SET_LOOKUP_KEY, mp);
11420
11421   mp->key = key;
11422
11423   S (mp);
11424   W (ret);
11425   return ret;
11426 }
11427
11428 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11429   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11430 {
11431   vat_main_t *vam = &vat_main;
11432
11433   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11434          format_ip6_address, mp->our_address,
11435          format_ip6_address, mp->client_address,
11436          clib_net_to_host_u32 (mp->sw_if_index));
11437
11438   print (vam->ofp,
11439          "   local cookies %016llx %016llx remote cookie %016llx",
11440          clib_net_to_host_u64 (mp->local_cookie[0]),
11441          clib_net_to_host_u64 (mp->local_cookie[1]),
11442          clib_net_to_host_u64 (mp->remote_cookie));
11443
11444   print (vam->ofp, "   local session-id %d remote session-id %d",
11445          clib_net_to_host_u32 (mp->local_session_id),
11446          clib_net_to_host_u32 (mp->remote_session_id));
11447
11448   print (vam->ofp, "   l2 specific sublayer %s\n",
11449          mp->l2_sublayer_present ? "preset" : "absent");
11450
11451 }
11452
11453 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11454   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11455 {
11456   vat_main_t *vam = &vat_main;
11457   vat_json_node_t *node = NULL;
11458   struct in6_addr addr;
11459
11460   if (VAT_JSON_ARRAY != vam->json_tree.type)
11461     {
11462       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11463       vat_json_init_array (&vam->json_tree);
11464     }
11465   node = vat_json_array_add (&vam->json_tree);
11466
11467   vat_json_init_object (node);
11468
11469   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11470   vat_json_object_add_ip6 (node, "our_address", addr);
11471   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11472   vat_json_object_add_ip6 (node, "client_address", addr);
11473
11474   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11475   vat_json_init_array (lc);
11476   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11477   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11478   vat_json_object_add_uint (node, "remote_cookie",
11479                             clib_net_to_host_u64 (mp->remote_cookie));
11480
11481   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11482   vat_json_object_add_uint (node, "local_session_id",
11483                             clib_net_to_host_u32 (mp->local_session_id));
11484   vat_json_object_add_uint (node, "remote_session_id",
11485                             clib_net_to_host_u32 (mp->remote_session_id));
11486   vat_json_object_add_string_copy (node, "l2_sublayer",
11487                                    mp->l2_sublayer_present ? (u8 *) "present"
11488                                    : (u8 *) "absent");
11489 }
11490
11491 static int
11492 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11493 {
11494   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11495   vl_api_control_ping_t *mp_ping;
11496   int ret;
11497
11498   /* Get list of l2tpv3-tunnel interfaces */
11499   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11500   S (mp);
11501
11502   /* Use a control ping for synchronization */
11503   MPING (CONTROL_PING, mp_ping);
11504   S (mp_ping);
11505
11506   W (ret);
11507   return ret;
11508 }
11509
11510
11511 static void vl_api_sw_interface_tap_v2_details_t_handler
11512   (vl_api_sw_interface_tap_v2_details_t * mp)
11513 {
11514   vat_main_t *vam = &vat_main;
11515
11516   u8 *ip4 =
11517     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11518             mp->host_ip4_prefix.len);
11519   u8 *ip6 =
11520     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11521             mp->host_ip6_prefix.len);
11522
11523   print (vam->ofp,
11524          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11525          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11526          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11527          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11528          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11529
11530   vec_free (ip4);
11531   vec_free (ip6);
11532 }
11533
11534 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11535   (vl_api_sw_interface_tap_v2_details_t * mp)
11536 {
11537   vat_main_t *vam = &vat_main;
11538   vat_json_node_t *node = NULL;
11539
11540   if (VAT_JSON_ARRAY != vam->json_tree.type)
11541     {
11542       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11543       vat_json_init_array (&vam->json_tree);
11544     }
11545   node = vat_json_array_add (&vam->json_tree);
11546
11547   vat_json_init_object (node);
11548   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11549   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11550   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11551   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11552   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11553   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11554   vat_json_object_add_string_copy (node, "host_mac_addr",
11555                                    format (0, "%U", format_ethernet_address,
11556                                            &mp->host_mac_addr));
11557   vat_json_object_add_string_copy (node, "host_namespace",
11558                                    mp->host_namespace);
11559   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11560   vat_json_object_add_string_copy (node, "host_ip4_addr",
11561                                    format (0, "%U/%d", format_ip4_address,
11562                                            mp->host_ip4_prefix.address,
11563                                            mp->host_ip4_prefix.len));
11564   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11565                                    format (0, "%U/%d", format_ip6_address,
11566                                            mp->host_ip6_prefix.address,
11567                                            mp->host_ip6_prefix.len));
11568
11569 }
11570
11571 static int
11572 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11573 {
11574   vl_api_sw_interface_tap_v2_dump_t *mp;
11575   vl_api_control_ping_t *mp_ping;
11576   int ret;
11577
11578   print (vam->ofp,
11579          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11580          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11581          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11582          "host_ip6_addr");
11583
11584   /* Get list of tap interfaces */
11585   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11586   S (mp);
11587
11588   /* Use a control ping for synchronization */
11589   MPING (CONTROL_PING, mp_ping);
11590   S (mp_ping);
11591
11592   W (ret);
11593   return ret;
11594 }
11595
11596 static void vl_api_sw_interface_virtio_pci_details_t_handler
11597   (vl_api_sw_interface_virtio_pci_details_t * mp)
11598 {
11599   vat_main_t *vam = &vat_main;
11600
11601   typedef union
11602   {
11603     struct
11604     {
11605       u16 domain;
11606       u8 bus;
11607       u8 slot:5;
11608       u8 function:3;
11609     };
11610     u32 as_u32;
11611   } pci_addr_t;
11612   pci_addr_t addr;
11613
11614   addr.domain = ntohs (mp->pci_addr.domain);
11615   addr.bus = mp->pci_addr.bus;
11616   addr.slot = mp->pci_addr.slot;
11617   addr.function = mp->pci_addr.function;
11618
11619   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11620                          addr.slot, addr.function);
11621
11622   print (vam->ofp,
11623          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11624          pci_addr, ntohl (mp->sw_if_index),
11625          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11626          format_ethernet_address, mp->mac_addr,
11627          clib_net_to_host_u64 (mp->features));
11628   vec_free (pci_addr);
11629 }
11630
11631 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11632   (vl_api_sw_interface_virtio_pci_details_t * mp)
11633 {
11634   vat_main_t *vam = &vat_main;
11635   vat_json_node_t *node = NULL;
11636   vlib_pci_addr_t pci_addr;
11637
11638   if (VAT_JSON_ARRAY != vam->json_tree.type)
11639     {
11640       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11641       vat_json_init_array (&vam->json_tree);
11642     }
11643   node = vat_json_array_add (&vam->json_tree);
11644
11645   pci_addr.domain = ntohs (mp->pci_addr.domain);
11646   pci_addr.bus = mp->pci_addr.bus;
11647   pci_addr.slot = mp->pci_addr.slot;
11648   pci_addr.function = mp->pci_addr.function;
11649
11650   vat_json_init_object (node);
11651   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11652   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11653   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11654   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11655   vat_json_object_add_uint (node, "features",
11656                             clib_net_to_host_u64 (mp->features));
11657   vat_json_object_add_string_copy (node, "mac_addr",
11658                                    format (0, "%U", format_ethernet_address,
11659                                            &mp->mac_addr));
11660 }
11661
11662 static int
11663 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11664 {
11665   vl_api_sw_interface_virtio_pci_dump_t *mp;
11666   vl_api_control_ping_t *mp_ping;
11667   int ret;
11668
11669   print (vam->ofp,
11670          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11671          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11672          "mac_addr", "features");
11673
11674   /* Get list of tap interfaces */
11675   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11676   S (mp);
11677
11678   /* Use a control ping for synchronization */
11679   MPING (CONTROL_PING, mp_ping);
11680   S (mp_ping);
11681
11682   W (ret);
11683   return ret;
11684 }
11685
11686 static int
11687 api_vxlan_offload_rx (vat_main_t * vam)
11688 {
11689   unformat_input_t *line_input = vam->input;
11690   vl_api_vxlan_offload_rx_t *mp;
11691   u32 hw_if_index = ~0, rx_if_index = ~0;
11692   u8 is_add = 1;
11693   int ret;
11694
11695   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11696     {
11697       if (unformat (line_input, "del"))
11698         is_add = 0;
11699       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11700                          &hw_if_index))
11701         ;
11702       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11703         ;
11704       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11705                          &rx_if_index))
11706         ;
11707       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11708         ;
11709       else
11710         {
11711           errmsg ("parse error '%U'", format_unformat_error, line_input);
11712           return -99;
11713         }
11714     }
11715
11716   if (hw_if_index == ~0)
11717     {
11718       errmsg ("no hw interface");
11719       return -99;
11720     }
11721
11722   if (rx_if_index == ~0)
11723     {
11724       errmsg ("no rx tunnel");
11725       return -99;
11726     }
11727
11728   M (VXLAN_OFFLOAD_RX, mp);
11729
11730   mp->hw_if_index = ntohl (hw_if_index);
11731   mp->sw_if_index = ntohl (rx_if_index);
11732   mp->enable = is_add;
11733
11734   S (mp);
11735   W (ret);
11736   return ret;
11737 }
11738
11739 static uword unformat_vxlan_decap_next
11740   (unformat_input_t * input, va_list * args)
11741 {
11742   u32 *result = va_arg (*args, u32 *);
11743   u32 tmp;
11744
11745   if (unformat (input, "l2"))
11746     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11747   else if (unformat (input, "%d", &tmp))
11748     *result = tmp;
11749   else
11750     return 0;
11751   return 1;
11752 }
11753
11754 static int
11755 api_vxlan_add_del_tunnel (vat_main_t * vam)
11756 {
11757   unformat_input_t *line_input = vam->input;
11758   vl_api_vxlan_add_del_tunnel_t *mp;
11759   ip46_address_t src, dst;
11760   u8 is_add = 1;
11761   u8 ipv4_set = 0, ipv6_set = 0;
11762   u8 src_set = 0;
11763   u8 dst_set = 0;
11764   u8 grp_set = 0;
11765   u32 instance = ~0;
11766   u32 mcast_sw_if_index = ~0;
11767   u32 encap_vrf_id = 0;
11768   u32 decap_next_index = ~0;
11769   u32 vni = 0;
11770   int ret;
11771
11772   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11773   clib_memset (&src, 0, sizeof src);
11774   clib_memset (&dst, 0, sizeof dst);
11775
11776   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11777     {
11778       if (unformat (line_input, "del"))
11779         is_add = 0;
11780       else if (unformat (line_input, "instance %d", &instance))
11781         ;
11782       else
11783         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11784         {
11785           ipv4_set = 1;
11786           src_set = 1;
11787         }
11788       else
11789         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11790         {
11791           ipv4_set = 1;
11792           dst_set = 1;
11793         }
11794       else
11795         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11796         {
11797           ipv6_set = 1;
11798           src_set = 1;
11799         }
11800       else
11801         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11802         {
11803           ipv6_set = 1;
11804           dst_set = 1;
11805         }
11806       else if (unformat (line_input, "group %U %U",
11807                          unformat_ip4_address, &dst.ip4,
11808                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11809         {
11810           grp_set = dst_set = 1;
11811           ipv4_set = 1;
11812         }
11813       else if (unformat (line_input, "group %U",
11814                          unformat_ip4_address, &dst.ip4))
11815         {
11816           grp_set = dst_set = 1;
11817           ipv4_set = 1;
11818         }
11819       else if (unformat (line_input, "group %U %U",
11820                          unformat_ip6_address, &dst.ip6,
11821                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11822         {
11823           grp_set = dst_set = 1;
11824           ipv6_set = 1;
11825         }
11826       else if (unformat (line_input, "group %U",
11827                          unformat_ip6_address, &dst.ip6))
11828         {
11829           grp_set = dst_set = 1;
11830           ipv6_set = 1;
11831         }
11832       else
11833         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11834         ;
11835       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11836         ;
11837       else if (unformat (line_input, "decap-next %U",
11838                          unformat_vxlan_decap_next, &decap_next_index))
11839         ;
11840       else if (unformat (line_input, "vni %d", &vni))
11841         ;
11842       else
11843         {
11844           errmsg ("parse error '%U'", format_unformat_error, line_input);
11845           return -99;
11846         }
11847     }
11848
11849   if (src_set == 0)
11850     {
11851       errmsg ("tunnel src address not specified");
11852       return -99;
11853     }
11854   if (dst_set == 0)
11855     {
11856       errmsg ("tunnel dst address not specified");
11857       return -99;
11858     }
11859
11860   if (grp_set && !ip46_address_is_multicast (&dst))
11861     {
11862       errmsg ("tunnel group address not multicast");
11863       return -99;
11864     }
11865   if (grp_set && mcast_sw_if_index == ~0)
11866     {
11867       errmsg ("tunnel nonexistent multicast device");
11868       return -99;
11869     }
11870   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11871     {
11872       errmsg ("tunnel dst address must be unicast");
11873       return -99;
11874     }
11875
11876
11877   if (ipv4_set && ipv6_set)
11878     {
11879       errmsg ("both IPv4 and IPv6 addresses specified");
11880       return -99;
11881     }
11882
11883   if ((vni == 0) || (vni >> 24))
11884     {
11885       errmsg ("vni not specified or out of range");
11886       return -99;
11887     }
11888
11889   M (VXLAN_ADD_DEL_TUNNEL, mp);
11890
11891   if (ipv6_set)
11892     {
11893       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11894       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11895     }
11896   else
11897     {
11898       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11899       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11900     }
11901   mp->src_address.af = ipv6_set;
11902   mp->dst_address.af = ipv6_set;
11903
11904   mp->instance = htonl (instance);
11905   mp->encap_vrf_id = ntohl (encap_vrf_id);
11906   mp->decap_next_index = ntohl (decap_next_index);
11907   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11908   mp->vni = ntohl (vni);
11909   mp->is_add = is_add;
11910
11911   S (mp);
11912   W (ret);
11913   return ret;
11914 }
11915
11916 static void vl_api_vxlan_tunnel_details_t_handler
11917   (vl_api_vxlan_tunnel_details_t * mp)
11918 {
11919   vat_main_t *vam = &vat_main;
11920   ip46_address_t src =
11921     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11922   ip46_address_t dst =
11923     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11924
11925   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11926          ntohl (mp->sw_if_index),
11927          ntohl (mp->instance),
11928          format_ip46_address, &src, IP46_TYPE_ANY,
11929          format_ip46_address, &dst, IP46_TYPE_ANY,
11930          ntohl (mp->encap_vrf_id),
11931          ntohl (mp->decap_next_index), ntohl (mp->vni),
11932          ntohl (mp->mcast_sw_if_index));
11933 }
11934
11935 static void vl_api_vxlan_tunnel_details_t_handler_json
11936   (vl_api_vxlan_tunnel_details_t * mp)
11937 {
11938   vat_main_t *vam = &vat_main;
11939   vat_json_node_t *node = NULL;
11940
11941   if (VAT_JSON_ARRAY != vam->json_tree.type)
11942     {
11943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11944       vat_json_init_array (&vam->json_tree);
11945     }
11946   node = vat_json_array_add (&vam->json_tree);
11947
11948   vat_json_init_object (node);
11949   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11950
11951   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11952
11953   if (mp->src_address.af)
11954     {
11955       struct in6_addr ip6;
11956
11957       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11958       vat_json_object_add_ip6 (node, "src_address", ip6);
11959       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11960       vat_json_object_add_ip6 (node, "dst_address", ip6);
11961     }
11962   else
11963     {
11964       struct in_addr ip4;
11965
11966       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11967       vat_json_object_add_ip4 (node, "src_address", ip4);
11968       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11969       vat_json_object_add_ip4 (node, "dst_address", ip4);
11970     }
11971   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11972   vat_json_object_add_uint (node, "decap_next_index",
11973                             ntohl (mp->decap_next_index));
11974   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11975   vat_json_object_add_uint (node, "mcast_sw_if_index",
11976                             ntohl (mp->mcast_sw_if_index));
11977 }
11978
11979 static int
11980 api_vxlan_tunnel_dump (vat_main_t * vam)
11981 {
11982   unformat_input_t *i = vam->input;
11983   vl_api_vxlan_tunnel_dump_t *mp;
11984   vl_api_control_ping_t *mp_ping;
11985   u32 sw_if_index;
11986   u8 sw_if_index_set = 0;
11987   int ret;
11988
11989   /* Parse args required to build the message */
11990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11991     {
11992       if (unformat (i, "sw_if_index %d", &sw_if_index))
11993         sw_if_index_set = 1;
11994       else
11995         break;
11996     }
11997
11998   if (sw_if_index_set == 0)
11999     {
12000       sw_if_index = ~0;
12001     }
12002
12003   if (!vam->json_output)
12004     {
12005       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12006              "sw_if_index", "instance", "src_address", "dst_address",
12007              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12008     }
12009
12010   /* Get list of vxlan-tunnel interfaces */
12011   M (VXLAN_TUNNEL_DUMP, mp);
12012
12013   mp->sw_if_index = htonl (sw_if_index);
12014
12015   S (mp);
12016
12017   /* Use a control ping for synchronization */
12018   MPING (CONTROL_PING, mp_ping);
12019   S (mp_ping);
12020
12021   W (ret);
12022   return ret;
12023 }
12024
12025 static uword unformat_geneve_decap_next
12026   (unformat_input_t * input, va_list * args)
12027 {
12028   u32 *result = va_arg (*args, u32 *);
12029   u32 tmp;
12030
12031   if (unformat (input, "l2"))
12032     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12033   else if (unformat (input, "%d", &tmp))
12034     *result = tmp;
12035   else
12036     return 0;
12037   return 1;
12038 }
12039
12040 static int
12041 api_geneve_add_del_tunnel (vat_main_t * vam)
12042 {
12043   unformat_input_t *line_input = vam->input;
12044   vl_api_geneve_add_del_tunnel_t *mp;
12045   ip46_address_t src, dst;
12046   u8 is_add = 1;
12047   u8 ipv4_set = 0, ipv6_set = 0;
12048   u8 src_set = 0;
12049   u8 dst_set = 0;
12050   u8 grp_set = 0;
12051   u32 mcast_sw_if_index = ~0;
12052   u32 encap_vrf_id = 0;
12053   u32 decap_next_index = ~0;
12054   u32 vni = 0;
12055   int ret;
12056
12057   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12058   clib_memset (&src, 0, sizeof src);
12059   clib_memset (&dst, 0, sizeof dst);
12060
12061   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12062     {
12063       if (unformat (line_input, "del"))
12064         is_add = 0;
12065       else
12066         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12067         {
12068           ipv4_set = 1;
12069           src_set = 1;
12070         }
12071       else
12072         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12073         {
12074           ipv4_set = 1;
12075           dst_set = 1;
12076         }
12077       else
12078         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12079         {
12080           ipv6_set = 1;
12081           src_set = 1;
12082         }
12083       else
12084         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12085         {
12086           ipv6_set = 1;
12087           dst_set = 1;
12088         }
12089       else if (unformat (line_input, "group %U %U",
12090                          unformat_ip4_address, &dst.ip4,
12091                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12092         {
12093           grp_set = dst_set = 1;
12094           ipv4_set = 1;
12095         }
12096       else if (unformat (line_input, "group %U",
12097                          unformat_ip4_address, &dst.ip4))
12098         {
12099           grp_set = dst_set = 1;
12100           ipv4_set = 1;
12101         }
12102       else if (unformat (line_input, "group %U %U",
12103                          unformat_ip6_address, &dst.ip6,
12104                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12105         {
12106           grp_set = dst_set = 1;
12107           ipv6_set = 1;
12108         }
12109       else if (unformat (line_input, "group %U",
12110                          unformat_ip6_address, &dst.ip6))
12111         {
12112           grp_set = dst_set = 1;
12113           ipv6_set = 1;
12114         }
12115       else
12116         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12117         ;
12118       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12119         ;
12120       else if (unformat (line_input, "decap-next %U",
12121                          unformat_geneve_decap_next, &decap_next_index))
12122         ;
12123       else if (unformat (line_input, "vni %d", &vni))
12124         ;
12125       else
12126         {
12127           errmsg ("parse error '%U'", format_unformat_error, line_input);
12128           return -99;
12129         }
12130     }
12131
12132   if (src_set == 0)
12133     {
12134       errmsg ("tunnel src address not specified");
12135       return -99;
12136     }
12137   if (dst_set == 0)
12138     {
12139       errmsg ("tunnel dst address not specified");
12140       return -99;
12141     }
12142
12143   if (grp_set && !ip46_address_is_multicast (&dst))
12144     {
12145       errmsg ("tunnel group address not multicast");
12146       return -99;
12147     }
12148   if (grp_set && mcast_sw_if_index == ~0)
12149     {
12150       errmsg ("tunnel nonexistent multicast device");
12151       return -99;
12152     }
12153   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12154     {
12155       errmsg ("tunnel dst address must be unicast");
12156       return -99;
12157     }
12158
12159
12160   if (ipv4_set && ipv6_set)
12161     {
12162       errmsg ("both IPv4 and IPv6 addresses specified");
12163       return -99;
12164     }
12165
12166   if ((vni == 0) || (vni >> 24))
12167     {
12168       errmsg ("vni not specified or out of range");
12169       return -99;
12170     }
12171
12172   M (GENEVE_ADD_DEL_TUNNEL, mp);
12173
12174   if (ipv6_set)
12175     {
12176       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12177       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12178     }
12179   else
12180     {
12181       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12182       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12183     }
12184   mp->encap_vrf_id = ntohl (encap_vrf_id);
12185   mp->decap_next_index = ntohl (decap_next_index);
12186   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12187   mp->vni = ntohl (vni);
12188   mp->is_add = is_add;
12189
12190   S (mp);
12191   W (ret);
12192   return ret;
12193 }
12194
12195 static void vl_api_geneve_tunnel_details_t_handler
12196   (vl_api_geneve_tunnel_details_t * mp)
12197 {
12198   vat_main_t *vam = &vat_main;
12199   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12200   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12201
12202   if (mp->src_address.af == ADDRESS_IP6)
12203     {
12204       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12205       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12206     }
12207   else
12208     {
12209       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12210       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12211     }
12212
12213   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12214          ntohl (mp->sw_if_index),
12215          format_ip46_address, &src, IP46_TYPE_ANY,
12216          format_ip46_address, &dst, IP46_TYPE_ANY,
12217          ntohl (mp->encap_vrf_id),
12218          ntohl (mp->decap_next_index), ntohl (mp->vni),
12219          ntohl (mp->mcast_sw_if_index));
12220 }
12221
12222 static void vl_api_geneve_tunnel_details_t_handler_json
12223   (vl_api_geneve_tunnel_details_t * mp)
12224 {
12225   vat_main_t *vam = &vat_main;
12226   vat_json_node_t *node = NULL;
12227   bool is_ipv6;
12228
12229   if (VAT_JSON_ARRAY != vam->json_tree.type)
12230     {
12231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12232       vat_json_init_array (&vam->json_tree);
12233     }
12234   node = vat_json_array_add (&vam->json_tree);
12235
12236   vat_json_init_object (node);
12237   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12238   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12239   if (is_ipv6)
12240     {
12241       struct in6_addr ip6;
12242
12243       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12244       vat_json_object_add_ip6 (node, "src_address", ip6);
12245       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12246       vat_json_object_add_ip6 (node, "dst_address", ip6);
12247     }
12248   else
12249     {
12250       struct in_addr ip4;
12251
12252       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12253       vat_json_object_add_ip4 (node, "src_address", ip4);
12254       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12255       vat_json_object_add_ip4 (node, "dst_address", ip4);
12256     }
12257   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12258   vat_json_object_add_uint (node, "decap_next_index",
12259                             ntohl (mp->decap_next_index));
12260   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12261   vat_json_object_add_uint (node, "mcast_sw_if_index",
12262                             ntohl (mp->mcast_sw_if_index));
12263 }
12264
12265 static int
12266 api_geneve_tunnel_dump (vat_main_t * vam)
12267 {
12268   unformat_input_t *i = vam->input;
12269   vl_api_geneve_tunnel_dump_t *mp;
12270   vl_api_control_ping_t *mp_ping;
12271   u32 sw_if_index;
12272   u8 sw_if_index_set = 0;
12273   int ret;
12274
12275   /* Parse args required to build the message */
12276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12277     {
12278       if (unformat (i, "sw_if_index %d", &sw_if_index))
12279         sw_if_index_set = 1;
12280       else
12281         break;
12282     }
12283
12284   if (sw_if_index_set == 0)
12285     {
12286       sw_if_index = ~0;
12287     }
12288
12289   if (!vam->json_output)
12290     {
12291       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12292              "sw_if_index", "local_address", "remote_address",
12293              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12294     }
12295
12296   /* Get list of geneve-tunnel interfaces */
12297   M (GENEVE_TUNNEL_DUMP, mp);
12298
12299   mp->sw_if_index = htonl (sw_if_index);
12300
12301   S (mp);
12302
12303   /* Use a control ping for synchronization */
12304   M (CONTROL_PING, mp_ping);
12305   S (mp_ping);
12306
12307   W (ret);
12308   return ret;
12309 }
12310
12311 static int
12312 api_gre_tunnel_add_del (vat_main_t * vam)
12313 {
12314   unformat_input_t *line_input = vam->input;
12315   vl_api_address_t src = { }, dst =
12316   {
12317   };
12318   vl_api_gre_tunnel_add_del_t *mp;
12319   vl_api_gre_tunnel_type_t t_type;
12320   u8 is_add = 1;
12321   u8 src_set = 0;
12322   u8 dst_set = 0;
12323   u32 outer_table_id = 0;
12324   u32 session_id = 0;
12325   u32 instance = ~0;
12326   int ret;
12327
12328   t_type = GRE_API_TUNNEL_TYPE_L3;
12329
12330   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (line_input, "del"))
12333         is_add = 0;
12334       else if (unformat (line_input, "instance %d", &instance))
12335         ;
12336       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12337         {
12338           src_set = 1;
12339         }
12340       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12341         {
12342           dst_set = 1;
12343         }
12344       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12345         ;
12346       else if (unformat (line_input, "teb"))
12347         t_type = GRE_API_TUNNEL_TYPE_TEB;
12348       else if (unformat (line_input, "erspan %d", &session_id))
12349         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12350       else
12351         {
12352           errmsg ("parse error '%U'", format_unformat_error, line_input);
12353           return -99;
12354         }
12355     }
12356
12357   if (src_set == 0)
12358     {
12359       errmsg ("tunnel src address not specified");
12360       return -99;
12361     }
12362   if (dst_set == 0)
12363     {
12364       errmsg ("tunnel dst address not specified");
12365       return -99;
12366     }
12367
12368   M (GRE_TUNNEL_ADD_DEL, mp);
12369
12370   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12371   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12372
12373   mp->tunnel.instance = htonl (instance);
12374   mp->tunnel.outer_table_id = htonl (outer_table_id);
12375   mp->is_add = is_add;
12376   mp->tunnel.session_id = htons ((u16) session_id);
12377   mp->tunnel.type = htonl (t_type);
12378
12379   S (mp);
12380   W (ret);
12381   return ret;
12382 }
12383
12384 static void vl_api_gre_tunnel_details_t_handler
12385   (vl_api_gre_tunnel_details_t * mp)
12386 {
12387   vat_main_t *vam = &vat_main;
12388
12389   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12390          ntohl (mp->tunnel.sw_if_index),
12391          ntohl (mp->tunnel.instance),
12392          format_vl_api_address, &mp->tunnel.src,
12393          format_vl_api_address, &mp->tunnel.dst,
12394          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12395          ntohl (mp->tunnel.session_id));
12396 }
12397
12398 static void vl_api_gre_tunnel_details_t_handler_json
12399   (vl_api_gre_tunnel_details_t * mp)
12400 {
12401   vat_main_t *vam = &vat_main;
12402   vat_json_node_t *node = NULL;
12403
12404   if (VAT_JSON_ARRAY != vam->json_tree.type)
12405     {
12406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12407       vat_json_init_array (&vam->json_tree);
12408     }
12409   node = vat_json_array_add (&vam->json_tree);
12410
12411   vat_json_init_object (node);
12412   vat_json_object_add_uint (node, "sw_if_index",
12413                             ntohl (mp->tunnel.sw_if_index));
12414   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12415
12416   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12417   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12418   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12419   vat_json_object_add_uint (node, "outer_table_id",
12420                             ntohl (mp->tunnel.outer_table_id));
12421   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12422 }
12423
12424 static int
12425 api_gre_tunnel_dump (vat_main_t * vam)
12426 {
12427   unformat_input_t *i = vam->input;
12428   vl_api_gre_tunnel_dump_t *mp;
12429   vl_api_control_ping_t *mp_ping;
12430   u32 sw_if_index;
12431   u8 sw_if_index_set = 0;
12432   int ret;
12433
12434   /* Parse args required to build the message */
12435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12436     {
12437       if (unformat (i, "sw_if_index %d", &sw_if_index))
12438         sw_if_index_set = 1;
12439       else
12440         break;
12441     }
12442
12443   if (sw_if_index_set == 0)
12444     {
12445       sw_if_index = ~0;
12446     }
12447
12448   if (!vam->json_output)
12449     {
12450       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12451              "sw_if_index", "instance", "src_address", "dst_address",
12452              "tunnel_type", "outer_fib_id", "session_id");
12453     }
12454
12455   /* Get list of gre-tunnel interfaces */
12456   M (GRE_TUNNEL_DUMP, mp);
12457
12458   mp->sw_if_index = htonl (sw_if_index);
12459
12460   S (mp);
12461
12462   /* Use a control ping for synchronization */
12463   MPING (CONTROL_PING, mp_ping);
12464   S (mp_ping);
12465
12466   W (ret);
12467   return ret;
12468 }
12469
12470 static int
12471 api_l2_fib_clear_table (vat_main_t * vam)
12472 {
12473 //  unformat_input_t * i = vam->input;
12474   vl_api_l2_fib_clear_table_t *mp;
12475   int ret;
12476
12477   M (L2_FIB_CLEAR_TABLE, mp);
12478
12479   S (mp);
12480   W (ret);
12481   return ret;
12482 }
12483
12484 static int
12485 api_l2_interface_efp_filter (vat_main_t * vam)
12486 {
12487   unformat_input_t *i = vam->input;
12488   vl_api_l2_interface_efp_filter_t *mp;
12489   u32 sw_if_index;
12490   u8 enable = 1;
12491   u8 sw_if_index_set = 0;
12492   int ret;
12493
12494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12495     {
12496       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12497         sw_if_index_set = 1;
12498       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12499         sw_if_index_set = 1;
12500       else if (unformat (i, "enable"))
12501         enable = 1;
12502       else if (unformat (i, "disable"))
12503         enable = 0;
12504       else
12505         {
12506           clib_warning ("parse error '%U'", format_unformat_error, i);
12507           return -99;
12508         }
12509     }
12510
12511   if (sw_if_index_set == 0)
12512     {
12513       errmsg ("missing sw_if_index");
12514       return -99;
12515     }
12516
12517   M (L2_INTERFACE_EFP_FILTER, mp);
12518
12519   mp->sw_if_index = ntohl (sw_if_index);
12520   mp->enable_disable = enable;
12521
12522   S (mp);
12523   W (ret);
12524   return ret;
12525 }
12526
12527 #define foreach_vtr_op                          \
12528 _("disable",  L2_VTR_DISABLED)                  \
12529 _("push-1",  L2_VTR_PUSH_1)                     \
12530 _("push-2",  L2_VTR_PUSH_2)                     \
12531 _("pop-1",  L2_VTR_POP_1)                       \
12532 _("pop-2",  L2_VTR_POP_2)                       \
12533 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12534 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12535 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12536 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12537
12538 static int
12539 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12540 {
12541   unformat_input_t *i = vam->input;
12542   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12543   u32 sw_if_index;
12544   u8 sw_if_index_set = 0;
12545   u8 vtr_op_set = 0;
12546   u32 vtr_op = 0;
12547   u32 push_dot1q = 1;
12548   u32 tag1 = ~0;
12549   u32 tag2 = ~0;
12550   int ret;
12551
12552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12553     {
12554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12555         sw_if_index_set = 1;
12556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12557         sw_if_index_set = 1;
12558       else if (unformat (i, "vtr_op %d", &vtr_op))
12559         vtr_op_set = 1;
12560 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12561       foreach_vtr_op
12562 #undef _
12563         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12564         ;
12565       else if (unformat (i, "tag1 %d", &tag1))
12566         ;
12567       else if (unformat (i, "tag2 %d", &tag2))
12568         ;
12569       else
12570         {
12571           clib_warning ("parse error '%U'", format_unformat_error, i);
12572           return -99;
12573         }
12574     }
12575
12576   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12577     {
12578       errmsg ("missing vtr operation or sw_if_index");
12579       return -99;
12580     }
12581
12582   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12583   mp->sw_if_index = ntohl (sw_if_index);
12584   mp->vtr_op = ntohl (vtr_op);
12585   mp->push_dot1q = ntohl (push_dot1q);
12586   mp->tag1 = ntohl (tag1);
12587   mp->tag2 = ntohl (tag2);
12588
12589   S (mp);
12590   W (ret);
12591   return ret;
12592 }
12593
12594 static int
12595 api_create_vhost_user_if (vat_main_t * vam)
12596 {
12597   unformat_input_t *i = vam->input;
12598   vl_api_create_vhost_user_if_t *mp;
12599   u8 *file_name;
12600   u8 is_server = 0;
12601   u8 file_name_set = 0;
12602   u32 custom_dev_instance = ~0;
12603   u8 hwaddr[6];
12604   u8 use_custom_mac = 0;
12605   u8 disable_mrg_rxbuf = 0;
12606   u8 disable_indirect_desc = 0;
12607   u8 *tag = 0;
12608   u8 enable_gso = 0;
12609   u8 enable_packed = 0;
12610   int ret;
12611
12612   /* Shut up coverity */
12613   clib_memset (hwaddr, 0, sizeof (hwaddr));
12614
12615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12616     {
12617       if (unformat (i, "socket %s", &file_name))
12618         {
12619           file_name_set = 1;
12620         }
12621       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12622         ;
12623       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12624         use_custom_mac = 1;
12625       else if (unformat (i, "server"))
12626         is_server = 1;
12627       else if (unformat (i, "disable_mrg_rxbuf"))
12628         disable_mrg_rxbuf = 1;
12629       else if (unformat (i, "disable_indirect_desc"))
12630         disable_indirect_desc = 1;
12631       else if (unformat (i, "gso"))
12632         enable_gso = 1;
12633       else if (unformat (i, "packed"))
12634         enable_packed = 1;
12635       else if (unformat (i, "tag %s", &tag))
12636         ;
12637       else
12638         break;
12639     }
12640
12641   if (file_name_set == 0)
12642     {
12643       errmsg ("missing socket file name");
12644       return -99;
12645     }
12646
12647   if (vec_len (file_name) > 255)
12648     {
12649       errmsg ("socket file name too long");
12650       return -99;
12651     }
12652   vec_add1 (file_name, 0);
12653
12654   M (CREATE_VHOST_USER_IF, mp);
12655
12656   mp->is_server = is_server;
12657   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12658   mp->disable_indirect_desc = disable_indirect_desc;
12659   mp->enable_gso = enable_gso;
12660   mp->enable_packed = enable_packed;
12661   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12662   vec_free (file_name);
12663   if (custom_dev_instance != ~0)
12664     {
12665       mp->renumber = 1;
12666       mp->custom_dev_instance = ntohl (custom_dev_instance);
12667     }
12668
12669   mp->use_custom_mac = use_custom_mac;
12670   clib_memcpy (mp->mac_address, hwaddr, 6);
12671   if (tag)
12672     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12673   vec_free (tag);
12674
12675   S (mp);
12676   W (ret);
12677   return ret;
12678 }
12679
12680 static int
12681 api_modify_vhost_user_if (vat_main_t * vam)
12682 {
12683   unformat_input_t *i = vam->input;
12684   vl_api_modify_vhost_user_if_t *mp;
12685   u8 *file_name;
12686   u8 is_server = 0;
12687   u8 file_name_set = 0;
12688   u32 custom_dev_instance = ~0;
12689   u8 sw_if_index_set = 0;
12690   u32 sw_if_index = (u32) ~ 0;
12691   u8 enable_gso = 0;
12692   u8 enable_packed = 0;
12693   int ret;
12694
12695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12696     {
12697       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12698         sw_if_index_set = 1;
12699       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12700         sw_if_index_set = 1;
12701       else if (unformat (i, "socket %s", &file_name))
12702         {
12703           file_name_set = 1;
12704         }
12705       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12706         ;
12707       else if (unformat (i, "server"))
12708         is_server = 1;
12709       else if (unformat (i, "gso"))
12710         enable_gso = 1;
12711       else if (unformat (i, "packed"))
12712         enable_packed = 1;
12713       else
12714         break;
12715     }
12716
12717   if (sw_if_index_set == 0)
12718     {
12719       errmsg ("missing sw_if_index or interface name");
12720       return -99;
12721     }
12722
12723   if (file_name_set == 0)
12724     {
12725       errmsg ("missing socket file name");
12726       return -99;
12727     }
12728
12729   if (vec_len (file_name) > 255)
12730     {
12731       errmsg ("socket file name too long");
12732       return -99;
12733     }
12734   vec_add1 (file_name, 0);
12735
12736   M (MODIFY_VHOST_USER_IF, mp);
12737
12738   mp->sw_if_index = ntohl (sw_if_index);
12739   mp->is_server = is_server;
12740   mp->enable_gso = enable_gso;
12741   mp->enable_packed = enable_packed;
12742   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12743   vec_free (file_name);
12744   if (custom_dev_instance != ~0)
12745     {
12746       mp->renumber = 1;
12747       mp->custom_dev_instance = ntohl (custom_dev_instance);
12748     }
12749
12750   S (mp);
12751   W (ret);
12752   return ret;
12753 }
12754
12755 static int
12756 api_delete_vhost_user_if (vat_main_t * vam)
12757 {
12758   unformat_input_t *i = vam->input;
12759   vl_api_delete_vhost_user_if_t *mp;
12760   u32 sw_if_index = ~0;
12761   u8 sw_if_index_set = 0;
12762   int ret;
12763
12764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12765     {
12766       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12767         sw_if_index_set = 1;
12768       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12769         sw_if_index_set = 1;
12770       else
12771         break;
12772     }
12773
12774   if (sw_if_index_set == 0)
12775     {
12776       errmsg ("missing sw_if_index or interface name");
12777       return -99;
12778     }
12779
12780
12781   M (DELETE_VHOST_USER_IF, mp);
12782
12783   mp->sw_if_index = ntohl (sw_if_index);
12784
12785   S (mp);
12786   W (ret);
12787   return ret;
12788 }
12789
12790 static void vl_api_sw_interface_vhost_user_details_t_handler
12791   (vl_api_sw_interface_vhost_user_details_t * mp)
12792 {
12793   vat_main_t *vam = &vat_main;
12794   u64 features;
12795
12796   features =
12797     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12798                                                     clib_net_to_host_u32
12799                                                     (mp->features_last_32) <<
12800                                                     32);
12801
12802   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12803          (char *) mp->interface_name,
12804          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12805          features, mp->is_server,
12806          ntohl (mp->num_regions), (char *) mp->sock_filename);
12807   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12808 }
12809
12810 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12811   (vl_api_sw_interface_vhost_user_details_t * mp)
12812 {
12813   vat_main_t *vam = &vat_main;
12814   vat_json_node_t *node = NULL;
12815
12816   if (VAT_JSON_ARRAY != vam->json_tree.type)
12817     {
12818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12819       vat_json_init_array (&vam->json_tree);
12820     }
12821   node = vat_json_array_add (&vam->json_tree);
12822
12823   vat_json_init_object (node);
12824   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12825   vat_json_object_add_string_copy (node, "interface_name",
12826                                    mp->interface_name);
12827   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12828                             ntohl (mp->virtio_net_hdr_sz));
12829   vat_json_object_add_uint (node, "features_first_32",
12830                             clib_net_to_host_u32 (mp->features_first_32));
12831   vat_json_object_add_uint (node, "features_last_32",
12832                             clib_net_to_host_u32 (mp->features_last_32));
12833   vat_json_object_add_uint (node, "is_server", mp->is_server);
12834   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12835   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12836   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12837 }
12838
12839 static int
12840 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12841 {
12842   unformat_input_t *i = vam->input;
12843   vl_api_sw_interface_vhost_user_dump_t *mp;
12844   vl_api_control_ping_t *mp_ping;
12845   int ret;
12846   u32 sw_if_index = ~0;
12847
12848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12849     {
12850       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12851         ;
12852       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12853         ;
12854       else
12855         break;
12856     }
12857
12858   print (vam->ofp,
12859          "Interface name            idx hdr_sz features server regions filename");
12860
12861   /* Get list of vhost-user interfaces */
12862   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12863   mp->sw_if_index = ntohl (sw_if_index);
12864   S (mp);
12865
12866   /* Use a control ping for synchronization */
12867   MPING (CONTROL_PING, mp_ping);
12868   S (mp_ping);
12869
12870   W (ret);
12871   return ret;
12872 }
12873
12874 static int
12875 api_show_version (vat_main_t * vam)
12876 {
12877   vl_api_show_version_t *mp;
12878   int ret;
12879
12880   M (SHOW_VERSION, mp);
12881
12882   S (mp);
12883   W (ret);
12884   return ret;
12885 }
12886
12887
12888 static int
12889 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12890 {
12891   unformat_input_t *line_input = vam->input;
12892   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12893   ip46_address_t local, remote;
12894   u8 is_add = 1;
12895   u8 local_set = 0;
12896   u8 remote_set = 0;
12897   u8 grp_set = 0;
12898   u32 mcast_sw_if_index = ~0;
12899   u32 encap_vrf_id = 0;
12900   u32 decap_vrf_id = 0;
12901   u8 protocol = ~0;
12902   u32 vni;
12903   u8 vni_set = 0;
12904   int ret;
12905
12906   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12907     {
12908       if (unformat (line_input, "del"))
12909         is_add = 0;
12910       else if (unformat (line_input, "local %U",
12911                          unformat_ip46_address, &local))
12912         {
12913           local_set = 1;
12914         }
12915       else if (unformat (line_input, "remote %U",
12916                          unformat_ip46_address, &remote))
12917         {
12918           remote_set = 1;
12919         }
12920       else if (unformat (line_input, "group %U %U",
12921                          unformat_ip46_address, &remote,
12922                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12923         {
12924           grp_set = remote_set = 1;
12925         }
12926       else if (unformat (line_input, "group %U",
12927                          unformat_ip46_address, &remote))
12928         {
12929           grp_set = remote_set = 1;
12930         }
12931       else
12932         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12933         ;
12934       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12935         ;
12936       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12937         ;
12938       else if (unformat (line_input, "vni %d", &vni))
12939         vni_set = 1;
12940       else if (unformat (line_input, "next-ip4"))
12941         protocol = 1;
12942       else if (unformat (line_input, "next-ip6"))
12943         protocol = 2;
12944       else if (unformat (line_input, "next-ethernet"))
12945         protocol = 3;
12946       else if (unformat (line_input, "next-nsh"))
12947         protocol = 4;
12948       else
12949         {
12950           errmsg ("parse error '%U'", format_unformat_error, line_input);
12951           return -99;
12952         }
12953     }
12954
12955   if (local_set == 0)
12956     {
12957       errmsg ("tunnel local address not specified");
12958       return -99;
12959     }
12960   if (remote_set == 0)
12961     {
12962       errmsg ("tunnel remote address not specified");
12963       return -99;
12964     }
12965   if (grp_set && mcast_sw_if_index == ~0)
12966     {
12967       errmsg ("tunnel nonexistent multicast device");
12968       return -99;
12969     }
12970   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12971     {
12972       errmsg ("both IPv4 and IPv6 addresses specified");
12973       return -99;
12974     }
12975
12976   if (vni_set == 0)
12977     {
12978       errmsg ("vni not specified");
12979       return -99;
12980     }
12981
12982   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12983
12984   ip_address_encode (&local,
12985                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12986                      IP46_TYPE_IP6, &mp->local);
12987   ip_address_encode (&remote,
12988                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12989                      IP46_TYPE_IP6, &mp->remote);
12990
12991   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12992   mp->encap_vrf_id = ntohl (encap_vrf_id);
12993   mp->decap_vrf_id = ntohl (decap_vrf_id);
12994   mp->protocol = protocol;
12995   mp->vni = ntohl (vni);
12996   mp->is_add = is_add;
12997
12998   S (mp);
12999   W (ret);
13000   return ret;
13001 }
13002
13003 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13004   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13005 {
13006   vat_main_t *vam = &vat_main;
13007   ip46_address_t local, remote;
13008
13009   ip_address_decode (&mp->local, &local);
13010   ip_address_decode (&mp->remote, &remote);
13011
13012   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13013          ntohl (mp->sw_if_index),
13014          format_ip46_address, &local, IP46_TYPE_ANY,
13015          format_ip46_address, &remote, IP46_TYPE_ANY,
13016          ntohl (mp->vni), mp->protocol,
13017          ntohl (mp->mcast_sw_if_index),
13018          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13019 }
13020
13021
13022 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13023   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13024 {
13025   vat_main_t *vam = &vat_main;
13026   vat_json_node_t *node = NULL;
13027   struct in_addr ip4;
13028   struct in6_addr ip6;
13029   ip46_address_t local, remote;
13030
13031   ip_address_decode (&mp->local, &local);
13032   ip_address_decode (&mp->remote, &remote);
13033
13034   if (VAT_JSON_ARRAY != vam->json_tree.type)
13035     {
13036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13037       vat_json_init_array (&vam->json_tree);
13038     }
13039   node = vat_json_array_add (&vam->json_tree);
13040
13041   vat_json_init_object (node);
13042   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13043   if (ip46_address_is_ip4 (&local))
13044     {
13045       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
13046       vat_json_object_add_ip4 (node, "local", ip4);
13047       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
13048       vat_json_object_add_ip4 (node, "remote", ip4);
13049     }
13050   else
13051     {
13052       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
13053       vat_json_object_add_ip6 (node, "local", ip6);
13054       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
13055       vat_json_object_add_ip6 (node, "remote", ip6);
13056     }
13057   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13058   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13059   vat_json_object_add_uint (node, "mcast_sw_if_index",
13060                             ntohl (mp->mcast_sw_if_index));
13061   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13062   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13063   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13064 }
13065
13066 static int
13067 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13068 {
13069   unformat_input_t *i = vam->input;
13070   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13071   vl_api_control_ping_t *mp_ping;
13072   u32 sw_if_index;
13073   u8 sw_if_index_set = 0;
13074   int ret;
13075
13076   /* Parse args required to build the message */
13077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13078     {
13079       if (unformat (i, "sw_if_index %d", &sw_if_index))
13080         sw_if_index_set = 1;
13081       else
13082         break;
13083     }
13084
13085   if (sw_if_index_set == 0)
13086     {
13087       sw_if_index = ~0;
13088     }
13089
13090   if (!vam->json_output)
13091     {
13092       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13093              "sw_if_index", "local", "remote", "vni",
13094              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13095     }
13096
13097   /* Get list of vxlan-tunnel interfaces */
13098   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13099
13100   mp->sw_if_index = htonl (sw_if_index);
13101
13102   S (mp);
13103
13104   /* Use a control ping for synchronization */
13105   MPING (CONTROL_PING, mp_ping);
13106   S (mp_ping);
13107
13108   W (ret);
13109   return ret;
13110 }
13111
13112 static void vl_api_l2_fib_table_details_t_handler
13113   (vl_api_l2_fib_table_details_t * mp)
13114 {
13115   vat_main_t *vam = &vat_main;
13116
13117   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13118          "       %d       %d     %d",
13119          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13120          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13121          mp->bvi_mac);
13122 }
13123
13124 static void vl_api_l2_fib_table_details_t_handler_json
13125   (vl_api_l2_fib_table_details_t * mp)
13126 {
13127   vat_main_t *vam = &vat_main;
13128   vat_json_node_t *node = NULL;
13129
13130   if (VAT_JSON_ARRAY != vam->json_tree.type)
13131     {
13132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13133       vat_json_init_array (&vam->json_tree);
13134     }
13135   node = vat_json_array_add (&vam->json_tree);
13136
13137   vat_json_init_object (node);
13138   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13139   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13140   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13141   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13142   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13143   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13144 }
13145
13146 static int
13147 api_l2_fib_table_dump (vat_main_t * vam)
13148 {
13149   unformat_input_t *i = vam->input;
13150   vl_api_l2_fib_table_dump_t *mp;
13151   vl_api_control_ping_t *mp_ping;
13152   u32 bd_id;
13153   u8 bd_id_set = 0;
13154   int ret;
13155
13156   /* Parse args required to build the message */
13157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13158     {
13159       if (unformat (i, "bd_id %d", &bd_id))
13160         bd_id_set = 1;
13161       else
13162         break;
13163     }
13164
13165   if (bd_id_set == 0)
13166     {
13167       errmsg ("missing bridge domain");
13168       return -99;
13169     }
13170
13171   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13172
13173   /* Get list of l2 fib entries */
13174   M (L2_FIB_TABLE_DUMP, mp);
13175
13176   mp->bd_id = ntohl (bd_id);
13177   S (mp);
13178
13179   /* Use a control ping for synchronization */
13180   MPING (CONTROL_PING, mp_ping);
13181   S (mp_ping);
13182
13183   W (ret);
13184   return ret;
13185 }
13186
13187
13188 static int
13189 api_interface_name_renumber (vat_main_t * vam)
13190 {
13191   unformat_input_t *line_input = vam->input;
13192   vl_api_interface_name_renumber_t *mp;
13193   u32 sw_if_index = ~0;
13194   u32 new_show_dev_instance = ~0;
13195   int ret;
13196
13197   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13198     {
13199       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13200                     &sw_if_index))
13201         ;
13202       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13203         ;
13204       else if (unformat (line_input, "new_show_dev_instance %d",
13205                          &new_show_dev_instance))
13206         ;
13207       else
13208         break;
13209     }
13210
13211   if (sw_if_index == ~0)
13212     {
13213       errmsg ("missing interface name or sw_if_index");
13214       return -99;
13215     }
13216
13217   if (new_show_dev_instance == ~0)
13218     {
13219       errmsg ("missing new_show_dev_instance");
13220       return -99;
13221     }
13222
13223   M (INTERFACE_NAME_RENUMBER, mp);
13224
13225   mp->sw_if_index = ntohl (sw_if_index);
13226   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13227
13228   S (mp);
13229   W (ret);
13230   return ret;
13231 }
13232
13233 static int
13234 api_want_l2_macs_events (vat_main_t * vam)
13235 {
13236   unformat_input_t *line_input = vam->input;
13237   vl_api_want_l2_macs_events_t *mp;
13238   u8 enable_disable = 1;
13239   u32 scan_delay = 0;
13240   u32 max_macs_in_event = 0;
13241   u32 learn_limit = 0;
13242   int ret;
13243
13244   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13245     {
13246       if (unformat (line_input, "learn-limit %d", &learn_limit))
13247         ;
13248       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13249         ;
13250       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13251         ;
13252       else if (unformat (line_input, "disable"))
13253         enable_disable = 0;
13254       else
13255         break;
13256     }
13257
13258   M (WANT_L2_MACS_EVENTS, mp);
13259   mp->enable_disable = enable_disable;
13260   mp->pid = htonl (getpid ());
13261   mp->learn_limit = htonl (learn_limit);
13262   mp->scan_delay = (u8) scan_delay;
13263   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13264   S (mp);
13265   W (ret);
13266   return ret;
13267 }
13268
13269 static int
13270 api_input_acl_set_interface (vat_main_t * vam)
13271 {
13272   unformat_input_t *i = vam->input;
13273   vl_api_input_acl_set_interface_t *mp;
13274   u32 sw_if_index;
13275   int sw_if_index_set;
13276   u32 ip4_table_index = ~0;
13277   u32 ip6_table_index = ~0;
13278   u32 l2_table_index = ~0;
13279   u8 is_add = 1;
13280   int ret;
13281
13282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13283     {
13284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13285         sw_if_index_set = 1;
13286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13287         sw_if_index_set = 1;
13288       else if (unformat (i, "del"))
13289         is_add = 0;
13290       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13291         ;
13292       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13293         ;
13294       else if (unformat (i, "l2-table %d", &l2_table_index))
13295         ;
13296       else
13297         {
13298           clib_warning ("parse error '%U'", format_unformat_error, i);
13299           return -99;
13300         }
13301     }
13302
13303   if (sw_if_index_set == 0)
13304     {
13305       errmsg ("missing interface name or sw_if_index");
13306       return -99;
13307     }
13308
13309   M (INPUT_ACL_SET_INTERFACE, mp);
13310
13311   mp->sw_if_index = ntohl (sw_if_index);
13312   mp->ip4_table_index = ntohl (ip4_table_index);
13313   mp->ip6_table_index = ntohl (ip6_table_index);
13314   mp->l2_table_index = ntohl (l2_table_index);
13315   mp->is_add = is_add;
13316
13317   S (mp);
13318   W (ret);
13319   return ret;
13320 }
13321
13322 static int
13323 api_output_acl_set_interface (vat_main_t * vam)
13324 {
13325   unformat_input_t *i = vam->input;
13326   vl_api_output_acl_set_interface_t *mp;
13327   u32 sw_if_index;
13328   int sw_if_index_set;
13329   u32 ip4_table_index = ~0;
13330   u32 ip6_table_index = ~0;
13331   u32 l2_table_index = ~0;
13332   u8 is_add = 1;
13333   int ret;
13334
13335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13336     {
13337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13338         sw_if_index_set = 1;
13339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13340         sw_if_index_set = 1;
13341       else if (unformat (i, "del"))
13342         is_add = 0;
13343       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13344         ;
13345       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13346         ;
13347       else if (unformat (i, "l2-table %d", &l2_table_index))
13348         ;
13349       else
13350         {
13351           clib_warning ("parse error '%U'", format_unformat_error, i);
13352           return -99;
13353         }
13354     }
13355
13356   if (sw_if_index_set == 0)
13357     {
13358       errmsg ("missing interface name or sw_if_index");
13359       return -99;
13360     }
13361
13362   M (OUTPUT_ACL_SET_INTERFACE, mp);
13363
13364   mp->sw_if_index = ntohl (sw_if_index);
13365   mp->ip4_table_index = ntohl (ip4_table_index);
13366   mp->ip6_table_index = ntohl (ip6_table_index);
13367   mp->l2_table_index = ntohl (l2_table_index);
13368   mp->is_add = is_add;
13369
13370   S (mp);
13371   W (ret);
13372   return ret;
13373 }
13374
13375 static int
13376 api_ip_address_dump (vat_main_t * vam)
13377 {
13378   unformat_input_t *i = vam->input;
13379   vl_api_ip_address_dump_t *mp;
13380   vl_api_control_ping_t *mp_ping;
13381   u32 sw_if_index = ~0;
13382   u8 sw_if_index_set = 0;
13383   u8 ipv4_set = 0;
13384   u8 ipv6_set = 0;
13385   int ret;
13386
13387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13388     {
13389       if (unformat (i, "sw_if_index %d", &sw_if_index))
13390         sw_if_index_set = 1;
13391       else
13392         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13393         sw_if_index_set = 1;
13394       else if (unformat (i, "ipv4"))
13395         ipv4_set = 1;
13396       else if (unformat (i, "ipv6"))
13397         ipv6_set = 1;
13398       else
13399         break;
13400     }
13401
13402   if (ipv4_set && ipv6_set)
13403     {
13404       errmsg ("ipv4 and ipv6 flags cannot be both set");
13405       return -99;
13406     }
13407
13408   if ((!ipv4_set) && (!ipv6_set))
13409     {
13410       errmsg ("no ipv4 nor ipv6 flag set");
13411       return -99;
13412     }
13413
13414   if (sw_if_index_set == 0)
13415     {
13416       errmsg ("missing interface name or sw_if_index");
13417       return -99;
13418     }
13419
13420   vam->current_sw_if_index = sw_if_index;
13421   vam->is_ipv6 = ipv6_set;
13422
13423   M (IP_ADDRESS_DUMP, mp);
13424   mp->sw_if_index = ntohl (sw_if_index);
13425   mp->is_ipv6 = ipv6_set;
13426   S (mp);
13427
13428   /* Use a control ping for synchronization */
13429   MPING (CONTROL_PING, mp_ping);
13430   S (mp_ping);
13431
13432   W (ret);
13433   return ret;
13434 }
13435
13436 static int
13437 api_ip_dump (vat_main_t * vam)
13438 {
13439   vl_api_ip_dump_t *mp;
13440   vl_api_control_ping_t *mp_ping;
13441   unformat_input_t *in = vam->input;
13442   int ipv4_set = 0;
13443   int ipv6_set = 0;
13444   int is_ipv6;
13445   int i;
13446   int ret;
13447
13448   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13449     {
13450       if (unformat (in, "ipv4"))
13451         ipv4_set = 1;
13452       else if (unformat (in, "ipv6"))
13453         ipv6_set = 1;
13454       else
13455         break;
13456     }
13457
13458   if (ipv4_set && ipv6_set)
13459     {
13460       errmsg ("ipv4 and ipv6 flags cannot be both set");
13461       return -99;
13462     }
13463
13464   if ((!ipv4_set) && (!ipv6_set))
13465     {
13466       errmsg ("no ipv4 nor ipv6 flag set");
13467       return -99;
13468     }
13469
13470   is_ipv6 = ipv6_set;
13471   vam->is_ipv6 = is_ipv6;
13472
13473   /* free old data */
13474   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13475     {
13476       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13477     }
13478   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13479
13480   M (IP_DUMP, mp);
13481   mp->is_ipv6 = ipv6_set;
13482   S (mp);
13483
13484   /* Use a control ping for synchronization */
13485   MPING (CONTROL_PING, mp_ping);
13486   S (mp_ping);
13487
13488   W (ret);
13489   return ret;
13490 }
13491
13492 static int
13493 api_ipsec_spd_add_del (vat_main_t * vam)
13494 {
13495   unformat_input_t *i = vam->input;
13496   vl_api_ipsec_spd_add_del_t *mp;
13497   u32 spd_id = ~0;
13498   u8 is_add = 1;
13499   int ret;
13500
13501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13502     {
13503       if (unformat (i, "spd_id %d", &spd_id))
13504         ;
13505       else if (unformat (i, "del"))
13506         is_add = 0;
13507       else
13508         {
13509           clib_warning ("parse error '%U'", format_unformat_error, i);
13510           return -99;
13511         }
13512     }
13513   if (spd_id == ~0)
13514     {
13515       errmsg ("spd_id must be set");
13516       return -99;
13517     }
13518
13519   M (IPSEC_SPD_ADD_DEL, mp);
13520
13521   mp->spd_id = ntohl (spd_id);
13522   mp->is_add = is_add;
13523
13524   S (mp);
13525   W (ret);
13526   return ret;
13527 }
13528
13529 static int
13530 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13531 {
13532   unformat_input_t *i = vam->input;
13533   vl_api_ipsec_interface_add_del_spd_t *mp;
13534   u32 sw_if_index;
13535   u8 sw_if_index_set = 0;
13536   u32 spd_id = (u32) ~ 0;
13537   u8 is_add = 1;
13538   int ret;
13539
13540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13541     {
13542       if (unformat (i, "del"))
13543         is_add = 0;
13544       else if (unformat (i, "spd_id %d", &spd_id))
13545         ;
13546       else
13547         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13548         sw_if_index_set = 1;
13549       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13550         sw_if_index_set = 1;
13551       else
13552         {
13553           clib_warning ("parse error '%U'", format_unformat_error, i);
13554           return -99;
13555         }
13556
13557     }
13558
13559   if (spd_id == (u32) ~ 0)
13560     {
13561       errmsg ("spd_id must be set");
13562       return -99;
13563     }
13564
13565   if (sw_if_index_set == 0)
13566     {
13567       errmsg ("missing interface name or sw_if_index");
13568       return -99;
13569     }
13570
13571   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13572
13573   mp->spd_id = ntohl (spd_id);
13574   mp->sw_if_index = ntohl (sw_if_index);
13575   mp->is_add = is_add;
13576
13577   S (mp);
13578   W (ret);
13579   return ret;
13580 }
13581
13582 static int
13583 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13584 {
13585   unformat_input_t *i = vam->input;
13586   vl_api_ipsec_spd_entry_add_del_t *mp;
13587   u8 is_add = 1, is_outbound = 0;
13588   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13589   i32 priority = 0;
13590   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13591   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13592   vl_api_address_t laddr_start = { }, laddr_stop =
13593   {
13594   }, raddr_start =
13595   {
13596   }, raddr_stop =
13597   {
13598   };
13599   int ret;
13600
13601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13602     {
13603       if (unformat (i, "del"))
13604         is_add = 0;
13605       if (unformat (i, "outbound"))
13606         is_outbound = 1;
13607       if (unformat (i, "inbound"))
13608         is_outbound = 0;
13609       else if (unformat (i, "spd_id %d", &spd_id))
13610         ;
13611       else if (unformat (i, "sa_id %d", &sa_id))
13612         ;
13613       else if (unformat (i, "priority %d", &priority))
13614         ;
13615       else if (unformat (i, "protocol %d", &protocol))
13616         ;
13617       else if (unformat (i, "lport_start %d", &lport_start))
13618         ;
13619       else if (unformat (i, "lport_stop %d", &lport_stop))
13620         ;
13621       else if (unformat (i, "rport_start %d", &rport_start))
13622         ;
13623       else if (unformat (i, "rport_stop %d", &rport_stop))
13624         ;
13625       else if (unformat (i, "laddr_start %U",
13626                          unformat_vl_api_address, &laddr_start))
13627         ;
13628       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13629                          &laddr_stop))
13630         ;
13631       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13632                          &raddr_start))
13633         ;
13634       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13635                          &raddr_stop))
13636         ;
13637       else
13638         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13639         {
13640           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13641             {
13642               clib_warning ("unsupported action: 'resolve'");
13643               return -99;
13644             }
13645         }
13646       else
13647         {
13648           clib_warning ("parse error '%U'", format_unformat_error, i);
13649           return -99;
13650         }
13651
13652     }
13653
13654   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13655
13656   mp->is_add = is_add;
13657
13658   mp->entry.spd_id = ntohl (spd_id);
13659   mp->entry.priority = ntohl (priority);
13660   mp->entry.is_outbound = is_outbound;
13661
13662   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13663                sizeof (vl_api_address_t));
13664   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13665                sizeof (vl_api_address_t));
13666   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13667                sizeof (vl_api_address_t));
13668   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13669                sizeof (vl_api_address_t));
13670
13671   mp->entry.protocol = (u8) protocol;
13672   mp->entry.local_port_start = ntohs ((u16) lport_start);
13673   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13674   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13675   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13676   mp->entry.policy = (u8) policy;
13677   mp->entry.sa_id = ntohl (sa_id);
13678
13679   S (mp);
13680   W (ret);
13681   return ret;
13682 }
13683
13684 static int
13685 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13686 {
13687   unformat_input_t *i = vam->input;
13688   vl_api_ipsec_sad_entry_add_del_t *mp;
13689   u32 sad_id = 0, spi = 0;
13690   u8 *ck = 0, *ik = 0;
13691   u8 is_add = 1;
13692
13693   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13694   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13695   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13696   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13697   vl_api_address_t tun_src, tun_dst;
13698   int ret;
13699
13700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13701     {
13702       if (unformat (i, "del"))
13703         is_add = 0;
13704       else if (unformat (i, "sad_id %d", &sad_id))
13705         ;
13706       else if (unformat (i, "spi %d", &spi))
13707         ;
13708       else if (unformat (i, "esp"))
13709         protocol = IPSEC_API_PROTO_ESP;
13710       else
13711         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13712         {
13713           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13714           if (ADDRESS_IP6 == tun_src.af)
13715             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13716         }
13717       else
13718         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13719         {
13720           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13721           if (ADDRESS_IP6 == tun_src.af)
13722             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13723         }
13724       else
13725         if (unformat (i, "crypto_alg %U",
13726                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13727         ;
13728       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13729         ;
13730       else if (unformat (i, "integ_alg %U",
13731                          unformat_ipsec_api_integ_alg, &integ_alg))
13732         ;
13733       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13734         ;
13735       else
13736         {
13737           clib_warning ("parse error '%U'", format_unformat_error, i);
13738           return -99;
13739         }
13740
13741     }
13742
13743   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13744
13745   mp->is_add = is_add;
13746   mp->entry.sad_id = ntohl (sad_id);
13747   mp->entry.protocol = protocol;
13748   mp->entry.spi = ntohl (spi);
13749   mp->entry.flags = flags;
13750
13751   mp->entry.crypto_algorithm = crypto_alg;
13752   mp->entry.integrity_algorithm = integ_alg;
13753   mp->entry.crypto_key.length = vec_len (ck);
13754   mp->entry.integrity_key.length = vec_len (ik);
13755
13756   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13757     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13758
13759   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13760     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13761
13762   if (ck)
13763     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13764   if (ik)
13765     clib_memcpy (mp->entry.integrity_key.data, ik,
13766                  mp->entry.integrity_key.length);
13767
13768   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13769     {
13770       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13771                    sizeof (mp->entry.tunnel_src));
13772       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13773                    sizeof (mp->entry.tunnel_dst));
13774     }
13775
13776   S (mp);
13777   W (ret);
13778   return ret;
13779 }
13780
13781 static int
13782 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13783 {
13784   unformat_input_t *i = vam->input;
13785   vl_api_ipsec_tunnel_if_add_del_t *mp;
13786   u32 local_spi = 0, remote_spi = 0;
13787   u32 crypto_alg = 0, integ_alg = 0;
13788   u8 *lck = NULL, *rck = NULL;
13789   u8 *lik = NULL, *rik = NULL;
13790   vl_api_address_t local_ip = { 0 };
13791   vl_api_address_t remote_ip = { 0 };
13792   f64 before = 0;
13793   u8 is_add = 1;
13794   u8 esn = 0;
13795   u8 anti_replay = 0;
13796   u8 renumber = 0;
13797   u32 instance = ~0;
13798   u32 count = 1, jj;
13799   int ret = -1;
13800
13801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13802     {
13803       if (unformat (i, "del"))
13804         is_add = 0;
13805       else if (unformat (i, "esn"))
13806         esn = 1;
13807       else if (unformat (i, "anti-replay"))
13808         anti_replay = 1;
13809       else if (unformat (i, "count %d", &count))
13810         ;
13811       else if (unformat (i, "local_spi %d", &local_spi))
13812         ;
13813       else if (unformat (i, "remote_spi %d", &remote_spi))
13814         ;
13815       else
13816         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13817         ;
13818       else
13819         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13820         ;
13821       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13822         ;
13823       else
13824         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13825         ;
13826       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13827         ;
13828       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13829         ;
13830       else
13831         if (unformat
13832             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13833         {
13834           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13835             {
13836               errmsg ("unsupported crypto-alg: '%U'\n",
13837                       format_ipsec_crypto_alg, crypto_alg);
13838               return -99;
13839             }
13840         }
13841       else
13842         if (unformat
13843             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13844         {
13845           if (integ_alg >= IPSEC_INTEG_N_ALG)
13846             {
13847               errmsg ("unsupported integ-alg: '%U'\n",
13848                       format_ipsec_integ_alg, integ_alg);
13849               return -99;
13850             }
13851         }
13852       else if (unformat (i, "instance %u", &instance))
13853         renumber = 1;
13854       else
13855         {
13856           errmsg ("parse error '%U'\n", format_unformat_error, i);
13857           return -99;
13858         }
13859     }
13860
13861   if (count > 1)
13862     {
13863       /* Turn on async mode */
13864       vam->async_mode = 1;
13865       vam->async_errors = 0;
13866       before = vat_time_now (vam);
13867     }
13868
13869   for (jj = 0; jj < count; jj++)
13870     {
13871       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13872
13873       mp->is_add = is_add;
13874       mp->esn = esn;
13875       mp->anti_replay = anti_replay;
13876
13877       if (jj > 0)
13878         increment_address (&remote_ip);
13879
13880       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13881       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13882
13883       mp->local_spi = htonl (local_spi + jj);
13884       mp->remote_spi = htonl (remote_spi + jj);
13885       mp->crypto_alg = (u8) crypto_alg;
13886
13887       mp->local_crypto_key_len = 0;
13888       if (lck)
13889         {
13890           mp->local_crypto_key_len = vec_len (lck);
13891           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13892             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13893           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13894         }
13895
13896       mp->remote_crypto_key_len = 0;
13897       if (rck)
13898         {
13899           mp->remote_crypto_key_len = vec_len (rck);
13900           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13901             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13902           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13903         }
13904
13905       mp->integ_alg = (u8) integ_alg;
13906
13907       mp->local_integ_key_len = 0;
13908       if (lik)
13909         {
13910           mp->local_integ_key_len = vec_len (lik);
13911           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13912             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13913           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13914         }
13915
13916       mp->remote_integ_key_len = 0;
13917       if (rik)
13918         {
13919           mp->remote_integ_key_len = vec_len (rik);
13920           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13921             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13922           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13923         }
13924
13925       if (renumber)
13926         {
13927           mp->renumber = renumber;
13928           mp->show_instance = ntohl (instance);
13929         }
13930       S (mp);
13931     }
13932
13933   /* When testing multiple add/del ops, use a control-ping to sync */
13934   if (count > 1)
13935     {
13936       vl_api_control_ping_t *mp_ping;
13937       f64 after;
13938       f64 timeout;
13939
13940       /* Shut off async mode */
13941       vam->async_mode = 0;
13942
13943       MPING (CONTROL_PING, mp_ping);
13944       S (mp_ping);
13945
13946       timeout = vat_time_now (vam) + 1.0;
13947       while (vat_time_now (vam) < timeout)
13948         if (vam->result_ready == 1)
13949           goto out;
13950       vam->retval = -99;
13951
13952     out:
13953       if (vam->retval == -99)
13954         errmsg ("timeout");
13955
13956       if (vam->async_errors > 0)
13957         {
13958           errmsg ("%d asynchronous errors", vam->async_errors);
13959           vam->retval = -98;
13960         }
13961       vam->async_errors = 0;
13962       after = vat_time_now (vam);
13963
13964       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13965       if (jj > 0)
13966         count = jj;
13967
13968       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13969              count, after - before, count / (after - before));
13970     }
13971   else
13972     {
13973       /* Wait for a reply... */
13974       W (ret);
13975       return ret;
13976     }
13977
13978   return ret;
13979 }
13980
13981 static void
13982 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13983 {
13984   vat_main_t *vam = &vat_main;
13985
13986   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13987          "crypto_key %U integ_alg %u integ_key %U flags %x "
13988          "tunnel_src_addr %U tunnel_dst_addr %U "
13989          "salt %u seq_outbound %lu last_seq_inbound %lu "
13990          "replay_window %lu stat_index %u\n",
13991          ntohl (mp->entry.sad_id),
13992          ntohl (mp->sw_if_index),
13993          ntohl (mp->entry.spi),
13994          ntohl (mp->entry.protocol),
13995          ntohl (mp->entry.crypto_algorithm),
13996          format_hex_bytes, mp->entry.crypto_key.data,
13997          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13998          format_hex_bytes, mp->entry.integrity_key.data,
13999          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14000          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14001          &mp->entry.tunnel_dst, ntohl (mp->salt),
14002          clib_net_to_host_u64 (mp->seq_outbound),
14003          clib_net_to_host_u64 (mp->last_seq_inbound),
14004          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
14005 }
14006
14007 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14008 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14009
14010 static void vl_api_ipsec_sa_details_t_handler_json
14011   (vl_api_ipsec_sa_details_t * mp)
14012 {
14013   vat_main_t *vam = &vat_main;
14014   vat_json_node_t *node = NULL;
14015   vl_api_ipsec_sad_flags_t flags;
14016
14017   if (VAT_JSON_ARRAY != vam->json_tree.type)
14018     {
14019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14020       vat_json_init_array (&vam->json_tree);
14021     }
14022   node = vat_json_array_add (&vam->json_tree);
14023
14024   vat_json_init_object (node);
14025   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14026   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14027   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14028   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14029   vat_json_object_add_uint (node, "crypto_alg",
14030                             ntohl (mp->entry.crypto_algorithm));
14031   vat_json_object_add_uint (node, "integ_alg",
14032                             ntohl (mp->entry.integrity_algorithm));
14033   flags = ntohl (mp->entry.flags);
14034   vat_json_object_add_uint (node, "use_esn",
14035                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14036   vat_json_object_add_uint (node, "use_anti_replay",
14037                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14038   vat_json_object_add_uint (node, "is_tunnel",
14039                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14040   vat_json_object_add_uint (node, "is_tunnel_ip6",
14041                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14042   vat_json_object_add_uint (node, "udp_encap",
14043                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14044   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14045                              mp->entry.crypto_key.length);
14046   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14047                              mp->entry.integrity_key.length);
14048   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14049   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14050   vat_json_object_add_uint (node, "replay_window",
14051                             clib_net_to_host_u64 (mp->replay_window));
14052   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
14053 }
14054
14055 static int
14056 api_ipsec_sa_dump (vat_main_t * vam)
14057 {
14058   unformat_input_t *i = vam->input;
14059   vl_api_ipsec_sa_dump_t *mp;
14060   vl_api_control_ping_t *mp_ping;
14061   u32 sa_id = ~0;
14062   int ret;
14063
14064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14065     {
14066       if (unformat (i, "sa_id %d", &sa_id))
14067         ;
14068       else
14069         {
14070           clib_warning ("parse error '%U'", format_unformat_error, i);
14071           return -99;
14072         }
14073     }
14074
14075   M (IPSEC_SA_DUMP, mp);
14076
14077   mp->sa_id = ntohl (sa_id);
14078
14079   S (mp);
14080
14081   /* Use a control ping for synchronization */
14082   M (CONTROL_PING, mp_ping);
14083   S (mp_ping);
14084
14085   W (ret);
14086   return ret;
14087 }
14088
14089 static int
14090 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14091 {
14092   unformat_input_t *i = vam->input;
14093   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14094   u32 sw_if_index = ~0;
14095   u32 sa_id = ~0;
14096   u8 is_outbound = (u8) ~ 0;
14097   int ret;
14098
14099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14100     {
14101       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14102         ;
14103       else if (unformat (i, "sa_id %d", &sa_id))
14104         ;
14105       else if (unformat (i, "outbound"))
14106         is_outbound = 1;
14107       else if (unformat (i, "inbound"))
14108         is_outbound = 0;
14109       else
14110         {
14111           clib_warning ("parse error '%U'", format_unformat_error, i);
14112           return -99;
14113         }
14114     }
14115
14116   if (sw_if_index == ~0)
14117     {
14118       errmsg ("interface must be specified");
14119       return -99;
14120     }
14121
14122   if (sa_id == ~0)
14123     {
14124       errmsg ("SA ID must be specified");
14125       return -99;
14126     }
14127
14128   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14129
14130   mp->sw_if_index = htonl (sw_if_index);
14131   mp->sa_id = htonl (sa_id);
14132   mp->is_outbound = is_outbound;
14133
14134   S (mp);
14135   W (ret);
14136
14137   return ret;
14138 }
14139
14140 static int
14141 api_get_first_msg_id (vat_main_t * vam)
14142 {
14143   vl_api_get_first_msg_id_t *mp;
14144   unformat_input_t *i = vam->input;
14145   u8 *name;
14146   u8 name_set = 0;
14147   int ret;
14148
14149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14150     {
14151       if (unformat (i, "client %s", &name))
14152         name_set = 1;
14153       else
14154         break;
14155     }
14156
14157   if (name_set == 0)
14158     {
14159       errmsg ("missing client name");
14160       return -99;
14161     }
14162   vec_add1 (name, 0);
14163
14164   if (vec_len (name) > 63)
14165     {
14166       errmsg ("client name too long");
14167       return -99;
14168     }
14169
14170   M (GET_FIRST_MSG_ID, mp);
14171   clib_memcpy (mp->name, name, vec_len (name));
14172   S (mp);
14173   W (ret);
14174   return ret;
14175 }
14176
14177 static int
14178 api_cop_interface_enable_disable (vat_main_t * vam)
14179 {
14180   unformat_input_t *line_input = vam->input;
14181   vl_api_cop_interface_enable_disable_t *mp;
14182   u32 sw_if_index = ~0;
14183   u8 enable_disable = 1;
14184   int ret;
14185
14186   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14187     {
14188       if (unformat (line_input, "disable"))
14189         enable_disable = 0;
14190       if (unformat (line_input, "enable"))
14191         enable_disable = 1;
14192       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14193                          vam, &sw_if_index))
14194         ;
14195       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14196         ;
14197       else
14198         break;
14199     }
14200
14201   if (sw_if_index == ~0)
14202     {
14203       errmsg ("missing interface name or sw_if_index");
14204       return -99;
14205     }
14206
14207   /* Construct the API message */
14208   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14209   mp->sw_if_index = ntohl (sw_if_index);
14210   mp->enable_disable = enable_disable;
14211
14212   /* send it... */
14213   S (mp);
14214   /* Wait for the reply */
14215   W (ret);
14216   return ret;
14217 }
14218
14219 static int
14220 api_cop_whitelist_enable_disable (vat_main_t * vam)
14221 {
14222   unformat_input_t *line_input = vam->input;
14223   vl_api_cop_whitelist_enable_disable_t *mp;
14224   u32 sw_if_index = ~0;
14225   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14226   u32 fib_id = 0;
14227   int ret;
14228
14229   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14230     {
14231       if (unformat (line_input, "ip4"))
14232         ip4 = 1;
14233       else if (unformat (line_input, "ip6"))
14234         ip6 = 1;
14235       else if (unformat (line_input, "default"))
14236         default_cop = 1;
14237       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14238                          vam, &sw_if_index))
14239         ;
14240       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14241         ;
14242       else if (unformat (line_input, "fib-id %d", &fib_id))
14243         ;
14244       else
14245         break;
14246     }
14247
14248   if (sw_if_index == ~0)
14249     {
14250       errmsg ("missing interface name or sw_if_index");
14251       return -99;
14252     }
14253
14254   /* Construct the API message */
14255   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14256   mp->sw_if_index = ntohl (sw_if_index);
14257   mp->fib_id = ntohl (fib_id);
14258   mp->ip4 = ip4;
14259   mp->ip6 = ip6;
14260   mp->default_cop = default_cop;
14261
14262   /* send it... */
14263   S (mp);
14264   /* Wait for the reply */
14265   W (ret);
14266   return ret;
14267 }
14268
14269 static int
14270 api_get_node_graph (vat_main_t * vam)
14271 {
14272   vl_api_get_node_graph_t *mp;
14273   int ret;
14274
14275   M (GET_NODE_GRAPH, mp);
14276
14277   /* send it... */
14278   S (mp);
14279   /* Wait for the reply */
14280   W (ret);
14281   return ret;
14282 }
14283
14284 /* *INDENT-OFF* */
14285 /** Used for parsing LISP eids */
14286 typedef CLIB_PACKED(struct{
14287   union {
14288           ip46_address_t ip;
14289           mac_address_t mac;
14290           lisp_nsh_api_t nsh;
14291   } addr;
14292   u32 len;       /**< prefix length if IP */
14293   u8 type;      /**< type of eid */
14294 }) lisp_eid_vat_t;
14295 /* *INDENT-ON* */
14296
14297 static uword
14298 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14299 {
14300   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14301
14302   clib_memset (a, 0, sizeof (a[0]));
14303
14304   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14305     {
14306       a->type = 0;              /* ip prefix type */
14307     }
14308   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14309     {
14310       a->type = 1;              /* mac type */
14311     }
14312   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14313     {
14314       a->type = 2;              /* NSH type */
14315       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14316     }
14317   else
14318     {
14319       return 0;
14320     }
14321
14322   if (a->type == 0)
14323     {
14324       if (ip46_address_is_ip4 (&a->addr.ip))
14325         return a->len > 32 ? 1 : 0;
14326       else
14327         return a->len > 128 ? 1 : 0;
14328     }
14329
14330   return 1;
14331 }
14332
14333 static void
14334 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14335 {
14336   eid->type = vat_eid->type;
14337   switch (eid->type)
14338     {
14339     case EID_TYPE_API_PREFIX:
14340       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14341         {
14342           clib_memcpy (&eid->address.prefix.address.un.ip4,
14343                        &vat_eid->addr.ip.ip4, 4);
14344           eid->address.prefix.address.af = ADDRESS_IP4;
14345           eid->address.prefix.len = vat_eid->len;
14346         }
14347       else
14348         {
14349           clib_memcpy (&eid->address.prefix.address.un.ip6,
14350                        &vat_eid->addr.ip.ip6, 16);
14351           eid->address.prefix.address.af = ADDRESS_IP6;
14352           eid->address.prefix.len = vat_eid->len;
14353         }
14354       return;
14355     case EID_TYPE_API_MAC:
14356       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14357                    sizeof (eid->address.mac));
14358       return;
14359     case EID_TYPE_API_NSH:
14360       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14361                    sizeof (eid->address.nsh));
14362       return;
14363     default:
14364       ASSERT (0);
14365       return;
14366     }
14367 }
14368
14369 static int
14370 api_one_add_del_locator_set (vat_main_t * vam)
14371 {
14372   unformat_input_t *input = vam->input;
14373   vl_api_one_add_del_locator_set_t *mp;
14374   u8 is_add = 1;
14375   u8 *locator_set_name = NULL;
14376   u8 locator_set_name_set = 0;
14377   vl_api_local_locator_t locator, *locators = 0;
14378   u32 sw_if_index, priority, weight;
14379   u32 data_len = 0;
14380
14381   int ret;
14382   /* Parse args required to build the message */
14383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14384     {
14385       if (unformat (input, "del"))
14386         {
14387           is_add = 0;
14388         }
14389       else if (unformat (input, "locator-set %s", &locator_set_name))
14390         {
14391           locator_set_name_set = 1;
14392         }
14393       else if (unformat (input, "sw_if_index %u p %u w %u",
14394                          &sw_if_index, &priority, &weight))
14395         {
14396           locator.sw_if_index = htonl (sw_if_index);
14397           locator.priority = priority;
14398           locator.weight = weight;
14399           vec_add1 (locators, locator);
14400         }
14401       else
14402         if (unformat
14403             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14404              &sw_if_index, &priority, &weight))
14405         {
14406           locator.sw_if_index = htonl (sw_if_index);
14407           locator.priority = priority;
14408           locator.weight = weight;
14409           vec_add1 (locators, locator);
14410         }
14411       else
14412         break;
14413     }
14414
14415   if (locator_set_name_set == 0)
14416     {
14417       errmsg ("missing locator-set name");
14418       vec_free (locators);
14419       return -99;
14420     }
14421
14422   if (vec_len (locator_set_name) > 64)
14423     {
14424       errmsg ("locator-set name too long");
14425       vec_free (locator_set_name);
14426       vec_free (locators);
14427       return -99;
14428     }
14429   vec_add1 (locator_set_name, 0);
14430
14431   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14432
14433   /* Construct the API message */
14434   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14435
14436   mp->is_add = is_add;
14437   clib_memcpy (mp->locator_set_name, locator_set_name,
14438                vec_len (locator_set_name));
14439   vec_free (locator_set_name);
14440
14441   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14442   if (locators)
14443     clib_memcpy (mp->locators, locators, data_len);
14444   vec_free (locators);
14445
14446   /* send it... */
14447   S (mp);
14448
14449   /* Wait for a reply... */
14450   W (ret);
14451   return ret;
14452 }
14453
14454 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14455
14456 static int
14457 api_one_add_del_locator (vat_main_t * vam)
14458 {
14459   unformat_input_t *input = vam->input;
14460   vl_api_one_add_del_locator_t *mp;
14461   u32 tmp_if_index = ~0;
14462   u32 sw_if_index = ~0;
14463   u8 sw_if_index_set = 0;
14464   u8 sw_if_index_if_name_set = 0;
14465   u32 priority = ~0;
14466   u8 priority_set = 0;
14467   u32 weight = ~0;
14468   u8 weight_set = 0;
14469   u8 is_add = 1;
14470   u8 *locator_set_name = NULL;
14471   u8 locator_set_name_set = 0;
14472   int ret;
14473
14474   /* Parse args required to build the message */
14475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14476     {
14477       if (unformat (input, "del"))
14478         {
14479           is_add = 0;
14480         }
14481       else if (unformat (input, "locator-set %s", &locator_set_name))
14482         {
14483           locator_set_name_set = 1;
14484         }
14485       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14486                          &tmp_if_index))
14487         {
14488           sw_if_index_if_name_set = 1;
14489           sw_if_index = tmp_if_index;
14490         }
14491       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14492         {
14493           sw_if_index_set = 1;
14494           sw_if_index = tmp_if_index;
14495         }
14496       else if (unformat (input, "p %d", &priority))
14497         {
14498           priority_set = 1;
14499         }
14500       else if (unformat (input, "w %d", &weight))
14501         {
14502           weight_set = 1;
14503         }
14504       else
14505         break;
14506     }
14507
14508   if (locator_set_name_set == 0)
14509     {
14510       errmsg ("missing locator-set name");
14511       return -99;
14512     }
14513
14514   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14515     {
14516       errmsg ("missing sw_if_index");
14517       vec_free (locator_set_name);
14518       return -99;
14519     }
14520
14521   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14522     {
14523       errmsg ("cannot use both params interface name and sw_if_index");
14524       vec_free (locator_set_name);
14525       return -99;
14526     }
14527
14528   if (priority_set == 0)
14529     {
14530       errmsg ("missing locator-set priority");
14531       vec_free (locator_set_name);
14532       return -99;
14533     }
14534
14535   if (weight_set == 0)
14536     {
14537       errmsg ("missing locator-set weight");
14538       vec_free (locator_set_name);
14539       return -99;
14540     }
14541
14542   if (vec_len (locator_set_name) > 64)
14543     {
14544       errmsg ("locator-set name too long");
14545       vec_free (locator_set_name);
14546       return -99;
14547     }
14548   vec_add1 (locator_set_name, 0);
14549
14550   /* Construct the API message */
14551   M (ONE_ADD_DEL_LOCATOR, mp);
14552
14553   mp->is_add = is_add;
14554   mp->sw_if_index = ntohl (sw_if_index);
14555   mp->priority = priority;
14556   mp->weight = weight;
14557   clib_memcpy (mp->locator_set_name, locator_set_name,
14558                vec_len (locator_set_name));
14559   vec_free (locator_set_name);
14560
14561   /* send it... */
14562   S (mp);
14563
14564   /* Wait for a reply... */
14565   W (ret);
14566   return ret;
14567 }
14568
14569 #define api_lisp_add_del_locator api_one_add_del_locator
14570
14571 uword
14572 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14573 {
14574   u32 *key_id = va_arg (*args, u32 *);
14575   u8 *s = 0;
14576
14577   if (unformat (input, "%s", &s))
14578     {
14579       if (!strcmp ((char *) s, "sha1"))
14580         key_id[0] = HMAC_SHA_1_96;
14581       else if (!strcmp ((char *) s, "sha256"))
14582         key_id[0] = HMAC_SHA_256_128;
14583       else
14584         {
14585           clib_warning ("invalid key_id: '%s'", s);
14586           key_id[0] = HMAC_NO_KEY;
14587         }
14588     }
14589   else
14590     return 0;
14591
14592   vec_free (s);
14593   return 1;
14594 }
14595
14596 static int
14597 api_one_add_del_local_eid (vat_main_t * vam)
14598 {
14599   unformat_input_t *input = vam->input;
14600   vl_api_one_add_del_local_eid_t *mp;
14601   u8 is_add = 1;
14602   u8 eid_set = 0;
14603   lisp_eid_vat_t _eid, *eid = &_eid;
14604   u8 *locator_set_name = 0;
14605   u8 locator_set_name_set = 0;
14606   u32 vni = 0;
14607   u16 key_id = 0;
14608   u8 *key = 0;
14609   int ret;
14610
14611   /* Parse args required to build the message */
14612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14613     {
14614       if (unformat (input, "del"))
14615         {
14616           is_add = 0;
14617         }
14618       else if (unformat (input, "vni %d", &vni))
14619         {
14620           ;
14621         }
14622       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14623         {
14624           eid_set = 1;
14625         }
14626       else if (unformat (input, "locator-set %s", &locator_set_name))
14627         {
14628           locator_set_name_set = 1;
14629         }
14630       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14631         ;
14632       else if (unformat (input, "secret-key %_%v%_", &key))
14633         ;
14634       else
14635         break;
14636     }
14637
14638   if (locator_set_name_set == 0)
14639     {
14640       errmsg ("missing locator-set name");
14641       return -99;
14642     }
14643
14644   if (0 == eid_set)
14645     {
14646       errmsg ("EID address not set!");
14647       vec_free (locator_set_name);
14648       return -99;
14649     }
14650
14651   if (key && (0 == key_id))
14652     {
14653       errmsg ("invalid key_id!");
14654       return -99;
14655     }
14656
14657   if (vec_len (key) > 64)
14658     {
14659       errmsg ("key too long");
14660       vec_free (key);
14661       return -99;
14662     }
14663
14664   if (vec_len (locator_set_name) > 64)
14665     {
14666       errmsg ("locator-set name too long");
14667       vec_free (locator_set_name);
14668       return -99;
14669     }
14670   vec_add1 (locator_set_name, 0);
14671
14672   /* Construct the API message */
14673   M (ONE_ADD_DEL_LOCAL_EID, mp);
14674
14675   mp->is_add = is_add;
14676   lisp_eid_put_vat (&mp->eid, eid);
14677   mp->vni = clib_host_to_net_u32 (vni);
14678   mp->key.id = key_id;
14679   clib_memcpy (mp->locator_set_name, locator_set_name,
14680                vec_len (locator_set_name));
14681   clib_memcpy (mp->key.key, key, vec_len (key));
14682
14683   vec_free (locator_set_name);
14684   vec_free (key);
14685
14686   /* send it... */
14687   S (mp);
14688
14689   /* Wait for a reply... */
14690   W (ret);
14691   return ret;
14692 }
14693
14694 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14695
14696 static int
14697 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14698 {
14699   u32 dp_table = 0, vni = 0;;
14700   unformat_input_t *input = vam->input;
14701   vl_api_gpe_add_del_fwd_entry_t *mp;
14702   u8 is_add = 1;
14703   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14704   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14705   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14706   u32 action = ~0, w;
14707   ip4_address_t rmt_rloc4, lcl_rloc4;
14708   ip6_address_t rmt_rloc6, lcl_rloc6;
14709   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14710   int ret;
14711
14712   clib_memset (&rloc, 0, sizeof (rloc));
14713
14714   /* Parse args required to build the message */
14715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14716     {
14717       if (unformat (input, "del"))
14718         is_add = 0;
14719       else if (unformat (input, "add"))
14720         is_add = 1;
14721       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14722         {
14723           rmt_eid_set = 1;
14724         }
14725       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14726         {
14727           lcl_eid_set = 1;
14728         }
14729       else if (unformat (input, "vrf %d", &dp_table))
14730         ;
14731       else if (unformat (input, "bd %d", &dp_table))
14732         ;
14733       else if (unformat (input, "vni %d", &vni))
14734         ;
14735       else if (unformat (input, "w %d", &w))
14736         {
14737           if (!curr_rloc)
14738             {
14739               errmsg ("No RLOC configured for setting priority/weight!");
14740               return -99;
14741             }
14742           curr_rloc->weight = w;
14743         }
14744       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14745                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14746         {
14747           rloc.addr.af = 0;
14748           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14749           rloc.weight = 0;
14750           vec_add1 (lcl_locs, rloc);
14751
14752           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14753           vec_add1 (rmt_locs, rloc);
14754           /* weight saved in rmt loc */
14755           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14756         }
14757       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14758                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14759         {
14760           rloc.addr.af = 1;
14761           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14762           rloc.weight = 0;
14763           vec_add1 (lcl_locs, rloc);
14764
14765           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14766           vec_add1 (rmt_locs, rloc);
14767           /* weight saved in rmt loc */
14768           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14769         }
14770       else if (unformat (input, "action %d", &action))
14771         {
14772           ;
14773         }
14774       else
14775         {
14776           clib_warning ("parse error '%U'", format_unformat_error, input);
14777           return -99;
14778         }
14779     }
14780
14781   if (!rmt_eid_set)
14782     {
14783       errmsg ("remote eid addresses not set");
14784       return -99;
14785     }
14786
14787   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14788     {
14789       errmsg ("eid types don't match");
14790       return -99;
14791     }
14792
14793   if (0 == rmt_locs && (u32) ~ 0 == action)
14794     {
14795       errmsg ("action not set for negative mapping");
14796       return -99;
14797     }
14798
14799   /* Construct the API message */
14800   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14801       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14802
14803   mp->is_add = is_add;
14804   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14805   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14806   mp->dp_table = clib_host_to_net_u32 (dp_table);
14807   mp->vni = clib_host_to_net_u32 (vni);
14808   mp->action = action;
14809
14810   if (0 != rmt_locs && 0 != lcl_locs)
14811     {
14812       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14813       clib_memcpy (mp->locs, lcl_locs,
14814                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14815
14816       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14817       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14818                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14819     }
14820   vec_free (lcl_locs);
14821   vec_free (rmt_locs);
14822
14823   /* send it... */
14824   S (mp);
14825
14826   /* Wait for a reply... */
14827   W (ret);
14828   return ret;
14829 }
14830
14831 static int
14832 api_one_add_del_map_server (vat_main_t * vam)
14833 {
14834   unformat_input_t *input = vam->input;
14835   vl_api_one_add_del_map_server_t *mp;
14836   u8 is_add = 1;
14837   u8 ipv4_set = 0;
14838   u8 ipv6_set = 0;
14839   ip4_address_t ipv4;
14840   ip6_address_t ipv6;
14841   int ret;
14842
14843   /* Parse args required to build the message */
14844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14845     {
14846       if (unformat (input, "del"))
14847         {
14848           is_add = 0;
14849         }
14850       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14851         {
14852           ipv4_set = 1;
14853         }
14854       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14855         {
14856           ipv6_set = 1;
14857         }
14858       else
14859         break;
14860     }
14861
14862   if (ipv4_set && ipv6_set)
14863     {
14864       errmsg ("both eid v4 and v6 addresses set");
14865       return -99;
14866     }
14867
14868   if (!ipv4_set && !ipv6_set)
14869     {
14870       errmsg ("eid addresses not set");
14871       return -99;
14872     }
14873
14874   /* Construct the API message */
14875   M (ONE_ADD_DEL_MAP_SERVER, mp);
14876
14877   mp->is_add = is_add;
14878   if (ipv6_set)
14879     {
14880       mp->ip_address.af = 1;
14881       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14882     }
14883   else
14884     {
14885       mp->ip_address.af = 0;
14886       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14887     }
14888
14889   /* send it... */
14890   S (mp);
14891
14892   /* Wait for a reply... */
14893   W (ret);
14894   return ret;
14895 }
14896
14897 #define api_lisp_add_del_map_server api_one_add_del_map_server
14898
14899 static int
14900 api_one_add_del_map_resolver (vat_main_t * vam)
14901 {
14902   unformat_input_t *input = vam->input;
14903   vl_api_one_add_del_map_resolver_t *mp;
14904   u8 is_add = 1;
14905   u8 ipv4_set = 0;
14906   u8 ipv6_set = 0;
14907   ip4_address_t ipv4;
14908   ip6_address_t ipv6;
14909   int ret;
14910
14911   /* Parse args required to build the message */
14912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14913     {
14914       if (unformat (input, "del"))
14915         {
14916           is_add = 0;
14917         }
14918       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14919         {
14920           ipv4_set = 1;
14921         }
14922       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14923         {
14924           ipv6_set = 1;
14925         }
14926       else
14927         break;
14928     }
14929
14930   if (ipv4_set && ipv6_set)
14931     {
14932       errmsg ("both eid v4 and v6 addresses set");
14933       return -99;
14934     }
14935
14936   if (!ipv4_set && !ipv6_set)
14937     {
14938       errmsg ("eid addresses not set");
14939       return -99;
14940     }
14941
14942   /* Construct the API message */
14943   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14944
14945   mp->is_add = is_add;
14946   if (ipv6_set)
14947     {
14948       mp->ip_address.af = 1;
14949       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14950     }
14951   else
14952     {
14953       mp->ip_address.af = 0;
14954       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14955     }
14956
14957   /* send it... */
14958   S (mp);
14959
14960   /* Wait for a reply... */
14961   W (ret);
14962   return ret;
14963 }
14964
14965 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14966
14967 static int
14968 api_lisp_gpe_enable_disable (vat_main_t * vam)
14969 {
14970   unformat_input_t *input = vam->input;
14971   vl_api_gpe_enable_disable_t *mp;
14972   u8 is_set = 0;
14973   u8 is_enable = 1;
14974   int ret;
14975
14976   /* Parse args required to build the message */
14977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14978     {
14979       if (unformat (input, "enable"))
14980         {
14981           is_set = 1;
14982           is_enable = 1;
14983         }
14984       else if (unformat (input, "disable"))
14985         {
14986           is_set = 1;
14987           is_enable = 0;
14988         }
14989       else
14990         break;
14991     }
14992
14993   if (is_set == 0)
14994     {
14995       errmsg ("Value not set");
14996       return -99;
14997     }
14998
14999   /* Construct the API message */
15000   M (GPE_ENABLE_DISABLE, mp);
15001
15002   mp->is_enable = is_enable;
15003
15004   /* send it... */
15005   S (mp);
15006
15007   /* Wait for a reply... */
15008   W (ret);
15009   return ret;
15010 }
15011
15012 static int
15013 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15014 {
15015   unformat_input_t *input = vam->input;
15016   vl_api_one_rloc_probe_enable_disable_t *mp;
15017   u8 is_set = 0;
15018   u8 is_enable = 0;
15019   int ret;
15020
15021   /* Parse args required to build the message */
15022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15023     {
15024       if (unformat (input, "enable"))
15025         {
15026           is_set = 1;
15027           is_enable = 1;
15028         }
15029       else if (unformat (input, "disable"))
15030         is_set = 1;
15031       else
15032         break;
15033     }
15034
15035   if (!is_set)
15036     {
15037       errmsg ("Value not set");
15038       return -99;
15039     }
15040
15041   /* Construct the API message */
15042   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15043
15044   mp->is_enable = is_enable;
15045
15046   /* send it... */
15047   S (mp);
15048
15049   /* Wait for a reply... */
15050   W (ret);
15051   return ret;
15052 }
15053
15054 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15055
15056 static int
15057 api_one_map_register_enable_disable (vat_main_t * vam)
15058 {
15059   unformat_input_t *input = vam->input;
15060   vl_api_one_map_register_enable_disable_t *mp;
15061   u8 is_set = 0;
15062   u8 is_enable = 0;
15063   int ret;
15064
15065   /* Parse args required to build the message */
15066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15067     {
15068       if (unformat (input, "enable"))
15069         {
15070           is_set = 1;
15071           is_enable = 1;
15072         }
15073       else if (unformat (input, "disable"))
15074         is_set = 1;
15075       else
15076         break;
15077     }
15078
15079   if (!is_set)
15080     {
15081       errmsg ("Value not set");
15082       return -99;
15083     }
15084
15085   /* Construct the API message */
15086   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15087
15088   mp->is_enable = is_enable;
15089
15090   /* send it... */
15091   S (mp);
15092
15093   /* Wait for a reply... */
15094   W (ret);
15095   return ret;
15096 }
15097
15098 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15099
15100 static int
15101 api_one_enable_disable (vat_main_t * vam)
15102 {
15103   unformat_input_t *input = vam->input;
15104   vl_api_one_enable_disable_t *mp;
15105   u8 is_set = 0;
15106   u8 is_enable = 0;
15107   int ret;
15108
15109   /* Parse args required to build the message */
15110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15111     {
15112       if (unformat (input, "enable"))
15113         {
15114           is_set = 1;
15115           is_enable = 1;
15116         }
15117       else if (unformat (input, "disable"))
15118         {
15119           is_set = 1;
15120         }
15121       else
15122         break;
15123     }
15124
15125   if (!is_set)
15126     {
15127       errmsg ("Value not set");
15128       return -99;
15129     }
15130
15131   /* Construct the API message */
15132   M (ONE_ENABLE_DISABLE, mp);
15133
15134   mp->is_enable = is_enable;
15135
15136   /* send it... */
15137   S (mp);
15138
15139   /* Wait for a reply... */
15140   W (ret);
15141   return ret;
15142 }
15143
15144 #define api_lisp_enable_disable api_one_enable_disable
15145
15146 static int
15147 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15148 {
15149   unformat_input_t *input = vam->input;
15150   vl_api_one_enable_disable_xtr_mode_t *mp;
15151   u8 is_set = 0;
15152   u8 is_enable = 0;
15153   int ret;
15154
15155   /* Parse args required to build the message */
15156   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15157     {
15158       if (unformat (input, "enable"))
15159         {
15160           is_set = 1;
15161           is_enable = 1;
15162         }
15163       else if (unformat (input, "disable"))
15164         {
15165           is_set = 1;
15166         }
15167       else
15168         break;
15169     }
15170
15171   if (!is_set)
15172     {
15173       errmsg ("Value not set");
15174       return -99;
15175     }
15176
15177   /* Construct the API message */
15178   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15179
15180   mp->is_enable = is_enable;
15181
15182   /* send it... */
15183   S (mp);
15184
15185   /* Wait for a reply... */
15186   W (ret);
15187   return ret;
15188 }
15189
15190 static int
15191 api_one_show_xtr_mode (vat_main_t * vam)
15192 {
15193   vl_api_one_show_xtr_mode_t *mp;
15194   int ret;
15195
15196   /* Construct the API message */
15197   M (ONE_SHOW_XTR_MODE, mp);
15198
15199   /* send it... */
15200   S (mp);
15201
15202   /* Wait for a reply... */
15203   W (ret);
15204   return ret;
15205 }
15206
15207 static int
15208 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15209 {
15210   unformat_input_t *input = vam->input;
15211   vl_api_one_enable_disable_pitr_mode_t *mp;
15212   u8 is_set = 0;
15213   u8 is_enable = 0;
15214   int ret;
15215
15216   /* Parse args required to build the message */
15217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15218     {
15219       if (unformat (input, "enable"))
15220         {
15221           is_set = 1;
15222           is_enable = 1;
15223         }
15224       else if (unformat (input, "disable"))
15225         {
15226           is_set = 1;
15227         }
15228       else
15229         break;
15230     }
15231
15232   if (!is_set)
15233     {
15234       errmsg ("Value not set");
15235       return -99;
15236     }
15237
15238   /* Construct the API message */
15239   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15240
15241   mp->is_enable = is_enable;
15242
15243   /* send it... */
15244   S (mp);
15245
15246   /* Wait for a reply... */
15247   W (ret);
15248   return ret;
15249 }
15250
15251 static int
15252 api_one_show_pitr_mode (vat_main_t * vam)
15253 {
15254   vl_api_one_show_pitr_mode_t *mp;
15255   int ret;
15256
15257   /* Construct the API message */
15258   M (ONE_SHOW_PITR_MODE, mp);
15259
15260   /* send it... */
15261   S (mp);
15262
15263   /* Wait for a reply... */
15264   W (ret);
15265   return ret;
15266 }
15267
15268 static int
15269 api_one_enable_disable_petr_mode (vat_main_t * vam)
15270 {
15271   unformat_input_t *input = vam->input;
15272   vl_api_one_enable_disable_petr_mode_t *mp;
15273   u8 is_set = 0;
15274   u8 is_enable = 0;
15275   int ret;
15276
15277   /* Parse args required to build the message */
15278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15279     {
15280       if (unformat (input, "enable"))
15281         {
15282           is_set = 1;
15283           is_enable = 1;
15284         }
15285       else if (unformat (input, "disable"))
15286         {
15287           is_set = 1;
15288         }
15289       else
15290         break;
15291     }
15292
15293   if (!is_set)
15294     {
15295       errmsg ("Value not set");
15296       return -99;
15297     }
15298
15299   /* Construct the API message */
15300   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15301
15302   mp->is_enable = is_enable;
15303
15304   /* send it... */
15305   S (mp);
15306
15307   /* Wait for a reply... */
15308   W (ret);
15309   return ret;
15310 }
15311
15312 static int
15313 api_one_show_petr_mode (vat_main_t * vam)
15314 {
15315   vl_api_one_show_petr_mode_t *mp;
15316   int ret;
15317
15318   /* Construct the API message */
15319   M (ONE_SHOW_PETR_MODE, mp);
15320
15321   /* send it... */
15322   S (mp);
15323
15324   /* Wait for a reply... */
15325   W (ret);
15326   return ret;
15327 }
15328
15329 static int
15330 api_show_one_map_register_state (vat_main_t * vam)
15331 {
15332   vl_api_show_one_map_register_state_t *mp;
15333   int ret;
15334
15335   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15336
15337   /* send */
15338   S (mp);
15339
15340   /* wait for reply */
15341   W (ret);
15342   return ret;
15343 }
15344
15345 #define api_show_lisp_map_register_state api_show_one_map_register_state
15346
15347 static int
15348 api_show_one_rloc_probe_state (vat_main_t * vam)
15349 {
15350   vl_api_show_one_rloc_probe_state_t *mp;
15351   int ret;
15352
15353   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15354
15355   /* send */
15356   S (mp);
15357
15358   /* wait for reply */
15359   W (ret);
15360   return ret;
15361 }
15362
15363 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15364
15365 static int
15366 api_one_add_del_ndp_entry (vat_main_t * vam)
15367 {
15368   vl_api_one_add_del_ndp_entry_t *mp;
15369   unformat_input_t *input = vam->input;
15370   u8 is_add = 1;
15371   u8 mac_set = 0;
15372   u8 bd_set = 0;
15373   u8 ip_set = 0;
15374   u8 mac[6] = { 0, };
15375   u8 ip6[16] = { 0, };
15376   u32 bd = ~0;
15377   int ret;
15378
15379   /* Parse args required to build the message */
15380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15381     {
15382       if (unformat (input, "del"))
15383         is_add = 0;
15384       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15385         mac_set = 1;
15386       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15387         ip_set = 1;
15388       else if (unformat (input, "bd %d", &bd))
15389         bd_set = 1;
15390       else
15391         {
15392           errmsg ("parse error '%U'", format_unformat_error, input);
15393           return -99;
15394         }
15395     }
15396
15397   if (!bd_set || !ip_set || (!mac_set && is_add))
15398     {
15399       errmsg ("Missing BD, IP or MAC!");
15400       return -99;
15401     }
15402
15403   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15404   mp->is_add = is_add;
15405   clib_memcpy (&mp->entry.mac, mac, 6);
15406   mp->bd = clib_host_to_net_u32 (bd);
15407   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15408
15409   /* send */
15410   S (mp);
15411
15412   /* wait for reply */
15413   W (ret);
15414   return ret;
15415 }
15416
15417 static int
15418 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15419 {
15420   vl_api_one_add_del_l2_arp_entry_t *mp;
15421   unformat_input_t *input = vam->input;
15422   u8 is_add = 1;
15423   u8 mac_set = 0;
15424   u8 bd_set = 0;
15425   u8 ip_set = 0;
15426   u8 mac[6] = { 0, };
15427   u32 ip4 = 0, bd = ~0;
15428   int ret;
15429
15430   /* Parse args required to build the message */
15431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15432     {
15433       if (unformat (input, "del"))
15434         is_add = 0;
15435       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15436         mac_set = 1;
15437       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15438         ip_set = 1;
15439       else if (unformat (input, "bd %d", &bd))
15440         bd_set = 1;
15441       else
15442         {
15443           errmsg ("parse error '%U'", format_unformat_error, input);
15444           return -99;
15445         }
15446     }
15447
15448   if (!bd_set || !ip_set || (!mac_set && is_add))
15449     {
15450       errmsg ("Missing BD, IP or MAC!");
15451       return -99;
15452     }
15453
15454   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15455   mp->is_add = is_add;
15456   clib_memcpy (&mp->entry.mac, mac, 6);
15457   mp->bd = clib_host_to_net_u32 (bd);
15458   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15459
15460   /* send */
15461   S (mp);
15462
15463   /* wait for reply */
15464   W (ret);
15465   return ret;
15466 }
15467
15468 static int
15469 api_one_ndp_bd_get (vat_main_t * vam)
15470 {
15471   vl_api_one_ndp_bd_get_t *mp;
15472   int ret;
15473
15474   M (ONE_NDP_BD_GET, mp);
15475
15476   /* send */
15477   S (mp);
15478
15479   /* wait for reply */
15480   W (ret);
15481   return ret;
15482 }
15483
15484 static int
15485 api_one_ndp_entries_get (vat_main_t * vam)
15486 {
15487   vl_api_one_ndp_entries_get_t *mp;
15488   unformat_input_t *input = vam->input;
15489   u8 bd_set = 0;
15490   u32 bd = ~0;
15491   int ret;
15492
15493   /* Parse args required to build the message */
15494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15495     {
15496       if (unformat (input, "bd %d", &bd))
15497         bd_set = 1;
15498       else
15499         {
15500           errmsg ("parse error '%U'", format_unformat_error, input);
15501           return -99;
15502         }
15503     }
15504
15505   if (!bd_set)
15506     {
15507       errmsg ("Expected bridge domain!");
15508       return -99;
15509     }
15510
15511   M (ONE_NDP_ENTRIES_GET, mp);
15512   mp->bd = clib_host_to_net_u32 (bd);
15513
15514   /* send */
15515   S (mp);
15516
15517   /* wait for reply */
15518   W (ret);
15519   return ret;
15520 }
15521
15522 static int
15523 api_one_l2_arp_bd_get (vat_main_t * vam)
15524 {
15525   vl_api_one_l2_arp_bd_get_t *mp;
15526   int ret;
15527
15528   M (ONE_L2_ARP_BD_GET, mp);
15529
15530   /* send */
15531   S (mp);
15532
15533   /* wait for reply */
15534   W (ret);
15535   return ret;
15536 }
15537
15538 static int
15539 api_one_l2_arp_entries_get (vat_main_t * vam)
15540 {
15541   vl_api_one_l2_arp_entries_get_t *mp;
15542   unformat_input_t *input = vam->input;
15543   u8 bd_set = 0;
15544   u32 bd = ~0;
15545   int ret;
15546
15547   /* Parse args required to build the message */
15548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15549     {
15550       if (unformat (input, "bd %d", &bd))
15551         bd_set = 1;
15552       else
15553         {
15554           errmsg ("parse error '%U'", format_unformat_error, input);
15555           return -99;
15556         }
15557     }
15558
15559   if (!bd_set)
15560     {
15561       errmsg ("Expected bridge domain!");
15562       return -99;
15563     }
15564
15565   M (ONE_L2_ARP_ENTRIES_GET, mp);
15566   mp->bd = clib_host_to_net_u32 (bd);
15567
15568   /* send */
15569   S (mp);
15570
15571   /* wait for reply */
15572   W (ret);
15573   return ret;
15574 }
15575
15576 static int
15577 api_one_stats_enable_disable (vat_main_t * vam)
15578 {
15579   vl_api_one_stats_enable_disable_t *mp;
15580   unformat_input_t *input = vam->input;
15581   u8 is_set = 0;
15582   u8 is_enable = 0;
15583   int ret;
15584
15585   /* Parse args required to build the message */
15586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15587     {
15588       if (unformat (input, "enable"))
15589         {
15590           is_set = 1;
15591           is_enable = 1;
15592         }
15593       else if (unformat (input, "disable"))
15594         {
15595           is_set = 1;
15596         }
15597       else
15598         break;
15599     }
15600
15601   if (!is_set)
15602     {
15603       errmsg ("Value not set");
15604       return -99;
15605     }
15606
15607   M (ONE_STATS_ENABLE_DISABLE, mp);
15608   mp->is_enable = is_enable;
15609
15610   /* send */
15611   S (mp);
15612
15613   /* wait for reply */
15614   W (ret);
15615   return ret;
15616 }
15617
15618 static int
15619 api_show_one_stats_enable_disable (vat_main_t * vam)
15620 {
15621   vl_api_show_one_stats_enable_disable_t *mp;
15622   int ret;
15623
15624   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15625
15626   /* send */
15627   S (mp);
15628
15629   /* wait for reply */
15630   W (ret);
15631   return ret;
15632 }
15633
15634 static int
15635 api_show_one_map_request_mode (vat_main_t * vam)
15636 {
15637   vl_api_show_one_map_request_mode_t *mp;
15638   int ret;
15639
15640   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15641
15642   /* send */
15643   S (mp);
15644
15645   /* wait for reply */
15646   W (ret);
15647   return ret;
15648 }
15649
15650 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15651
15652 static int
15653 api_one_map_request_mode (vat_main_t * vam)
15654 {
15655   unformat_input_t *input = vam->input;
15656   vl_api_one_map_request_mode_t *mp;
15657   u8 mode = 0;
15658   int ret;
15659
15660   /* Parse args required to build the message */
15661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15662     {
15663       if (unformat (input, "dst-only"))
15664         mode = 0;
15665       else if (unformat (input, "src-dst"))
15666         mode = 1;
15667       else
15668         {
15669           errmsg ("parse error '%U'", format_unformat_error, input);
15670           return -99;
15671         }
15672     }
15673
15674   M (ONE_MAP_REQUEST_MODE, mp);
15675
15676   mp->mode = mode;
15677
15678   /* send */
15679   S (mp);
15680
15681   /* wait for reply */
15682   W (ret);
15683   return ret;
15684 }
15685
15686 #define api_lisp_map_request_mode api_one_map_request_mode
15687
15688 /**
15689  * Enable/disable ONE proxy ITR.
15690  *
15691  * @param vam vpp API test context
15692  * @return return code
15693  */
15694 static int
15695 api_one_pitr_set_locator_set (vat_main_t * vam)
15696 {
15697   u8 ls_name_set = 0;
15698   unformat_input_t *input = vam->input;
15699   vl_api_one_pitr_set_locator_set_t *mp;
15700   u8 is_add = 1;
15701   u8 *ls_name = 0;
15702   int ret;
15703
15704   /* Parse args required to build the message */
15705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15706     {
15707       if (unformat (input, "del"))
15708         is_add = 0;
15709       else if (unformat (input, "locator-set %s", &ls_name))
15710         ls_name_set = 1;
15711       else
15712         {
15713           errmsg ("parse error '%U'", format_unformat_error, input);
15714           return -99;
15715         }
15716     }
15717
15718   if (!ls_name_set)
15719     {
15720       errmsg ("locator-set name not set!");
15721       return -99;
15722     }
15723
15724   M (ONE_PITR_SET_LOCATOR_SET, mp);
15725
15726   mp->is_add = is_add;
15727   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15728   vec_free (ls_name);
15729
15730   /* send */
15731   S (mp);
15732
15733   /* wait for reply */
15734   W (ret);
15735   return ret;
15736 }
15737
15738 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15739
15740 static int
15741 api_one_nsh_set_locator_set (vat_main_t * vam)
15742 {
15743   u8 ls_name_set = 0;
15744   unformat_input_t *input = vam->input;
15745   vl_api_one_nsh_set_locator_set_t *mp;
15746   u8 is_add = 1;
15747   u8 *ls_name = 0;
15748   int ret;
15749
15750   /* Parse args required to build the message */
15751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15752     {
15753       if (unformat (input, "del"))
15754         is_add = 0;
15755       else if (unformat (input, "ls %s", &ls_name))
15756         ls_name_set = 1;
15757       else
15758         {
15759           errmsg ("parse error '%U'", format_unformat_error, input);
15760           return -99;
15761         }
15762     }
15763
15764   if (!ls_name_set && is_add)
15765     {
15766       errmsg ("locator-set name not set!");
15767       return -99;
15768     }
15769
15770   M (ONE_NSH_SET_LOCATOR_SET, mp);
15771
15772   mp->is_add = is_add;
15773   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15774   vec_free (ls_name);
15775
15776   /* send */
15777   S (mp);
15778
15779   /* wait for reply */
15780   W (ret);
15781   return ret;
15782 }
15783
15784 static int
15785 api_show_one_pitr (vat_main_t * vam)
15786 {
15787   vl_api_show_one_pitr_t *mp;
15788   int ret;
15789
15790   if (!vam->json_output)
15791     {
15792       print (vam->ofp, "%=20s", "lisp status:");
15793     }
15794
15795   M (SHOW_ONE_PITR, mp);
15796   /* send it... */
15797   S (mp);
15798
15799   /* Wait for a reply... */
15800   W (ret);
15801   return ret;
15802 }
15803
15804 #define api_show_lisp_pitr api_show_one_pitr
15805
15806 static int
15807 api_one_use_petr (vat_main_t * vam)
15808 {
15809   unformat_input_t *input = vam->input;
15810   vl_api_one_use_petr_t *mp;
15811   u8 is_add = 0;
15812   ip_address_t ip;
15813   int ret;
15814
15815   clib_memset (&ip, 0, sizeof (ip));
15816
15817   /* Parse args required to build the message */
15818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15819     {
15820       if (unformat (input, "disable"))
15821         is_add = 0;
15822       else
15823         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15824         {
15825           is_add = 1;
15826           ip_addr_version (&ip) = AF_IP4;
15827         }
15828       else
15829         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15830         {
15831           is_add = 1;
15832           ip_addr_version (&ip) = AF_IP6;
15833         }
15834       else
15835         {
15836           errmsg ("parse error '%U'", format_unformat_error, input);
15837           return -99;
15838         }
15839     }
15840
15841   M (ONE_USE_PETR, mp);
15842
15843   mp->is_add = is_add;
15844   if (is_add)
15845     {
15846       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15847       if (mp->ip_address.af)
15848         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15849       else
15850         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15851     }
15852
15853   /* send */
15854   S (mp);
15855
15856   /* wait for reply */
15857   W (ret);
15858   return ret;
15859 }
15860
15861 #define api_lisp_use_petr api_one_use_petr
15862
15863 static int
15864 api_show_one_nsh_mapping (vat_main_t * vam)
15865 {
15866   vl_api_show_one_use_petr_t *mp;
15867   int ret;
15868
15869   if (!vam->json_output)
15870     {
15871       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15872     }
15873
15874   M (SHOW_ONE_NSH_MAPPING, mp);
15875   /* send it... */
15876   S (mp);
15877
15878   /* Wait for a reply... */
15879   W (ret);
15880   return ret;
15881 }
15882
15883 static int
15884 api_show_one_use_petr (vat_main_t * vam)
15885 {
15886   vl_api_show_one_use_petr_t *mp;
15887   int ret;
15888
15889   if (!vam->json_output)
15890     {
15891       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15892     }
15893
15894   M (SHOW_ONE_USE_PETR, mp);
15895   /* send it... */
15896   S (mp);
15897
15898   /* Wait for a reply... */
15899   W (ret);
15900   return ret;
15901 }
15902
15903 #define api_show_lisp_use_petr api_show_one_use_petr
15904
15905 /**
15906  * Add/delete mapping between vni and vrf
15907  */
15908 static int
15909 api_one_eid_table_add_del_map (vat_main_t * vam)
15910 {
15911   unformat_input_t *input = vam->input;
15912   vl_api_one_eid_table_add_del_map_t *mp;
15913   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15914   u32 vni, vrf, bd_index;
15915   int ret;
15916
15917   /* Parse args required to build the message */
15918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15919     {
15920       if (unformat (input, "del"))
15921         is_add = 0;
15922       else if (unformat (input, "vrf %d", &vrf))
15923         vrf_set = 1;
15924       else if (unformat (input, "bd_index %d", &bd_index))
15925         bd_index_set = 1;
15926       else if (unformat (input, "vni %d", &vni))
15927         vni_set = 1;
15928       else
15929         break;
15930     }
15931
15932   if (!vni_set || (!vrf_set && !bd_index_set))
15933     {
15934       errmsg ("missing arguments!");
15935       return -99;
15936     }
15937
15938   if (vrf_set && bd_index_set)
15939     {
15940       errmsg ("error: both vrf and bd entered!");
15941       return -99;
15942     }
15943
15944   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15945
15946   mp->is_add = is_add;
15947   mp->vni = htonl (vni);
15948   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15949   mp->is_l2 = bd_index_set;
15950
15951   /* send */
15952   S (mp);
15953
15954   /* wait for reply */
15955   W (ret);
15956   return ret;
15957 }
15958
15959 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15960
15961 uword
15962 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15963 {
15964   u32 *action = va_arg (*args, u32 *);
15965   u8 *s = 0;
15966
15967   if (unformat (input, "%s", &s))
15968     {
15969       if (!strcmp ((char *) s, "no-action"))
15970         action[0] = 0;
15971       else if (!strcmp ((char *) s, "natively-forward"))
15972         action[0] = 1;
15973       else if (!strcmp ((char *) s, "send-map-request"))
15974         action[0] = 2;
15975       else if (!strcmp ((char *) s, "drop"))
15976         action[0] = 3;
15977       else
15978         {
15979           clib_warning ("invalid action: '%s'", s);
15980           action[0] = 3;
15981         }
15982     }
15983   else
15984     return 0;
15985
15986   vec_free (s);
15987   return 1;
15988 }
15989
15990 /**
15991  * Add/del remote mapping to/from ONE control plane
15992  *
15993  * @param vam vpp API test context
15994  * @return return code
15995  */
15996 static int
15997 api_one_add_del_remote_mapping (vat_main_t * vam)
15998 {
15999   unformat_input_t *input = vam->input;
16000   vl_api_one_add_del_remote_mapping_t *mp;
16001   u32 vni = 0;
16002   lisp_eid_vat_t _eid, *eid = &_eid;
16003   lisp_eid_vat_t _seid, *seid = &_seid;
16004   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16005   u32 action = ~0, p, w, data_len;
16006   ip4_address_t rloc4;
16007   ip6_address_t rloc6;
16008   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16009   int ret;
16010
16011   clib_memset (&rloc, 0, sizeof (rloc));
16012
16013   /* Parse args required to build the message */
16014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16015     {
16016       if (unformat (input, "del-all"))
16017         {
16018           del_all = 1;
16019         }
16020       else if (unformat (input, "del"))
16021         {
16022           is_add = 0;
16023         }
16024       else if (unformat (input, "add"))
16025         {
16026           is_add = 1;
16027         }
16028       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16029         {
16030           eid_set = 1;
16031         }
16032       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16033         {
16034           seid_set = 1;
16035         }
16036       else if (unformat (input, "vni %d", &vni))
16037         {
16038           ;
16039         }
16040       else if (unformat (input, "p %d w %d", &p, &w))
16041         {
16042           if (!curr_rloc)
16043             {
16044               errmsg ("No RLOC configured for setting priority/weight!");
16045               return -99;
16046             }
16047           curr_rloc->priority = p;
16048           curr_rloc->weight = w;
16049         }
16050       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16051         {
16052           rloc.ip_address.af = 0;
16053           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
16054           vec_add1 (rlocs, rloc);
16055           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16056         }
16057       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16058         {
16059           rloc.ip_address.af = 1;
16060           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
16061           vec_add1 (rlocs, rloc);
16062           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16063         }
16064       else if (unformat (input, "action %U",
16065                          unformat_negative_mapping_action, &action))
16066         {
16067           ;
16068         }
16069       else
16070         {
16071           clib_warning ("parse error '%U'", format_unformat_error, input);
16072           return -99;
16073         }
16074     }
16075
16076   if (0 == eid_set)
16077     {
16078       errmsg ("missing params!");
16079       return -99;
16080     }
16081
16082   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16083     {
16084       errmsg ("no action set for negative map-reply!");
16085       return -99;
16086     }
16087
16088   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16089
16090   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16091   mp->is_add = is_add;
16092   mp->vni = htonl (vni);
16093   mp->action = (u8) action;
16094   mp->is_src_dst = seid_set;
16095   mp->del_all = del_all;
16096   lisp_eid_put_vat (&mp->deid, eid);
16097   lisp_eid_put_vat (&mp->seid, seid);
16098
16099   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16100   clib_memcpy (mp->rlocs, rlocs, data_len);
16101   vec_free (rlocs);
16102
16103   /* send it... */
16104   S (mp);
16105
16106   /* Wait for a reply... */
16107   W (ret);
16108   return ret;
16109 }
16110
16111 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16112
16113 /**
16114  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16115  * forwarding entries in data-plane accordingly.
16116  *
16117  * @param vam vpp API test context
16118  * @return return code
16119  */
16120 static int
16121 api_one_add_del_adjacency (vat_main_t * vam)
16122 {
16123   unformat_input_t *input = vam->input;
16124   vl_api_one_add_del_adjacency_t *mp;
16125   u32 vni = 0;
16126   u8 is_add = 1;
16127   int ret;
16128   lisp_eid_vat_t leid, reid;
16129
16130   leid.type = reid.type = (u8) ~ 0;
16131
16132   /* Parse args required to build the message */
16133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16134     {
16135       if (unformat (input, "del"))
16136         {
16137           is_add = 0;
16138         }
16139       else if (unformat (input, "add"))
16140         {
16141           is_add = 1;
16142         }
16143       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
16144                          &reid.addr.ip, &reid.len))
16145         {
16146           reid.type = 0;        /* ipv4 */
16147         }
16148       else if (unformat (input, "reid %U", unformat_ethernet_address,
16149                          &reid.addr.mac))
16150         {
16151           reid.type = 1;        /* mac */
16152         }
16153       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
16154                          &leid.addr.ip, &leid.len))
16155         {
16156           leid.type = 0;        /* ipv4 */
16157         }
16158       else if (unformat (input, "leid %U", unformat_ethernet_address,
16159                          &leid.addr.mac))
16160         {
16161           leid.type = 1;        /* mac */
16162         }
16163       else if (unformat (input, "vni %d", &vni))
16164         {
16165           ;
16166         }
16167       else
16168         {
16169           errmsg ("parse error '%U'", format_unformat_error, input);
16170           return -99;
16171         }
16172     }
16173
16174   if ((u8) ~ 0 == reid.type)
16175     {
16176       errmsg ("missing params!");
16177       return -99;
16178     }
16179
16180   if (leid.type != reid.type)
16181     {
16182       errmsg ("remote and local EIDs are of different types!");
16183       return -99;
16184     }
16185
16186   M (ONE_ADD_DEL_ADJACENCY, mp);
16187   mp->is_add = is_add;
16188   mp->vni = htonl (vni);
16189   lisp_eid_put_vat (&mp->leid, &leid);
16190   lisp_eid_put_vat (&mp->reid, &reid);
16191
16192   /* send it... */
16193   S (mp);
16194
16195   /* Wait for a reply... */
16196   W (ret);
16197   return ret;
16198 }
16199
16200 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16201
16202 uword
16203 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16204 {
16205   u32 *mode = va_arg (*args, u32 *);
16206
16207   if (unformat (input, "lisp"))
16208     *mode = 0;
16209   else if (unformat (input, "vxlan"))
16210     *mode = 1;
16211   else
16212     return 0;
16213
16214   return 1;
16215 }
16216
16217 static int
16218 api_gpe_get_encap_mode (vat_main_t * vam)
16219 {
16220   vl_api_gpe_get_encap_mode_t *mp;
16221   int ret;
16222
16223   /* Construct the API message */
16224   M (GPE_GET_ENCAP_MODE, mp);
16225
16226   /* send it... */
16227   S (mp);
16228
16229   /* Wait for a reply... */
16230   W (ret);
16231   return ret;
16232 }
16233
16234 static int
16235 api_gpe_set_encap_mode (vat_main_t * vam)
16236 {
16237   unformat_input_t *input = vam->input;
16238   vl_api_gpe_set_encap_mode_t *mp;
16239   int ret;
16240   u32 mode = 0;
16241
16242   /* Parse args required to build the message */
16243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16244     {
16245       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16246         ;
16247       else
16248         break;
16249     }
16250
16251   /* Construct the API message */
16252   M (GPE_SET_ENCAP_MODE, mp);
16253
16254   mp->is_vxlan = mode;
16255
16256   /* send it... */
16257   S (mp);
16258
16259   /* Wait for a reply... */
16260   W (ret);
16261   return ret;
16262 }
16263
16264 static int
16265 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16266 {
16267   unformat_input_t *input = vam->input;
16268   vl_api_gpe_add_del_iface_t *mp;
16269   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16270   u32 dp_table = 0, vni = 0;
16271   int ret;
16272
16273   /* Parse args required to build the message */
16274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16275     {
16276       if (unformat (input, "up"))
16277         {
16278           action_set = 1;
16279           is_add = 1;
16280         }
16281       else if (unformat (input, "down"))
16282         {
16283           action_set = 1;
16284           is_add = 0;
16285         }
16286       else if (unformat (input, "table_id %d", &dp_table))
16287         {
16288           dp_table_set = 1;
16289         }
16290       else if (unformat (input, "bd_id %d", &dp_table))
16291         {
16292           dp_table_set = 1;
16293           is_l2 = 1;
16294         }
16295       else if (unformat (input, "vni %d", &vni))
16296         {
16297           vni_set = 1;
16298         }
16299       else
16300         break;
16301     }
16302
16303   if (action_set == 0)
16304     {
16305       errmsg ("Action not set");
16306       return -99;
16307     }
16308   if (dp_table_set == 0 || vni_set == 0)
16309     {
16310       errmsg ("vni and dp_table must be set");
16311       return -99;
16312     }
16313
16314   /* Construct the API message */
16315   M (GPE_ADD_DEL_IFACE, mp);
16316
16317   mp->is_add = is_add;
16318   mp->dp_table = clib_host_to_net_u32 (dp_table);
16319   mp->is_l2 = is_l2;
16320   mp->vni = clib_host_to_net_u32 (vni);
16321
16322   /* send it... */
16323   S (mp);
16324
16325   /* Wait for a reply... */
16326   W (ret);
16327   return ret;
16328 }
16329
16330 static int
16331 api_one_map_register_fallback_threshold (vat_main_t * vam)
16332 {
16333   unformat_input_t *input = vam->input;
16334   vl_api_one_map_register_fallback_threshold_t *mp;
16335   u32 value = 0;
16336   u8 is_set = 0;
16337   int ret;
16338
16339   /* Parse args required to build the message */
16340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16341     {
16342       if (unformat (input, "%u", &value))
16343         is_set = 1;
16344       else
16345         {
16346           clib_warning ("parse error '%U'", format_unformat_error, input);
16347           return -99;
16348         }
16349     }
16350
16351   if (!is_set)
16352     {
16353       errmsg ("fallback threshold value is missing!");
16354       return -99;
16355     }
16356
16357   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16358   mp->value = clib_host_to_net_u32 (value);
16359
16360   /* send it... */
16361   S (mp);
16362
16363   /* Wait for a reply... */
16364   W (ret);
16365   return ret;
16366 }
16367
16368 static int
16369 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16370 {
16371   vl_api_show_one_map_register_fallback_threshold_t *mp;
16372   int ret;
16373
16374   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16375
16376   /* send it... */
16377   S (mp);
16378
16379   /* Wait for a reply... */
16380   W (ret);
16381   return ret;
16382 }
16383
16384 uword
16385 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16386 {
16387   u32 *proto = va_arg (*args, u32 *);
16388
16389   if (unformat (input, "udp"))
16390     *proto = 1;
16391   else if (unformat (input, "api"))
16392     *proto = 2;
16393   else
16394     return 0;
16395
16396   return 1;
16397 }
16398
16399 static int
16400 api_one_set_transport_protocol (vat_main_t * vam)
16401 {
16402   unformat_input_t *input = vam->input;
16403   vl_api_one_set_transport_protocol_t *mp;
16404   u8 is_set = 0;
16405   u32 protocol = 0;
16406   int ret;
16407
16408   /* Parse args required to build the message */
16409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16410     {
16411       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16412         is_set = 1;
16413       else
16414         {
16415           clib_warning ("parse error '%U'", format_unformat_error, input);
16416           return -99;
16417         }
16418     }
16419
16420   if (!is_set)
16421     {
16422       errmsg ("Transport protocol missing!");
16423       return -99;
16424     }
16425
16426   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16427   mp->protocol = (u8) protocol;
16428
16429   /* send it... */
16430   S (mp);
16431
16432   /* Wait for a reply... */
16433   W (ret);
16434   return ret;
16435 }
16436
16437 static int
16438 api_one_get_transport_protocol (vat_main_t * vam)
16439 {
16440   vl_api_one_get_transport_protocol_t *mp;
16441   int ret;
16442
16443   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16444
16445   /* send it... */
16446   S (mp);
16447
16448   /* Wait for a reply... */
16449   W (ret);
16450   return ret;
16451 }
16452
16453 static int
16454 api_one_map_register_set_ttl (vat_main_t * vam)
16455 {
16456   unformat_input_t *input = vam->input;
16457   vl_api_one_map_register_set_ttl_t *mp;
16458   u32 ttl = 0;
16459   u8 is_set = 0;
16460   int ret;
16461
16462   /* Parse args required to build the message */
16463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16464     {
16465       if (unformat (input, "%u", &ttl))
16466         is_set = 1;
16467       else
16468         {
16469           clib_warning ("parse error '%U'", format_unformat_error, input);
16470           return -99;
16471         }
16472     }
16473
16474   if (!is_set)
16475     {
16476       errmsg ("TTL value missing!");
16477       return -99;
16478     }
16479
16480   M (ONE_MAP_REGISTER_SET_TTL, mp);
16481   mp->ttl = clib_host_to_net_u32 (ttl);
16482
16483   /* send it... */
16484   S (mp);
16485
16486   /* Wait for a reply... */
16487   W (ret);
16488   return ret;
16489 }
16490
16491 static int
16492 api_show_one_map_register_ttl (vat_main_t * vam)
16493 {
16494   vl_api_show_one_map_register_ttl_t *mp;
16495   int ret;
16496
16497   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16498
16499   /* send it... */
16500   S (mp);
16501
16502   /* Wait for a reply... */
16503   W (ret);
16504   return ret;
16505 }
16506
16507 /**
16508  * Add/del map request itr rlocs from ONE control plane and updates
16509  *
16510  * @param vam vpp API test context
16511  * @return return code
16512  */
16513 static int
16514 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16515 {
16516   unformat_input_t *input = vam->input;
16517   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16518   u8 *locator_set_name = 0;
16519   u8 locator_set_name_set = 0;
16520   u8 is_add = 1;
16521   int ret;
16522
16523   /* Parse args required to build the message */
16524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16525     {
16526       if (unformat (input, "del"))
16527         {
16528           is_add = 0;
16529         }
16530       else if (unformat (input, "%_%v%_", &locator_set_name))
16531         {
16532           locator_set_name_set = 1;
16533         }
16534       else
16535         {
16536           clib_warning ("parse error '%U'", format_unformat_error, input);
16537           return -99;
16538         }
16539     }
16540
16541   if (is_add && !locator_set_name_set)
16542     {
16543       errmsg ("itr-rloc is not set!");
16544       return -99;
16545     }
16546
16547   if (is_add && vec_len (locator_set_name) > 64)
16548     {
16549       errmsg ("itr-rloc locator-set name too long");
16550       vec_free (locator_set_name);
16551       return -99;
16552     }
16553
16554   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16555   mp->is_add = is_add;
16556   if (is_add)
16557     {
16558       clib_memcpy (mp->locator_set_name, locator_set_name,
16559                    vec_len (locator_set_name));
16560     }
16561   else
16562     {
16563       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16564     }
16565   vec_free (locator_set_name);
16566
16567   /* send it... */
16568   S (mp);
16569
16570   /* Wait for a reply... */
16571   W (ret);
16572   return ret;
16573 }
16574
16575 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16576
16577 static int
16578 api_one_locator_dump (vat_main_t * vam)
16579 {
16580   unformat_input_t *input = vam->input;
16581   vl_api_one_locator_dump_t *mp;
16582   vl_api_control_ping_t *mp_ping;
16583   u8 is_index_set = 0, is_name_set = 0;
16584   u8 *ls_name = 0;
16585   u32 ls_index = ~0;
16586   int ret;
16587
16588   /* Parse args required to build the message */
16589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16590     {
16591       if (unformat (input, "ls_name %_%v%_", &ls_name))
16592         {
16593           is_name_set = 1;
16594         }
16595       else if (unformat (input, "ls_index %d", &ls_index))
16596         {
16597           is_index_set = 1;
16598         }
16599       else
16600         {
16601           errmsg ("parse error '%U'", format_unformat_error, input);
16602           return -99;
16603         }
16604     }
16605
16606   if (!is_index_set && !is_name_set)
16607     {
16608       errmsg ("error: expected one of index or name!");
16609       return -99;
16610     }
16611
16612   if (is_index_set && is_name_set)
16613     {
16614       errmsg ("error: only one param expected!");
16615       return -99;
16616     }
16617
16618   if (vec_len (ls_name) > 62)
16619     {
16620       errmsg ("error: locator set name too long!");
16621       return -99;
16622     }
16623
16624   if (!vam->json_output)
16625     {
16626       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16627     }
16628
16629   M (ONE_LOCATOR_DUMP, mp);
16630   mp->is_index_set = is_index_set;
16631
16632   if (is_index_set)
16633     mp->ls_index = clib_host_to_net_u32 (ls_index);
16634   else
16635     {
16636       vec_add1 (ls_name, 0);
16637       strncpy ((char *) mp->ls_name, (char *) ls_name,
16638                sizeof (mp->ls_name) - 1);
16639     }
16640
16641   /* send it... */
16642   S (mp);
16643
16644   /* Use a control ping for synchronization */
16645   MPING (CONTROL_PING, mp_ping);
16646   S (mp_ping);
16647
16648   /* Wait for a reply... */
16649   W (ret);
16650   return ret;
16651 }
16652
16653 #define api_lisp_locator_dump api_one_locator_dump
16654
16655 static int
16656 api_one_locator_set_dump (vat_main_t * vam)
16657 {
16658   vl_api_one_locator_set_dump_t *mp;
16659   vl_api_control_ping_t *mp_ping;
16660   unformat_input_t *input = vam->input;
16661   u8 filter = 0;
16662   int ret;
16663
16664   /* Parse args required to build the message */
16665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16666     {
16667       if (unformat (input, "local"))
16668         {
16669           filter = 1;
16670         }
16671       else if (unformat (input, "remote"))
16672         {
16673           filter = 2;
16674         }
16675       else
16676         {
16677           errmsg ("parse error '%U'", format_unformat_error, input);
16678           return -99;
16679         }
16680     }
16681
16682   if (!vam->json_output)
16683     {
16684       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16685     }
16686
16687   M (ONE_LOCATOR_SET_DUMP, mp);
16688
16689   mp->filter = filter;
16690
16691   /* send it... */
16692   S (mp);
16693
16694   /* Use a control ping for synchronization */
16695   MPING (CONTROL_PING, mp_ping);
16696   S (mp_ping);
16697
16698   /* Wait for a reply... */
16699   W (ret);
16700   return ret;
16701 }
16702
16703 #define api_lisp_locator_set_dump api_one_locator_set_dump
16704
16705 static int
16706 api_one_eid_table_map_dump (vat_main_t * vam)
16707 {
16708   u8 is_l2 = 0;
16709   u8 mode_set = 0;
16710   unformat_input_t *input = vam->input;
16711   vl_api_one_eid_table_map_dump_t *mp;
16712   vl_api_control_ping_t *mp_ping;
16713   int ret;
16714
16715   /* Parse args required to build the message */
16716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16717     {
16718       if (unformat (input, "l2"))
16719         {
16720           is_l2 = 1;
16721           mode_set = 1;
16722         }
16723       else if (unformat (input, "l3"))
16724         {
16725           is_l2 = 0;
16726           mode_set = 1;
16727         }
16728       else
16729         {
16730           errmsg ("parse error '%U'", format_unformat_error, input);
16731           return -99;
16732         }
16733     }
16734
16735   if (!mode_set)
16736     {
16737       errmsg ("expected one of 'l2' or 'l3' parameter!");
16738       return -99;
16739     }
16740
16741   if (!vam->json_output)
16742     {
16743       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16744     }
16745
16746   M (ONE_EID_TABLE_MAP_DUMP, mp);
16747   mp->is_l2 = is_l2;
16748
16749   /* send it... */
16750   S (mp);
16751
16752   /* Use a control ping for synchronization */
16753   MPING (CONTROL_PING, mp_ping);
16754   S (mp_ping);
16755
16756   /* Wait for a reply... */
16757   W (ret);
16758   return ret;
16759 }
16760
16761 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16762
16763 static int
16764 api_one_eid_table_vni_dump (vat_main_t * vam)
16765 {
16766   vl_api_one_eid_table_vni_dump_t *mp;
16767   vl_api_control_ping_t *mp_ping;
16768   int ret;
16769
16770   if (!vam->json_output)
16771     {
16772       print (vam->ofp, "VNI");
16773     }
16774
16775   M (ONE_EID_TABLE_VNI_DUMP, mp);
16776
16777   /* send it... */
16778   S (mp);
16779
16780   /* Use a control ping for synchronization */
16781   MPING (CONTROL_PING, mp_ping);
16782   S (mp_ping);
16783
16784   /* Wait for a reply... */
16785   W (ret);
16786   return ret;
16787 }
16788
16789 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16790
16791 static int
16792 api_one_eid_table_dump (vat_main_t * vam)
16793 {
16794   unformat_input_t *i = vam->input;
16795   vl_api_one_eid_table_dump_t *mp;
16796   vl_api_control_ping_t *mp_ping;
16797   u8 filter = 0;
16798   int ret;
16799   u32 vni, t = 0;
16800   lisp_eid_vat_t eid;
16801   u8 eid_set = 0;
16802
16803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16804     {
16805       if (unformat
16806           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16807         {
16808           eid_set = 1;
16809           eid.type = 0;
16810         }
16811       else
16812         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16813         {
16814           eid_set = 1;
16815           eid.type = 1;
16816         }
16817       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16818         {
16819           eid_set = 1;
16820           eid.type = 2;
16821         }
16822       else if (unformat (i, "vni %d", &t))
16823         {
16824           vni = t;
16825         }
16826       else if (unformat (i, "local"))
16827         {
16828           filter = 1;
16829         }
16830       else if (unformat (i, "remote"))
16831         {
16832           filter = 2;
16833         }
16834       else
16835         {
16836           errmsg ("parse error '%U'", format_unformat_error, i);
16837           return -99;
16838         }
16839     }
16840
16841   if (!vam->json_output)
16842     {
16843       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16844              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16845     }
16846
16847   M (ONE_EID_TABLE_DUMP, mp);
16848
16849   mp->filter = filter;
16850   if (eid_set)
16851     {
16852       mp->eid_set = 1;
16853       mp->vni = htonl (vni);
16854       lisp_eid_put_vat (&mp->eid, &eid);
16855     }
16856
16857   /* send it... */
16858   S (mp);
16859
16860   /* Use a control ping for synchronization */
16861   MPING (CONTROL_PING, mp_ping);
16862   S (mp_ping);
16863
16864   /* Wait for a reply... */
16865   W (ret);
16866   return ret;
16867 }
16868
16869 #define api_lisp_eid_table_dump api_one_eid_table_dump
16870
16871 static int
16872 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16873 {
16874   unformat_input_t *i = vam->input;
16875   vl_api_gpe_fwd_entries_get_t *mp;
16876   u8 vni_set = 0;
16877   u32 vni = ~0;
16878   int ret;
16879
16880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16881     {
16882       if (unformat (i, "vni %d", &vni))
16883         {
16884           vni_set = 1;
16885         }
16886       else
16887         {
16888           errmsg ("parse error '%U'", format_unformat_error, i);
16889           return -99;
16890         }
16891     }
16892
16893   if (!vni_set)
16894     {
16895       errmsg ("vni not set!");
16896       return -99;
16897     }
16898
16899   if (!vam->json_output)
16900     {
16901       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16902              "leid", "reid");
16903     }
16904
16905   M (GPE_FWD_ENTRIES_GET, mp);
16906   mp->vni = clib_host_to_net_u32 (vni);
16907
16908   /* send it... */
16909   S (mp);
16910
16911   /* Wait for a reply... */
16912   W (ret);
16913   return ret;
16914 }
16915
16916 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16917 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16918 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16919 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16920 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16921 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16922 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16923 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16924
16925 static int
16926 api_one_adjacencies_get (vat_main_t * vam)
16927 {
16928   unformat_input_t *i = vam->input;
16929   vl_api_one_adjacencies_get_t *mp;
16930   u8 vni_set = 0;
16931   u32 vni = ~0;
16932   int ret;
16933
16934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16935     {
16936       if (unformat (i, "vni %d", &vni))
16937         {
16938           vni_set = 1;
16939         }
16940       else
16941         {
16942           errmsg ("parse error '%U'", format_unformat_error, i);
16943           return -99;
16944         }
16945     }
16946
16947   if (!vni_set)
16948     {
16949       errmsg ("vni not set!");
16950       return -99;
16951     }
16952
16953   if (!vam->json_output)
16954     {
16955       print (vam->ofp, "%s %40s", "leid", "reid");
16956     }
16957
16958   M (ONE_ADJACENCIES_GET, mp);
16959   mp->vni = clib_host_to_net_u32 (vni);
16960
16961   /* send it... */
16962   S (mp);
16963
16964   /* Wait for a reply... */
16965   W (ret);
16966   return ret;
16967 }
16968
16969 #define api_lisp_adjacencies_get api_one_adjacencies_get
16970
16971 static int
16972 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16973 {
16974   unformat_input_t *i = vam->input;
16975   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16976   int ret;
16977   u8 ip_family_set = 0, is_ip4 = 1;
16978
16979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16980     {
16981       if (unformat (i, "ip4"))
16982         {
16983           ip_family_set = 1;
16984           is_ip4 = 1;
16985         }
16986       else if (unformat (i, "ip6"))
16987         {
16988           ip_family_set = 1;
16989           is_ip4 = 0;
16990         }
16991       else
16992         {
16993           errmsg ("parse error '%U'", format_unformat_error, i);
16994           return -99;
16995         }
16996     }
16997
16998   if (!ip_family_set)
16999     {
17000       errmsg ("ip family not set!");
17001       return -99;
17002     }
17003
17004   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17005   mp->is_ip4 = is_ip4;
17006
17007   /* send it... */
17008   S (mp);
17009
17010   /* Wait for a reply... */
17011   W (ret);
17012   return ret;
17013 }
17014
17015 static int
17016 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17017 {
17018   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17019   int ret;
17020
17021   if (!vam->json_output)
17022     {
17023       print (vam->ofp, "VNIs");
17024     }
17025
17026   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17027
17028   /* send it... */
17029   S (mp);
17030
17031   /* Wait for a reply... */
17032   W (ret);
17033   return ret;
17034 }
17035
17036 static int
17037 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17038 {
17039   unformat_input_t *i = vam->input;
17040   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17041   int ret = 0;
17042   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17043   struct in_addr ip4;
17044   struct in6_addr ip6;
17045   u32 table_id = 0, nh_sw_if_index = ~0;
17046
17047   clib_memset (&ip4, 0, sizeof (ip4));
17048   clib_memset (&ip6, 0, sizeof (ip6));
17049
17050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17051     {
17052       if (unformat (i, "del"))
17053         is_add = 0;
17054       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17055                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17056         {
17057           ip_set = 1;
17058           is_ip4 = 1;
17059         }
17060       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17061                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17062         {
17063           ip_set = 1;
17064           is_ip4 = 0;
17065         }
17066       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17067         {
17068           ip_set = 1;
17069           is_ip4 = 1;
17070           nh_sw_if_index = ~0;
17071         }
17072       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17073         {
17074           ip_set = 1;
17075           is_ip4 = 0;
17076           nh_sw_if_index = ~0;
17077         }
17078       else if (unformat (i, "table %d", &table_id))
17079         ;
17080       else
17081         {
17082           errmsg ("parse error '%U'", format_unformat_error, i);
17083           return -99;
17084         }
17085     }
17086
17087   if (!ip_set)
17088     {
17089       errmsg ("nh addr not set!");
17090       return -99;
17091     }
17092
17093   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17094   mp->is_add = is_add;
17095   mp->table_id = clib_host_to_net_u32 (table_id);
17096   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17097   mp->nh_addr.af = is_ip4 ? 0 : 1;
17098   if (is_ip4)
17099     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
17100   else
17101     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
17102
17103   /* send it... */
17104   S (mp);
17105
17106   /* Wait for a reply... */
17107   W (ret);
17108   return ret;
17109 }
17110
17111 static int
17112 api_one_map_server_dump (vat_main_t * vam)
17113 {
17114   vl_api_one_map_server_dump_t *mp;
17115   vl_api_control_ping_t *mp_ping;
17116   int ret;
17117
17118   if (!vam->json_output)
17119     {
17120       print (vam->ofp, "%=20s", "Map server");
17121     }
17122
17123   M (ONE_MAP_SERVER_DUMP, mp);
17124   /* send it... */
17125   S (mp);
17126
17127   /* Use a control ping for synchronization */
17128   MPING (CONTROL_PING, mp_ping);
17129   S (mp_ping);
17130
17131   /* Wait for a reply... */
17132   W (ret);
17133   return ret;
17134 }
17135
17136 #define api_lisp_map_server_dump api_one_map_server_dump
17137
17138 static int
17139 api_one_map_resolver_dump (vat_main_t * vam)
17140 {
17141   vl_api_one_map_resolver_dump_t *mp;
17142   vl_api_control_ping_t *mp_ping;
17143   int ret;
17144
17145   if (!vam->json_output)
17146     {
17147       print (vam->ofp, "%=20s", "Map resolver");
17148     }
17149
17150   M (ONE_MAP_RESOLVER_DUMP, mp);
17151   /* send it... */
17152   S (mp);
17153
17154   /* Use a control ping for synchronization */
17155   MPING (CONTROL_PING, mp_ping);
17156   S (mp_ping);
17157
17158   /* Wait for a reply... */
17159   W (ret);
17160   return ret;
17161 }
17162
17163 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17164
17165 static int
17166 api_one_stats_flush (vat_main_t * vam)
17167 {
17168   vl_api_one_stats_flush_t *mp;
17169   int ret = 0;
17170
17171   M (ONE_STATS_FLUSH, mp);
17172   S (mp);
17173   W (ret);
17174   return ret;
17175 }
17176
17177 static int
17178 api_one_stats_dump (vat_main_t * vam)
17179 {
17180   vl_api_one_stats_dump_t *mp;
17181   vl_api_control_ping_t *mp_ping;
17182   int ret;
17183
17184   M (ONE_STATS_DUMP, mp);
17185   /* send it... */
17186   S (mp);
17187
17188   /* Use a control ping for synchronization */
17189   MPING (CONTROL_PING, mp_ping);
17190   S (mp_ping);
17191
17192   /* Wait for a reply... */
17193   W (ret);
17194   return ret;
17195 }
17196
17197 static int
17198 api_show_one_status (vat_main_t * vam)
17199 {
17200   vl_api_show_one_status_t *mp;
17201   int ret;
17202
17203   if (!vam->json_output)
17204     {
17205       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17206     }
17207
17208   M (SHOW_ONE_STATUS, mp);
17209   /* send it... */
17210   S (mp);
17211   /* Wait for a reply... */
17212   W (ret);
17213   return ret;
17214 }
17215
17216 #define api_show_lisp_status api_show_one_status
17217
17218 static int
17219 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17220 {
17221   vl_api_gpe_fwd_entry_path_dump_t *mp;
17222   vl_api_control_ping_t *mp_ping;
17223   unformat_input_t *i = vam->input;
17224   u32 fwd_entry_index = ~0;
17225   int ret;
17226
17227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17228     {
17229       if (unformat (i, "index %d", &fwd_entry_index))
17230         ;
17231       else
17232         break;
17233     }
17234
17235   if (~0 == fwd_entry_index)
17236     {
17237       errmsg ("no index specified!");
17238       return -99;
17239     }
17240
17241   if (!vam->json_output)
17242     {
17243       print (vam->ofp, "first line");
17244     }
17245
17246   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17247
17248   /* send it... */
17249   S (mp);
17250   /* Use a control ping for synchronization */
17251   MPING (CONTROL_PING, mp_ping);
17252   S (mp_ping);
17253
17254   /* Wait for a reply... */
17255   W (ret);
17256   return ret;
17257 }
17258
17259 static int
17260 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17261 {
17262   vl_api_one_get_map_request_itr_rlocs_t *mp;
17263   int ret;
17264
17265   if (!vam->json_output)
17266     {
17267       print (vam->ofp, "%=20s", "itr-rlocs:");
17268     }
17269
17270   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17271   /* send it... */
17272   S (mp);
17273   /* Wait for a reply... */
17274   W (ret);
17275   return ret;
17276 }
17277
17278 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17279
17280 static int
17281 api_af_packet_create (vat_main_t * vam)
17282 {
17283   unformat_input_t *i = vam->input;
17284   vl_api_af_packet_create_t *mp;
17285   u8 *host_if_name = 0;
17286   u8 hw_addr[6];
17287   u8 random_hw_addr = 1;
17288   int ret;
17289
17290   clib_memset (hw_addr, 0, sizeof (hw_addr));
17291
17292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17293     {
17294       if (unformat (i, "name %s", &host_if_name))
17295         vec_add1 (host_if_name, 0);
17296       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17297         random_hw_addr = 0;
17298       else
17299         break;
17300     }
17301
17302   if (!vec_len (host_if_name))
17303     {
17304       errmsg ("host-interface name must be specified");
17305       return -99;
17306     }
17307
17308   if (vec_len (host_if_name) > 64)
17309     {
17310       errmsg ("host-interface name too long");
17311       return -99;
17312     }
17313
17314   M (AF_PACKET_CREATE, mp);
17315
17316   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17317   clib_memcpy (mp->hw_addr, hw_addr, 6);
17318   mp->use_random_hw_addr = random_hw_addr;
17319   vec_free (host_if_name);
17320
17321   S (mp);
17322
17323   /* *INDENT-OFF* */
17324   W2 (ret,
17325       ({
17326         if (ret == 0)
17327           fprintf (vam->ofp ? vam->ofp : stderr,
17328                    " new sw_if_index = %d\n", vam->sw_if_index);
17329       }));
17330   /* *INDENT-ON* */
17331   return ret;
17332 }
17333
17334 static int
17335 api_af_packet_delete (vat_main_t * vam)
17336 {
17337   unformat_input_t *i = vam->input;
17338   vl_api_af_packet_delete_t *mp;
17339   u8 *host_if_name = 0;
17340   int ret;
17341
17342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17343     {
17344       if (unformat (i, "name %s", &host_if_name))
17345         vec_add1 (host_if_name, 0);
17346       else
17347         break;
17348     }
17349
17350   if (!vec_len (host_if_name))
17351     {
17352       errmsg ("host-interface name must be specified");
17353       return -99;
17354     }
17355
17356   if (vec_len (host_if_name) > 64)
17357     {
17358       errmsg ("host-interface name too long");
17359       return -99;
17360     }
17361
17362   M (AF_PACKET_DELETE, mp);
17363
17364   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17365   vec_free (host_if_name);
17366
17367   S (mp);
17368   W (ret);
17369   return ret;
17370 }
17371
17372 static void vl_api_af_packet_details_t_handler
17373   (vl_api_af_packet_details_t * mp)
17374 {
17375   vat_main_t *vam = &vat_main;
17376
17377   print (vam->ofp, "%-16s %d",
17378          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17379 }
17380
17381 static void vl_api_af_packet_details_t_handler_json
17382   (vl_api_af_packet_details_t * mp)
17383 {
17384   vat_main_t *vam = &vat_main;
17385   vat_json_node_t *node = NULL;
17386
17387   if (VAT_JSON_ARRAY != vam->json_tree.type)
17388     {
17389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17390       vat_json_init_array (&vam->json_tree);
17391     }
17392   node = vat_json_array_add (&vam->json_tree);
17393
17394   vat_json_init_object (node);
17395   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17396   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17397 }
17398
17399 static int
17400 api_af_packet_dump (vat_main_t * vam)
17401 {
17402   vl_api_af_packet_dump_t *mp;
17403   vl_api_control_ping_t *mp_ping;
17404   int ret;
17405
17406   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17407   /* Get list of tap interfaces */
17408   M (AF_PACKET_DUMP, mp);
17409   S (mp);
17410
17411   /* Use a control ping for synchronization */
17412   MPING (CONTROL_PING, mp_ping);
17413   S (mp_ping);
17414
17415   W (ret);
17416   return ret;
17417 }
17418
17419 static int
17420 api_policer_add_del (vat_main_t * vam)
17421 {
17422   unformat_input_t *i = vam->input;
17423   vl_api_policer_add_del_t *mp;
17424   u8 is_add = 1;
17425   u8 *name = 0;
17426   u32 cir = 0;
17427   u32 eir = 0;
17428   u64 cb = 0;
17429   u64 eb = 0;
17430   u8 rate_type = 0;
17431   u8 round_type = 0;
17432   u8 type = 0;
17433   u8 color_aware = 0;
17434   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17435   int ret;
17436
17437   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17438   conform_action.dscp = 0;
17439   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17440   exceed_action.dscp = 0;
17441   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17442   violate_action.dscp = 0;
17443
17444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17445     {
17446       if (unformat (i, "del"))
17447         is_add = 0;
17448       else if (unformat (i, "name %s", &name))
17449         vec_add1 (name, 0);
17450       else if (unformat (i, "cir %u", &cir))
17451         ;
17452       else if (unformat (i, "eir %u", &eir))
17453         ;
17454       else if (unformat (i, "cb %u", &cb))
17455         ;
17456       else if (unformat (i, "eb %u", &eb))
17457         ;
17458       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17459                          &rate_type))
17460         ;
17461       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17462                          &round_type))
17463         ;
17464       else if (unformat (i, "type %U", unformat_policer_type, &type))
17465         ;
17466       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17467                          &conform_action))
17468         ;
17469       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17470                          &exceed_action))
17471         ;
17472       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17473                          &violate_action))
17474         ;
17475       else if (unformat (i, "color-aware"))
17476         color_aware = 1;
17477       else
17478         break;
17479     }
17480
17481   if (!vec_len (name))
17482     {
17483       errmsg ("policer name must be specified");
17484       return -99;
17485     }
17486
17487   if (vec_len (name) > 64)
17488     {
17489       errmsg ("policer name too long");
17490       return -99;
17491     }
17492
17493   M (POLICER_ADD_DEL, mp);
17494
17495   clib_memcpy (mp->name, name, vec_len (name));
17496   vec_free (name);
17497   mp->is_add = is_add;
17498   mp->cir = ntohl (cir);
17499   mp->eir = ntohl (eir);
17500   mp->cb = clib_net_to_host_u64 (cb);
17501   mp->eb = clib_net_to_host_u64 (eb);
17502   mp->rate_type = rate_type;
17503   mp->round_type = round_type;
17504   mp->type = type;
17505   mp->conform_action.type = conform_action.action_type;
17506   mp->conform_action.dscp = conform_action.dscp;
17507   mp->exceed_action.type = exceed_action.action_type;
17508   mp->exceed_action.dscp = exceed_action.dscp;
17509   mp->violate_action.type = violate_action.action_type;
17510   mp->violate_action.dscp = violate_action.dscp;
17511   mp->color_aware = color_aware;
17512
17513   S (mp);
17514   W (ret);
17515   return ret;
17516 }
17517
17518 static int
17519 api_policer_dump (vat_main_t * vam)
17520 {
17521   unformat_input_t *i = vam->input;
17522   vl_api_policer_dump_t *mp;
17523   vl_api_control_ping_t *mp_ping;
17524   u8 *match_name = 0;
17525   u8 match_name_valid = 0;
17526   int ret;
17527
17528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17529     {
17530       if (unformat (i, "name %s", &match_name))
17531         {
17532           vec_add1 (match_name, 0);
17533           match_name_valid = 1;
17534         }
17535       else
17536         break;
17537     }
17538
17539   M (POLICER_DUMP, mp);
17540   mp->match_name_valid = match_name_valid;
17541   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17542   vec_free (match_name);
17543   /* send it... */
17544   S (mp);
17545
17546   /* Use a control ping for synchronization */
17547   MPING (CONTROL_PING, mp_ping);
17548   S (mp_ping);
17549
17550   /* Wait for a reply... */
17551   W (ret);
17552   return ret;
17553 }
17554
17555 static int
17556 api_policer_classify_set_interface (vat_main_t * vam)
17557 {
17558   unformat_input_t *i = vam->input;
17559   vl_api_policer_classify_set_interface_t *mp;
17560   u32 sw_if_index;
17561   int sw_if_index_set;
17562   u32 ip4_table_index = ~0;
17563   u32 ip6_table_index = ~0;
17564   u32 l2_table_index = ~0;
17565   u8 is_add = 1;
17566   int ret;
17567
17568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17569     {
17570       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17571         sw_if_index_set = 1;
17572       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17573         sw_if_index_set = 1;
17574       else if (unformat (i, "del"))
17575         is_add = 0;
17576       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17577         ;
17578       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17579         ;
17580       else if (unformat (i, "l2-table %d", &l2_table_index))
17581         ;
17582       else
17583         {
17584           clib_warning ("parse error '%U'", format_unformat_error, i);
17585           return -99;
17586         }
17587     }
17588
17589   if (sw_if_index_set == 0)
17590     {
17591       errmsg ("missing interface name or sw_if_index");
17592       return -99;
17593     }
17594
17595   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17596
17597   mp->sw_if_index = ntohl (sw_if_index);
17598   mp->ip4_table_index = ntohl (ip4_table_index);
17599   mp->ip6_table_index = ntohl (ip6_table_index);
17600   mp->l2_table_index = ntohl (l2_table_index);
17601   mp->is_add = is_add;
17602
17603   S (mp);
17604   W (ret);
17605   return ret;
17606 }
17607
17608 static int
17609 api_policer_classify_dump (vat_main_t * vam)
17610 {
17611   unformat_input_t *i = vam->input;
17612   vl_api_policer_classify_dump_t *mp;
17613   vl_api_control_ping_t *mp_ping;
17614   u8 type = POLICER_CLASSIFY_N_TABLES;
17615   int ret;
17616
17617   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17618     ;
17619   else
17620     {
17621       errmsg ("classify table type must be specified");
17622       return -99;
17623     }
17624
17625   if (!vam->json_output)
17626     {
17627       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17628     }
17629
17630   M (POLICER_CLASSIFY_DUMP, mp);
17631   mp->type = type;
17632   /* send it... */
17633   S (mp);
17634
17635   /* Use a control ping for synchronization */
17636   MPING (CONTROL_PING, mp_ping);
17637   S (mp_ping);
17638
17639   /* Wait for a reply... */
17640   W (ret);
17641   return ret;
17642 }
17643
17644 static u8 *
17645 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17646 {
17647   vl_api_fib_path_nh_proto_t proto =
17648     va_arg (*args, vl_api_fib_path_nh_proto_t);
17649
17650   switch (proto)
17651     {
17652     case FIB_API_PATH_NH_PROTO_IP4:
17653       s = format (s, "ip4");
17654       break;
17655     case FIB_API_PATH_NH_PROTO_IP6:
17656       s = format (s, "ip6");
17657       break;
17658     case FIB_API_PATH_NH_PROTO_MPLS:
17659       s = format (s, "mpls");
17660       break;
17661     case FIB_API_PATH_NH_PROTO_BIER:
17662       s = format (s, "bier");
17663       break;
17664     case FIB_API_PATH_NH_PROTO_ETHERNET:
17665       s = format (s, "ethernet");
17666       break;
17667     }
17668
17669   return (s);
17670 }
17671
17672 static u8 *
17673 format_vl_api_ip_address_union (u8 * s, va_list * args)
17674 {
17675   vl_api_address_family_t af = va_arg (*args, int);
17676   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17677
17678   switch (af)
17679     {
17680     case ADDRESS_IP4:
17681       s = format (s, "%U", format_ip4_address, u->ip4);
17682       break;
17683     case ADDRESS_IP6:
17684       s = format (s, "%U", format_ip6_address, u->ip6);
17685       break;
17686     }
17687   return (s);
17688 }
17689
17690 static u8 *
17691 format_vl_api_fib_path_type (u8 * s, va_list * args)
17692 {
17693   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17694
17695   switch (t)
17696     {
17697     case FIB_API_PATH_TYPE_NORMAL:
17698       s = format (s, "normal");
17699       break;
17700     case FIB_API_PATH_TYPE_LOCAL:
17701       s = format (s, "local");
17702       break;
17703     case FIB_API_PATH_TYPE_DROP:
17704       s = format (s, "drop");
17705       break;
17706     case FIB_API_PATH_TYPE_UDP_ENCAP:
17707       s = format (s, "udp-encap");
17708       break;
17709     case FIB_API_PATH_TYPE_BIER_IMP:
17710       s = format (s, "bier-imp");
17711       break;
17712     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17713       s = format (s, "unreach");
17714       break;
17715     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17716       s = format (s, "prohibit");
17717       break;
17718     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17719       s = format (s, "src-lookup");
17720       break;
17721     case FIB_API_PATH_TYPE_DVR:
17722       s = format (s, "dvr");
17723       break;
17724     case FIB_API_PATH_TYPE_INTERFACE_RX:
17725       s = format (s, "interface-rx");
17726       break;
17727     case FIB_API_PATH_TYPE_CLASSIFY:
17728       s = format (s, "classify");
17729       break;
17730     }
17731
17732   return (s);
17733 }
17734
17735 static void
17736 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17737 {
17738   print (vam->ofp,
17739          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17740          ntohl (fp->weight), ntohl (fp->sw_if_index),
17741          format_vl_api_fib_path_type, fp->type,
17742          format_fib_api_path_nh_proto, fp->proto,
17743          format_vl_api_ip_address_union, &fp->nh.address);
17744 }
17745
17746 static void
17747 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17748                                  vl_api_fib_path_t * fp)
17749 {
17750   struct in_addr ip4;
17751   struct in6_addr ip6;
17752
17753   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17754   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17755   vat_json_object_add_uint (node, "type", fp->type);
17756   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17757   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17758     {
17759       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17760       vat_json_object_add_ip4 (node, "next_hop", ip4);
17761     }
17762   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17763     {
17764       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17765       vat_json_object_add_ip6 (node, "next_hop", ip6);
17766     }
17767 }
17768
17769 static void
17770 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17771 {
17772   vat_main_t *vam = &vat_main;
17773   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17774   vl_api_fib_path_t *fp;
17775   i32 i;
17776
17777   print (vam->ofp, "sw_if_index %d via:",
17778          ntohl (mp->mt_tunnel.mt_sw_if_index));
17779   fp = mp->mt_tunnel.mt_paths;
17780   for (i = 0; i < count; i++)
17781     {
17782       vl_api_fib_path_print (vam, fp);
17783       fp++;
17784     }
17785
17786   print (vam->ofp, "");
17787 }
17788
17789 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17790 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17791
17792 static void
17793 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17794 {
17795   vat_main_t *vam = &vat_main;
17796   vat_json_node_t *node = NULL;
17797   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17798   vl_api_fib_path_t *fp;
17799   i32 i;
17800
17801   if (VAT_JSON_ARRAY != vam->json_tree.type)
17802     {
17803       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17804       vat_json_init_array (&vam->json_tree);
17805     }
17806   node = vat_json_array_add (&vam->json_tree);
17807
17808   vat_json_init_object (node);
17809   vat_json_object_add_uint (node, "sw_if_index",
17810                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17811
17812   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17813
17814   fp = mp->mt_tunnel.mt_paths;
17815   for (i = 0; i < count; i++)
17816     {
17817       vl_api_mpls_fib_path_json_print (node, fp);
17818       fp++;
17819     }
17820 }
17821
17822 static int
17823 api_mpls_tunnel_dump (vat_main_t * vam)
17824 {
17825   vl_api_mpls_tunnel_dump_t *mp;
17826   vl_api_control_ping_t *mp_ping;
17827   int ret;
17828
17829   M (MPLS_TUNNEL_DUMP, mp);
17830
17831   S (mp);
17832
17833   /* Use a control ping for synchronization */
17834   MPING (CONTROL_PING, mp_ping);
17835   S (mp_ping);
17836
17837   W (ret);
17838   return ret;
17839 }
17840
17841 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17842 #define vl_api_mpls_table_details_t_print vl_noop_handler
17843
17844
17845 static void
17846 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17847 {
17848   vat_main_t *vam = &vat_main;
17849
17850   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17851 }
17852
17853 static void vl_api_mpls_table_details_t_handler_json
17854   (vl_api_mpls_table_details_t * mp)
17855 {
17856   vat_main_t *vam = &vat_main;
17857   vat_json_node_t *node = NULL;
17858
17859   if (VAT_JSON_ARRAY != vam->json_tree.type)
17860     {
17861       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17862       vat_json_init_array (&vam->json_tree);
17863     }
17864   node = vat_json_array_add (&vam->json_tree);
17865
17866   vat_json_init_object (node);
17867   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17868 }
17869
17870 static int
17871 api_mpls_table_dump (vat_main_t * vam)
17872 {
17873   vl_api_mpls_table_dump_t *mp;
17874   vl_api_control_ping_t *mp_ping;
17875   int ret;
17876
17877   M (MPLS_TABLE_DUMP, mp);
17878   S (mp);
17879
17880   /* Use a control ping for synchronization */
17881   MPING (CONTROL_PING, mp_ping);
17882   S (mp_ping);
17883
17884   W (ret);
17885   return ret;
17886 }
17887
17888 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17889 #define vl_api_mpls_route_details_t_print vl_noop_handler
17890
17891 static void
17892 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17893 {
17894   vat_main_t *vam = &vat_main;
17895   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17896   vl_api_fib_path_t *fp;
17897   int i;
17898
17899   print (vam->ofp,
17900          "table-id %d, label %u, ess_bit %u",
17901          ntohl (mp->mr_route.mr_table_id),
17902          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17903   fp = mp->mr_route.mr_paths;
17904   for (i = 0; i < count; i++)
17905     {
17906       vl_api_fib_path_print (vam, fp);
17907       fp++;
17908     }
17909 }
17910
17911 static void vl_api_mpls_route_details_t_handler_json
17912   (vl_api_mpls_route_details_t * mp)
17913 {
17914   vat_main_t *vam = &vat_main;
17915   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17916   vat_json_node_t *node = NULL;
17917   vl_api_fib_path_t *fp;
17918   int i;
17919
17920   if (VAT_JSON_ARRAY != vam->json_tree.type)
17921     {
17922       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17923       vat_json_init_array (&vam->json_tree);
17924     }
17925   node = vat_json_array_add (&vam->json_tree);
17926
17927   vat_json_init_object (node);
17928   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17929   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17930   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17931   vat_json_object_add_uint (node, "path_count", count);
17932   fp = mp->mr_route.mr_paths;
17933   for (i = 0; i < count; i++)
17934     {
17935       vl_api_mpls_fib_path_json_print (node, fp);
17936       fp++;
17937     }
17938 }
17939
17940 static int
17941 api_mpls_route_dump (vat_main_t * vam)
17942 {
17943   unformat_input_t *input = vam->input;
17944   vl_api_mpls_route_dump_t *mp;
17945   vl_api_control_ping_t *mp_ping;
17946   u32 table_id;
17947   int ret;
17948
17949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17950     {
17951       if (unformat (input, "table_id %d", &table_id))
17952         ;
17953       else
17954         break;
17955     }
17956   if (table_id == ~0)
17957     {
17958       errmsg ("missing table id");
17959       return -99;
17960     }
17961
17962   M (MPLS_ROUTE_DUMP, mp);
17963
17964   mp->table.mt_table_id = ntohl (table_id);
17965   S (mp);
17966
17967   /* Use a control ping for synchronization */
17968   MPING (CONTROL_PING, mp_ping);
17969   S (mp_ping);
17970
17971   W (ret);
17972   return ret;
17973 }
17974
17975 #define vl_api_ip_table_details_t_endian vl_noop_handler
17976 #define vl_api_ip_table_details_t_print vl_noop_handler
17977
17978 static void
17979 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17980 {
17981   vat_main_t *vam = &vat_main;
17982
17983   print (vam->ofp,
17984          "%s; table-id %d, prefix %U/%d",
17985          mp->table.name, ntohl (mp->table.table_id));
17986 }
17987
17988
17989 static void vl_api_ip_table_details_t_handler_json
17990   (vl_api_ip_table_details_t * mp)
17991 {
17992   vat_main_t *vam = &vat_main;
17993   vat_json_node_t *node = NULL;
17994
17995   if (VAT_JSON_ARRAY != vam->json_tree.type)
17996     {
17997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17998       vat_json_init_array (&vam->json_tree);
17999     }
18000   node = vat_json_array_add (&vam->json_tree);
18001
18002   vat_json_init_object (node);
18003   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18004 }
18005
18006 static int
18007 api_ip_table_dump (vat_main_t * vam)
18008 {
18009   vl_api_ip_table_dump_t *mp;
18010   vl_api_control_ping_t *mp_ping;
18011   int ret;
18012
18013   M (IP_TABLE_DUMP, mp);
18014   S (mp);
18015
18016   /* Use a control ping for synchronization */
18017   MPING (CONTROL_PING, mp_ping);
18018   S (mp_ping);
18019
18020   W (ret);
18021   return ret;
18022 }
18023
18024 static int
18025 api_ip_mtable_dump (vat_main_t * vam)
18026 {
18027   vl_api_ip_mtable_dump_t *mp;
18028   vl_api_control_ping_t *mp_ping;
18029   int ret;
18030
18031   M (IP_MTABLE_DUMP, mp);
18032   S (mp);
18033
18034   /* Use a control ping for synchronization */
18035   MPING (CONTROL_PING, mp_ping);
18036   S (mp_ping);
18037
18038   W (ret);
18039   return ret;
18040 }
18041
18042 static int
18043 api_ip_mroute_dump (vat_main_t * vam)
18044 {
18045   unformat_input_t *input = vam->input;
18046   vl_api_control_ping_t *mp_ping;
18047   vl_api_ip_mroute_dump_t *mp;
18048   int ret, is_ip6;
18049   u32 table_id;
18050
18051   is_ip6 = 0;
18052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18053     {
18054       if (unformat (input, "table_id %d", &table_id))
18055         ;
18056       else if (unformat (input, "ip6"))
18057         is_ip6 = 1;
18058       else if (unformat (input, "ip4"))
18059         is_ip6 = 0;
18060       else
18061         break;
18062     }
18063   if (table_id == ~0)
18064     {
18065       errmsg ("missing table id");
18066       return -99;
18067     }
18068
18069   M (IP_MROUTE_DUMP, mp);
18070   mp->table.table_id = table_id;
18071   mp->table.is_ip6 = is_ip6;
18072   S (mp);
18073
18074   /* Use a control ping for synchronization */
18075   MPING (CONTROL_PING, mp_ping);
18076   S (mp_ping);
18077
18078   W (ret);
18079   return ret;
18080 }
18081
18082 #define vl_api_ip_route_details_t_endian vl_noop_handler
18083 #define vl_api_ip_route_details_t_print vl_noop_handler
18084
18085 static void
18086 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18087 {
18088   vat_main_t *vam = &vat_main;
18089   u8 count = mp->route.n_paths;
18090   vl_api_fib_path_t *fp;
18091   int i;
18092
18093   print (vam->ofp,
18094          "table-id %d, prefix %U/%d",
18095          ntohl (mp->route.table_id),
18096          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18097   for (i = 0; i < count; i++)
18098     {
18099       fp = &mp->route.paths[i];
18100
18101       vl_api_fib_path_print (vam, fp);
18102       fp++;
18103     }
18104 }
18105
18106 static void vl_api_ip_route_details_t_handler_json
18107   (vl_api_ip_route_details_t * mp)
18108 {
18109   vat_main_t *vam = &vat_main;
18110   u8 count = mp->route.n_paths;
18111   vat_json_node_t *node = NULL;
18112   struct in_addr ip4;
18113   struct in6_addr ip6;
18114   vl_api_fib_path_t *fp;
18115   int i;
18116
18117   if (VAT_JSON_ARRAY != vam->json_tree.type)
18118     {
18119       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18120       vat_json_init_array (&vam->json_tree);
18121     }
18122   node = vat_json_array_add (&vam->json_tree);
18123
18124   vat_json_init_object (node);
18125   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18126   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18127     {
18128       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18129       vat_json_object_add_ip6 (node, "prefix", ip6);
18130     }
18131   else
18132     {
18133       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18134       vat_json_object_add_ip4 (node, "prefix", ip4);
18135     }
18136   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18137   vat_json_object_add_uint (node, "path_count", count);
18138   for (i = 0; i < count; i++)
18139     {
18140       fp = &mp->route.paths[i];
18141       vl_api_mpls_fib_path_json_print (node, fp);
18142     }
18143 }
18144
18145 static int
18146 api_ip_route_dump (vat_main_t * vam)
18147 {
18148   unformat_input_t *input = vam->input;
18149   vl_api_ip_route_dump_t *mp;
18150   vl_api_control_ping_t *mp_ping;
18151   u32 table_id;
18152   u8 is_ip6;
18153   int ret;
18154
18155   is_ip6 = 0;
18156   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18157     {
18158       if (unformat (input, "table_id %d", &table_id))
18159         ;
18160       else if (unformat (input, "ip6"))
18161         is_ip6 = 1;
18162       else if (unformat (input, "ip4"))
18163         is_ip6 = 0;
18164       else
18165         break;
18166     }
18167   if (table_id == ~0)
18168     {
18169       errmsg ("missing table id");
18170       return -99;
18171     }
18172
18173   M (IP_ROUTE_DUMP, mp);
18174
18175   mp->table.table_id = table_id;
18176   mp->table.is_ip6 = is_ip6;
18177
18178   S (mp);
18179
18180   /* Use a control ping for synchronization */
18181   MPING (CONTROL_PING, mp_ping);
18182   S (mp_ping);
18183
18184   W (ret);
18185   return ret;
18186 }
18187
18188 int
18189 api_classify_table_ids (vat_main_t * vam)
18190 {
18191   vl_api_classify_table_ids_t *mp;
18192   int ret;
18193
18194   /* Construct the API message */
18195   M (CLASSIFY_TABLE_IDS, mp);
18196   mp->context = 0;
18197
18198   S (mp);
18199   W (ret);
18200   return ret;
18201 }
18202
18203 int
18204 api_classify_table_by_interface (vat_main_t * vam)
18205 {
18206   unformat_input_t *input = vam->input;
18207   vl_api_classify_table_by_interface_t *mp;
18208
18209   u32 sw_if_index = ~0;
18210   int ret;
18211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18212     {
18213       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18214         ;
18215       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18216         ;
18217       else
18218         break;
18219     }
18220   if (sw_if_index == ~0)
18221     {
18222       errmsg ("missing interface name or sw_if_index");
18223       return -99;
18224     }
18225
18226   /* Construct the API message */
18227   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18228   mp->context = 0;
18229   mp->sw_if_index = ntohl (sw_if_index);
18230
18231   S (mp);
18232   W (ret);
18233   return ret;
18234 }
18235
18236 int
18237 api_classify_table_info (vat_main_t * vam)
18238 {
18239   unformat_input_t *input = vam->input;
18240   vl_api_classify_table_info_t *mp;
18241
18242   u32 table_id = ~0;
18243   int ret;
18244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18245     {
18246       if (unformat (input, "table_id %d", &table_id))
18247         ;
18248       else
18249         break;
18250     }
18251   if (table_id == ~0)
18252     {
18253       errmsg ("missing table id");
18254       return -99;
18255     }
18256
18257   /* Construct the API message */
18258   M (CLASSIFY_TABLE_INFO, mp);
18259   mp->context = 0;
18260   mp->table_id = ntohl (table_id);
18261
18262   S (mp);
18263   W (ret);
18264   return ret;
18265 }
18266
18267 int
18268 api_classify_session_dump (vat_main_t * vam)
18269 {
18270   unformat_input_t *input = vam->input;
18271   vl_api_classify_session_dump_t *mp;
18272   vl_api_control_ping_t *mp_ping;
18273
18274   u32 table_id = ~0;
18275   int ret;
18276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18277     {
18278       if (unformat (input, "table_id %d", &table_id))
18279         ;
18280       else
18281         break;
18282     }
18283   if (table_id == ~0)
18284     {
18285       errmsg ("missing table id");
18286       return -99;
18287     }
18288
18289   /* Construct the API message */
18290   M (CLASSIFY_SESSION_DUMP, mp);
18291   mp->context = 0;
18292   mp->table_id = ntohl (table_id);
18293   S (mp);
18294
18295   /* Use a control ping for synchronization */
18296   MPING (CONTROL_PING, mp_ping);
18297   S (mp_ping);
18298
18299   W (ret);
18300   return ret;
18301 }
18302
18303 static void
18304 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18305 {
18306   vat_main_t *vam = &vat_main;
18307
18308   print (vam->ofp, "collector_address %U, collector_port %d, "
18309          "src_address %U, vrf_id %d, path_mtu %u, "
18310          "template_interval %u, udp_checksum %d",
18311          format_ip4_address, mp->collector_address,
18312          ntohs (mp->collector_port),
18313          format_ip4_address, mp->src_address,
18314          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18315          ntohl (mp->template_interval), mp->udp_checksum);
18316
18317   vam->retval = 0;
18318   vam->result_ready = 1;
18319 }
18320
18321 static void
18322   vl_api_ipfix_exporter_details_t_handler_json
18323   (vl_api_ipfix_exporter_details_t * mp)
18324 {
18325   vat_main_t *vam = &vat_main;
18326   vat_json_node_t node;
18327   struct in_addr collector_address;
18328   struct in_addr src_address;
18329
18330   vat_json_init_object (&node);
18331   clib_memcpy (&collector_address, &mp->collector_address,
18332                sizeof (collector_address));
18333   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18334   vat_json_object_add_uint (&node, "collector_port",
18335                             ntohs (mp->collector_port));
18336   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18337   vat_json_object_add_ip4 (&node, "src_address", src_address);
18338   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18339   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18340   vat_json_object_add_uint (&node, "template_interval",
18341                             ntohl (mp->template_interval));
18342   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18343
18344   vat_json_print (vam->ofp, &node);
18345   vat_json_free (&node);
18346   vam->retval = 0;
18347   vam->result_ready = 1;
18348 }
18349
18350 int
18351 api_ipfix_exporter_dump (vat_main_t * vam)
18352 {
18353   vl_api_ipfix_exporter_dump_t *mp;
18354   int ret;
18355
18356   /* Construct the API message */
18357   M (IPFIX_EXPORTER_DUMP, mp);
18358   mp->context = 0;
18359
18360   S (mp);
18361   W (ret);
18362   return ret;
18363 }
18364
18365 static int
18366 api_ipfix_classify_stream_dump (vat_main_t * vam)
18367 {
18368   vl_api_ipfix_classify_stream_dump_t *mp;
18369   int ret;
18370
18371   /* Construct the API message */
18372   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18373   mp->context = 0;
18374
18375   S (mp);
18376   W (ret);
18377   return ret;
18378   /* NOTREACHED */
18379   return 0;
18380 }
18381
18382 static void
18383   vl_api_ipfix_classify_stream_details_t_handler
18384   (vl_api_ipfix_classify_stream_details_t * mp)
18385 {
18386   vat_main_t *vam = &vat_main;
18387   print (vam->ofp, "domain_id %d, src_port %d",
18388          ntohl (mp->domain_id), ntohs (mp->src_port));
18389   vam->retval = 0;
18390   vam->result_ready = 1;
18391 }
18392
18393 static void
18394   vl_api_ipfix_classify_stream_details_t_handler_json
18395   (vl_api_ipfix_classify_stream_details_t * mp)
18396 {
18397   vat_main_t *vam = &vat_main;
18398   vat_json_node_t node;
18399
18400   vat_json_init_object (&node);
18401   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18402   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18403
18404   vat_json_print (vam->ofp, &node);
18405   vat_json_free (&node);
18406   vam->retval = 0;
18407   vam->result_ready = 1;
18408 }
18409
18410 static int
18411 api_ipfix_classify_table_dump (vat_main_t * vam)
18412 {
18413   vl_api_ipfix_classify_table_dump_t *mp;
18414   vl_api_control_ping_t *mp_ping;
18415   int ret;
18416
18417   if (!vam->json_output)
18418     {
18419       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18420              "transport_protocol");
18421     }
18422
18423   /* Construct the API message */
18424   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18425
18426   /* send it... */
18427   S (mp);
18428
18429   /* Use a control ping for synchronization */
18430   MPING (CONTROL_PING, mp_ping);
18431   S (mp_ping);
18432
18433   W (ret);
18434   return ret;
18435 }
18436
18437 static void
18438   vl_api_ipfix_classify_table_details_t_handler
18439   (vl_api_ipfix_classify_table_details_t * mp)
18440 {
18441   vat_main_t *vam = &vat_main;
18442   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18443          mp->transport_protocol);
18444 }
18445
18446 static void
18447   vl_api_ipfix_classify_table_details_t_handler_json
18448   (vl_api_ipfix_classify_table_details_t * mp)
18449 {
18450   vat_json_node_t *node = NULL;
18451   vat_main_t *vam = &vat_main;
18452
18453   if (VAT_JSON_ARRAY != vam->json_tree.type)
18454     {
18455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18456       vat_json_init_array (&vam->json_tree);
18457     }
18458
18459   node = vat_json_array_add (&vam->json_tree);
18460   vat_json_init_object (node);
18461
18462   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18463   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18464   vat_json_object_add_uint (node, "transport_protocol",
18465                             mp->transport_protocol);
18466 }
18467
18468 static int
18469 api_sw_interface_span_enable_disable (vat_main_t * vam)
18470 {
18471   unformat_input_t *i = vam->input;
18472   vl_api_sw_interface_span_enable_disable_t *mp;
18473   u32 src_sw_if_index = ~0;
18474   u32 dst_sw_if_index = ~0;
18475   u8 state = 3;
18476   int ret;
18477   u8 is_l2 = 0;
18478
18479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18480     {
18481       if (unformat
18482           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18483         ;
18484       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18485         ;
18486       else
18487         if (unformat
18488             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18489         ;
18490       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18491         ;
18492       else if (unformat (i, "disable"))
18493         state = 0;
18494       else if (unformat (i, "rx"))
18495         state = 1;
18496       else if (unformat (i, "tx"))
18497         state = 2;
18498       else if (unformat (i, "both"))
18499         state = 3;
18500       else if (unformat (i, "l2"))
18501         is_l2 = 1;
18502       else
18503         break;
18504     }
18505
18506   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18507
18508   mp->sw_if_index_from = htonl (src_sw_if_index);
18509   mp->sw_if_index_to = htonl (dst_sw_if_index);
18510   mp->state = state;
18511   mp->is_l2 = is_l2;
18512
18513   S (mp);
18514   W (ret);
18515   return ret;
18516 }
18517
18518 static void
18519 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18520                                             * mp)
18521 {
18522   vat_main_t *vam = &vat_main;
18523   u8 *sw_if_from_name = 0;
18524   u8 *sw_if_to_name = 0;
18525   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18526   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18527   char *states[] = { "none", "rx", "tx", "both" };
18528   hash_pair_t *p;
18529
18530   /* *INDENT-OFF* */
18531   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18532   ({
18533     if ((u32) p->value[0] == sw_if_index_from)
18534       {
18535         sw_if_from_name = (u8 *)(p->key);
18536         if (sw_if_to_name)
18537           break;
18538       }
18539     if ((u32) p->value[0] == sw_if_index_to)
18540       {
18541         sw_if_to_name = (u8 *)(p->key);
18542         if (sw_if_from_name)
18543           break;
18544       }
18545   }));
18546   /* *INDENT-ON* */
18547   print (vam->ofp, "%20s => %20s (%s) %s",
18548          sw_if_from_name, sw_if_to_name, states[mp->state],
18549          mp->is_l2 ? "l2" : "device");
18550 }
18551
18552 static void
18553   vl_api_sw_interface_span_details_t_handler_json
18554   (vl_api_sw_interface_span_details_t * mp)
18555 {
18556   vat_main_t *vam = &vat_main;
18557   vat_json_node_t *node = NULL;
18558   u8 *sw_if_from_name = 0;
18559   u8 *sw_if_to_name = 0;
18560   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18561   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18562   hash_pair_t *p;
18563
18564   /* *INDENT-OFF* */
18565   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18566   ({
18567     if ((u32) p->value[0] == sw_if_index_from)
18568       {
18569         sw_if_from_name = (u8 *)(p->key);
18570         if (sw_if_to_name)
18571           break;
18572       }
18573     if ((u32) p->value[0] == sw_if_index_to)
18574       {
18575         sw_if_to_name = (u8 *)(p->key);
18576         if (sw_if_from_name)
18577           break;
18578       }
18579   }));
18580   /* *INDENT-ON* */
18581
18582   if (VAT_JSON_ARRAY != vam->json_tree.type)
18583     {
18584       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18585       vat_json_init_array (&vam->json_tree);
18586     }
18587   node = vat_json_array_add (&vam->json_tree);
18588
18589   vat_json_init_object (node);
18590   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18591   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18592   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18593   if (0 != sw_if_to_name)
18594     {
18595       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18596     }
18597   vat_json_object_add_uint (node, "state", mp->state);
18598   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18599 }
18600
18601 static int
18602 api_sw_interface_span_dump (vat_main_t * vam)
18603 {
18604   unformat_input_t *input = vam->input;
18605   vl_api_sw_interface_span_dump_t *mp;
18606   vl_api_control_ping_t *mp_ping;
18607   u8 is_l2 = 0;
18608   int ret;
18609
18610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18611     {
18612       if (unformat (input, "l2"))
18613         is_l2 = 1;
18614       else
18615         break;
18616     }
18617
18618   M (SW_INTERFACE_SPAN_DUMP, mp);
18619   mp->is_l2 = is_l2;
18620   S (mp);
18621
18622   /* Use a control ping for synchronization */
18623   MPING (CONTROL_PING, mp_ping);
18624   S (mp_ping);
18625
18626   W (ret);
18627   return ret;
18628 }
18629
18630 int
18631 api_pg_create_interface (vat_main_t * vam)
18632 {
18633   unformat_input_t *input = vam->input;
18634   vl_api_pg_create_interface_t *mp;
18635
18636   u32 if_id = ~0, gso_size = 0;
18637   u8 gso_enabled = 0;
18638   int ret;
18639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18640     {
18641       if (unformat (input, "if_id %d", &if_id))
18642         ;
18643       else if (unformat (input, "gso-enabled"))
18644         {
18645           gso_enabled = 1;
18646           if (unformat (input, "gso-size %u", &gso_size))
18647             ;
18648           else
18649             {
18650               errmsg ("missing gso-size");
18651               return -99;
18652             }
18653         }
18654       else
18655         break;
18656     }
18657   if (if_id == ~0)
18658     {
18659       errmsg ("missing pg interface index");
18660       return -99;
18661     }
18662
18663   /* Construct the API message */
18664   M (PG_CREATE_INTERFACE, mp);
18665   mp->context = 0;
18666   mp->interface_id = ntohl (if_id);
18667   mp->gso_enabled = gso_enabled;
18668
18669   S (mp);
18670   W (ret);
18671   return ret;
18672 }
18673
18674 int
18675 api_pg_capture (vat_main_t * vam)
18676 {
18677   unformat_input_t *input = vam->input;
18678   vl_api_pg_capture_t *mp;
18679
18680   u32 if_id = ~0;
18681   u8 enable = 1;
18682   u32 count = 1;
18683   u8 pcap_file_set = 0;
18684   u8 *pcap_file = 0;
18685   int ret;
18686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18687     {
18688       if (unformat (input, "if_id %d", &if_id))
18689         ;
18690       else if (unformat (input, "pcap %s", &pcap_file))
18691         pcap_file_set = 1;
18692       else if (unformat (input, "count %d", &count))
18693         ;
18694       else if (unformat (input, "disable"))
18695         enable = 0;
18696       else
18697         break;
18698     }
18699   if (if_id == ~0)
18700     {
18701       errmsg ("missing pg interface index");
18702       return -99;
18703     }
18704   if (pcap_file_set > 0)
18705     {
18706       if (vec_len (pcap_file) > 255)
18707         {
18708           errmsg ("pcap file name is too long");
18709           return -99;
18710         }
18711     }
18712
18713   /* Construct the API message */
18714   M (PG_CAPTURE, mp);
18715   mp->context = 0;
18716   mp->interface_id = ntohl (if_id);
18717   mp->is_enabled = enable;
18718   mp->count = ntohl (count);
18719   if (pcap_file_set != 0)
18720     {
18721       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18722     }
18723   vec_free (pcap_file);
18724
18725   S (mp);
18726   W (ret);
18727   return ret;
18728 }
18729
18730 int
18731 api_pg_enable_disable (vat_main_t * vam)
18732 {
18733   unformat_input_t *input = vam->input;
18734   vl_api_pg_enable_disable_t *mp;
18735
18736   u8 enable = 1;
18737   u8 stream_name_set = 0;
18738   u8 *stream_name = 0;
18739   int ret;
18740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18741     {
18742       if (unformat (input, "stream %s", &stream_name))
18743         stream_name_set = 1;
18744       else if (unformat (input, "disable"))
18745         enable = 0;
18746       else
18747         break;
18748     }
18749
18750   if (stream_name_set > 0)
18751     {
18752       if (vec_len (stream_name) > 255)
18753         {
18754           errmsg ("stream name too long");
18755           return -99;
18756         }
18757     }
18758
18759   /* Construct the API message */
18760   M (PG_ENABLE_DISABLE, mp);
18761   mp->context = 0;
18762   mp->is_enabled = enable;
18763   if (stream_name_set != 0)
18764     {
18765       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18766     }
18767   vec_free (stream_name);
18768
18769   S (mp);
18770   W (ret);
18771   return ret;
18772 }
18773
18774 int
18775 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
18776 {
18777   unformat_input_t *input = vam->input;
18778   vl_api_pg_interface_enable_disable_coalesce_t *mp;
18779
18780   u32 sw_if_index = ~0;
18781   u8 enable = 1;
18782   int ret;
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, "disable"))
18790         enable = 0;
18791       else
18792         break;
18793     }
18794
18795   if (sw_if_index == ~0)
18796     {
18797       errmsg ("Interface required but not specified");
18798       return -99;
18799     }
18800
18801   /* Construct the API message */
18802   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
18803   mp->context = 0;
18804   mp->coalesce_enabled = enable;
18805   mp->sw_if_index = htonl (sw_if_index);
18806
18807   S (mp);
18808   W (ret);
18809   return ret;
18810 }
18811
18812 int
18813 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18814 {
18815   unformat_input_t *input = vam->input;
18816   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18817
18818   u16 *low_ports = 0;
18819   u16 *high_ports = 0;
18820   u16 this_low;
18821   u16 this_hi;
18822   vl_api_prefix_t prefix;
18823   u32 tmp, tmp2;
18824   u8 prefix_set = 0;
18825   u32 vrf_id = ~0;
18826   u8 is_add = 1;
18827   int ret;
18828
18829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18830     {
18831       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18832         prefix_set = 1;
18833       else if (unformat (input, "vrf %d", &vrf_id))
18834         ;
18835       else if (unformat (input, "del"))
18836         is_add = 0;
18837       else if (unformat (input, "port %d", &tmp))
18838         {
18839           if (tmp == 0 || tmp > 65535)
18840             {
18841               errmsg ("port %d out of range", tmp);
18842               return -99;
18843             }
18844           this_low = tmp;
18845           this_hi = this_low + 1;
18846           vec_add1 (low_ports, this_low);
18847           vec_add1 (high_ports, this_hi);
18848         }
18849       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18850         {
18851           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18852             {
18853               errmsg ("incorrect range parameters");
18854               return -99;
18855             }
18856           this_low = tmp;
18857           /* Note: in debug CLI +1 is added to high before
18858              passing to real fn that does "the work"
18859              (ip_source_and_port_range_check_add_del).
18860              This fn is a wrapper around the binary API fn a
18861              control plane will call, which expects this increment
18862              to have occurred. Hence letting the binary API control
18863              plane fn do the increment for consistency between VAT
18864              and other control planes.
18865            */
18866           this_hi = tmp2;
18867           vec_add1 (low_ports, this_low);
18868           vec_add1 (high_ports, this_hi);
18869         }
18870       else
18871         break;
18872     }
18873
18874   if (prefix_set == 0)
18875     {
18876       errmsg ("<address>/<mask> not specified");
18877       return -99;
18878     }
18879
18880   if (vrf_id == ~0)
18881     {
18882       errmsg ("VRF ID required, not specified");
18883       return -99;
18884     }
18885
18886   if (vrf_id == 0)
18887     {
18888       errmsg
18889         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18890       return -99;
18891     }
18892
18893   if (vec_len (low_ports) == 0)
18894     {
18895       errmsg ("At least one port or port range required");
18896       return -99;
18897     }
18898
18899   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18900
18901   mp->is_add = is_add;
18902
18903   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18904
18905   mp->number_of_ranges = vec_len (low_ports);
18906
18907   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18908   vec_free (low_ports);
18909
18910   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18911   vec_free (high_ports);
18912
18913   mp->vrf_id = ntohl (vrf_id);
18914
18915   S (mp);
18916   W (ret);
18917   return ret;
18918 }
18919
18920 int
18921 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18922 {
18923   unformat_input_t *input = vam->input;
18924   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18925   u32 sw_if_index = ~0;
18926   int vrf_set = 0;
18927   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18928   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18929   u8 is_add = 1;
18930   int ret;
18931
18932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18933     {
18934       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18935         ;
18936       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18937         ;
18938       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18939         vrf_set = 1;
18940       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18941         vrf_set = 1;
18942       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18943         vrf_set = 1;
18944       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18945         vrf_set = 1;
18946       else if (unformat (input, "del"))
18947         is_add = 0;
18948       else
18949         break;
18950     }
18951
18952   if (sw_if_index == ~0)
18953     {
18954       errmsg ("Interface required but not specified");
18955       return -99;
18956     }
18957
18958   if (vrf_set == 0)
18959     {
18960       errmsg ("VRF ID required but not specified");
18961       return -99;
18962     }
18963
18964   if (tcp_out_vrf_id == 0
18965       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18966     {
18967       errmsg
18968         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18969       return -99;
18970     }
18971
18972   /* Construct the API message */
18973   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18974
18975   mp->sw_if_index = ntohl (sw_if_index);
18976   mp->is_add = is_add;
18977   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18978   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18979   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18980   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18981
18982   /* send it... */
18983   S (mp);
18984
18985   /* Wait for a reply... */
18986   W (ret);
18987   return ret;
18988 }
18989
18990 static int
18991 api_set_punt (vat_main_t * vam)
18992 {
18993   unformat_input_t *i = vam->input;
18994   vl_api_address_family_t af;
18995   vl_api_set_punt_t *mp;
18996   u32 protocol = ~0;
18997   u32 port = ~0;
18998   int is_add = 1;
18999   int ret;
19000
19001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19002     {
19003       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19004         ;
19005       else if (unformat (i, "protocol %d", &protocol))
19006         ;
19007       else if (unformat (i, "port %d", &port))
19008         ;
19009       else if (unformat (i, "del"))
19010         is_add = 0;
19011       else
19012         {
19013           clib_warning ("parse error '%U'", format_unformat_error, i);
19014           return -99;
19015         }
19016     }
19017
19018   M (SET_PUNT, mp);
19019
19020   mp->is_add = (u8) is_add;
19021   mp->punt.type = PUNT_API_TYPE_L4;
19022   mp->punt.punt.l4.af = af;
19023   mp->punt.punt.l4.protocol = (u8) protocol;
19024   mp->punt.punt.l4.port = htons ((u16) port);
19025
19026   S (mp);
19027   W (ret);
19028   return ret;
19029 }
19030
19031 static int
19032 api_delete_subif (vat_main_t * vam)
19033 {
19034   unformat_input_t *i = vam->input;
19035   vl_api_delete_subif_t *mp;
19036   u32 sw_if_index = ~0;
19037   int ret;
19038
19039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19040     {
19041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19042         ;
19043       if (unformat (i, "sw_if_index %d", &sw_if_index))
19044         ;
19045       else
19046         break;
19047     }
19048
19049   if (sw_if_index == ~0)
19050     {
19051       errmsg ("missing sw_if_index");
19052       return -99;
19053     }
19054
19055   /* Construct the API message */
19056   M (DELETE_SUBIF, mp);
19057   mp->sw_if_index = ntohl (sw_if_index);
19058
19059   S (mp);
19060   W (ret);
19061   return ret;
19062 }
19063
19064 #define foreach_pbb_vtr_op      \
19065 _("disable",  L2_VTR_DISABLED)  \
19066 _("pop",  L2_VTR_POP_2)         \
19067 _("push",  L2_VTR_PUSH_2)
19068
19069 static int
19070 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19071 {
19072   unformat_input_t *i = vam->input;
19073   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19074   u32 sw_if_index = ~0, vtr_op = ~0;
19075   u16 outer_tag = ~0;
19076   u8 dmac[6], smac[6];
19077   u8 dmac_set = 0, smac_set = 0;
19078   u16 vlanid = 0;
19079   u32 sid = ~0;
19080   u32 tmp;
19081   int ret;
19082
19083   /* Shut up coverity */
19084   clib_memset (dmac, 0, sizeof (dmac));
19085   clib_memset (smac, 0, sizeof (smac));
19086
19087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19088     {
19089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19090         ;
19091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19092         ;
19093       else if (unformat (i, "vtr_op %d", &vtr_op))
19094         ;
19095 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19096       foreach_pbb_vtr_op
19097 #undef _
19098         else if (unformat (i, "translate_pbb_stag"))
19099         {
19100           if (unformat (i, "%d", &tmp))
19101             {
19102               vtr_op = L2_VTR_TRANSLATE_2_1;
19103               outer_tag = tmp;
19104             }
19105           else
19106             {
19107               errmsg
19108                 ("translate_pbb_stag operation requires outer tag definition");
19109               return -99;
19110             }
19111         }
19112       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19113         dmac_set++;
19114       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19115         smac_set++;
19116       else if (unformat (i, "sid %d", &sid))
19117         ;
19118       else if (unformat (i, "vlanid %d", &tmp))
19119         vlanid = tmp;
19120       else
19121         {
19122           clib_warning ("parse error '%U'", format_unformat_error, i);
19123           return -99;
19124         }
19125     }
19126
19127   if ((sw_if_index == ~0) || (vtr_op == ~0))
19128     {
19129       errmsg ("missing sw_if_index or vtr operation");
19130       return -99;
19131     }
19132   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19133       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19134     {
19135       errmsg
19136         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19137       return -99;
19138     }
19139
19140   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19141   mp->sw_if_index = ntohl (sw_if_index);
19142   mp->vtr_op = ntohl (vtr_op);
19143   mp->outer_tag = ntohs (outer_tag);
19144   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19145   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19146   mp->b_vlanid = ntohs (vlanid);
19147   mp->i_sid = ntohl (sid);
19148
19149   S (mp);
19150   W (ret);
19151   return ret;
19152 }
19153
19154 static int
19155 api_flow_classify_set_interface (vat_main_t * vam)
19156 {
19157   unformat_input_t *i = vam->input;
19158   vl_api_flow_classify_set_interface_t *mp;
19159   u32 sw_if_index;
19160   int sw_if_index_set;
19161   u32 ip4_table_index = ~0;
19162   u32 ip6_table_index = ~0;
19163   u8 is_add = 1;
19164   int ret;
19165
19166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19167     {
19168       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19169         sw_if_index_set = 1;
19170       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19171         sw_if_index_set = 1;
19172       else if (unformat (i, "del"))
19173         is_add = 0;
19174       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19175         ;
19176       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19177         ;
19178       else
19179         {
19180           clib_warning ("parse error '%U'", format_unformat_error, i);
19181           return -99;
19182         }
19183     }
19184
19185   if (sw_if_index_set == 0)
19186     {
19187       errmsg ("missing interface name or sw_if_index");
19188       return -99;
19189     }
19190
19191   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19192
19193   mp->sw_if_index = ntohl (sw_if_index);
19194   mp->ip4_table_index = ntohl (ip4_table_index);
19195   mp->ip6_table_index = ntohl (ip6_table_index);
19196   mp->is_add = is_add;
19197
19198   S (mp);
19199   W (ret);
19200   return ret;
19201 }
19202
19203 static int
19204 api_flow_classify_dump (vat_main_t * vam)
19205 {
19206   unformat_input_t *i = vam->input;
19207   vl_api_flow_classify_dump_t *mp;
19208   vl_api_control_ping_t *mp_ping;
19209   u8 type = FLOW_CLASSIFY_N_TABLES;
19210   int ret;
19211
19212   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19213     ;
19214   else
19215     {
19216       errmsg ("classify table type must be specified");
19217       return -99;
19218     }
19219
19220   if (!vam->json_output)
19221     {
19222       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19223     }
19224
19225   M (FLOW_CLASSIFY_DUMP, mp);
19226   mp->type = type;
19227   /* send it... */
19228   S (mp);
19229
19230   /* Use a control ping for synchronization */
19231   MPING (CONTROL_PING, mp_ping);
19232   S (mp_ping);
19233
19234   /* Wait for a reply... */
19235   W (ret);
19236   return ret;
19237 }
19238
19239 static int
19240 api_feature_enable_disable (vat_main_t * vam)
19241 {
19242   unformat_input_t *i = vam->input;
19243   vl_api_feature_enable_disable_t *mp;
19244   u8 *arc_name = 0;
19245   u8 *feature_name = 0;
19246   u32 sw_if_index = ~0;
19247   u8 enable = 1;
19248   int ret;
19249
19250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19251     {
19252       if (unformat (i, "arc_name %s", &arc_name))
19253         ;
19254       else if (unformat (i, "feature_name %s", &feature_name))
19255         ;
19256       else
19257         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19258         ;
19259       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19260         ;
19261       else if (unformat (i, "disable"))
19262         enable = 0;
19263       else
19264         break;
19265     }
19266
19267   if (arc_name == 0)
19268     {
19269       errmsg ("missing arc name");
19270       return -99;
19271     }
19272   if (vec_len (arc_name) > 63)
19273     {
19274       errmsg ("arc name too long");
19275     }
19276
19277   if (feature_name == 0)
19278     {
19279       errmsg ("missing feature name");
19280       return -99;
19281     }
19282   if (vec_len (feature_name) > 63)
19283     {
19284       errmsg ("feature name too long");
19285     }
19286
19287   if (sw_if_index == ~0)
19288     {
19289       errmsg ("missing interface name or sw_if_index");
19290       return -99;
19291     }
19292
19293   /* Construct the API message */
19294   M (FEATURE_ENABLE_DISABLE, mp);
19295   mp->sw_if_index = ntohl (sw_if_index);
19296   mp->enable = enable;
19297   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19298   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19299   vec_free (arc_name);
19300   vec_free (feature_name);
19301
19302   S (mp);
19303   W (ret);
19304   return ret;
19305 }
19306
19307 static int
19308 api_feature_gso_enable_disable (vat_main_t * vam)
19309 {
19310   unformat_input_t *i = vam->input;
19311   vl_api_feature_gso_enable_disable_t *mp;
19312   u32 sw_if_index = ~0;
19313   u8 enable = 1;
19314   int ret;
19315
19316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19317     {
19318       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19319         ;
19320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19321         ;
19322       else if (unformat (i, "enable"))
19323         enable = 1;
19324       else if (unformat (i, "disable"))
19325         enable = 0;
19326       else
19327         break;
19328     }
19329
19330   if (sw_if_index == ~0)
19331     {
19332       errmsg ("missing interface name or sw_if_index");
19333       return -99;
19334     }
19335
19336   /* Construct the API message */
19337   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19338   mp->sw_if_index = ntohl (sw_if_index);
19339   mp->enable_disable = enable;
19340
19341   S (mp);
19342   W (ret);
19343   return ret;
19344 }
19345
19346 static int
19347 api_sw_interface_tag_add_del (vat_main_t * vam)
19348 {
19349   unformat_input_t *i = vam->input;
19350   vl_api_sw_interface_tag_add_del_t *mp;
19351   u32 sw_if_index = ~0;
19352   u8 *tag = 0;
19353   u8 enable = 1;
19354   int ret;
19355
19356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19357     {
19358       if (unformat (i, "tag %s", &tag))
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 if (unformat (i, "del"))
19365         enable = 0;
19366       else
19367         break;
19368     }
19369
19370   if (sw_if_index == ~0)
19371     {
19372       errmsg ("missing interface name or sw_if_index");
19373       return -99;
19374     }
19375
19376   if (enable && (tag == 0))
19377     {
19378       errmsg ("no tag specified");
19379       return -99;
19380     }
19381
19382   /* Construct the API message */
19383   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19384   mp->sw_if_index = ntohl (sw_if_index);
19385   mp->is_add = enable;
19386   if (enable)
19387     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19388   vec_free (tag);
19389
19390   S (mp);
19391   W (ret);
19392   return ret;
19393 }
19394
19395 static int
19396 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19397 {
19398   unformat_input_t *i = vam->input;
19399   vl_api_mac_address_t mac = { 0 };
19400   vl_api_sw_interface_add_del_mac_address_t *mp;
19401   u32 sw_if_index = ~0;
19402   u8 is_add = 1;
19403   u8 mac_set = 0;
19404   int ret;
19405
19406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19407     {
19408       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19409         ;
19410       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19411         ;
19412       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19413         mac_set++;
19414       else if (unformat (i, "del"))
19415         is_add = 0;
19416       else
19417         break;
19418     }
19419
19420   if (sw_if_index == ~0)
19421     {
19422       errmsg ("missing interface name or sw_if_index");
19423       return -99;
19424     }
19425
19426   if (!mac_set)
19427     {
19428       errmsg ("missing MAC address");
19429       return -99;
19430     }
19431
19432   /* Construct the API message */
19433   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19434   mp->sw_if_index = ntohl (sw_if_index);
19435   mp->is_add = is_add;
19436   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19437
19438   S (mp);
19439   W (ret);
19440   return ret;
19441 }
19442
19443 static void vl_api_l2_xconnect_details_t_handler
19444   (vl_api_l2_xconnect_details_t * mp)
19445 {
19446   vat_main_t *vam = &vat_main;
19447
19448   print (vam->ofp, "%15d%15d",
19449          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19450 }
19451
19452 static void vl_api_l2_xconnect_details_t_handler_json
19453   (vl_api_l2_xconnect_details_t * mp)
19454 {
19455   vat_main_t *vam = &vat_main;
19456   vat_json_node_t *node = NULL;
19457
19458   if (VAT_JSON_ARRAY != vam->json_tree.type)
19459     {
19460       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19461       vat_json_init_array (&vam->json_tree);
19462     }
19463   node = vat_json_array_add (&vam->json_tree);
19464
19465   vat_json_init_object (node);
19466   vat_json_object_add_uint (node, "rx_sw_if_index",
19467                             ntohl (mp->rx_sw_if_index));
19468   vat_json_object_add_uint (node, "tx_sw_if_index",
19469                             ntohl (mp->tx_sw_if_index));
19470 }
19471
19472 static int
19473 api_l2_xconnect_dump (vat_main_t * vam)
19474 {
19475   vl_api_l2_xconnect_dump_t *mp;
19476   vl_api_control_ping_t *mp_ping;
19477   int ret;
19478
19479   if (!vam->json_output)
19480     {
19481       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19482     }
19483
19484   M (L2_XCONNECT_DUMP, mp);
19485
19486   S (mp);
19487
19488   /* Use a control ping for synchronization */
19489   MPING (CONTROL_PING, mp_ping);
19490   S (mp_ping);
19491
19492   W (ret);
19493   return ret;
19494 }
19495
19496 static int
19497 api_hw_interface_set_mtu (vat_main_t * vam)
19498 {
19499   unformat_input_t *i = vam->input;
19500   vl_api_hw_interface_set_mtu_t *mp;
19501   u32 sw_if_index = ~0;
19502   u32 mtu = 0;
19503   int ret;
19504
19505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19506     {
19507       if (unformat (i, "mtu %d", &mtu))
19508         ;
19509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19510         ;
19511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19512         ;
19513       else
19514         break;
19515     }
19516
19517   if (sw_if_index == ~0)
19518     {
19519       errmsg ("missing interface name or sw_if_index");
19520       return -99;
19521     }
19522
19523   if (mtu == 0)
19524     {
19525       errmsg ("no mtu specified");
19526       return -99;
19527     }
19528
19529   /* Construct the API message */
19530   M (HW_INTERFACE_SET_MTU, mp);
19531   mp->sw_if_index = ntohl (sw_if_index);
19532   mp->mtu = ntohs ((u16) mtu);
19533
19534   S (mp);
19535   W (ret);
19536   return ret;
19537 }
19538
19539 static int
19540 api_p2p_ethernet_add (vat_main_t * vam)
19541 {
19542   unformat_input_t *i = vam->input;
19543   vl_api_p2p_ethernet_add_t *mp;
19544   u32 parent_if_index = ~0;
19545   u32 sub_id = ~0;
19546   u8 remote_mac[6];
19547   u8 mac_set = 0;
19548   int ret;
19549
19550   clib_memset (remote_mac, 0, sizeof (remote_mac));
19551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19552     {
19553       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19554         ;
19555       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19556         ;
19557       else
19558         if (unformat
19559             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19560         mac_set++;
19561       else if (unformat (i, "sub_id %d", &sub_id))
19562         ;
19563       else
19564         {
19565           clib_warning ("parse error '%U'", format_unformat_error, i);
19566           return -99;
19567         }
19568     }
19569
19570   if (parent_if_index == ~0)
19571     {
19572       errmsg ("missing interface name or sw_if_index");
19573       return -99;
19574     }
19575   if (mac_set == 0)
19576     {
19577       errmsg ("missing remote mac address");
19578       return -99;
19579     }
19580   if (sub_id == ~0)
19581     {
19582       errmsg ("missing sub-interface id");
19583       return -99;
19584     }
19585
19586   M (P2P_ETHERNET_ADD, mp);
19587   mp->parent_if_index = ntohl (parent_if_index);
19588   mp->subif_id = ntohl (sub_id);
19589   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19590
19591   S (mp);
19592   W (ret);
19593   return ret;
19594 }
19595
19596 static int
19597 api_p2p_ethernet_del (vat_main_t * vam)
19598 {
19599   unformat_input_t *i = vam->input;
19600   vl_api_p2p_ethernet_del_t *mp;
19601   u32 parent_if_index = ~0;
19602   u8 remote_mac[6];
19603   u8 mac_set = 0;
19604   int ret;
19605
19606   clib_memset (remote_mac, 0, sizeof (remote_mac));
19607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19608     {
19609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19610         ;
19611       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19612         ;
19613       else
19614         if (unformat
19615             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19616         mac_set++;
19617       else
19618         {
19619           clib_warning ("parse error '%U'", format_unformat_error, i);
19620           return -99;
19621         }
19622     }
19623
19624   if (parent_if_index == ~0)
19625     {
19626       errmsg ("missing interface name or sw_if_index");
19627       return -99;
19628     }
19629   if (mac_set == 0)
19630     {
19631       errmsg ("missing remote mac address");
19632       return -99;
19633     }
19634
19635   M (P2P_ETHERNET_DEL, mp);
19636   mp->parent_if_index = ntohl (parent_if_index);
19637   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19638
19639   S (mp);
19640   W (ret);
19641   return ret;
19642 }
19643
19644 static int
19645 api_lldp_config (vat_main_t * vam)
19646 {
19647   unformat_input_t *i = vam->input;
19648   vl_api_lldp_config_t *mp;
19649   int tx_hold = 0;
19650   int tx_interval = 0;
19651   u8 *sys_name = NULL;
19652   int ret;
19653
19654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19655     {
19656       if (unformat (i, "system-name %s", &sys_name))
19657         ;
19658       else if (unformat (i, "tx-hold %d", &tx_hold))
19659         ;
19660       else if (unformat (i, "tx-interval %d", &tx_interval))
19661         ;
19662       else
19663         {
19664           clib_warning ("parse error '%U'", format_unformat_error, i);
19665           return -99;
19666         }
19667     }
19668
19669   vec_add1 (sys_name, 0);
19670
19671   M (LLDP_CONFIG, mp);
19672   mp->tx_hold = htonl (tx_hold);
19673   mp->tx_interval = htonl (tx_interval);
19674   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19675   vec_free (sys_name);
19676
19677   S (mp);
19678   W (ret);
19679   return ret;
19680 }
19681
19682 static int
19683 api_sw_interface_set_lldp (vat_main_t * vam)
19684 {
19685   unformat_input_t *i = vam->input;
19686   vl_api_sw_interface_set_lldp_t *mp;
19687   u32 sw_if_index = ~0;
19688   u32 enable = 1;
19689   u8 *port_desc = NULL, *mgmt_oid = NULL;
19690   ip4_address_t ip4_addr;
19691   ip6_address_t ip6_addr;
19692   int ret;
19693
19694   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19695   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19696
19697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19698     {
19699       if (unformat (i, "disable"))
19700         enable = 0;
19701       else
19702         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19703         ;
19704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19705         ;
19706       else if (unformat (i, "port-desc %s", &port_desc))
19707         ;
19708       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19709         ;
19710       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19711         ;
19712       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19713         ;
19714       else
19715         break;
19716     }
19717
19718   if (sw_if_index == ~0)
19719     {
19720       errmsg ("missing interface name or sw_if_index");
19721       return -99;
19722     }
19723
19724   /* Construct the API message */
19725   vec_add1 (port_desc, 0);
19726   vec_add1 (mgmt_oid, 0);
19727   M (SW_INTERFACE_SET_LLDP, mp);
19728   mp->sw_if_index = ntohl (sw_if_index);
19729   mp->enable = enable;
19730   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19731   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19732   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19733   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19734   vec_free (port_desc);
19735   vec_free (mgmt_oid);
19736
19737   S (mp);
19738   W (ret);
19739   return ret;
19740 }
19741
19742 static int
19743 api_tcp_configure_src_addresses (vat_main_t * vam)
19744 {
19745   vl_api_tcp_configure_src_addresses_t *mp;
19746   unformat_input_t *i = vam->input;
19747   vl_api_address_t first, last;
19748   u8 range_set = 0;
19749   u32 vrf_id = 0;
19750   int ret;
19751
19752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19753     {
19754       if (unformat (i, "%U - %U",
19755                     unformat_vl_api_address, &first,
19756                     unformat_vl_api_address, &last))
19757         {
19758           if (range_set)
19759             {
19760               errmsg ("one range per message (range already set)");
19761               return -99;
19762             }
19763           range_set = 1;
19764         }
19765       else if (unformat (i, "vrf %d", &vrf_id))
19766         ;
19767       else
19768         break;
19769     }
19770
19771   if (range_set == 0)
19772     {
19773       errmsg ("address range not set");
19774       return -99;
19775     }
19776
19777   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19778
19779   mp->vrf_id = ntohl (vrf_id);
19780   clib_memcpy (&mp->first_address, &first, sizeof (first));
19781   clib_memcpy (&mp->last_address, &last, sizeof (last));
19782
19783   S (mp);
19784   W (ret);
19785   return ret;
19786 }
19787
19788 static void vl_api_app_namespace_add_del_reply_t_handler
19789   (vl_api_app_namespace_add_del_reply_t * mp)
19790 {
19791   vat_main_t *vam = &vat_main;
19792   i32 retval = ntohl (mp->retval);
19793   if (vam->async_mode)
19794     {
19795       vam->async_errors += (retval < 0);
19796     }
19797   else
19798     {
19799       vam->retval = retval;
19800       if (retval == 0)
19801         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19802       vam->result_ready = 1;
19803     }
19804 }
19805
19806 static void vl_api_app_namespace_add_del_reply_t_handler_json
19807   (vl_api_app_namespace_add_del_reply_t * mp)
19808 {
19809   vat_main_t *vam = &vat_main;
19810   vat_json_node_t node;
19811
19812   vat_json_init_object (&node);
19813   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19814   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19815
19816   vat_json_print (vam->ofp, &node);
19817   vat_json_free (&node);
19818
19819   vam->retval = ntohl (mp->retval);
19820   vam->result_ready = 1;
19821 }
19822
19823 static int
19824 api_app_namespace_add_del (vat_main_t * vam)
19825 {
19826   vl_api_app_namespace_add_del_t *mp;
19827   unformat_input_t *i = vam->input;
19828   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19829   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19830   u64 secret;
19831   int ret;
19832
19833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19834     {
19835       if (unformat (i, "id %_%v%_", &ns_id))
19836         ;
19837       else if (unformat (i, "secret %lu", &secret))
19838         secret_set = 1;
19839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19840         sw_if_index_set = 1;
19841       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19842         ;
19843       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19844         ;
19845       else
19846         break;
19847     }
19848   if (!ns_id || !secret_set || !sw_if_index_set)
19849     {
19850       errmsg ("namespace id, secret and sw_if_index must be set");
19851       return -99;
19852     }
19853   if (vec_len (ns_id) > 64)
19854     {
19855       errmsg ("namespace id too long");
19856       return -99;
19857     }
19858   M (APP_NAMESPACE_ADD_DEL, mp);
19859
19860   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19861   mp->secret = clib_host_to_net_u64 (secret);
19862   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19863   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19864   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19865   vec_free (ns_id);
19866   S (mp);
19867   W (ret);
19868   return ret;
19869 }
19870
19871 static int
19872 api_sock_init_shm (vat_main_t * vam)
19873 {
19874 #if VPP_API_TEST_BUILTIN == 0
19875   unformat_input_t *i = vam->input;
19876   vl_api_shm_elem_config_t *config = 0;
19877   u64 size = 64 << 20;
19878   int rv;
19879
19880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19881     {
19882       if (unformat (i, "size %U", unformat_memory_size, &size))
19883         ;
19884       else
19885         break;
19886     }
19887
19888   /*
19889    * Canned custom ring allocator config.
19890    * Should probably parse all of this
19891    */
19892   vec_validate (config, 6);
19893   config[0].type = VL_API_VLIB_RING;
19894   config[0].size = 256;
19895   config[0].count = 32;
19896
19897   config[1].type = VL_API_VLIB_RING;
19898   config[1].size = 1024;
19899   config[1].count = 16;
19900
19901   config[2].type = VL_API_VLIB_RING;
19902   config[2].size = 4096;
19903   config[2].count = 2;
19904
19905   config[3].type = VL_API_CLIENT_RING;
19906   config[3].size = 256;
19907   config[3].count = 32;
19908
19909   config[4].type = VL_API_CLIENT_RING;
19910   config[4].size = 1024;
19911   config[4].count = 16;
19912
19913   config[5].type = VL_API_CLIENT_RING;
19914   config[5].size = 4096;
19915   config[5].count = 2;
19916
19917   config[6].type = VL_API_QUEUE;
19918   config[6].count = 128;
19919   config[6].size = sizeof (uword);
19920
19921   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19922   if (!rv)
19923     vam->client_index_invalid = 1;
19924   return rv;
19925 #else
19926   return -99;
19927 #endif
19928 }
19929
19930 static void
19931 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19932 {
19933   vat_main_t *vam = &vat_main;
19934   fib_prefix_t lcl, rmt;
19935
19936   ip_prefix_decode (&mp->lcl, &lcl);
19937   ip_prefix_decode (&mp->rmt, &rmt);
19938
19939   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19940     {
19941       print (vam->ofp,
19942              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19943              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19944              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19945              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19946              &rmt.fp_addr.ip4, rmt.fp_len,
19947              clib_net_to_host_u16 (mp->rmt_port),
19948              clib_net_to_host_u32 (mp->action_index), mp->tag);
19949     }
19950   else
19951     {
19952       print (vam->ofp,
19953              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19954              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19955              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19956              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19957              &rmt.fp_addr.ip6, rmt.fp_len,
19958              clib_net_to_host_u16 (mp->rmt_port),
19959              clib_net_to_host_u32 (mp->action_index), mp->tag);
19960     }
19961 }
19962
19963 static void
19964 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19965                                              mp)
19966 {
19967   vat_main_t *vam = &vat_main;
19968   vat_json_node_t *node = NULL;
19969   struct in6_addr ip6;
19970   struct in_addr ip4;
19971
19972   fib_prefix_t lcl, rmt;
19973
19974   ip_prefix_decode (&mp->lcl, &lcl);
19975   ip_prefix_decode (&mp->rmt, &rmt);
19976
19977   if (VAT_JSON_ARRAY != vam->json_tree.type)
19978     {
19979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19980       vat_json_init_array (&vam->json_tree);
19981     }
19982   node = vat_json_array_add (&vam->json_tree);
19983   vat_json_init_object (node);
19984
19985   vat_json_object_add_uint (node, "appns_index",
19986                             clib_net_to_host_u32 (mp->appns_index));
19987   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19988   vat_json_object_add_uint (node, "scope", mp->scope);
19989   vat_json_object_add_uint (node, "action_index",
19990                             clib_net_to_host_u32 (mp->action_index));
19991   vat_json_object_add_uint (node, "lcl_port",
19992                             clib_net_to_host_u16 (mp->lcl_port));
19993   vat_json_object_add_uint (node, "rmt_port",
19994                             clib_net_to_host_u16 (mp->rmt_port));
19995   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19996   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19997   vat_json_object_add_string_copy (node, "tag", mp->tag);
19998   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19999     {
20000       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
20001       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20002       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
20003       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20004     }
20005   else
20006     {
20007       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
20008       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20009       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
20010       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20011     }
20012 }
20013
20014 static int
20015 api_session_rule_add_del (vat_main_t * vam)
20016 {
20017   vl_api_session_rule_add_del_t *mp;
20018   unformat_input_t *i = vam->input;
20019   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20020   u32 appns_index = 0, scope = 0;
20021   ip4_address_t lcl_ip4, rmt_ip4;
20022   ip6_address_t lcl_ip6, rmt_ip6;
20023   u8 is_ip4 = 1, conn_set = 0;
20024   u8 is_add = 1, *tag = 0;
20025   int ret;
20026   fib_prefix_t lcl, rmt;
20027
20028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20029     {
20030       if (unformat (i, "del"))
20031         is_add = 0;
20032       else if (unformat (i, "add"))
20033         ;
20034       else if (unformat (i, "proto tcp"))
20035         proto = 0;
20036       else if (unformat (i, "proto udp"))
20037         proto = 1;
20038       else if (unformat (i, "appns %d", &appns_index))
20039         ;
20040       else if (unformat (i, "scope %d", &scope))
20041         ;
20042       else if (unformat (i, "tag %_%v%_", &tag))
20043         ;
20044       else
20045         if (unformat
20046             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20047              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20048              &rmt_port))
20049         {
20050           is_ip4 = 1;
20051           conn_set = 1;
20052         }
20053       else
20054         if (unformat
20055             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20056              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20057              &rmt_port))
20058         {
20059           is_ip4 = 0;
20060           conn_set = 1;
20061         }
20062       else if (unformat (i, "action %d", &action))
20063         ;
20064       else
20065         break;
20066     }
20067   if (proto == ~0 || !conn_set || action == ~0)
20068     {
20069       errmsg ("transport proto, connection and action must be set");
20070       return -99;
20071     }
20072
20073   if (scope > 3)
20074     {
20075       errmsg ("scope should be 0-3");
20076       return -99;
20077     }
20078
20079   M (SESSION_RULE_ADD_DEL, mp);
20080
20081   clib_memset (&lcl, 0, sizeof (lcl));
20082   clib_memset (&rmt, 0, sizeof (rmt));
20083   if (is_ip4)
20084     {
20085       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
20086       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
20087       lcl.fp_len = lcl_plen;
20088       rmt.fp_len = rmt_plen;
20089     }
20090   else
20091     {
20092       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
20093       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
20094       lcl.fp_len = lcl_plen;
20095       rmt.fp_len = rmt_plen;
20096     }
20097
20098
20099   ip_prefix_encode (&lcl, &mp->lcl);
20100   ip_prefix_encode (&rmt, &mp->rmt);
20101   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20102   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20103   mp->transport_proto =
20104     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
20105   mp->action_index = clib_host_to_net_u32 (action);
20106   mp->appns_index = clib_host_to_net_u32 (appns_index);
20107   mp->scope = scope;
20108   mp->is_add = is_add;
20109   if (tag)
20110     {
20111       clib_memcpy (mp->tag, tag, vec_len (tag));
20112       vec_free (tag);
20113     }
20114
20115   S (mp);
20116   W (ret);
20117   return ret;
20118 }
20119
20120 static int
20121 api_session_rules_dump (vat_main_t * vam)
20122 {
20123   vl_api_session_rules_dump_t *mp;
20124   vl_api_control_ping_t *mp_ping;
20125   int ret;
20126
20127   if (!vam->json_output)
20128     {
20129       print (vam->ofp, "%=20s", "Session Rules");
20130     }
20131
20132   M (SESSION_RULES_DUMP, mp);
20133   /* send it... */
20134   S (mp);
20135
20136   /* Use a control ping for synchronization */
20137   MPING (CONTROL_PING, mp_ping);
20138   S (mp_ping);
20139
20140   /* Wait for a reply... */
20141   W (ret);
20142   return ret;
20143 }
20144
20145 static int
20146 api_ip_container_proxy_add_del (vat_main_t * vam)
20147 {
20148   vl_api_ip_container_proxy_add_del_t *mp;
20149   unformat_input_t *i = vam->input;
20150   u32 sw_if_index = ~0;
20151   vl_api_prefix_t pfx = { };
20152   u8 is_add = 1;
20153   int ret;
20154
20155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20156     {
20157       if (unformat (i, "del"))
20158         is_add = 0;
20159       else if (unformat (i, "add"))
20160         ;
20161       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20162         ;
20163       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20164         ;
20165       else
20166         break;
20167     }
20168   if (sw_if_index == ~0 || pfx.len == 0)
20169     {
20170       errmsg ("address and sw_if_index must be set");
20171       return -99;
20172     }
20173
20174   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20175
20176   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20177   mp->is_add = is_add;
20178   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20179
20180   S (mp);
20181   W (ret);
20182   return ret;
20183 }
20184
20185 static int
20186 api_qos_record_enable_disable (vat_main_t * vam)
20187 {
20188   unformat_input_t *i = vam->input;
20189   vl_api_qos_record_enable_disable_t *mp;
20190   u32 sw_if_index, qs = 0xff;
20191   u8 sw_if_index_set = 0;
20192   u8 enable = 1;
20193   int ret;
20194
20195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20196     {
20197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20198         sw_if_index_set = 1;
20199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20200         sw_if_index_set = 1;
20201       else if (unformat (i, "%U", unformat_qos_source, &qs))
20202         ;
20203       else if (unformat (i, "disable"))
20204         enable = 0;
20205       else
20206         {
20207           clib_warning ("parse error '%U'", format_unformat_error, i);
20208           return -99;
20209         }
20210     }
20211
20212   if (sw_if_index_set == 0)
20213     {
20214       errmsg ("missing interface name or sw_if_index");
20215       return -99;
20216     }
20217   if (qs == 0xff)
20218     {
20219       errmsg ("input location must be specified");
20220       return -99;
20221     }
20222
20223   M (QOS_RECORD_ENABLE_DISABLE, mp);
20224
20225   mp->record.sw_if_index = ntohl (sw_if_index);
20226   mp->record.input_source = qs;
20227   mp->enable = enable;
20228
20229   S (mp);
20230   W (ret);
20231   return ret;
20232 }
20233
20234
20235 static int
20236 q_or_quit (vat_main_t * vam)
20237 {
20238 #if VPP_API_TEST_BUILTIN == 0
20239   longjmp (vam->jump_buf, 1);
20240 #endif
20241   return 0;                     /* not so much */
20242 }
20243
20244 static int
20245 q (vat_main_t * vam)
20246 {
20247   return q_or_quit (vam);
20248 }
20249
20250 static int
20251 quit (vat_main_t * vam)
20252 {
20253   return q_or_quit (vam);
20254 }
20255
20256 static int
20257 comment (vat_main_t * vam)
20258 {
20259   return 0;
20260 }
20261
20262 static int
20263 elog_save (vat_main_t * vam)
20264 {
20265 #if VPP_API_TEST_BUILTIN == 0
20266   elog_main_t *em = &vam->elog_main;
20267   unformat_input_t *i = vam->input;
20268   char *file, *chroot_file;
20269   clib_error_t *error;
20270
20271   if (!unformat (i, "%s", &file))
20272     {
20273       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20274       return 0;
20275     }
20276
20277   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20278   if (strstr (file, "..") || index (file, '/'))
20279     {
20280       errmsg ("illegal characters in filename '%s'", file);
20281       return 0;
20282     }
20283
20284   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20285
20286   vec_free (file);
20287
20288   errmsg ("Saving %wd of %wd events to %s",
20289           elog_n_events_in_buffer (em),
20290           elog_buffer_capacity (em), chroot_file);
20291
20292   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20293   vec_free (chroot_file);
20294
20295   if (error)
20296     clib_error_report (error);
20297 #else
20298   errmsg ("Use the vpp event loger...");
20299 #endif
20300
20301   return 0;
20302 }
20303
20304 static int
20305 elog_setup (vat_main_t * vam)
20306 {
20307 #if VPP_API_TEST_BUILTIN == 0
20308   elog_main_t *em = &vam->elog_main;
20309   unformat_input_t *i = vam->input;
20310   u32 nevents = 128 << 10;
20311
20312   (void) unformat (i, "nevents %d", &nevents);
20313
20314   elog_init (em, nevents);
20315   vl_api_set_elog_main (em);
20316   vl_api_set_elog_trace_api_messages (1);
20317   errmsg ("Event logger initialized with %u events", nevents);
20318 #else
20319   errmsg ("Use the vpp event loger...");
20320 #endif
20321   return 0;
20322 }
20323
20324 static int
20325 elog_enable (vat_main_t * vam)
20326 {
20327 #if VPP_API_TEST_BUILTIN == 0
20328   elog_main_t *em = &vam->elog_main;
20329
20330   elog_enable_disable (em, 1 /* enable */ );
20331   vl_api_set_elog_trace_api_messages (1);
20332   errmsg ("Event logger enabled...");
20333 #else
20334   errmsg ("Use the vpp event loger...");
20335 #endif
20336   return 0;
20337 }
20338
20339 static int
20340 elog_disable (vat_main_t * vam)
20341 {
20342 #if VPP_API_TEST_BUILTIN == 0
20343   elog_main_t *em = &vam->elog_main;
20344
20345   elog_enable_disable (em, 0 /* enable */ );
20346   vl_api_set_elog_trace_api_messages (1);
20347   errmsg ("Event logger disabled...");
20348 #else
20349   errmsg ("Use the vpp event loger...");
20350 #endif
20351   return 0;
20352 }
20353
20354 static int
20355 statseg (vat_main_t * vam)
20356 {
20357   ssvm_private_t *ssvmp = &vam->stat_segment;
20358   ssvm_shared_header_t *shared_header = ssvmp->sh;
20359   vlib_counter_t **counters;
20360   u64 thread0_index1_packets;
20361   u64 thread0_index1_bytes;
20362   f64 vector_rate, input_rate;
20363   uword *p;
20364
20365   uword *counter_vector_by_name;
20366   if (vam->stat_segment_lockp == 0)
20367     {
20368       errmsg ("Stat segment not mapped...");
20369       return -99;
20370     }
20371
20372   /* look up "/if/rx for sw_if_index 1 as a test */
20373
20374   clib_spinlock_lock (vam->stat_segment_lockp);
20375
20376   counter_vector_by_name = (uword *) shared_header->opaque[1];
20377
20378   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20379   if (p == 0)
20380     {
20381       clib_spinlock_unlock (vam->stat_segment_lockp);
20382       errmsg ("/if/tx not found?");
20383       return -99;
20384     }
20385
20386   /* Fish per-thread vector of combined counters from shared memory */
20387   counters = (vlib_counter_t **) p[0];
20388
20389   if (vec_len (counters[0]) < 2)
20390     {
20391       clib_spinlock_unlock (vam->stat_segment_lockp);
20392       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20393       return -99;
20394     }
20395
20396   /* Read thread 0 sw_if_index 1 counter */
20397   thread0_index1_packets = counters[0][1].packets;
20398   thread0_index1_bytes = counters[0][1].bytes;
20399
20400   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20401   if (p == 0)
20402     {
20403       clib_spinlock_unlock (vam->stat_segment_lockp);
20404       errmsg ("vector_rate not found?");
20405       return -99;
20406     }
20407
20408   vector_rate = *(f64 *) (p[0]);
20409   p = hash_get_mem (counter_vector_by_name, "input_rate");
20410   if (p == 0)
20411     {
20412       clib_spinlock_unlock (vam->stat_segment_lockp);
20413       errmsg ("input_rate not found?");
20414       return -99;
20415     }
20416   input_rate = *(f64 *) (p[0]);
20417
20418   clib_spinlock_unlock (vam->stat_segment_lockp);
20419
20420   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20421          vector_rate, input_rate);
20422   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20423          thread0_index1_packets, thread0_index1_bytes);
20424
20425   return 0;
20426 }
20427
20428 static int
20429 cmd_cmp (void *a1, void *a2)
20430 {
20431   u8 **c1 = a1;
20432   u8 **c2 = a2;
20433
20434   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20435 }
20436
20437 static int
20438 help (vat_main_t * vam)
20439 {
20440   u8 **cmds = 0;
20441   u8 *name = 0;
20442   hash_pair_t *p;
20443   unformat_input_t *i = vam->input;
20444   int j;
20445
20446   if (unformat (i, "%s", &name))
20447     {
20448       uword *hs;
20449
20450       vec_add1 (name, 0);
20451
20452       hs = hash_get_mem (vam->help_by_name, name);
20453       if (hs)
20454         print (vam->ofp, "usage: %s %s", name, hs[0]);
20455       else
20456         print (vam->ofp, "No such msg / command '%s'", name);
20457       vec_free (name);
20458       return 0;
20459     }
20460
20461   print (vam->ofp, "Help is available for the following:");
20462
20463     /* *INDENT-OFF* */
20464     hash_foreach_pair (p, vam->function_by_name,
20465     ({
20466       vec_add1 (cmds, (u8 *)(p->key));
20467     }));
20468     /* *INDENT-ON* */
20469
20470   vec_sort_with_function (cmds, cmd_cmp);
20471
20472   for (j = 0; j < vec_len (cmds); j++)
20473     print (vam->ofp, "%s", cmds[j]);
20474
20475   vec_free (cmds);
20476   return 0;
20477 }
20478
20479 static int
20480 set (vat_main_t * vam)
20481 {
20482   u8 *name = 0, *value = 0;
20483   unformat_input_t *i = vam->input;
20484
20485   if (unformat (i, "%s", &name))
20486     {
20487       /* The input buffer is a vector, not a string. */
20488       value = vec_dup (i->buffer);
20489       vec_delete (value, i->index, 0);
20490       /* Almost certainly has a trailing newline */
20491       if (value[vec_len (value) - 1] == '\n')
20492         value[vec_len (value) - 1] = 0;
20493       /* Make sure it's a proper string, one way or the other */
20494       vec_add1 (value, 0);
20495       (void) clib_macro_set_value (&vam->macro_main,
20496                                    (char *) name, (char *) value);
20497     }
20498   else
20499     errmsg ("usage: set <name> <value>");
20500
20501   vec_free (name);
20502   vec_free (value);
20503   return 0;
20504 }
20505
20506 static int
20507 unset (vat_main_t * vam)
20508 {
20509   u8 *name = 0;
20510
20511   if (unformat (vam->input, "%s", &name))
20512     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20513       errmsg ("unset: %s wasn't set", name);
20514   vec_free (name);
20515   return 0;
20516 }
20517
20518 typedef struct
20519 {
20520   u8 *name;
20521   u8 *value;
20522 } macro_sort_t;
20523
20524
20525 static int
20526 macro_sort_cmp (void *a1, void *a2)
20527 {
20528   macro_sort_t *s1 = a1;
20529   macro_sort_t *s2 = a2;
20530
20531   return strcmp ((char *) (s1->name), (char *) (s2->name));
20532 }
20533
20534 static int
20535 dump_macro_table (vat_main_t * vam)
20536 {
20537   macro_sort_t *sort_me = 0, *sm;
20538   int i;
20539   hash_pair_t *p;
20540
20541     /* *INDENT-OFF* */
20542     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20543     ({
20544       vec_add2 (sort_me, sm, 1);
20545       sm->name = (u8 *)(p->key);
20546       sm->value = (u8 *) (p->value[0]);
20547     }));
20548     /* *INDENT-ON* */
20549
20550   vec_sort_with_function (sort_me, macro_sort_cmp);
20551
20552   if (vec_len (sort_me))
20553     print (vam->ofp, "%-15s%s", "Name", "Value");
20554   else
20555     print (vam->ofp, "The macro table is empty...");
20556
20557   for (i = 0; i < vec_len (sort_me); i++)
20558     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20559   return 0;
20560 }
20561
20562 static int
20563 dump_node_table (vat_main_t * vam)
20564 {
20565   int i, j;
20566   vlib_node_t *node, *next_node;
20567
20568   if (vec_len (vam->graph_nodes) == 0)
20569     {
20570       print (vam->ofp, "Node table empty, issue get_node_graph...");
20571       return 0;
20572     }
20573
20574   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20575     {
20576       node = vam->graph_nodes[0][i];
20577       print (vam->ofp, "[%d] %s", i, node->name);
20578       for (j = 0; j < vec_len (node->next_nodes); j++)
20579         {
20580           if (node->next_nodes[j] != ~0)
20581             {
20582               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20583               print (vam->ofp, "  [%d] %s", j, next_node->name);
20584             }
20585         }
20586     }
20587   return 0;
20588 }
20589
20590 static int
20591 value_sort_cmp (void *a1, void *a2)
20592 {
20593   name_sort_t *n1 = a1;
20594   name_sort_t *n2 = a2;
20595
20596   if (n1->value < n2->value)
20597     return -1;
20598   if (n1->value > n2->value)
20599     return 1;
20600   return 0;
20601 }
20602
20603
20604 static int
20605 dump_msg_api_table (vat_main_t * vam)
20606 {
20607   api_main_t *am = vlibapi_get_main ();
20608   name_sort_t *nses = 0, *ns;
20609   hash_pair_t *hp;
20610   int i;
20611
20612   /* *INDENT-OFF* */
20613   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20614   ({
20615     vec_add2 (nses, ns, 1);
20616     ns->name = (u8 *)(hp->key);
20617     ns->value = (u32) hp->value[0];
20618   }));
20619   /* *INDENT-ON* */
20620
20621   vec_sort_with_function (nses, value_sort_cmp);
20622
20623   for (i = 0; i < vec_len (nses); i++)
20624     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20625   vec_free (nses);
20626   return 0;
20627 }
20628
20629 static int
20630 get_msg_id (vat_main_t * vam)
20631 {
20632   u8 *name_and_crc;
20633   u32 message_index;
20634
20635   if (unformat (vam->input, "%s", &name_and_crc))
20636     {
20637       message_index = vl_msg_api_get_msg_index (name_and_crc);
20638       if (message_index == ~0)
20639         {
20640           print (vam->ofp, " '%s' not found", name_and_crc);
20641           return 0;
20642         }
20643       print (vam->ofp, " '%s' has message index %d",
20644              name_and_crc, message_index);
20645       return 0;
20646     }
20647   errmsg ("name_and_crc required...");
20648   return 0;
20649 }
20650
20651 static int
20652 search_node_table (vat_main_t * vam)
20653 {
20654   unformat_input_t *line_input = vam->input;
20655   u8 *node_to_find;
20656   int j;
20657   vlib_node_t *node, *next_node;
20658   uword *p;
20659
20660   if (vam->graph_node_index_by_name == 0)
20661     {
20662       print (vam->ofp, "Node table empty, issue get_node_graph...");
20663       return 0;
20664     }
20665
20666   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20667     {
20668       if (unformat (line_input, "%s", &node_to_find))
20669         {
20670           vec_add1 (node_to_find, 0);
20671           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20672           if (p == 0)
20673             {
20674               print (vam->ofp, "%s not found...", node_to_find);
20675               goto out;
20676             }
20677           node = vam->graph_nodes[0][p[0]];
20678           print (vam->ofp, "[%d] %s", p[0], node->name);
20679           for (j = 0; j < vec_len (node->next_nodes); j++)
20680             {
20681               if (node->next_nodes[j] != ~0)
20682                 {
20683                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20684                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20685                 }
20686             }
20687         }
20688
20689       else
20690         {
20691           clib_warning ("parse error '%U'", format_unformat_error,
20692                         line_input);
20693           return -99;
20694         }
20695
20696     out:
20697       vec_free (node_to_find);
20698
20699     }
20700
20701   return 0;
20702 }
20703
20704
20705 static int
20706 script (vat_main_t * vam)
20707 {
20708 #if (VPP_API_TEST_BUILTIN==0)
20709   u8 *s = 0;
20710   char *save_current_file;
20711   unformat_input_t save_input;
20712   jmp_buf save_jump_buf;
20713   u32 save_line_number;
20714
20715   FILE *new_fp, *save_ifp;
20716
20717   if (unformat (vam->input, "%s", &s))
20718     {
20719       new_fp = fopen ((char *) s, "r");
20720       if (new_fp == 0)
20721         {
20722           errmsg ("Couldn't open script file %s", s);
20723           vec_free (s);
20724           return -99;
20725         }
20726     }
20727   else
20728     {
20729       errmsg ("Missing script name");
20730       return -99;
20731     }
20732
20733   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20734   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20735   save_ifp = vam->ifp;
20736   save_line_number = vam->input_line_number;
20737   save_current_file = (char *) vam->current_file;
20738
20739   vam->input_line_number = 0;
20740   vam->ifp = new_fp;
20741   vam->current_file = s;
20742   do_one_file (vam);
20743
20744   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20745   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20746   vam->ifp = save_ifp;
20747   vam->input_line_number = save_line_number;
20748   vam->current_file = (u8 *) save_current_file;
20749   vec_free (s);
20750
20751   return 0;
20752 #else
20753   clib_warning ("use the exec command...");
20754   return -99;
20755 #endif
20756 }
20757
20758 static int
20759 echo (vat_main_t * vam)
20760 {
20761   print (vam->ofp, "%v", vam->input->buffer);
20762   return 0;
20763 }
20764
20765 /* List of API message constructors, CLI names map to api_xxx */
20766 #define foreach_vpe_api_msg                                             \
20767 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20768 _(sw_interface_dump,"")                                                 \
20769 _(sw_interface_set_flags,                                               \
20770   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20771 _(sw_interface_add_del_address,                                         \
20772   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20773 _(sw_interface_set_rx_mode,                                             \
20774   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20775 _(sw_interface_set_rx_placement,                                        \
20776   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20777 _(sw_interface_rx_placement_dump,                                       \
20778   "[<intfc> | sw_if_index <id>]")                                         \
20779 _(sw_interface_set_table,                                               \
20780   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20781 _(sw_interface_set_mpls_enable,                                         \
20782   "<intfc> | sw_if_index [disable | dis]")                              \
20783 _(sw_interface_set_vpath,                                               \
20784   "<intfc> | sw_if_index <id> enable | disable")                        \
20785 _(sw_interface_set_vxlan_bypass,                                        \
20786   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20787 _(sw_interface_set_geneve_bypass,                                       \
20788   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20789 _(sw_interface_set_l2_xconnect,                                         \
20790   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20791   "enable | disable")                                                   \
20792 _(sw_interface_set_l2_bridge,                                           \
20793   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20794   "[shg <split-horizon-group>] [bvi]\n"                                 \
20795   "enable | disable")                                                   \
20796 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20797 _(bridge_domain_add_del,                                                \
20798   "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") \
20799 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20800 _(l2fib_add_del,                                                        \
20801   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20802 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20803 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20804 _(l2_flags,                                                             \
20805   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20806 _(bridge_flags,                                                         \
20807   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20808 _(tap_create_v2,                                                        \
20809   "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] [packed] [in-order]") \
20810 _(tap_delete_v2,                                                        \
20811   "<vpp-if-name> | sw_if_index <id>")                                   \
20812 _(sw_interface_tap_v2_dump, "")                                         \
20813 _(virtio_pci_create_v2,                                                    \
20814   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled [gro-coalesce] | csum-offload-enabled] [packed] [in-order]") \
20815 _(virtio_pci_delete,                                                    \
20816   "<vpp-if-name> | sw_if_index <id>")                                   \
20817 _(sw_interface_virtio_pci_dump, "")                                     \
20818 _(bond_create,                                                          \
20819   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20820   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20821   "[id <if-id>]")                                                       \
20822 _(bond_create2,                                                         \
20823   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
20824   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20825   "[id <if-id>] [gso]")                                                 \
20826 _(bond_delete,                                                          \
20827   "<vpp-if-name> | sw_if_index <id>")                                   \
20828 _(bond_add_member,                                                      \
20829   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20830 _(bond_detach_member,                                                   \
20831   "sw_if_index <n>")                                                    \
20832  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20833  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20834  _(sw_member_interface_dump,                                            \
20835   "<vpp-if-name> | sw_if_index <id>")                                   \
20836 _(ip_table_add_del,                                                     \
20837   "table <n> [ipv6] [add | del]\n")                                     \
20838 _(ip_route_add_del,                                                     \
20839   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20840   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20841   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20842   "[multipath] [count <n>] [del]")                                      \
20843 _(ip_mroute_add_del,                                                    \
20844   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20845   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20846 _(mpls_table_add_del,                                                   \
20847   "table <n> [add | del]\n")                                            \
20848 _(mpls_route_add_del,                                                   \
20849   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20850   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20851   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20852   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20853   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20854   "[count <n>] [del]")                                                  \
20855 _(mpls_ip_bind_unbind,                                                  \
20856   "<label> <addr/len>")                                                 \
20857 _(mpls_tunnel_add_del,                                                  \
20858   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20859   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20860   "[l2-only]  [out-label <n>]")                                         \
20861 _(sr_mpls_policy_add,                                                   \
20862   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20863 _(sr_mpls_policy_del,                                                   \
20864   "bsid <id>")                                                          \
20865 _(bier_table_add_del,                                                   \
20866   "<label> <sub-domain> <set> <bsl> [del]")                             \
20867 _(bier_route_add_del,                                                   \
20868   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20869   "[<intfc> | sw_if_index <id>]"                                        \
20870   "[weight <n>] [del] [multipath]")                                     \
20871 _(sw_interface_set_unnumbered,                                          \
20872   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20873 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20874 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20875   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20876   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20877   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20878 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20879 _(ip_table_flush, "table <n> [ipv6]")                                   \
20880 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20881 _(set_ip_flow_hash,                                                     \
20882   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20883 _(sw_interface_ip6_enable_disable,                                      \
20884   "<intfc> | sw_if_index <id> enable | disable")                        \
20885 _(l2_patch_add_del,                                                     \
20886   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20887   "enable | disable")                                                   \
20888 _(sr_localsid_add_del,                                                  \
20889   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20890   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20891 _(classify_add_del_table,                                               \
20892   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20893   " [del] [del-chain] mask <mask-value>\n"                              \
20894   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20895   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20896 _(classify_add_del_session,                                             \
20897   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20898   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20899   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20900   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20901 _(classify_set_interface_ip_table,                                      \
20902   "<intfc> | sw_if_index <nn> table <nn>")                              \
20903 _(classify_set_interface_l2_tables,                                     \
20904   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20905   "  [other-table <nn>]")                                               \
20906 _(get_node_index, "node <node-name")                                    \
20907 _(add_node_next, "node <node-name> next <next-node-name>")              \
20908 _(l2tpv3_create_tunnel,                                                 \
20909   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20910   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20911   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20912 _(l2tpv3_set_tunnel_cookies,                                            \
20913   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20914   "[new_remote_cookie <nn>]\n")                                         \
20915 _(l2tpv3_interface_enable_disable,                                      \
20916   "<intfc> | sw_if_index <nn> enable | disable")                        \
20917 _(l2tpv3_set_lookup_key,                                                \
20918   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20919 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20920 _(vxlan_offload_rx,                                                     \
20921   "hw { <interface name> | hw_if_index <nn>} "                          \
20922   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20923 _(vxlan_add_del_tunnel,                                                 \
20924   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20925   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20926   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20927 _(geneve_add_del_tunnel,                                                \
20928   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20929   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20930   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20931 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20932 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20933 _(gre_tunnel_add_del,                                                   \
20934   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20935   "[teb | erspan <session-id>] [del]")                                  \
20936 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20937 _(l2_fib_clear_table, "")                                               \
20938 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20939 _(l2_interface_vlan_tag_rewrite,                                        \
20940   "<intfc> | sw_if_index <nn> \n"                                       \
20941   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20942   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20943 _(create_vhost_user_if,                                                 \
20944         "socket <filename> [server] [renumber <dev_instance>] "         \
20945         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20946         "[mac <mac_address>] [packed]")                                 \
20947 _(modify_vhost_user_if,                                                 \
20948         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20949         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20950 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20951 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20952 _(show_version, "")                                                     \
20953 _(show_threads, "")                                                     \
20954 _(vxlan_gpe_add_del_tunnel,                                             \
20955   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20956   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20957   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20958   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20959 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20960 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20961 _(interface_name_renumber,                                              \
20962   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20963 _(input_acl_set_interface,                                              \
20964   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20965   "  [l2-table <nn>] [del]")                                            \
20966 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20967 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20968 _(ip_dump, "ipv4 | ipv6")                                               \
20969 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20970 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20971   "  spid_id <n> ")                                                     \
20972 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20973   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20974   "  integ_alg <alg> integ_key <hex>")                                  \
20975 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20976   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20977   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20978   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20979 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20980   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20981   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20982   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20983   "  [instance <n>]")     \
20984 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20985 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20986 _(delete_loopback,"sw_if_index <nn>")                                   \
20987 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20988 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20989 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20990 _(want_interface_events,  "enable|disable")                             \
20991 _(get_first_msg_id, "client <name>")                                    \
20992 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20993 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20994   "fib-id <nn> [ip4][ip6][default]")                                    \
20995 _(get_node_graph, " ")                                                  \
20996 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20997 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20998 _(ioam_disable, "")                                                     \
20999 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21000                             " sw_if_index <sw_if_index> p <priority> "  \
21001                             "w <weight>] [del]")                        \
21002 _(one_add_del_locator, "locator-set <locator_name> "                    \
21003                         "iface <intf> | sw_if_index <sw_if_index> "     \
21004                         "p <priority> w <weight> [del]")                \
21005 _(one_add_del_local_eid,"vni <vni> eid "                                \
21006                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21007                          "locator-set <locator_name> [del]"             \
21008                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21009 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21010 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21011 _(one_enable_disable, "enable|disable")                                 \
21012 _(one_map_register_enable_disable, "enable|disable")                    \
21013 _(one_map_register_fallback_threshold, "<value>")                       \
21014 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21015 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21016                                "[seid <seid>] "                         \
21017                                "rloc <locator> p <prio> "               \
21018                                "w <weight> [rloc <loc> ... ] "          \
21019                                "action <action> [del-all]")             \
21020 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21021                           "<local-eid>")                                \
21022 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21023 _(one_use_petr, "ip-address> | disable")                                \
21024 _(one_map_request_mode, "src-dst|dst-only")                             \
21025 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21026 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21027 _(one_locator_set_dump, "[local | remote]")                             \
21028 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21029 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21030                        "[local] | [remote]")                            \
21031 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21032 _(one_ndp_bd_get, "")                                                   \
21033 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21034 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21035 _(one_l2_arp_bd_get, "")                                                \
21036 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21037 _(one_stats_enable_disable, "enable|disable")                           \
21038 _(show_one_stats_enable_disable, "")                                    \
21039 _(one_eid_table_vni_dump, "")                                           \
21040 _(one_eid_table_map_dump, "l2|l3")                                      \
21041 _(one_map_resolver_dump, "")                                            \
21042 _(one_map_server_dump, "")                                              \
21043 _(one_adjacencies_get, "vni <vni>")                                     \
21044 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21045 _(show_one_rloc_probe_state, "")                                        \
21046 _(show_one_map_register_state, "")                                      \
21047 _(show_one_status, "")                                                  \
21048 _(one_stats_dump, "")                                                   \
21049 _(one_stats_flush, "")                                                  \
21050 _(one_get_map_request_itr_rlocs, "")                                    \
21051 _(one_map_register_set_ttl, "<ttl>")                                    \
21052 _(one_set_transport_protocol, "udp|api")                                \
21053 _(one_get_transport_protocol, "")                                       \
21054 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21055 _(one_show_xtr_mode, "")                                                \
21056 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21057 _(one_show_pitr_mode, "")                                               \
21058 _(one_enable_disable_petr_mode, "enable|disable")                       \
21059 _(one_show_petr_mode, "")                                               \
21060 _(show_one_nsh_mapping, "")                                             \
21061 _(show_one_pitr, "")                                                    \
21062 _(show_one_use_petr, "")                                                \
21063 _(show_one_map_request_mode, "")                                        \
21064 _(show_one_map_register_ttl, "")                                        \
21065 _(show_one_map_register_fallback_threshold, "")                         \
21066 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21067                             " sw_if_index <sw_if_index> p <priority> "  \
21068                             "w <weight>] [del]")                        \
21069 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21070                         "iface <intf> | sw_if_index <sw_if_index> "     \
21071                         "p <priority> w <weight> [del]")                \
21072 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21073                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21074                          "locator-set <locator_name> [del]"             \
21075                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21076 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21077 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21078 _(lisp_enable_disable, "enable|disable")                                \
21079 _(lisp_map_register_enable_disable, "enable|disable")                   \
21080 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21081 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21082                                "[seid <seid>] "                         \
21083                                "rloc <locator> p <prio> "               \
21084                                "w <weight> [rloc <loc> ... ] "          \
21085                                "action <action> [del-all]")             \
21086 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21087                           "<local-eid>")                                \
21088 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21089 _(lisp_use_petr, "<ip-address> | disable")                              \
21090 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21091 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21092 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21093 _(lisp_locator_set_dump, "[local | remote]")                            \
21094 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21095 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21096                        "[local] | [remote]")                            \
21097 _(lisp_eid_table_vni_dump, "")                                          \
21098 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21099 _(lisp_map_resolver_dump, "")                                           \
21100 _(lisp_map_server_dump, "")                                             \
21101 _(lisp_adjacencies_get, "vni <vni>")                                    \
21102 _(gpe_fwd_entry_vnis_get, "")                                           \
21103 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21104 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21105                                 "[table <table-id>]")                   \
21106 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21107 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21108 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21109 _(gpe_get_encap_mode, "")                                               \
21110 _(lisp_gpe_add_del_iface, "up|down")                                    \
21111 _(lisp_gpe_enable_disable, "enable|disable")                            \
21112 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21113   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21114 _(show_lisp_rloc_probe_state, "")                                       \
21115 _(show_lisp_map_register_state, "")                                     \
21116 _(show_lisp_status, "")                                                 \
21117 _(lisp_get_map_request_itr_rlocs, "")                                   \
21118 _(show_lisp_pitr, "")                                                   \
21119 _(show_lisp_use_petr, "")                                               \
21120 _(show_lisp_map_request_mode, "")                                       \
21121 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21122 _(af_packet_delete, "name <host interface name>")                       \
21123 _(af_packet_dump, "")                                                   \
21124 _(policer_add_del, "name <policer name> <params> [del]")                \
21125 _(policer_dump, "[name <policer name>]")                                \
21126 _(policer_classify_set_interface,                                       \
21127   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21128   "  [l2-table <nn>] [del]")                                            \
21129 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21130 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21131 _(mpls_table_dump, "")                                                  \
21132 _(mpls_route_dump, "table-id <ID>")                                     \
21133 _(classify_table_ids, "")                                               \
21134 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21135 _(classify_table_info, "table_id <nn>")                                 \
21136 _(classify_session_dump, "table_id <nn>")                               \
21137 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21138     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21139     "[template_interval <nn>] [udp_checksum]")                          \
21140 _(ipfix_exporter_dump, "")                                              \
21141 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21142 _(ipfix_classify_stream_dump, "")                                       \
21143 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21144 _(ipfix_classify_table_dump, "")                                        \
21145 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21146 _(sw_interface_span_dump, "[l2]")                                           \
21147 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21148 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21149 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21150 _(pg_enable_disable, "[stream <id>] disable")                           \
21151 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
21152 _(ip_source_and_port_range_check_add_del,                               \
21153   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21154 _(ip_source_and_port_range_check_interface_add_del,                     \
21155   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21156   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21157 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21158 _(l2_interface_pbb_tag_rewrite,                                         \
21159   "<intfc> | sw_if_index <nn> \n"                                       \
21160   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21161   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21162 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21163 _(flow_classify_set_interface,                                          \
21164   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21165 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21166 _(ip_table_dump, "")                                                    \
21167 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21168 _(ip_mtable_dump, "")                                                   \
21169 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21170 _(feature_enable_disable, "arc_name <arc_name> "                        \
21171   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21172 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21173   "[enable | disable] ")                                                \
21174 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21175 "[disable]")                                                            \
21176 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21177   "mac <mac-address> [del]")                                            \
21178 _(l2_xconnect_dump, "")                                                 \
21179 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21180 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21181 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21182 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21183 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21184 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21185   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21186 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21187 _(sock_init_shm, "size <nnn>")                                          \
21188 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21189 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21190   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21191 _(session_rules_dump, "")                                               \
21192 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21193 _(output_acl_set_interface,                                             \
21194   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21195   "  [l2-table <nn>] [del]")                                            \
21196 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21197
21198 /* List of command functions, CLI names map directly to functions */
21199 #define foreach_cli_function                                    \
21200 _(comment, "usage: comment <ignore-rest-of-line>")              \
21201 _(dump_interface_table, "usage: dump_interface_table")          \
21202 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21203 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21204 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21205 _(dump_macro_table, "usage: dump_macro_table ")                 \
21206 _(dump_node_table, "usage: dump_node_table")                    \
21207 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21208 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21209 _(elog_disable, "usage: elog_disable")                          \
21210 _(elog_enable, "usage: elog_enable")                            \
21211 _(elog_save, "usage: elog_save <filename>")                     \
21212 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21213 _(echo, "usage: echo <message>")                                \
21214 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21215 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21216 _(help, "usage: help")                                          \
21217 _(q, "usage: quit")                                             \
21218 _(quit, "usage: quit")                                          \
21219 _(search_node_table, "usage: search_node_table <name>...")      \
21220 _(set, "usage: set <variable-name> <value>")                    \
21221 _(script, "usage: script <file-name>")                          \
21222 _(statseg, "usage: statseg")                                    \
21223 _(unset, "usage: unset <variable-name>")
21224
21225 #define _(N,n)                                  \
21226     static void vl_api_##n##_t_handler_uni      \
21227     (vl_api_##n##_t * mp)                       \
21228     {                                           \
21229         vat_main_t * vam = &vat_main;           \
21230         if (vam->json_output) {                 \
21231             vl_api_##n##_t_handler_json(mp);    \
21232         } else {                                \
21233             vl_api_##n##_t_handler(mp);         \
21234         }                                       \
21235     }
21236 foreach_vpe_api_reply_msg;
21237 #if VPP_API_TEST_BUILTIN == 0
21238 foreach_standalone_reply_msg;
21239 #endif
21240 #undef _
21241
21242 void
21243 vat_api_hookup (vat_main_t * vam)
21244 {
21245 #define _(N,n)                                                  \
21246     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21247                            vl_api_##n##_t_handler_uni,          \
21248                            vl_noop_handler,                     \
21249                            vl_api_##n##_t_endian,               \
21250                            vl_api_##n##_t_print,                \
21251                            sizeof(vl_api_##n##_t), 1);
21252   foreach_vpe_api_reply_msg;
21253 #if VPP_API_TEST_BUILTIN == 0
21254   foreach_standalone_reply_msg;
21255 #endif
21256 #undef _
21257
21258 #if (VPP_API_TEST_BUILTIN==0)
21259   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21260
21261   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21262
21263   vam->function_by_name = hash_create_string (0, sizeof (uword));
21264
21265   vam->help_by_name = hash_create_string (0, sizeof (uword));
21266 #endif
21267
21268   /* API messages we can send */
21269 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21270   foreach_vpe_api_msg;
21271 #undef _
21272
21273   /* Help strings */
21274 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21275   foreach_vpe_api_msg;
21276 #undef _
21277
21278   /* CLI functions */
21279 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21280   foreach_cli_function;
21281 #undef _
21282
21283   /* Help strings */
21284 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21285   foreach_cli_function;
21286 #undef _
21287 }
21288
21289 #if VPP_API_TEST_BUILTIN
21290 static clib_error_t *
21291 vat_api_hookup_shim (vlib_main_t * vm)
21292 {
21293   vat_api_hookup (&vat_main);
21294   return 0;
21295 }
21296
21297 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21298 #endif
21299
21300 /*
21301  * fd.io coding-style-patch-verification: ON
21302  *
21303  * Local Variables:
21304  * eval: (c-set-style "gnu")
21305  * End:
21306  */