bonding lacp: replace slave string with member
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2020 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
55 #include <vnet/ethernet/ethernet_types_api.h>
56 #include <vnet/ip/ip_types_api.h>
57 #include "vat/json_format.h"
58 #include <vnet/ip/ip_types_api.h>
59 #include <vnet/ethernet/ethernet_types_api.h>
60
61 #include <inttypes.h>
62 #include <sys/stat.h>
63
64 #define vl_typedefs             /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_typedefs
67
68 /* declare message handlers for each api */
69
70 #define vl_endianfun            /* define message structures */
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_endianfun
73
74 /* instantiate all the print functions we know about */
75 #if VPP_API_TEST_BUILTIN == 0
76 #define vl_print(handle, ...)
77 #else
78 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
79 #endif
80 #define vl_printfun
81 #include <vpp/api/vpe_all_api_h.h>
82 #undef vl_printfun
83
84 #define __plugin_msg_base 0
85 #include <vlibapi/vat_helper_macros.h>
86
87 #include <vnet/format_fns.h>
88
89 void vl_api_set_elog_main (elog_main_t * m);
90 int vl_api_set_elog_trace_api_messages (int enable);
91
92 #if VPP_API_TEST_BUILTIN == 0
93 #include <netdb.h>
94
95 u32
96 vl (void *p)
97 {
98   return vec_len (p);
99 }
100
101 int
102 vat_socket_connect (vat_main_t * vam)
103 {
104   int rv;
105   api_main_t *am = vlibapi_get_main ();
106   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111
112   /* vpp expects the client index in network order */
113   vam->my_client_index = htonl (socket_client_main.client_index);
114   am->my_client_index = vam->my_client_index;
115   return 0;
116 }
117 #else /* vpp built-in case, we don't do sockets... */
118 int
119 vat_socket_connect (vat_main_t * vam)
120 {
121   return 0;
122 }
123
124 int
125 vl_socket_client_read (int wait)
126 {
127   return -1;
128 };
129
130 int
131 vl_socket_client_write ()
132 {
133   return -1;
134 };
135
136 void *
137 vl_socket_client_msg_alloc (int nbytes)
138 {
139   return 0;
140 }
141 #endif
142
143
144 f64
145 vat_time_now (vat_main_t * vam)
146 {
147 #if VPP_API_TEST_BUILTIN
148   return vlib_time_now (vam->vlib_main);
149 #else
150   return clib_time_now (&vam->clib_time);
151 #endif
152 }
153
154 void
155 errmsg (char *fmt, ...)
156 {
157   vat_main_t *vam = &vat_main;
158   va_list va;
159   u8 *s;
160
161   va_start (va, fmt);
162   s = va_format (0, fmt, &va);
163   va_end (va);
164
165   vec_add1 (s, 0);
166
167 #if VPP_API_TEST_BUILTIN
168   vlib_cli_output (vam->vlib_main, (char *) s);
169 #else
170   {
171     if (vam->ifp != stdin)
172       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
173                vam->input_line_number);
174     else
175       fformat (vam->ofp, "%s\n", (char *) s);
176     fflush (vam->ofp);
177   }
178 #endif
179
180   vec_free (s);
181 }
182
183 #if VPP_API_TEST_BUILTIN == 0
184 static uword
185 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
186 {
187   vat_main_t *vam = va_arg (*args, vat_main_t *);
188   u32 *result = va_arg (*args, u32 *);
189   u8 *if_name;
190   uword *p;
191
192   if (!unformat (input, "%s", &if_name))
193     return 0;
194
195   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
196   if (p == 0)
197     return 0;
198   *result = p[0];
199   return 1;
200 }
201
202 static uword
203 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
204 {
205   return 0;
206 }
207
208 /* Parse an IP4 address %d.%d.%d.%d. */
209 uword
210 unformat_ip4_address (unformat_input_t * input, va_list * args)
211 {
212   u8 *result = va_arg (*args, u8 *);
213   unsigned a[4];
214
215   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
216     return 0;
217
218   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
219     return 0;
220
221   result[0] = a[0];
222   result[1] = a[1];
223   result[2] = a[2];
224   result[3] = a[3];
225
226   return 1;
227 }
228
229 uword
230 unformat_ethernet_address (unformat_input_t * input, va_list * args)
231 {
232   u8 *result = va_arg (*args, u8 *);
233   u32 i, a[6];
234
235   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
236                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
237     return 0;
238
239   /* Check range. */
240   for (i = 0; i < 6; i++)
241     if (a[i] >= (1 << 8))
242       return 0;
243
244   for (i = 0; i < 6; i++)
245     result[i] = a[i];
246
247   return 1;
248 }
249
250 /* Returns ethernet type as an int in host byte order. */
251 uword
252 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
253                                         va_list * args)
254 {
255   u16 *result = va_arg (*args, u16 *);
256   int type;
257
258   /* Numeric type. */
259   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
260     {
261       if (type >= (1 << 16))
262         return 0;
263       *result = type;
264       return 1;
265     }
266   return 0;
267 }
268
269 /* Parse an IP46 address. */
270 uword
271 unformat_ip46_address (unformat_input_t * input, va_list * args)
272 {
273   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
274   ip46_type_t type = va_arg (*args, ip46_type_t);
275   if ((type != IP46_TYPE_IP6) &&
276       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
277     {
278       ip46_address_mask_ip4 (ip46);
279       return 1;
280     }
281   else if ((type != IP46_TYPE_IP4) &&
282            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
283     {
284       return 1;
285     }
286   return 0;
287 }
288
289 /* Parse an IP6 address. */
290 uword
291 unformat_ip6_address (unformat_input_t * input, va_list * args)
292 {
293   ip6_address_t *result = va_arg (*args, ip6_address_t *);
294   u16 hex_quads[8];
295   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
296   uword c, n_colon, double_colon_index;
297
298   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
299   double_colon_index = ARRAY_LEN (hex_quads);
300   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
301     {
302       hex_digit = 16;
303       if (c >= '0' && c <= '9')
304         hex_digit = c - '0';
305       else if (c >= 'a' && c <= 'f')
306         hex_digit = c + 10 - 'a';
307       else if (c >= 'A' && c <= 'F')
308         hex_digit = c + 10 - 'A';
309       else if (c == ':' && n_colon < 2)
310         n_colon++;
311       else
312         {
313           unformat_put_input (input);
314           break;
315         }
316
317       /* Too many hex quads. */
318       if (n_hex_quads >= ARRAY_LEN (hex_quads))
319         return 0;
320
321       if (hex_digit < 16)
322         {
323           hex_quad = (hex_quad << 4) | hex_digit;
324
325           /* Hex quad must fit in 16 bits. */
326           if (n_hex_digits >= 4)
327             return 0;
328
329           n_colon = 0;
330           n_hex_digits++;
331         }
332
333       /* Save position of :: */
334       if (n_colon == 2)
335         {
336           /* More than one :: ? */
337           if (double_colon_index < ARRAY_LEN (hex_quads))
338             return 0;
339           double_colon_index = n_hex_quads;
340         }
341
342       if (n_colon > 0 && n_hex_digits > 0)
343         {
344           hex_quads[n_hex_quads++] = hex_quad;
345           hex_quad = 0;
346           n_hex_digits = 0;
347         }
348     }
349
350   if (n_hex_digits > 0)
351     hex_quads[n_hex_quads++] = hex_quad;
352
353   {
354     word i;
355
356     /* Expand :: to appropriate number of zero hex quads. */
357     if (double_colon_index < ARRAY_LEN (hex_quads))
358       {
359         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
360
361         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
362           hex_quads[n_zero + i] = hex_quads[i];
363
364         for (i = 0; i < n_zero; i++)
365           hex_quads[double_colon_index + i] = 0;
366
367         n_hex_quads = ARRAY_LEN (hex_quads);
368       }
369
370     /* Too few hex quads given. */
371     if (n_hex_quads < ARRAY_LEN (hex_quads))
372       return 0;
373
374     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
375       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
376
377     return 1;
378   }
379 }
380
381 uword
382 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
383 {
384   u32 *r = va_arg (*args, u32 *);
385
386   if (0);
387 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
388   foreach_ipsec_policy_action
389 #undef _
390     else
391     return 0;
392   return 1;
393 }
394
395 u8 *
396 format_ipsec_crypto_alg (u8 * s, va_list * args)
397 {
398   u32 i = va_arg (*args, u32);
399   u8 *t = 0;
400
401   switch (i)
402     {
403 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
404       foreach_ipsec_crypto_alg
405 #undef _
406     default:
407       return format (s, "unknown");
408     }
409   return format (s, "%s", t);
410 }
411
412 u8 *
413 format_ipsec_integ_alg (u8 * s, va_list * args)
414 {
415   u32 i = va_arg (*args, u32);
416   u8 *t = 0;
417
418   switch (i)
419     {
420 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
421       foreach_ipsec_integ_alg
422 #undef _
423     default:
424       return format (s, "unknown");
425     }
426   return format (s, "%s", t);
427 }
428
429 #else /* VPP_API_TEST_BUILTIN == 1 */
430 static uword
431 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
432 {
433   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
434   vnet_main_t *vnm = vnet_get_main ();
435   u32 *result = va_arg (*args, u32 *);
436
437   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
438 }
439
440 static uword
441 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
442 {
443   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
444   vnet_main_t *vnm = vnet_get_main ();
445   u32 *result = va_arg (*args, u32 *);
446
447   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
448 }
449
450 #endif /* VPP_API_TEST_BUILTIN */
451
452 uword
453 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
454 {
455   u32 *r = va_arg (*args, u32 *);
456
457   if (0);
458 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
459   foreach_ipsec_crypto_alg
460 #undef _
461     else
462     return 0;
463   return 1;
464 }
465
466 uword
467 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
468 {
469   u32 *r = va_arg (*args, u32 *);
470
471   if (0);
472 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
473   foreach_ipsec_integ_alg
474 #undef _
475     else
476     return 0;
477   return 1;
478 }
479
480 static uword
481 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
482 {
483   u8 *r = va_arg (*args, u8 *);
484
485   if (unformat (input, "kbps"))
486     *r = SSE2_QOS_RATE_KBPS;
487   else if (unformat (input, "pps"))
488     *r = SSE2_QOS_RATE_PPS;
489   else
490     return 0;
491   return 1;
492 }
493
494 static uword
495 unformat_policer_round_type (unformat_input_t * input, va_list * args)
496 {
497   u8 *r = va_arg (*args, u8 *);
498
499   if (unformat (input, "closest"))
500     *r = SSE2_QOS_ROUND_TO_CLOSEST;
501   else if (unformat (input, "up"))
502     *r = SSE2_QOS_ROUND_TO_UP;
503   else if (unformat (input, "down"))
504     *r = SSE2_QOS_ROUND_TO_DOWN;
505   else
506     return 0;
507   return 1;
508 }
509
510 static uword
511 unformat_policer_type (unformat_input_t * input, va_list * args)
512 {
513   u8 *r = va_arg (*args, u8 *);
514
515   if (unformat (input, "1r2c"))
516     *r = SSE2_QOS_POLICER_TYPE_1R2C;
517   else if (unformat (input, "1r3c"))
518     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
519   else if (unformat (input, "2r3c-2698"))
520     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
521   else if (unformat (input, "2r3c-4115"))
522     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
523   else if (unformat (input, "2r3c-mef5cf1"))
524     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
525   else
526     return 0;
527   return 1;
528 }
529
530 static uword
531 unformat_dscp (unformat_input_t * input, va_list * va)
532 {
533   u8 *r = va_arg (*va, u8 *);
534
535   if (0);
536 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
537   foreach_vnet_dscp
538 #undef _
539     else
540     return 0;
541   return 1;
542 }
543
544 static uword
545 unformat_policer_action_type (unformat_input_t * input, va_list * va)
546 {
547   sse2_qos_pol_action_params_st *a
548     = va_arg (*va, sse2_qos_pol_action_params_st *);
549
550   if (unformat (input, "drop"))
551     a->action_type = SSE2_QOS_ACTION_DROP;
552   else if (unformat (input, "transmit"))
553     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
554   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
555     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
556   else
557     return 0;
558   return 1;
559 }
560
561 static uword
562 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
563 {
564   u32 *r = va_arg (*va, u32 *);
565   u32 tid;
566
567   if (unformat (input, "ip4"))
568     tid = POLICER_CLASSIFY_TABLE_IP4;
569   else if (unformat (input, "ip6"))
570     tid = POLICER_CLASSIFY_TABLE_IP6;
571   else if (unformat (input, "l2"))
572     tid = POLICER_CLASSIFY_TABLE_L2;
573   else
574     return 0;
575
576   *r = tid;
577   return 1;
578 }
579
580 static uword
581 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
582 {
583   u32 *r = va_arg (*va, u32 *);
584   u32 tid;
585
586   if (unformat (input, "ip4"))
587     tid = FLOW_CLASSIFY_TABLE_IP4;
588   else if (unformat (input, "ip6"))
589     tid = FLOW_CLASSIFY_TABLE_IP6;
590   else
591     return 0;
592
593   *r = tid;
594   return 1;
595 }
596
597 #if (VPP_API_TEST_BUILTIN==0)
598
599 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
600 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
601 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
602 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
603
604 uword
605 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
606 {
607   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
608   mfib_itf_attribute_t attr;
609
610   old = *iflags;
611   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
612   {
613     if (unformat (input, mfib_itf_flag_long_names[attr]))
614       *iflags |= (1 << attr);
615   }
616   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
617   {
618     if (unformat (input, mfib_itf_flag_names[attr]))
619       *iflags |= (1 << attr);
620   }
621
622   return (old == *iflags ? 0 : 1);
623 }
624
625 uword
626 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
627 {
628   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
629   mfib_entry_attribute_t attr;
630
631   old = *eflags;
632   FOR_EACH_MFIB_ATTRIBUTE (attr)
633   {
634     if (unformat (input, mfib_flag_long_names[attr]))
635       *eflags |= (1 << attr);
636   }
637   FOR_EACH_MFIB_ATTRIBUTE (attr)
638   {
639     if (unformat (input, mfib_flag_names[attr]))
640       *eflags |= (1 << attr);
641   }
642
643   return (old == *eflags ? 0 : 1);
644 }
645
646 u8 *
647 format_ip4_address (u8 * s, va_list * args)
648 {
649   u8 *a = va_arg (*args, u8 *);
650   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
651 }
652
653 u8 *
654 format_ip6_address (u8 * s, va_list * args)
655 {
656   ip6_address_t *a = va_arg (*args, ip6_address_t *);
657   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
658
659   i_max_n_zero = ARRAY_LEN (a->as_u16);
660   max_n_zeros = 0;
661   i_first_zero = i_max_n_zero;
662   n_zeros = 0;
663   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
664     {
665       u32 is_zero = a->as_u16[i] == 0;
666       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
667         {
668           i_first_zero = i;
669           n_zeros = 0;
670         }
671       n_zeros += is_zero;
672       if ((!is_zero && n_zeros > max_n_zeros)
673           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
674         {
675           i_max_n_zero = i_first_zero;
676           max_n_zeros = n_zeros;
677           i_first_zero = ARRAY_LEN (a->as_u16);
678           n_zeros = 0;
679         }
680     }
681
682   last_double_colon = 0;
683   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
684     {
685       if (i == i_max_n_zero && max_n_zeros > 1)
686         {
687           s = format (s, "::");
688           i += max_n_zeros - 1;
689           last_double_colon = 1;
690         }
691       else
692         {
693           s = format (s, "%s%x",
694                       (last_double_colon || i == 0) ? "" : ":",
695                       clib_net_to_host_u16 (a->as_u16[i]));
696           last_double_colon = 0;
697         }
698     }
699
700   return s;
701 }
702
703 /* Format an IP46 address. */
704 u8 *
705 format_ip46_address (u8 * s, va_list * args)
706 {
707   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
708   ip46_type_t type = va_arg (*args, ip46_type_t);
709   int is_ip4 = 1;
710
711   switch (type)
712     {
713     case IP46_TYPE_ANY:
714       is_ip4 = ip46_address_is_ip4 (ip46);
715       break;
716     case IP46_TYPE_IP4:
717       is_ip4 = 1;
718       break;
719     case IP46_TYPE_IP6:
720       is_ip4 = 0;
721       break;
722     }
723
724   return is_ip4 ?
725     format (s, "%U", format_ip4_address, &ip46->ip4) :
726     format (s, "%U", format_ip6_address, &ip46->ip6);
727 }
728
729 u8 *
730 format_ethernet_address (u8 * s, va_list * args)
731 {
732   u8 *a = va_arg (*args, u8 *);
733
734   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
735                  a[0], a[1], a[2], a[3], a[4], a[5]);
736 }
737 #endif
738
739 static void
740 increment_v4_address (vl_api_ip4_address_t * i)
741 {
742   ip4_address_t *a = (ip4_address_t *) i;
743   u32 v;
744
745   v = ntohl (a->as_u32) + 1;
746   a->as_u32 = ntohl (v);
747 }
748
749 static void
750 increment_v6_address (vl_api_ip6_address_t * i)
751 {
752   ip6_address_t *a = (ip6_address_t *) i;
753   u64 v0, v1;
754
755   v0 = clib_net_to_host_u64 (a->as_u64[0]);
756   v1 = clib_net_to_host_u64 (a->as_u64[1]);
757
758   v1 += 1;
759   if (v1 == 0)
760     v0 += 1;
761   a->as_u64[0] = clib_net_to_host_u64 (v0);
762   a->as_u64[1] = clib_net_to_host_u64 (v1);
763 }
764
765 static void
766 increment_address (vl_api_address_t * a)
767 {
768   if (a->af == ADDRESS_IP4)
769     increment_v4_address (&a->un.ip4);
770   else if (a->af == ADDRESS_IP6)
771     increment_v6_address (&a->un.ip6);
772 }
773
774 static void
775 set_ip4_address (vl_api_address_t * a, u32 v)
776 {
777   if (a->af == ADDRESS_IP4)
778     {
779       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
780       i->as_u32 = v;
781     }
782 }
783
784 void
785 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
786 {
787   if (is_ip4)
788     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
789   else
790     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
791                       sizeof (ip6_address_t));
792 }
793
794 static void
795 increment_mac_address (u8 * mac)
796 {
797   u64 tmp = *((u64 *) mac);
798   tmp = clib_net_to_host_u64 (tmp);
799   tmp += 1 << 16;               /* skip unused (least significant) octets */
800   tmp = clib_host_to_net_u64 (tmp);
801
802   clib_memcpy (mac, &tmp, 6);
803 }
804
805 static void
806 vat_json_object_add_address (vat_json_node_t * node,
807                              const char *str, const vl_api_address_t * addr)
808 {
809   if (ADDRESS_IP6 == addr->af)
810     {
811       struct in6_addr ip6;
812
813       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
814       vat_json_object_add_ip6 (node, str, ip6);
815     }
816   else
817     {
818       struct in_addr ip4;
819
820       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
821       vat_json_object_add_ip4 (node, str, ip4);
822     }
823 }
824
825 static void
826 vat_json_object_add_prefix (vat_json_node_t * node,
827                             const vl_api_prefix_t * prefix)
828 {
829   vat_json_object_add_uint (node, "len", prefix->len);
830   vat_json_object_add_address (node, "address", &prefix->address);
831 }
832
833 static void vl_api_create_loopback_reply_t_handler
834   (vl_api_create_loopback_reply_t * mp)
835 {
836   vat_main_t *vam = &vat_main;
837   i32 retval = ntohl (mp->retval);
838
839   vam->retval = retval;
840   vam->regenerate_interface_table = 1;
841   vam->sw_if_index = ntohl (mp->sw_if_index);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_loopback_reply_t_handler_json
846   (vl_api_create_loopback_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   vat_json_node_t node;
850
851   vat_json_init_object (&node);
852   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
853   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
854
855   vat_json_print (vam->ofp, &node);
856   vat_json_free (&node);
857   vam->retval = ntohl (mp->retval);
858   vam->result_ready = 1;
859 }
860
861 static void vl_api_create_loopback_instance_reply_t_handler
862   (vl_api_create_loopback_instance_reply_t * mp)
863 {
864   vat_main_t *vam = &vat_main;
865   i32 retval = ntohl (mp->retval);
866
867   vam->retval = retval;
868   vam->regenerate_interface_table = 1;
869   vam->sw_if_index = ntohl (mp->sw_if_index);
870   vam->result_ready = 1;
871 }
872
873 static void vl_api_create_loopback_instance_reply_t_handler_json
874   (vl_api_create_loopback_instance_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   vat_json_node_t node;
878
879   vat_json_init_object (&node);
880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
881   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
882
883   vat_json_print (vam->ofp, &node);
884   vat_json_free (&node);
885   vam->retval = ntohl (mp->retval);
886   vam->result_ready = 1;
887 }
888
889 static void vl_api_af_packet_create_reply_t_handler
890   (vl_api_af_packet_create_reply_t * mp)
891 {
892   vat_main_t *vam = &vat_main;
893   i32 retval = ntohl (mp->retval);
894
895   vam->retval = retval;
896   vam->regenerate_interface_table = 1;
897   vam->sw_if_index = ntohl (mp->sw_if_index);
898   vam->result_ready = 1;
899 }
900
901 static void vl_api_af_packet_create_reply_t_handler_json
902   (vl_api_af_packet_create_reply_t * mp)
903 {
904   vat_main_t *vam = &vat_main;
905   vat_json_node_t node;
906
907   vat_json_init_object (&node);
908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
909   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
910
911   vat_json_print (vam->ofp, &node);
912   vat_json_free (&node);
913
914   vam->retval = ntohl (mp->retval);
915   vam->result_ready = 1;
916 }
917
918 static void vl_api_create_vlan_subif_reply_t_handler
919   (vl_api_create_vlan_subif_reply_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   i32 retval = ntohl (mp->retval);
923
924   vam->retval = retval;
925   vam->regenerate_interface_table = 1;
926   vam->sw_if_index = ntohl (mp->sw_if_index);
927   vam->result_ready = 1;
928 }
929
930 static void vl_api_create_vlan_subif_reply_t_handler_json
931   (vl_api_create_vlan_subif_reply_t * mp)
932 {
933   vat_main_t *vam = &vat_main;
934   vat_json_node_t node;
935
936   vat_json_init_object (&node);
937   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
938   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
939
940   vat_json_print (vam->ofp, &node);
941   vat_json_free (&node);
942
943   vam->retval = ntohl (mp->retval);
944   vam->result_ready = 1;
945 }
946
947 static void vl_api_create_subif_reply_t_handler
948   (vl_api_create_subif_reply_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   i32 retval = ntohl (mp->retval);
952
953   vam->retval = retval;
954   vam->regenerate_interface_table = 1;
955   vam->sw_if_index = ntohl (mp->sw_if_index);
956   vam->result_ready = 1;
957 }
958
959 static void vl_api_create_subif_reply_t_handler_json
960   (vl_api_create_subif_reply_t * mp)
961 {
962   vat_main_t *vam = &vat_main;
963   vat_json_node_t node;
964
965   vat_json_init_object (&node);
966   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
967   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
968
969   vat_json_print (vam->ofp, &node);
970   vat_json_free (&node);
971
972   vam->retval = ntohl (mp->retval);
973   vam->result_ready = 1;
974 }
975
976 static void vl_api_interface_name_renumber_reply_t_handler
977   (vl_api_interface_name_renumber_reply_t * mp)
978 {
979   vat_main_t *vam = &vat_main;
980   i32 retval = ntohl (mp->retval);
981
982   vam->retval = retval;
983   vam->regenerate_interface_table = 1;
984   vam->result_ready = 1;
985 }
986
987 static void vl_api_interface_name_renumber_reply_t_handler_json
988   (vl_api_interface_name_renumber_reply_t * mp)
989 {
990   vat_main_t *vam = &vat_main;
991   vat_json_node_t node;
992
993   vat_json_init_object (&node);
994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
995
996   vat_json_print (vam->ofp, &node);
997   vat_json_free (&node);
998
999   vam->retval = ntohl (mp->retval);
1000   vam->result_ready = 1;
1001 }
1002
1003 /*
1004  * Special-case: build the interface table, maintain
1005  * the next loopback sw_if_index vbl.
1006  */
1007 static void vl_api_sw_interface_details_t_handler
1008   (vl_api_sw_interface_details_t * mp)
1009 {
1010   vat_main_t *vam = &vat_main;
1011   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1012
1013   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1014                 ntohl (mp->sw_if_index));
1015
1016   /* In sub interface case, fill the sub interface table entry */
1017   if (mp->sw_if_index != mp->sup_sw_if_index)
1018     {
1019       sw_interface_subif_t *sub = NULL;
1020
1021       vec_add2 (vam->sw_if_subif_table, sub, 1);
1022
1023       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1024       strncpy ((char *) sub->interface_name, (char *) s,
1025                vec_len (sub->interface_name));
1026       sub->sw_if_index = ntohl (mp->sw_if_index);
1027       sub->sub_id = ntohl (mp->sub_id);
1028
1029       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1030
1031       sub->sub_number_of_tags = mp->sub_number_of_tags;
1032       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1033       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1034
1035       /* vlan tag rewrite */
1036       sub->vtr_op = ntohl (mp->vtr_op);
1037       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1038       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1039       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1040     }
1041 }
1042
1043 static void vl_api_sw_interface_details_t_handler_json
1044   (vl_api_sw_interface_details_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   vat_json_node_t *node = NULL;
1048
1049   if (VAT_JSON_ARRAY != vam->json_tree.type)
1050     {
1051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1052       vat_json_init_array (&vam->json_tree);
1053     }
1054   node = vat_json_array_add (&vam->json_tree);
1055
1056   vat_json_init_object (node);
1057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1058   vat_json_object_add_uint (node, "sup_sw_if_index",
1059                             ntohl (mp->sup_sw_if_index));
1060   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1061                              sizeof (mp->l2_address));
1062   vat_json_object_add_string_copy (node, "interface_name",
1063                                    mp->interface_name);
1064   vat_json_object_add_string_copy (node, "interface_dev_type",
1065                                    mp->interface_dev_type);
1066   vat_json_object_add_uint (node, "flags", mp->flags);
1067   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1068   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1069   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1070   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1071   vat_json_object_add_uint (node, "sub_number_of_tags",
1072                             mp->sub_number_of_tags);
1073   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1074                             ntohs (mp->sub_outer_vlan_id));
1075   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1076                             ntohs (mp->sub_inner_vlan_id));
1077   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1078   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1079   vat_json_object_add_uint (node, "vtr_push_dot1q",
1080                             ntohl (mp->vtr_push_dot1q));
1081   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1082   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1083   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1084     {
1085       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1086                                        format (0, "%U",
1087                                                format_ethernet_address,
1088                                                &mp->b_dmac));
1089       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1090                                        format (0, "%U",
1091                                                format_ethernet_address,
1092                                                &mp->b_smac));
1093       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1094       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1095     }
1096 }
1097
1098 #if VPP_API_TEST_BUILTIN == 0
1099 static void vl_api_sw_interface_event_t_handler
1100   (vl_api_sw_interface_event_t * mp)
1101 {
1102   vat_main_t *vam = &vat_main;
1103   if (vam->interface_event_display)
1104     errmsg ("interface flags: sw_if_index %d %s %s",
1105             ntohl (mp->sw_if_index),
1106             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1107             "admin-up" : "admin-down",
1108             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1109             "link-up" : "link-down");
1110 }
1111 #endif
1112
1113 __clib_unused static void
1114 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1115 {
1116   /* JSON output not supported */
1117 }
1118
1119 static void
1120 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1121 {
1122   vat_main_t *vam = &vat_main;
1123   i32 retval = ntohl (mp->retval);
1124
1125   vam->retval = retval;
1126   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void
1131 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   vat_json_node_t node;
1135   void *oldheap;
1136   u8 *reply;
1137
1138   vat_json_init_object (&node);
1139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1140   vat_json_object_add_uint (&node, "reply_in_shmem",
1141                             ntohl (mp->reply_in_shmem));
1142   /* Toss the shared-memory original... */
1143   oldheap = vl_msg_push_heap ();
1144
1145   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1146   vec_free (reply);
1147
1148   vl_msg_pop_heap (oldheap);
1149
1150   vat_json_print (vam->ofp, &node);
1151   vat_json_free (&node);
1152
1153   vam->retval = ntohl (mp->retval);
1154   vam->result_ready = 1;
1155 }
1156
1157 static void
1158 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1159 {
1160   vat_main_t *vam = &vat_main;
1161   i32 retval = ntohl (mp->retval);
1162
1163   vec_reset_length (vam->cmd_reply);
1164
1165   vam->retval = retval;
1166   if (retval == 0)
1167     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1168   vam->result_ready = 1;
1169 }
1170
1171 static void
1172 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   vat_json_node_t node;
1176   u8 *reply = 0;                /* reply vector */
1177
1178   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1179   vec_reset_length (vam->cmd_reply);
1180
1181   vat_json_init_object (&node);
1182   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1183   vat_json_object_add_string_copy (&node, "reply", reply);
1184
1185   vat_json_print (vam->ofp, &node);
1186   vat_json_free (&node);
1187   vec_free (reply);
1188
1189   vam->retval = ntohl (mp->retval);
1190   vam->result_ready = 1;
1191 }
1192
1193 static void vl_api_classify_add_del_table_reply_t_handler
1194   (vl_api_classify_add_del_table_reply_t * mp)
1195 {
1196   vat_main_t *vam = &vat_main;
1197   i32 retval = ntohl (mp->retval);
1198   if (vam->async_mode)
1199     {
1200       vam->async_errors += (retval < 0);
1201     }
1202   else
1203     {
1204       vam->retval = retval;
1205       if (retval == 0 &&
1206           ((mp->new_table_index != 0xFFFFFFFF) ||
1207            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1208            (mp->match_n_vectors != 0xFFFFFFFF)))
1209         /*
1210          * Note: this is just barely thread-safe, depends on
1211          * the main thread spinning waiting for an answer...
1212          */
1213         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1214                 ntohl (mp->new_table_index),
1215                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1216       vam->result_ready = 1;
1217     }
1218 }
1219
1220 static void vl_api_classify_add_del_table_reply_t_handler_json
1221   (vl_api_classify_add_del_table_reply_t * mp)
1222 {
1223   vat_main_t *vam = &vat_main;
1224   vat_json_node_t node;
1225
1226   vat_json_init_object (&node);
1227   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1228   vat_json_object_add_uint (&node, "new_table_index",
1229                             ntohl (mp->new_table_index));
1230   vat_json_object_add_uint (&node, "skip_n_vectors",
1231                             ntohl (mp->skip_n_vectors));
1232   vat_json_object_add_uint (&node, "match_n_vectors",
1233                             ntohl (mp->match_n_vectors));
1234
1235   vat_json_print (vam->ofp, &node);
1236   vat_json_free (&node);
1237
1238   vam->retval = ntohl (mp->retval);
1239   vam->result_ready = 1;
1240 }
1241
1242 static void vl_api_get_node_index_reply_t_handler
1243   (vl_api_get_node_index_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   i32 retval = ntohl (mp->retval);
1247   if (vam->async_mode)
1248     {
1249       vam->async_errors += (retval < 0);
1250     }
1251   else
1252     {
1253       vam->retval = retval;
1254       if (retval == 0)
1255         errmsg ("node index %d", ntohl (mp->node_index));
1256       vam->result_ready = 1;
1257     }
1258 }
1259
1260 static void vl_api_get_node_index_reply_t_handler_json
1261   (vl_api_get_node_index_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   vat_json_node_t node;
1265
1266   vat_json_init_object (&node);
1267   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1268   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1269
1270   vat_json_print (vam->ofp, &node);
1271   vat_json_free (&node);
1272
1273   vam->retval = ntohl (mp->retval);
1274   vam->result_ready = 1;
1275 }
1276
1277 static void vl_api_get_next_index_reply_t_handler
1278   (vl_api_get_next_index_reply_t * mp)
1279 {
1280   vat_main_t *vam = &vat_main;
1281   i32 retval = ntohl (mp->retval);
1282   if (vam->async_mode)
1283     {
1284       vam->async_errors += (retval < 0);
1285     }
1286   else
1287     {
1288       vam->retval = retval;
1289       if (retval == 0)
1290         errmsg ("next node index %d", ntohl (mp->next_index));
1291       vam->result_ready = 1;
1292     }
1293 }
1294
1295 static void vl_api_get_next_index_reply_t_handler_json
1296   (vl_api_get_next_index_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   vat_json_node_t node;
1300
1301   vat_json_init_object (&node);
1302   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1303   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1304
1305   vat_json_print (vam->ofp, &node);
1306   vat_json_free (&node);
1307
1308   vam->retval = ntohl (mp->retval);
1309   vam->result_ready = 1;
1310 }
1311
1312 static void vl_api_add_node_next_reply_t_handler
1313   (vl_api_add_node_next_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   i32 retval = ntohl (mp->retval);
1317   if (vam->async_mode)
1318     {
1319       vam->async_errors += (retval < 0);
1320     }
1321   else
1322     {
1323       vam->retval = retval;
1324       if (retval == 0)
1325         errmsg ("next index %d", ntohl (mp->next_index));
1326       vam->result_ready = 1;
1327     }
1328 }
1329
1330 static void vl_api_add_node_next_reply_t_handler_json
1331   (vl_api_add_node_next_reply_t * mp)
1332 {
1333   vat_main_t *vam = &vat_main;
1334   vat_json_node_t node;
1335
1336   vat_json_init_object (&node);
1337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1338   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1339
1340   vat_json_print (vam->ofp, &node);
1341   vat_json_free (&node);
1342
1343   vam->retval = ntohl (mp->retval);
1344   vam->result_ready = 1;
1345 }
1346
1347 static void vl_api_show_version_reply_t_handler
1348   (vl_api_show_version_reply_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   i32 retval = ntohl (mp->retval);
1352
1353   if (retval >= 0)
1354     {
1355       errmsg ("        program: %s", mp->program);
1356       errmsg ("        version: %s", mp->version);
1357       errmsg ("     build date: %s", mp->build_date);
1358       errmsg ("build directory: %s", mp->build_directory);
1359     }
1360   vam->retval = retval;
1361   vam->result_ready = 1;
1362 }
1363
1364 static void vl_api_show_version_reply_t_handler_json
1365   (vl_api_show_version_reply_t * mp)
1366 {
1367   vat_main_t *vam = &vat_main;
1368   vat_json_node_t node;
1369
1370   vat_json_init_object (&node);
1371   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1372   vat_json_object_add_string_copy (&node, "program", mp->program);
1373   vat_json_object_add_string_copy (&node, "version", mp->version);
1374   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1375   vat_json_object_add_string_copy (&node, "build_directory",
1376                                    mp->build_directory);
1377
1378   vat_json_print (vam->ofp, &node);
1379   vat_json_free (&node);
1380
1381   vam->retval = ntohl (mp->retval);
1382   vam->result_ready = 1;
1383 }
1384
1385 static void vl_api_show_threads_reply_t_handler
1386   (vl_api_show_threads_reply_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   i32 retval = ntohl (mp->retval);
1390   int i, count = 0;
1391
1392   if (retval >= 0)
1393     count = ntohl (mp->count);
1394
1395   for (i = 0; i < count; i++)
1396     print (vam->ofp,
1397            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1398            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1399            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1400            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1401            ntohl (mp->thread_data[i].cpu_socket));
1402
1403   vam->retval = retval;
1404   vam->result_ready = 1;
1405 }
1406
1407 static void vl_api_show_threads_reply_t_handler_json
1408   (vl_api_show_threads_reply_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   vat_json_node_t node;
1412   vl_api_thread_data_t *td;
1413   i32 retval = ntohl (mp->retval);
1414   int i, count = 0;
1415
1416   if (retval >= 0)
1417     count = ntohl (mp->count);
1418
1419   vat_json_init_object (&node);
1420   vat_json_object_add_int (&node, "retval", retval);
1421   vat_json_object_add_uint (&node, "count", count);
1422
1423   for (i = 0; i < count; i++)
1424     {
1425       td = &mp->thread_data[i];
1426       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1427       vat_json_object_add_string_copy (&node, "name", td->name);
1428       vat_json_object_add_string_copy (&node, "type", td->type);
1429       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1430       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1431       vat_json_object_add_int (&node, "core", ntohl (td->id));
1432       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1433     }
1434
1435   vat_json_print (vam->ofp, &node);
1436   vat_json_free (&node);
1437
1438   vam->retval = retval;
1439   vam->result_ready = 1;
1440 }
1441
1442 static int
1443 api_show_threads (vat_main_t * vam)
1444 {
1445   vl_api_show_threads_t *mp;
1446   int ret;
1447
1448   print (vam->ofp,
1449          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1450          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1451
1452   M (SHOW_THREADS, mp);
1453
1454   S (mp);
1455   W (ret);
1456   return ret;
1457 }
1458
1459 static void
1460 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1461 {
1462   u32 n_macs = ntohl (mp->n_macs);
1463   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1464           ntohl (mp->pid), mp->client_index, n_macs);
1465   int i;
1466   for (i = 0; i < n_macs; i++)
1467     {
1468       vl_api_mac_entry_t *mac = &mp->mac[i];
1469       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1470               i + 1, ntohl (mac->sw_if_index),
1471               format_ethernet_address, mac->mac_addr, mac->action);
1472       if (i == 1000)
1473         break;
1474     }
1475 }
1476
1477 static void
1478 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1479 {
1480   /* JSON output not supported */
1481 }
1482
1483 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1484 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1485
1486 /*
1487  * Special-case: build the bridge domain table, maintain
1488  * the next bd id vbl.
1489  */
1490 static void vl_api_bridge_domain_details_t_handler
1491   (vl_api_bridge_domain_details_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1495   int i;
1496
1497   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1498          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1499
1500   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1501          ntohl (mp->bd_id), mp->learn, mp->forward,
1502          mp->flood, ntohl (mp->bvi_sw_if_index),
1503          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1504
1505   if (n_sw_ifs)
1506     {
1507       vl_api_bridge_domain_sw_if_t *sw_ifs;
1508       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1509              "Interface Name");
1510
1511       sw_ifs = mp->sw_if_details;
1512       for (i = 0; i < n_sw_ifs; i++)
1513         {
1514           u8 *sw_if_name = 0;
1515           u32 sw_if_index;
1516           hash_pair_t *p;
1517
1518           sw_if_index = ntohl (sw_ifs->sw_if_index);
1519
1520           /* *INDENT-OFF* */
1521           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1522                              ({
1523                                if ((u32) p->value[0] == sw_if_index)
1524                                  {
1525                                    sw_if_name = (u8 *)(p->key);
1526                                    break;
1527                                  }
1528                              }));
1529           /* *INDENT-ON* */
1530           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1531                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1532                  "sw_if_index not found!");
1533
1534           sw_ifs++;
1535         }
1536     }
1537 }
1538
1539 static void vl_api_bridge_domain_details_t_handler_json
1540   (vl_api_bridge_domain_details_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   vat_json_node_t *node, *array = NULL;
1544   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1545
1546   if (VAT_JSON_ARRAY != vam->json_tree.type)
1547     {
1548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1549       vat_json_init_array (&vam->json_tree);
1550     }
1551   node = vat_json_array_add (&vam->json_tree);
1552
1553   vat_json_init_object (node);
1554   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1555   vat_json_object_add_uint (node, "flood", mp->flood);
1556   vat_json_object_add_uint (node, "forward", mp->forward);
1557   vat_json_object_add_uint (node, "learn", mp->learn);
1558   vat_json_object_add_uint (node, "bvi_sw_if_index",
1559                             ntohl (mp->bvi_sw_if_index));
1560   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1561   array = vat_json_object_add (node, "sw_if");
1562   vat_json_init_array (array);
1563
1564
1565
1566   if (n_sw_ifs)
1567     {
1568       vl_api_bridge_domain_sw_if_t *sw_ifs;
1569       int i;
1570
1571       sw_ifs = mp->sw_if_details;
1572       for (i = 0; i < n_sw_ifs; i++)
1573         {
1574           node = vat_json_array_add (array);
1575           vat_json_init_object (node);
1576           vat_json_object_add_uint (node, "sw_if_index",
1577                                     ntohl (sw_ifs->sw_if_index));
1578           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1579           sw_ifs++;
1580         }
1581     }
1582 }
1583
1584 static void vl_api_control_ping_reply_t_handler
1585   (vl_api_control_ping_reply_t * mp)
1586 {
1587   vat_main_t *vam = &vat_main;
1588   i32 retval = ntohl (mp->retval);
1589   if (vam->async_mode)
1590     {
1591       vam->async_errors += (retval < 0);
1592     }
1593   else
1594     {
1595       vam->retval = retval;
1596       vam->result_ready = 1;
1597     }
1598   if (vam->socket_client_main)
1599     vam->socket_client_main->control_pings_outstanding--;
1600 }
1601
1602 static void vl_api_control_ping_reply_t_handler_json
1603   (vl_api_control_ping_reply_t * mp)
1604 {
1605   vat_main_t *vam = &vat_main;
1606   i32 retval = ntohl (mp->retval);
1607
1608   if (VAT_JSON_NONE != vam->json_tree.type)
1609     {
1610       vat_json_print (vam->ofp, &vam->json_tree);
1611       vat_json_free (&vam->json_tree);
1612       vam->json_tree.type = VAT_JSON_NONE;
1613     }
1614   else
1615     {
1616       /* just print [] */
1617       vat_json_init_array (&vam->json_tree);
1618       vat_json_print (vam->ofp, &vam->json_tree);
1619       vam->json_tree.type = VAT_JSON_NONE;
1620     }
1621
1622   vam->retval = retval;
1623   vam->result_ready = 1;
1624 }
1625
1626 static void
1627   vl_api_bridge_domain_set_mac_age_reply_t_handler
1628   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1629 {
1630   vat_main_t *vam = &vat_main;
1631   i32 retval = ntohl (mp->retval);
1632   if (vam->async_mode)
1633     {
1634       vam->async_errors += (retval < 0);
1635     }
1636   else
1637     {
1638       vam->retval = retval;
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1644   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651
1652   vat_json_print (vam->ofp, &node);
1653   vat_json_free (&node);
1654
1655   vam->retval = ntohl (mp->retval);
1656   vam->result_ready = 1;
1657 }
1658
1659 static void
1660 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   i32 retval = ntohl (mp->retval);
1664   if (vam->async_mode)
1665     {
1666       vam->async_errors += (retval < 0);
1667     }
1668   else
1669     {
1670       vam->retval = retval;
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_l2_flags_reply_t_handler_json
1676   (vl_api_l2_flags_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1684                             ntohl (mp->resulting_feature_bitmap));
1685
1686   vat_json_print (vam->ofp, &node);
1687   vat_json_free (&node);
1688
1689   vam->retval = ntohl (mp->retval);
1690   vam->result_ready = 1;
1691 }
1692
1693 static void vl_api_bridge_flags_reply_t_handler
1694   (vl_api_bridge_flags_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   i32 retval = ntohl (mp->retval);
1698   if (vam->async_mode)
1699     {
1700       vam->async_errors += (retval < 0);
1701     }
1702   else
1703     {
1704       vam->retval = retval;
1705       vam->result_ready = 1;
1706     }
1707 }
1708
1709 static void vl_api_bridge_flags_reply_t_handler_json
1710   (vl_api_bridge_flags_reply_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t node;
1714
1715   vat_json_init_object (&node);
1716   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1717   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1718                             ntohl (mp->resulting_feature_bitmap));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725 }
1726
1727 static void
1728 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   i32 retval = ntohl (mp->retval);
1732   if (vam->async_mode)
1733     {
1734       vam->async_errors += (retval < 0);
1735     }
1736   else
1737     {
1738       vam->retval = retval;
1739       vam->sw_if_index = ntohl (mp->sw_if_index);
1740       vam->result_ready = 1;
1741     }
1742
1743 }
1744
1745 static void vl_api_tap_create_v2_reply_t_handler_json
1746   (vl_api_tap_create_v2_reply_t * mp)
1747 {
1748   vat_main_t *vam = &vat_main;
1749   vat_json_node_t node;
1750
1751   vat_json_init_object (&node);
1752   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1753   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1754
1755   vat_json_print (vam->ofp, &node);
1756   vat_json_free (&node);
1757
1758   vam->retval = ntohl (mp->retval);
1759   vam->result_ready = 1;
1760
1761 }
1762
1763 static void
1764 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1765 {
1766   vat_main_t *vam = &vat_main;
1767   i32 retval = ntohl (mp->retval);
1768   if (vam->async_mode)
1769     {
1770       vam->async_errors += (retval < 0);
1771     }
1772   else
1773     {
1774       vam->retval = retval;
1775       vam->result_ready = 1;
1776     }
1777 }
1778
1779 static void vl_api_tap_delete_v2_reply_t_handler_json
1780   (vl_api_tap_delete_v2_reply_t * mp)
1781 {
1782   vat_main_t *vam = &vat_main;
1783   vat_json_node_t node;
1784
1785   vat_json_init_object (&node);
1786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1787
1788   vat_json_print (vam->ofp, &node);
1789   vat_json_free (&node);
1790
1791   vam->retval = ntohl (mp->retval);
1792   vam->result_ready = 1;
1793 }
1794
1795 static void
1796 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1797                                           mp)
1798 {
1799   vat_main_t *vam = &vat_main;
1800   i32 retval = ntohl (mp->retval);
1801   if (vam->async_mode)
1802     {
1803       vam->async_errors += (retval < 0);
1804     }
1805   else
1806     {
1807       vam->retval = retval;
1808       vam->sw_if_index = ntohl (mp->sw_if_index);
1809       vam->result_ready = 1;
1810     }
1811 }
1812
1813 static void vl_api_virtio_pci_create_reply_t_handler_json
1814   (vl_api_virtio_pci_create_reply_t * mp)
1815 {
1816   vat_main_t *vam = &vat_main;
1817   vat_json_node_t node;
1818
1819   vat_json_init_object (&node);
1820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1822
1823   vat_json_print (vam->ofp, &node);
1824   vat_json_free (&node);
1825
1826   vam->retval = ntohl (mp->retval);
1827   vam->result_ready = 1;
1828
1829 }
1830
1831 static void
1832 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1833                                           mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->result_ready = 1;
1845     }
1846 }
1847
1848 static void vl_api_virtio_pci_delete_reply_t_handler_json
1849   (vl_api_virtio_pci_delete_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   vat_json_node_t node;
1853
1854   vat_json_init_object (&node);
1855   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1856
1857   vat_json_print (vam->ofp, &node);
1858   vat_json_free (&node);
1859
1860   vam->retval = ntohl (mp->retval);
1861   vam->result_ready = 1;
1862 }
1863
1864 static void
1865 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   i32 retval = ntohl (mp->retval);
1869
1870   if (vam->async_mode)
1871     {
1872       vam->async_errors += (retval < 0);
1873     }
1874   else
1875     {
1876       vam->retval = retval;
1877       vam->sw_if_index = ntohl (mp->sw_if_index);
1878       vam->result_ready = 1;
1879     }
1880 }
1881
1882 static void vl_api_bond_create_reply_t_handler_json
1883   (vl_api_bond_create_reply_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   vat_json_node_t node;
1887
1888   vat_json_init_object (&node);
1889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1890   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1891
1892   vat_json_print (vam->ofp, &node);
1893   vat_json_free (&node);
1894
1895   vam->retval = ntohl (mp->retval);
1896   vam->result_ready = 1;
1897 }
1898
1899 static void
1900 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   i32 retval = ntohl (mp->retval);
1904
1905   if (vam->async_mode)
1906     {
1907       vam->async_errors += (retval < 0);
1908     }
1909   else
1910     {
1911       vam->retval = retval;
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_bond_delete_reply_t_handler_json
1917   (vl_api_bond_delete_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921
1922   vat_json_init_object (&node);
1923   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1924
1925   vat_json_print (vam->ofp, &node);
1926   vat_json_free (&node);
1927
1928   vam->retval = ntohl (mp->retval);
1929   vam->result_ready = 1;
1930 }
1931
1932 static void
1933 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
1934 {
1935   vat_main_t *vam = &vat_main;
1936   i32 retval = ntohl (mp->retval);
1937
1938   if (vam->async_mode)
1939     {
1940       vam->async_errors += (retval < 0);
1941     }
1942   else
1943     {
1944       vam->retval = retval;
1945       vam->result_ready = 1;
1946     }
1947 }
1948
1949 static void vl_api_bond_add_member_reply_t_handler_json
1950   (vl_api_bond_add_member_reply_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953   vat_json_node_t node;
1954
1955   vat_json_init_object (&node);
1956   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1957
1958   vat_json_print (vam->ofp, &node);
1959   vat_json_free (&node);
1960
1961   vam->retval = ntohl (mp->retval);
1962   vam->result_ready = 1;
1963 }
1964
1965 static void
1966 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
1967                                            mp)
1968 {
1969   vat_main_t *vam = &vat_main;
1970   i32 retval = ntohl (mp->retval);
1971
1972   if (vam->async_mode)
1973     {
1974       vam->async_errors += (retval < 0);
1975     }
1976   else
1977     {
1978       vam->retval = retval;
1979       vam->result_ready = 1;
1980     }
1981 }
1982
1983 static void vl_api_bond_detach_member_reply_t_handler_json
1984   (vl_api_bond_detach_member_reply_t * mp)
1985 {
1986   vat_main_t *vam = &vat_main;
1987   vat_json_node_t node;
1988
1989   vat_json_init_object (&node);
1990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1991
1992   vat_json_print (vam->ofp, &node);
1993   vat_json_free (&node);
1994
1995   vam->retval = ntohl (mp->retval);
1996   vam->result_ready = 1;
1997 }
1998
1999 static int
2000 api_sw_interface_set_bond_weight (vat_main_t * vam)
2001 {
2002   unformat_input_t *i = vam->input;
2003   vl_api_sw_interface_set_bond_weight_t *mp;
2004   u32 sw_if_index = ~0;
2005   u32 weight = 0;
2006   u8 weight_enter = 0;
2007   int ret;
2008
2009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2010     {
2011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2012         ;
2013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2014         ;
2015       else if (unformat (i, "weight %u", &weight))
2016         weight_enter = 1;
2017       else
2018         break;
2019     }
2020
2021   if (sw_if_index == ~0)
2022     {
2023       errmsg ("missing interface name or sw_if_index");
2024       return -99;
2025     }
2026   if (weight_enter == 0)
2027     {
2028       errmsg ("missing valid weight");
2029       return -99;
2030     }
2031
2032   /* Construct the API message */
2033   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2034   mp->sw_if_index = ntohl (sw_if_index);
2035   mp->weight = ntohl (weight);
2036
2037   S (mp);
2038   W (ret);
2039   return ret;
2040 }
2041
2042 static void vl_api_sw_bond_interface_details_t_handler
2043   (vl_api_sw_bond_interface_details_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046
2047   print (vam->ofp,
2048          "%-16s %-12d %-12U %-13U %-14u %-14u",
2049          mp->interface_name, ntohl (mp->sw_if_index),
2050          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2051          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2052 }
2053
2054 static void vl_api_sw_bond_interface_details_t_handler_json
2055   (vl_api_sw_bond_interface_details_t * mp)
2056 {
2057   vat_main_t *vam = &vat_main;
2058   vat_json_node_t *node = NULL;
2059
2060   if (VAT_JSON_ARRAY != vam->json_tree.type)
2061     {
2062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2063       vat_json_init_array (&vam->json_tree);
2064     }
2065   node = vat_json_array_add (&vam->json_tree);
2066
2067   vat_json_init_object (node);
2068   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2069   vat_json_object_add_string_copy (node, "interface_name",
2070                                    mp->interface_name);
2071   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2072   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2073   vat_json_object_add_uint (node, "active_members",
2074                             ntohl (mp->active_members));
2075   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2076 }
2077
2078 static int
2079 api_sw_bond_interface_dump (vat_main_t * vam)
2080 {
2081   unformat_input_t *i = vam->input;
2082   vl_api_sw_bond_interface_dump_t *mp;
2083   vl_api_control_ping_t *mp_ping;
2084   int ret;
2085   u32 sw_if_index = ~0;
2086
2087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2088     {
2089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2090         ;
2091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2092         ;
2093       else
2094         break;
2095     }
2096
2097   print (vam->ofp,
2098          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2099          "interface name", "sw_if_index", "mode", "load balance",
2100          "active members", "members");
2101
2102   /* Get list of bond interfaces */
2103   M (SW_BOND_INTERFACE_DUMP, mp);
2104   mp->sw_if_index = ntohl (sw_if_index);
2105   S (mp);
2106
2107   /* Use a control ping for synchronization */
2108   MPING (CONTROL_PING, mp_ping);
2109   S (mp_ping);
2110
2111   W (ret);
2112   return ret;
2113 }
2114
2115 static void vl_api_sw_member_interface_details_t_handler
2116   (vl_api_sw_member_interface_details_t * mp)
2117 {
2118   vat_main_t *vam = &vat_main;
2119
2120   print (vam->ofp,
2121          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2122          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2123          ntohl (mp->weight), mp->is_local_numa);
2124 }
2125
2126 static void vl_api_sw_member_interface_details_t_handler_json
2127   (vl_api_sw_member_interface_details_t * mp)
2128 {
2129   vat_main_t *vam = &vat_main;
2130   vat_json_node_t *node = NULL;
2131
2132   if (VAT_JSON_ARRAY != vam->json_tree.type)
2133     {
2134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2135       vat_json_init_array (&vam->json_tree);
2136     }
2137   node = vat_json_array_add (&vam->json_tree);
2138
2139   vat_json_init_object (node);
2140   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2141   vat_json_object_add_string_copy (node, "interface_name",
2142                                    mp->interface_name);
2143   vat_json_object_add_uint (node, "passive", mp->is_passive);
2144   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2145   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2146   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2147 }
2148
2149 static int
2150 api_sw_member_interface_dump (vat_main_t * vam)
2151 {
2152   unformat_input_t *i = vam->input;
2153   vl_api_sw_member_interface_dump_t *mp;
2154   vl_api_control_ping_t *mp_ping;
2155   u32 sw_if_index = ~0;
2156   u8 sw_if_index_set = 0;
2157   int ret;
2158
2159   /* Parse args required to build the message */
2160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2161     {
2162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2163         sw_if_index_set = 1;
2164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2165         sw_if_index_set = 1;
2166       else
2167         break;
2168     }
2169
2170   if (sw_if_index_set == 0)
2171     {
2172       errmsg ("missing vpp interface name. ");
2173       return -99;
2174     }
2175
2176   print (vam->ofp,
2177          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2178          "member interface name", "sw_if_index", "passive", "long_timeout",
2179          "weight", "local numa");
2180
2181   /* Get list of bond interfaces */
2182   M (SW_MEMBER_INTERFACE_DUMP, mp);
2183   mp->sw_if_index = ntohl (sw_if_index);
2184   S (mp);
2185
2186   /* Use a control ping for synchronization */
2187   MPING (CONTROL_PING, mp_ping);
2188   S (mp_ping);
2189
2190   W (ret);
2191   return ret;
2192 }
2193
2194 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2195   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2196 {
2197   vat_main_t *vam = &vat_main;
2198   i32 retval = ntohl (mp->retval);
2199   if (vam->async_mode)
2200     {
2201       vam->async_errors += (retval < 0);
2202     }
2203   else
2204     {
2205       vam->retval = retval;
2206       vam->sw_if_index = ntohl (mp->sw_if_index);
2207       vam->result_ready = 1;
2208     }
2209   vam->regenerate_interface_table = 1;
2210 }
2211
2212 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2213   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2214 {
2215   vat_main_t *vam = &vat_main;
2216   vat_json_node_t node;
2217
2218   vat_json_init_object (&node);
2219   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2220   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2221                             ntohl (mp->sw_if_index));
2222
2223   vat_json_print (vam->ofp, &node);
2224   vat_json_free (&node);
2225
2226   vam->retval = ntohl (mp->retval);
2227   vam->result_ready = 1;
2228 }
2229
2230 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2231   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   i32 retval = ntohl (mp->retval);
2235   if (vam->async_mode)
2236     {
2237       vam->async_errors += (retval < 0);
2238     }
2239   else
2240     {
2241       vam->retval = retval;
2242       vam->sw_if_index = ntohl (mp->sw_if_index);
2243       vam->result_ready = 1;
2244     }
2245 }
2246
2247 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2248   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   vat_json_node_t node;
2252
2253   vat_json_init_object (&node);
2254   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2255   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2256
2257   vat_json_print (vam->ofp, &node);
2258   vat_json_free (&node);
2259
2260   vam->retval = ntohl (mp->retval);
2261   vam->result_ready = 1;
2262 }
2263
2264 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2265   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   i32 retval = ntohl (mp->retval);
2269   if (vam->async_mode)
2270     {
2271       vam->async_errors += (retval < 0);
2272     }
2273   else
2274     {
2275       vam->retval = retval;
2276       vam->result_ready = 1;
2277     }
2278 }
2279
2280 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2281   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2282 {
2283   vat_main_t *vam = &vat_main;
2284   vat_json_node_t node;
2285
2286   vat_json_init_object (&node);
2287   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2288   vat_json_object_add_uint (&node, "fwd_entry_index",
2289                             clib_net_to_host_u32 (mp->fwd_entry_index));
2290
2291   vat_json_print (vam->ofp, &node);
2292   vat_json_free (&node);
2293
2294   vam->retval = ntohl (mp->retval);
2295   vam->result_ready = 1;
2296 }
2297
2298 u8 *
2299 format_lisp_transport_protocol (u8 * s, va_list * args)
2300 {
2301   u32 proto = va_arg (*args, u32);
2302
2303   switch (proto)
2304     {
2305     case 1:
2306       return format (s, "udp");
2307     case 2:
2308       return format (s, "api");
2309     default:
2310       return 0;
2311     }
2312   return 0;
2313 }
2314
2315 static void vl_api_one_get_transport_protocol_reply_t_handler
2316   (vl_api_one_get_transport_protocol_reply_t * mp)
2317 {
2318   vat_main_t *vam = &vat_main;
2319   i32 retval = ntohl (mp->retval);
2320   if (vam->async_mode)
2321     {
2322       vam->async_errors += (retval < 0);
2323     }
2324   else
2325     {
2326       u32 proto = mp->protocol;
2327       print (vam->ofp, "Transport protocol: %U",
2328              format_lisp_transport_protocol, proto);
2329       vam->retval = retval;
2330       vam->result_ready = 1;
2331     }
2332 }
2333
2334 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2335   (vl_api_one_get_transport_protocol_reply_t * mp)
2336 {
2337   vat_main_t *vam = &vat_main;
2338   vat_json_node_t node;
2339   u8 *s;
2340
2341   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2342   vec_add1 (s, 0);
2343
2344   vat_json_init_object (&node);
2345   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2346   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2347
2348   vec_free (s);
2349   vat_json_print (vam->ofp, &node);
2350   vat_json_free (&node);
2351
2352   vam->retval = ntohl (mp->retval);
2353   vam->result_ready = 1;
2354 }
2355
2356 static void vl_api_one_add_del_locator_set_reply_t_handler
2357   (vl_api_one_add_del_locator_set_reply_t * mp)
2358 {
2359   vat_main_t *vam = &vat_main;
2360   i32 retval = ntohl (mp->retval);
2361   if (vam->async_mode)
2362     {
2363       vam->async_errors += (retval < 0);
2364     }
2365   else
2366     {
2367       vam->retval = retval;
2368       vam->result_ready = 1;
2369     }
2370 }
2371
2372 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2373   (vl_api_one_add_del_locator_set_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2390   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404   vam->regenerate_interface_table = 1;
2405 }
2406
2407 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2408   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   vat_json_node_t node;
2412
2413   vat_json_init_object (&node);
2414   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2415   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2416
2417   vat_json_print (vam->ofp, &node);
2418   vat_json_free (&node);
2419
2420   vam->retval = ntohl (mp->retval);
2421   vam->result_ready = 1;
2422 }
2423
2424 static void vl_api_vxlan_offload_rx_reply_t_handler
2425   (vl_api_vxlan_offload_rx_reply_t * mp)
2426 {
2427   vat_main_t *vam = &vat_main;
2428   i32 retval = ntohl (mp->retval);
2429   if (vam->async_mode)
2430     {
2431       vam->async_errors += (retval < 0);
2432     }
2433   else
2434     {
2435       vam->retval = retval;
2436       vam->result_ready = 1;
2437     }
2438 }
2439
2440 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2441   (vl_api_vxlan_offload_rx_reply_t * mp)
2442 {
2443   vat_main_t *vam = &vat_main;
2444   vat_json_node_t node;
2445
2446   vat_json_init_object (&node);
2447   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2448
2449   vat_json_print (vam->ofp, &node);
2450   vat_json_free (&node);
2451
2452   vam->retval = ntohl (mp->retval);
2453   vam->result_ready = 1;
2454 }
2455
2456 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2457   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   i32 retval = ntohl (mp->retval);
2461   if (vam->async_mode)
2462     {
2463       vam->async_errors += (retval < 0);
2464     }
2465   else
2466     {
2467       vam->retval = retval;
2468       vam->sw_if_index = ntohl (mp->sw_if_index);
2469       vam->result_ready = 1;
2470     }
2471 }
2472
2473 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2474   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477   vat_json_node_t node;
2478
2479   vat_json_init_object (&node);
2480   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2481   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2482
2483   vat_json_print (vam->ofp, &node);
2484   vat_json_free (&node);
2485
2486   vam->retval = ntohl (mp->retval);
2487   vam->result_ready = 1;
2488 }
2489
2490 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2491   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2492 {
2493   vat_main_t *vam = &vat_main;
2494   i32 retval = ntohl (mp->retval);
2495   if (vam->async_mode)
2496     {
2497       vam->async_errors += (retval < 0);
2498     }
2499   else
2500     {
2501       vam->retval = retval;
2502       vam->sw_if_index = ntohl (mp->sw_if_index);
2503       vam->result_ready = 1;
2504     }
2505   vam->regenerate_interface_table = 1;
2506 }
2507
2508 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2509   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   vat_json_node_t node;
2513
2514   vat_json_init_object (&node);
2515   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2516   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2517
2518   vat_json_print (vam->ofp, &node);
2519   vat_json_free (&node);
2520
2521   vam->retval = ntohl (mp->retval);
2522   vam->result_ready = 1;
2523 }
2524
2525 static void vl_api_gre_tunnel_add_del_reply_t_handler
2526   (vl_api_gre_tunnel_add_del_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   i32 retval = ntohl (mp->retval);
2530   if (vam->async_mode)
2531     {
2532       vam->async_errors += (retval < 0);
2533     }
2534   else
2535     {
2536       vam->retval = retval;
2537       vam->sw_if_index = ntohl (mp->sw_if_index);
2538       vam->result_ready = 1;
2539     }
2540 }
2541
2542 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2543   (vl_api_gre_tunnel_add_del_reply_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   vat_json_node_t node;
2547
2548   vat_json_init_object (&node);
2549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2551
2552   vat_json_print (vam->ofp, &node);
2553   vat_json_free (&node);
2554
2555   vam->retval = ntohl (mp->retval);
2556   vam->result_ready = 1;
2557 }
2558
2559 static void vl_api_create_vhost_user_if_reply_t_handler
2560   (vl_api_create_vhost_user_if_reply_t * mp)
2561 {
2562   vat_main_t *vam = &vat_main;
2563   i32 retval = ntohl (mp->retval);
2564   if (vam->async_mode)
2565     {
2566       vam->async_errors += (retval < 0);
2567     }
2568   else
2569     {
2570       vam->retval = retval;
2571       vam->sw_if_index = ntohl (mp->sw_if_index);
2572       vam->result_ready = 1;
2573     }
2574   vam->regenerate_interface_table = 1;
2575 }
2576
2577 static void vl_api_create_vhost_user_if_reply_t_handler_json
2578   (vl_api_create_vhost_user_if_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   vat_json_node_t node;
2582
2583   vat_json_init_object (&node);
2584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2585   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2586
2587   vat_json_print (vam->ofp, &node);
2588   vat_json_free (&node);
2589
2590   vam->retval = ntohl (mp->retval);
2591   vam->result_ready = 1;
2592 }
2593
2594 static void vl_api_ip_address_details_t_handler
2595   (vl_api_ip_address_details_t * mp)
2596 {
2597   vat_main_t *vam = &vat_main;
2598   static ip_address_details_t empty_ip_address_details = { {0} };
2599   ip_address_details_t *address = NULL;
2600   ip_details_t *current_ip_details = NULL;
2601   ip_details_t *details = NULL;
2602
2603   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2604
2605   if (!details || vam->current_sw_if_index >= vec_len (details)
2606       || !details[vam->current_sw_if_index].present)
2607     {
2608       errmsg ("ip address details arrived but not stored");
2609       errmsg ("ip_dump should be called first");
2610       return;
2611     }
2612
2613   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2614
2615 #define addresses (current_ip_details->addr)
2616
2617   vec_validate_init_empty (addresses, vec_len (addresses),
2618                            empty_ip_address_details);
2619
2620   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2621
2622   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2623   address->prefix_length = mp->prefix.len;
2624 #undef addresses
2625 }
2626
2627 static void vl_api_ip_address_details_t_handler_json
2628   (vl_api_ip_address_details_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vat_json_node_t *node = NULL;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639
2640   vat_json_init_object (node);
2641   vat_json_object_add_prefix (node, &mp->prefix);
2642 }
2643
2644 static void
2645 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   static ip_details_t empty_ip_details = { 0 };
2649   ip_details_t *ip = NULL;
2650   u32 sw_if_index = ~0;
2651
2652   sw_if_index = ntohl (mp->sw_if_index);
2653
2654   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2655                            sw_if_index, empty_ip_details);
2656
2657   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2658                          sw_if_index);
2659
2660   ip->present = 1;
2661 }
2662
2663 static void
2664 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2665 {
2666   vat_main_t *vam = &vat_main;
2667
2668   if (VAT_JSON_ARRAY != vam->json_tree.type)
2669     {
2670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2671       vat_json_init_array (&vam->json_tree);
2672     }
2673   vat_json_array_add_uint (&vam->json_tree,
2674                            clib_net_to_host_u32 (mp->sw_if_index));
2675 }
2676
2677 static void vl_api_get_first_msg_id_reply_t_handler
2678   (vl_api_get_first_msg_id_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   i32 retval = ntohl (mp->retval);
2682
2683   if (vam->async_mode)
2684     {
2685       vam->async_errors += (retval < 0);
2686     }
2687   else
2688     {
2689       vam->retval = retval;
2690       vam->result_ready = 1;
2691     }
2692   if (retval >= 0)
2693     {
2694       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2695     }
2696 }
2697
2698 static void vl_api_get_first_msg_id_reply_t_handler_json
2699   (vl_api_get_first_msg_id_reply_t * mp)
2700 {
2701   vat_main_t *vam = &vat_main;
2702   vat_json_node_t node;
2703
2704   vat_json_init_object (&node);
2705   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2706   vat_json_object_add_uint (&node, "first_msg_id",
2707                             (uint) ntohs (mp->first_msg_id));
2708
2709   vat_json_print (vam->ofp, &node);
2710   vat_json_free (&node);
2711
2712   vam->retval = ntohl (mp->retval);
2713   vam->result_ready = 1;
2714 }
2715
2716 static void vl_api_get_node_graph_reply_t_handler
2717   (vl_api_get_node_graph_reply_t * mp)
2718 {
2719   vat_main_t *vam = &vat_main;
2720   i32 retval = ntohl (mp->retval);
2721   u8 *pvt_copy, *reply;
2722   void *oldheap;
2723   vlib_node_t *node;
2724   int i;
2725
2726   if (vam->async_mode)
2727     {
2728       vam->async_errors += (retval < 0);
2729     }
2730   else
2731     {
2732       vam->retval = retval;
2733       vam->result_ready = 1;
2734     }
2735
2736   /* "Should never happen..." */
2737   if (retval != 0)
2738     return;
2739
2740   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2741   pvt_copy = vec_dup (reply);
2742
2743   /* Toss the shared-memory original... */
2744   oldheap = vl_msg_push_heap ();
2745
2746   vec_free (reply);
2747
2748   vl_msg_pop_heap (oldheap);
2749
2750   if (vam->graph_nodes)
2751     {
2752       hash_free (vam->graph_node_index_by_name);
2753
2754       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2755         {
2756           node = vam->graph_nodes[0][i];
2757           vec_free (node->name);
2758           vec_free (node->next_nodes);
2759           vec_free (node);
2760         }
2761       vec_free (vam->graph_nodes[0]);
2762       vec_free (vam->graph_nodes);
2763     }
2764
2765   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2766   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2767   vec_free (pvt_copy);
2768
2769   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2770     {
2771       node = vam->graph_nodes[0][i];
2772       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2773     }
2774 }
2775
2776 static void vl_api_get_node_graph_reply_t_handler_json
2777   (vl_api_get_node_graph_reply_t * mp)
2778 {
2779   vat_main_t *vam = &vat_main;
2780   void *oldheap;
2781   vat_json_node_t node;
2782   u8 *reply;
2783
2784   /* $$$$ make this real? */
2785   vat_json_init_object (&node);
2786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2787   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2788
2789   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2790
2791   /* Toss the shared-memory original... */
2792   oldheap = vl_msg_push_heap ();
2793
2794   vec_free (reply);
2795
2796   vl_msg_pop_heap (oldheap);
2797
2798   vat_json_print (vam->ofp, &node);
2799   vat_json_free (&node);
2800
2801   vam->retval = ntohl (mp->retval);
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   u8 *s = 0;
2810
2811   if (mp->local)
2812     {
2813       s = format (s, "%=16d%=16d%=16d",
2814                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2815     }
2816   else
2817     {
2818       s = format (s, "%=16U%=16d%=16d",
2819                   format_ip46_address,
2820                   mp->ip_address, mp->priority, mp->weight);
2821     }
2822
2823   print (vam->ofp, "%v", s);
2824   vec_free (s);
2825 }
2826
2827 static void
2828 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   vat_json_node_t *node = NULL;
2832   struct in6_addr ip6;
2833   struct in_addr ip4;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842
2843   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2844   vat_json_object_add_uint (node, "priority", mp->priority);
2845   vat_json_object_add_uint (node, "weight", mp->weight);
2846
2847   if (mp->local)
2848     vat_json_object_add_uint (node, "sw_if_index",
2849                               clib_net_to_host_u32 (mp->sw_if_index));
2850   else
2851     {
2852       if (mp->ip_address.af)
2853         {
2854           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2855           vat_json_object_add_ip6 (node, "address", ip6);
2856         }
2857       else
2858         {
2859           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2860           vat_json_object_add_ip4 (node, "address", ip4);
2861         }
2862     }
2863 }
2864
2865 static void
2866 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2867                                           mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *ls_name = 0;
2871
2872   ls_name = format (0, "%s", mp->ls_name);
2873
2874   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2875          ls_name);
2876   vec_free (ls_name);
2877 }
2878
2879 static void
2880   vl_api_one_locator_set_details_t_handler_json
2881   (vl_api_one_locator_set_details_t * mp)
2882 {
2883   vat_main_t *vam = &vat_main;
2884   vat_json_node_t *node = 0;
2885   u8 *ls_name = 0;
2886
2887   ls_name = format (0, "%s", mp->ls_name);
2888   vec_add1 (ls_name, 0);
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896
2897   vat_json_init_object (node);
2898   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2899   vat_json_object_add_uint (node, "ls_index",
2900                             clib_net_to_host_u32 (mp->ls_index));
2901   vec_free (ls_name);
2902 }
2903
2904 typedef struct
2905 {
2906   u32 spi;
2907   u8 si;
2908 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2909
2910 uword
2911 unformat_nsh_address (unformat_input_t * input, va_list * args)
2912 {
2913   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2914   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2915 }
2916
2917 static u8 *
2918 format_nsh_address_vat (u8 * s, va_list * args)
2919 {
2920   nsh_t *a = va_arg (*args, nsh_t *);
2921   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2922 }
2923
2924 static u8 *
2925 format_lisp_flat_eid (u8 * s, va_list * args)
2926 {
2927   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2928
2929   switch (eid->type)
2930     {
2931     case EID_TYPE_API_PREFIX:
2932       if (eid->address.prefix.address.af)
2933         return format (s, "%U/%d", format_ip6_address,
2934                        eid->address.prefix.address.un.ip6,
2935                        eid->address.prefix.len);
2936       return format (s, "%U/%d", format_ip4_address,
2937                      eid->address.prefix.address.un.ip4,
2938                      eid->address.prefix.len);
2939     case EID_TYPE_API_MAC:
2940       return format (s, "%U", format_ethernet_address, eid->address.mac);
2941     case EID_TYPE_API_NSH:
2942       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2943     }
2944   return 0;
2945 }
2946
2947 static u8 *
2948 format_lisp_eid_vat (u8 * s, va_list * args)
2949 {
2950   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2951   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2952   u8 is_src_dst = (u8) va_arg (*args, int);
2953
2954   if (is_src_dst)
2955     s = format (s, "%U|", format_lisp_flat_eid, seid);
2956
2957   s = format (s, "%U", format_lisp_flat_eid, deid);
2958
2959   return s;
2960 }
2961
2962 static void
2963 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   u8 *s = 0, *eid = 0;
2967
2968   if (~0 == mp->locator_set_index)
2969     s = format (0, "action: %d", mp->action);
2970   else
2971     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   eid = format (0, "%U", format_lisp_eid_vat,
2974                 &mp->deid, &mp->seid, mp->is_src_dst);
2975   vec_add1 (eid, 0);
2976
2977   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2978          clib_net_to_host_u32 (mp->vni),
2979          eid,
2980          mp->is_local ? "local" : "remote",
2981          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2982          clib_net_to_host_u16 (mp->key.id), mp->key.key);
2983
2984   vec_free (s);
2985   vec_free (eid);
2986 }
2987
2988 static void
2989 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2990                                              * mp)
2991 {
2992   vat_main_t *vam = &vat_main;
2993   vat_json_node_t *node = 0;
2994   u8 *eid = 0;
2995
2996   if (VAT_JSON_ARRAY != vam->json_tree.type)
2997     {
2998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2999       vat_json_init_array (&vam->json_tree);
3000     }
3001   node = vat_json_array_add (&vam->json_tree);
3002
3003   vat_json_init_object (node);
3004   if (~0 == mp->locator_set_index)
3005     vat_json_object_add_uint (node, "action", mp->action);
3006   else
3007     vat_json_object_add_uint (node, "locator_set_index",
3008                               clib_net_to_host_u32 (mp->locator_set_index));
3009
3010   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3011   if (mp->deid.type == 3)
3012     {
3013       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3014       vat_json_init_object (nsh_json);
3015       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3016       vat_json_object_add_uint (nsh_json, "spi",
3017                                 clib_net_to_host_u32 (nsh->spi));
3018       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3019     }
3020   else
3021     {
3022       eid = format (0, "%U", format_lisp_eid_vat,
3023                     &mp->deid, &mp->seid, mp->is_src_dst);
3024       vec_add1 (eid, 0);
3025       vat_json_object_add_string_copy (node, "eid", eid);
3026       vec_free (eid);
3027     }
3028   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3029   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3030   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3031
3032   if (mp->key.id)
3033     {
3034       vat_json_object_add_uint (node, "key_id",
3035                                 clib_net_to_host_u16 (mp->key.id));
3036       vat_json_object_add_string_copy (node, "key", mp->key.key);
3037     }
3038 }
3039
3040 static void
3041 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3042 {
3043   vat_main_t *vam = &vat_main;
3044   u8 *seid = 0, *deid = 0;
3045   ip46_address_t lloc, rloc;
3046
3047   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3048
3049   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3050
3051   vec_add1 (deid, 0);
3052   vec_add1 (seid, 0);
3053
3054   if (mp->lloc.af)
3055     {
3056       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3057       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3058     }
3059   else
3060     {
3061       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3062       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3063     }
3064
3065
3066   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3067          clib_net_to_host_u32 (mp->vni),
3068          seid, deid,
3069          format_ip46_address, lloc,
3070          format_ip46_address, rloc,
3071          clib_net_to_host_u32 (mp->pkt_count),
3072          clib_net_to_host_u32 (mp->bytes));
3073
3074   vec_free (deid);
3075   vec_free (seid);
3076 }
3077
3078 static void
3079 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3080 {
3081   struct in6_addr ip6;
3082   struct in_addr ip4;
3083   vat_main_t *vam = &vat_main;
3084   vat_json_node_t *node = 0;
3085   u8 *deid = 0, *seid = 0;
3086
3087   if (VAT_JSON_ARRAY != vam->json_tree.type)
3088     {
3089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3090       vat_json_init_array (&vam->json_tree);
3091     }
3092   node = vat_json_array_add (&vam->json_tree);
3093
3094   vat_json_init_object (node);
3095   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3096
3097   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3098
3099   vec_add1 (deid, 0);
3100   vec_add1 (seid, 0);
3101
3102   vat_json_object_add_string_copy (node, "seid", seid);
3103   vat_json_object_add_string_copy (node, "deid", deid);
3104   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3105
3106   if (mp->lloc.af)
3107     {
3108       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3109       vat_json_object_add_ip6 (node, "lloc", ip6);
3110       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3111       vat_json_object_add_ip6 (node, "rloc", ip6);
3112
3113     }
3114   else
3115     {
3116       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3117       vat_json_object_add_ip4 (node, "lloc", ip4);
3118       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3119       vat_json_object_add_ip4 (node, "rloc", ip4);
3120     }
3121   vat_json_object_add_uint (node, "pkt_count",
3122                             clib_net_to_host_u32 (mp->pkt_count));
3123   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3124
3125   vec_free (deid);
3126   vec_free (seid);
3127 }
3128
3129 static void
3130   vl_api_one_eid_table_map_details_t_handler
3131   (vl_api_one_eid_table_map_details_t * mp)
3132 {
3133   vat_main_t *vam = &vat_main;
3134
3135   u8 *line = format (0, "%=10d%=10d",
3136                      clib_net_to_host_u32 (mp->vni),
3137                      clib_net_to_host_u32 (mp->dp_table));
3138   print (vam->ofp, "%v", line);
3139   vec_free (line);
3140 }
3141
3142 static void
3143   vl_api_one_eid_table_map_details_t_handler_json
3144   (vl_api_one_eid_table_map_details_t * mp)
3145 {
3146   vat_main_t *vam = &vat_main;
3147   vat_json_node_t *node = NULL;
3148
3149   if (VAT_JSON_ARRAY != vam->json_tree.type)
3150     {
3151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3152       vat_json_init_array (&vam->json_tree);
3153     }
3154   node = vat_json_array_add (&vam->json_tree);
3155   vat_json_init_object (node);
3156   vat_json_object_add_uint (node, "dp_table",
3157                             clib_net_to_host_u32 (mp->dp_table));
3158   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3159 }
3160
3161 static void
3162   vl_api_one_eid_table_vni_details_t_handler
3163   (vl_api_one_eid_table_vni_details_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166
3167   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3168   print (vam->ofp, "%v", line);
3169   vec_free (line);
3170 }
3171
3172 static void
3173   vl_api_one_eid_table_vni_details_t_handler_json
3174   (vl_api_one_eid_table_vni_details_t * mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *node = NULL;
3178
3179   if (VAT_JSON_ARRAY != vam->json_tree.type)
3180     {
3181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3182       vat_json_init_array (&vam->json_tree);
3183     }
3184   node = vat_json_array_add (&vam->json_tree);
3185   vat_json_init_object (node);
3186   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3187 }
3188
3189 static void
3190   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3191   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194   int retval = clib_net_to_host_u32 (mp->retval);
3195
3196   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3197   print (vam->ofp, "fallback threshold value: %d", mp->value);
3198
3199   vam->retval = retval;
3200   vam->result_ready = 1;
3201 }
3202
3203 static void
3204   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3205   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t _node, *node = &_node;
3209   int retval = clib_net_to_host_u32 (mp->retval);
3210
3211   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3212   vat_json_init_object (node);
3213   vat_json_object_add_uint (node, "value", mp->value);
3214
3215   vat_json_print (vam->ofp, node);
3216   vat_json_free (node);
3217
3218   vam->retval = retval;
3219   vam->result_ready = 1;
3220 }
3221
3222 static void
3223   vl_api_show_one_map_register_state_reply_t_handler
3224   (vl_api_show_one_map_register_state_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   int retval = clib_net_to_host_u32 (mp->retval);
3228
3229   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3230
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_map_register_state_reply_t_handler_json
3237   (vl_api_show_one_map_register_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t _node, *node = &_node;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242
3243   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3244
3245   vat_json_init_object (node);
3246   vat_json_object_add_string_copy (node, "state", s);
3247
3248   vat_json_print (vam->ofp, node);
3249   vat_json_free (node);
3250
3251   vam->retval = retval;
3252   vam->result_ready = 1;
3253   vec_free (s);
3254 }
3255
3256 static void
3257   vl_api_show_one_rloc_probe_state_reply_t_handler
3258   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3259 {
3260   vat_main_t *vam = &vat_main;
3261   int retval = clib_net_to_host_u32 (mp->retval);
3262
3263   if (retval)
3264     goto end;
3265
3266   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3267 end:
3268   vam->retval = retval;
3269   vam->result_ready = 1;
3270 }
3271
3272 static void
3273   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3274   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3275 {
3276   vat_main_t *vam = &vat_main;
3277   vat_json_node_t _node, *node = &_node;
3278   int retval = clib_net_to_host_u32 (mp->retval);
3279
3280   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3281   vat_json_init_object (node);
3282   vat_json_object_add_string_copy (node, "state", s);
3283
3284   vat_json_print (vam->ofp, node);
3285   vat_json_free (node);
3286
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289   vec_free (s);
3290 }
3291
3292 static void
3293   vl_api_show_one_stats_enable_disable_reply_t_handler
3294   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3303 end:
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306 }
3307
3308 static void
3309   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3310   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   vat_json_node_t _node, *node = &_node;
3314   int retval = clib_net_to_host_u32 (mp->retval);
3315
3316   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3317   vat_json_init_object (node);
3318   vat_json_object_add_string_copy (node, "state", s);
3319
3320   vat_json_print (vam->ofp, node);
3321   vat_json_free (node);
3322
3323   vam->retval = retval;
3324   vam->result_ready = 1;
3325   vec_free (s);
3326 }
3327
3328 static void
3329 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3330 {
3331   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3332   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3333   e->vni = clib_net_to_host_u32 (e->vni);
3334 }
3335
3336 static void
3337   gpe_fwd_entries_get_reply_t_net_to_host
3338   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3339 {
3340   u32 i;
3341
3342   mp->count = clib_net_to_host_u32 (mp->count);
3343   for (i = 0; i < mp->count; i++)
3344     {
3345       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3346     }
3347 }
3348
3349 static u8 *
3350 format_gpe_encap_mode (u8 * s, va_list * args)
3351 {
3352   u32 mode = va_arg (*args, u32);
3353
3354   switch (mode)
3355     {
3356     case 0:
3357       return format (s, "lisp");
3358     case 1:
3359       return format (s, "vxlan");
3360     }
3361   return 0;
3362 }
3363
3364 static void
3365   vl_api_gpe_get_encap_mode_reply_t_handler
3366   (vl_api_gpe_get_encap_mode_reply_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369
3370   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3371   vam->retval = ntohl (mp->retval);
3372   vam->result_ready = 1;
3373 }
3374
3375 static void
3376   vl_api_gpe_get_encap_mode_reply_t_handler_json
3377   (vl_api_gpe_get_encap_mode_reply_t * mp)
3378 {
3379   vat_main_t *vam = &vat_main;
3380   vat_json_node_t node;
3381
3382   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3383   vec_add1 (encap_mode, 0);
3384
3385   vat_json_init_object (&node);
3386   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3387
3388   vec_free (encap_mode);
3389   vat_json_print (vam->ofp, &node);
3390   vat_json_free (&node);
3391
3392   vam->retval = ntohl (mp->retval);
3393   vam->result_ready = 1;
3394 }
3395
3396 static void
3397   vl_api_gpe_fwd_entry_path_details_t_handler
3398   (vl_api_gpe_fwd_entry_path_details_t * mp)
3399 {
3400   vat_main_t *vam = &vat_main;
3401   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3402
3403   if (mp->lcl_loc.addr.af)
3404     format_ip_address_fcn = format_ip6_address;
3405   else
3406     format_ip_address_fcn = format_ip4_address;
3407
3408   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3409          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3410          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3411 }
3412
3413 static void
3414 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3415 {
3416   struct in6_addr ip6;
3417   struct in_addr ip4;
3418
3419   if (loc->addr.af)
3420     {
3421       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3422       vat_json_object_add_ip6 (n, "address", ip6);
3423     }
3424   else
3425     {
3426       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3427       vat_json_object_add_ip4 (n, "address", ip4);
3428     }
3429   vat_json_object_add_uint (n, "weight", loc->weight);
3430 }
3431
3432 static void
3433   vl_api_gpe_fwd_entry_path_details_t_handler_json
3434   (vl_api_gpe_fwd_entry_path_details_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   vat_json_node_t *node = NULL;
3438   vat_json_node_t *loc_node;
3439
3440   if (VAT_JSON_ARRAY != vam->json_tree.type)
3441     {
3442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3443       vat_json_init_array (&vam->json_tree);
3444     }
3445   node = vat_json_array_add (&vam->json_tree);
3446   vat_json_init_object (node);
3447
3448   loc_node = vat_json_object_add (node, "local_locator");
3449   vat_json_init_object (loc_node);
3450   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3451
3452   loc_node = vat_json_object_add (node, "remote_locator");
3453   vat_json_init_object (loc_node);
3454   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3455 }
3456
3457 static void
3458   vl_api_gpe_fwd_entries_get_reply_t_handler
3459   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   u32 i;
3463   int retval = clib_net_to_host_u32 (mp->retval);
3464   vl_api_gpe_fwd_entry_t *e;
3465
3466   if (retval)
3467     goto end;
3468
3469   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3470
3471   for (i = 0; i < mp->count; i++)
3472     {
3473       e = &mp->entries[i];
3474       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3475              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3476     }
3477
3478 end:
3479   vam->retval = retval;
3480   vam->result_ready = 1;
3481 }
3482
3483 static void
3484   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3485   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3486 {
3487   u8 *s = 0;
3488   vat_main_t *vam = &vat_main;
3489   vat_json_node_t *e = 0, root;
3490   u32 i;
3491   int retval = clib_net_to_host_u32 (mp->retval);
3492   vl_api_gpe_fwd_entry_t *fwd;
3493
3494   if (retval)
3495     goto end;
3496
3497   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3498   vat_json_init_array (&root);
3499
3500   for (i = 0; i < mp->count; i++)
3501     {
3502       e = vat_json_array_add (&root);
3503       fwd = &mp->entries[i];
3504
3505       vat_json_init_object (e);
3506       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3507       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3508       vat_json_object_add_int (e, "vni", fwd->vni);
3509       vat_json_object_add_int (e, "action", fwd->action);
3510
3511       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3512       vec_add1 (s, 0);
3513       vat_json_object_add_string_copy (e, "leid", s);
3514       vec_free (s);
3515
3516       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3517       vec_add1 (s, 0);
3518       vat_json_object_add_string_copy (e, "reid", s);
3519       vec_free (s);
3520     }
3521
3522   vat_json_print (vam->ofp, &root);
3523   vat_json_free (&root);
3524
3525 end:
3526   vam->retval = retval;
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3532   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u32 i, n;
3536   int retval = clib_net_to_host_u32 (mp->retval);
3537   vl_api_gpe_native_fwd_rpath_t *r;
3538
3539   if (retval)
3540     goto end;
3541
3542   n = clib_net_to_host_u32 (mp->count);
3543
3544   for (i = 0; i < n; i++)
3545     {
3546       r = &mp->entries[i];
3547       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3548              clib_net_to_host_u32 (r->fib_index),
3549              clib_net_to_host_u32 (r->nh_sw_if_index),
3550              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3551              r->nh_addr.un);
3552     }
3553
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3561   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t root, *e;
3565   u32 i, n;
3566   int retval = clib_net_to_host_u32 (mp->retval);
3567   vl_api_gpe_native_fwd_rpath_t *r;
3568   u8 *s;
3569
3570   if (retval)
3571     goto end;
3572
3573   n = clib_net_to_host_u32 (mp->count);
3574   vat_json_init_array (&root);
3575
3576   for (i = 0; i < n; i++)
3577     {
3578       e = vat_json_array_add (&root);
3579       vat_json_init_object (e);
3580       r = &mp->entries[i];
3581       s =
3582         format (0, "%U",
3583                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3584                 r->nh_addr.un);
3585       vec_add1 (s, 0);
3586       vat_json_object_add_string_copy (e, "ip4", s);
3587       vec_free (s);
3588
3589       vat_json_object_add_uint (e, "fib_index",
3590                                 clib_net_to_host_u32 (r->fib_index));
3591       vat_json_object_add_uint (e, "nh_sw_if_index",
3592                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3593     }
3594
3595   vat_json_print (vam->ofp, &root);
3596   vat_json_free (&root);
3597
3598 end:
3599   vam->retval = retval;
3600   vam->result_ready = 1;
3601 }
3602
3603 static void
3604   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3605   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3606 {
3607   vat_main_t *vam = &vat_main;
3608   u32 i, n;
3609   int retval = clib_net_to_host_u32 (mp->retval);
3610
3611   if (retval)
3612     goto end;
3613
3614   n = clib_net_to_host_u32 (mp->count);
3615
3616   for (i = 0; i < n; i++)
3617     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3618
3619 end:
3620   vam->retval = retval;
3621   vam->result_ready = 1;
3622 }
3623
3624 static void
3625   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3626   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3627 {
3628   vat_main_t *vam = &vat_main;
3629   vat_json_node_t root;
3630   u32 i, n;
3631   int retval = clib_net_to_host_u32 (mp->retval);
3632
3633   if (retval)
3634     goto end;
3635
3636   n = clib_net_to_host_u32 (mp->count);
3637   vat_json_init_array (&root);
3638
3639   for (i = 0; i < n; i++)
3640     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3641
3642   vat_json_print (vam->ofp, &root);
3643   vat_json_free (&root);
3644
3645 end:
3646   vam->retval = retval;
3647   vam->result_ready = 1;
3648 }
3649
3650 static void
3651   vl_api_one_ndp_entries_get_reply_t_handler
3652   (vl_api_one_ndp_entries_get_reply_t * mp)
3653 {
3654   vat_main_t *vam = &vat_main;
3655   u32 i, n;
3656   int retval = clib_net_to_host_u32 (mp->retval);
3657
3658   if (retval)
3659     goto end;
3660
3661   n = clib_net_to_host_u32 (mp->count);
3662
3663   for (i = 0; i < n; i++)
3664     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3665            format_ethernet_address, mp->entries[i].mac);
3666
3667 end:
3668   vam->retval = retval;
3669   vam->result_ready = 1;
3670 }
3671
3672 static void
3673   vl_api_one_ndp_entries_get_reply_t_handler_json
3674   (vl_api_one_ndp_entries_get_reply_t * mp)
3675 {
3676   u8 *s = 0;
3677   vat_main_t *vam = &vat_main;
3678   vat_json_node_t *e = 0, root;
3679   u32 i, n;
3680   int retval = clib_net_to_host_u32 (mp->retval);
3681   vl_api_one_ndp_entry_t *arp_entry;
3682
3683   if (retval)
3684     goto end;
3685
3686   n = clib_net_to_host_u32 (mp->count);
3687   vat_json_init_array (&root);
3688
3689   for (i = 0; i < n; i++)
3690     {
3691       e = vat_json_array_add (&root);
3692       arp_entry = &mp->entries[i];
3693
3694       vat_json_init_object (e);
3695       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3696       vec_add1 (s, 0);
3697
3698       vat_json_object_add_string_copy (e, "mac", s);
3699       vec_free (s);
3700
3701       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3702       vec_add1 (s, 0);
3703       vat_json_object_add_string_copy (e, "ip6", s);
3704       vec_free (s);
3705     }
3706
3707   vat_json_print (vam->ofp, &root);
3708   vat_json_free (&root);
3709
3710 end:
3711   vam->retval = retval;
3712   vam->result_ready = 1;
3713 }
3714
3715 static void
3716   vl_api_one_l2_arp_entries_get_reply_t_handler
3717   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3718 {
3719   vat_main_t *vam = &vat_main;
3720   u32 i, n;
3721   int retval = clib_net_to_host_u32 (mp->retval);
3722
3723   if (retval)
3724     goto end;
3725
3726   n = clib_net_to_host_u32 (mp->count);
3727
3728   for (i = 0; i < n; i++)
3729     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3730            format_ethernet_address, mp->entries[i].mac);
3731
3732 end:
3733   vam->retval = retval;
3734   vam->result_ready = 1;
3735 }
3736
3737 static void
3738   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3739   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3740 {
3741   u8 *s = 0;
3742   vat_main_t *vam = &vat_main;
3743   vat_json_node_t *e = 0, root;
3744   u32 i, n;
3745   int retval = clib_net_to_host_u32 (mp->retval);
3746   vl_api_one_l2_arp_entry_t *arp_entry;
3747
3748   if (retval)
3749     goto end;
3750
3751   n = clib_net_to_host_u32 (mp->count);
3752   vat_json_init_array (&root);
3753
3754   for (i = 0; i < n; i++)
3755     {
3756       e = vat_json_array_add (&root);
3757       arp_entry = &mp->entries[i];
3758
3759       vat_json_init_object (e);
3760       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3761       vec_add1 (s, 0);
3762
3763       vat_json_object_add_string_copy (e, "mac", s);
3764       vec_free (s);
3765
3766       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3767       vec_add1 (s, 0);
3768       vat_json_object_add_string_copy (e, "ip4", s);
3769       vec_free (s);
3770     }
3771
3772   vat_json_print (vam->ofp, &root);
3773   vat_json_free (&root);
3774
3775 end:
3776   vam->retval = retval;
3777   vam->result_ready = 1;
3778 }
3779
3780 static void
3781 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3782 {
3783   vat_main_t *vam = &vat_main;
3784   u32 i, n;
3785   int retval = clib_net_to_host_u32 (mp->retval);
3786
3787   if (retval)
3788     goto end;
3789
3790   n = clib_net_to_host_u32 (mp->count);
3791
3792   for (i = 0; i < n; i++)
3793     {
3794       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3795     }
3796
3797 end:
3798   vam->retval = retval;
3799   vam->result_ready = 1;
3800 }
3801
3802 static void
3803   vl_api_one_ndp_bd_get_reply_t_handler_json
3804   (vl_api_one_ndp_bd_get_reply_t * mp)
3805 {
3806   vat_main_t *vam = &vat_main;
3807   vat_json_node_t root;
3808   u32 i, n;
3809   int retval = clib_net_to_host_u32 (mp->retval);
3810
3811   if (retval)
3812     goto end;
3813
3814   n = clib_net_to_host_u32 (mp->count);
3815   vat_json_init_array (&root);
3816
3817   for (i = 0; i < n; i++)
3818     {
3819       vat_json_array_add_uint (&root,
3820                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3821     }
3822
3823   vat_json_print (vam->ofp, &root);
3824   vat_json_free (&root);
3825
3826 end:
3827   vam->retval = retval;
3828   vam->result_ready = 1;
3829 }
3830
3831 static void
3832   vl_api_one_l2_arp_bd_get_reply_t_handler
3833   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3834 {
3835   vat_main_t *vam = &vat_main;
3836   u32 i, n;
3837   int retval = clib_net_to_host_u32 (mp->retval);
3838
3839   if (retval)
3840     goto end;
3841
3842   n = clib_net_to_host_u32 (mp->count);
3843
3844   for (i = 0; i < n; i++)
3845     {
3846       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3847     }
3848
3849 end:
3850   vam->retval = retval;
3851   vam->result_ready = 1;
3852 }
3853
3854 static void
3855   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3856   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3857 {
3858   vat_main_t *vam = &vat_main;
3859   vat_json_node_t root;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867   vat_json_init_array (&root);
3868
3869   for (i = 0; i < n; i++)
3870     {
3871       vat_json_array_add_uint (&root,
3872                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3873     }
3874
3875   vat_json_print (vam->ofp, &root);
3876   vat_json_free (&root);
3877
3878 end:
3879   vam->retval = retval;
3880   vam->result_ready = 1;
3881 }
3882
3883 static void
3884   vl_api_one_adjacencies_get_reply_t_handler
3885   (vl_api_one_adjacencies_get_reply_t * mp)
3886 {
3887   vat_main_t *vam = &vat_main;
3888   u32 i, n;
3889   int retval = clib_net_to_host_u32 (mp->retval);
3890   vl_api_one_adjacency_t *a;
3891
3892   if (retval)
3893     goto end;
3894
3895   n = clib_net_to_host_u32 (mp->count);
3896
3897   for (i = 0; i < n; i++)
3898     {
3899       a = &mp->adjacencies[i];
3900       print (vam->ofp, "%U %40U",
3901              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3902     }
3903
3904 end:
3905   vam->retval = retval;
3906   vam->result_ready = 1;
3907 }
3908
3909 static void
3910   vl_api_one_adjacencies_get_reply_t_handler_json
3911   (vl_api_one_adjacencies_get_reply_t * mp)
3912 {
3913   u8 *s = 0;
3914   vat_main_t *vam = &vat_main;
3915   vat_json_node_t *e = 0, root;
3916   u32 i, n;
3917   int retval = clib_net_to_host_u32 (mp->retval);
3918   vl_api_one_adjacency_t *a;
3919
3920   if (retval)
3921     goto end;
3922
3923   n = clib_net_to_host_u32 (mp->count);
3924   vat_json_init_array (&root);
3925
3926   for (i = 0; i < n; i++)
3927     {
3928       e = vat_json_array_add (&root);
3929       a = &mp->adjacencies[i];
3930
3931       vat_json_init_object (e);
3932       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3933       vec_add1 (s, 0);
3934       vat_json_object_add_string_copy (e, "leid", s);
3935       vec_free (s);
3936
3937       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3938       vec_add1 (s, 0);
3939       vat_json_object_add_string_copy (e, "reid", s);
3940       vec_free (s);
3941     }
3942
3943   vat_json_print (vam->ofp, &root);
3944   vat_json_free (&root);
3945
3946 end:
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
3955
3956   print (vam->ofp, "%=20U",
3957          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3958          mp->ip_address.un);
3959 }
3960
3961 static void
3962   vl_api_one_map_server_details_t_handler_json
3963   (vl_api_one_map_server_details_t * mp)
3964 {
3965   vat_main_t *vam = &vat_main;
3966   vat_json_node_t *node = NULL;
3967   struct in6_addr ip6;
3968   struct in_addr ip4;
3969
3970   if (VAT_JSON_ARRAY != vam->json_tree.type)
3971     {
3972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3973       vat_json_init_array (&vam->json_tree);
3974     }
3975   node = vat_json_array_add (&vam->json_tree);
3976
3977   vat_json_init_object (node);
3978   if (mp->ip_address.af)
3979     {
3980       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3981       vat_json_object_add_ip6 (node, "map-server", ip6);
3982     }
3983   else
3984     {
3985       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3986       vat_json_object_add_ip4 (node, "map-server", ip4);
3987     }
3988 }
3989
3990 static void
3991 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3992                                            * mp)
3993 {
3994   vat_main_t *vam = &vat_main;
3995
3996   print (vam->ofp, "%=20U",
3997          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3998          mp->ip_address.un);
3999 }
4000
4001 static void
4002   vl_api_one_map_resolver_details_t_handler_json
4003   (vl_api_one_map_resolver_details_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   vat_json_node_t *node = NULL;
4007   struct in6_addr ip6;
4008   struct in_addr ip4;
4009
4010   if (VAT_JSON_ARRAY != vam->json_tree.type)
4011     {
4012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4013       vat_json_init_array (&vam->json_tree);
4014     }
4015   node = vat_json_array_add (&vam->json_tree);
4016
4017   vat_json_init_object (node);
4018   if (mp->ip_address.af)
4019     {
4020       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4021       vat_json_object_add_ip6 (node, "map resolver", ip6);
4022     }
4023   else
4024     {
4025       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4026       vat_json_object_add_ip4 (node, "map resolver", ip4);
4027     }
4028 }
4029
4030 static void
4031 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4032 {
4033   vat_main_t *vam = &vat_main;
4034   i32 retval = ntohl (mp->retval);
4035
4036   if (0 <= retval)
4037     {
4038       print (vam->ofp, "feature: %s\ngpe: %s",
4039              mp->feature_status ? "enabled" : "disabled",
4040              mp->gpe_status ? "enabled" : "disabled");
4041     }
4042
4043   vam->retval = retval;
4044   vam->result_ready = 1;
4045 }
4046
4047 static void
4048   vl_api_show_one_status_reply_t_handler_json
4049   (vl_api_show_one_status_reply_t * mp)
4050 {
4051   vat_main_t *vam = &vat_main;
4052   vat_json_node_t node;
4053   u8 *gpe_status = NULL;
4054   u8 *feature_status = NULL;
4055
4056   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4057   feature_status = format (0, "%s",
4058                            mp->feature_status ? "enabled" : "disabled");
4059   vec_add1 (gpe_status, 0);
4060   vec_add1 (feature_status, 0);
4061
4062   vat_json_init_object (&node);
4063   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4064   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4065
4066   vec_free (gpe_status);
4067   vec_free (feature_status);
4068
4069   vat_json_print (vam->ofp, &node);
4070   vat_json_free (&node);
4071
4072   vam->retval = ntohl (mp->retval);
4073   vam->result_ready = 1;
4074 }
4075
4076 static void
4077   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4078   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081   i32 retval = ntohl (mp->retval);
4082
4083   if (retval >= 0)
4084     {
4085       print (vam->ofp, "%=20s", mp->locator_set_name);
4086     }
4087
4088   vam->retval = retval;
4089   vam->result_ready = 1;
4090 }
4091
4092 static void
4093   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4094   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4095 {
4096   vat_main_t *vam = &vat_main;
4097   vat_json_node_t *node = NULL;
4098
4099   if (VAT_JSON_ARRAY != vam->json_tree.type)
4100     {
4101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4102       vat_json_init_array (&vam->json_tree);
4103     }
4104   node = vat_json_array_add (&vam->json_tree);
4105
4106   vat_json_init_object (node);
4107   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4108
4109   vat_json_print (vam->ofp, node);
4110   vat_json_free (node);
4111
4112   vam->retval = ntohl (mp->retval);
4113   vam->result_ready = 1;
4114 }
4115
4116 static u8 *
4117 format_lisp_map_request_mode (u8 * s, va_list * args)
4118 {
4119   u32 mode = va_arg (*args, u32);
4120
4121   switch (mode)
4122     {
4123     case 0:
4124       return format (0, "dst-only");
4125     case 1:
4126       return format (0, "src-dst");
4127     }
4128   return 0;
4129 }
4130
4131 static void
4132   vl_api_show_one_map_request_mode_reply_t_handler
4133   (vl_api_show_one_map_request_mode_reply_t * mp)
4134 {
4135   vat_main_t *vam = &vat_main;
4136   i32 retval = ntohl (mp->retval);
4137
4138   if (0 <= retval)
4139     {
4140       u32 mode = mp->mode;
4141       print (vam->ofp, "map_request_mode: %U",
4142              format_lisp_map_request_mode, mode);
4143     }
4144
4145   vam->retval = retval;
4146   vam->result_ready = 1;
4147 }
4148
4149 static void
4150   vl_api_show_one_map_request_mode_reply_t_handler_json
4151   (vl_api_show_one_map_request_mode_reply_t * mp)
4152 {
4153   vat_main_t *vam = &vat_main;
4154   vat_json_node_t node;
4155   u8 *s = 0;
4156   u32 mode;
4157
4158   mode = mp->mode;
4159   s = format (0, "%U", format_lisp_map_request_mode, mode);
4160   vec_add1 (s, 0);
4161
4162   vat_json_init_object (&node);
4163   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4164   vat_json_print (vam->ofp, &node);
4165   vat_json_free (&node);
4166
4167   vec_free (s);
4168   vam->retval = ntohl (mp->retval);
4169   vam->result_ready = 1;
4170 }
4171
4172 static void
4173   vl_api_one_show_xtr_mode_reply_t_handler
4174   (vl_api_one_show_xtr_mode_reply_t * mp)
4175 {
4176   vat_main_t *vam = &vat_main;
4177   i32 retval = ntohl (mp->retval);
4178
4179   if (0 <= retval)
4180     {
4181       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4182     }
4183
4184   vam->retval = retval;
4185   vam->result_ready = 1;
4186 }
4187
4188 static void
4189   vl_api_one_show_xtr_mode_reply_t_handler_json
4190   (vl_api_one_show_xtr_mode_reply_t * mp)
4191 {
4192   vat_main_t *vam = &vat_main;
4193   vat_json_node_t node;
4194   u8 *status = 0;
4195
4196   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4197   vec_add1 (status, 0);
4198
4199   vat_json_init_object (&node);
4200   vat_json_object_add_string_copy (&node, "status", status);
4201
4202   vec_free (status);
4203
4204   vat_json_print (vam->ofp, &node);
4205   vat_json_free (&node);
4206
4207   vam->retval = ntohl (mp->retval);
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_one_show_pitr_mode_reply_t_handler
4213   (vl_api_one_show_pitr_mode_reply_t * mp)
4214 {
4215   vat_main_t *vam = &vat_main;
4216   i32 retval = ntohl (mp->retval);
4217
4218   if (0 <= retval)
4219     {
4220       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4221     }
4222
4223   vam->retval = retval;
4224   vam->result_ready = 1;
4225 }
4226
4227 static void
4228   vl_api_one_show_pitr_mode_reply_t_handler_json
4229   (vl_api_one_show_pitr_mode_reply_t * mp)
4230 {
4231   vat_main_t *vam = &vat_main;
4232   vat_json_node_t node;
4233   u8 *status = 0;
4234
4235   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4236   vec_add1 (status, 0);
4237
4238   vat_json_init_object (&node);
4239   vat_json_object_add_string_copy (&node, "status", status);
4240
4241   vec_free (status);
4242
4243   vat_json_print (vam->ofp, &node);
4244   vat_json_free (&node);
4245
4246   vam->retval = ntohl (mp->retval);
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_show_petr_mode_reply_t_handler
4252   (vl_api_one_show_petr_mode_reply_t * mp)
4253 {
4254   vat_main_t *vam = &vat_main;
4255   i32 retval = ntohl (mp->retval);
4256
4257   if (0 <= retval)
4258     {
4259       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4260     }
4261
4262   vam->retval = retval;
4263   vam->result_ready = 1;
4264 }
4265
4266 static void
4267   vl_api_one_show_petr_mode_reply_t_handler_json
4268   (vl_api_one_show_petr_mode_reply_t * mp)
4269 {
4270   vat_main_t *vam = &vat_main;
4271   vat_json_node_t node;
4272   u8 *status = 0;
4273
4274   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4275   vec_add1 (status, 0);
4276
4277   vat_json_init_object (&node);
4278   vat_json_object_add_string_copy (&node, "status", status);
4279
4280   vec_free (status);
4281
4282   vat_json_print (vam->ofp, &node);
4283   vat_json_free (&node);
4284
4285   vam->retval = ntohl (mp->retval);
4286   vam->result_ready = 1;
4287 }
4288
4289 static void
4290   vl_api_show_one_use_petr_reply_t_handler
4291   (vl_api_show_one_use_petr_reply_t * mp)
4292 {
4293   vat_main_t *vam = &vat_main;
4294   i32 retval = ntohl (mp->retval);
4295
4296   if (0 <= retval)
4297     {
4298       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4299       if (mp->status)
4300         {
4301           print (vam->ofp, "Proxy-ETR address; %U",
4302                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4303                  mp->ip_address.un);
4304         }
4305     }
4306
4307   vam->retval = retval;
4308   vam->result_ready = 1;
4309 }
4310
4311 static void
4312   vl_api_show_one_use_petr_reply_t_handler_json
4313   (vl_api_show_one_use_petr_reply_t * mp)
4314 {
4315   vat_main_t *vam = &vat_main;
4316   vat_json_node_t node;
4317   u8 *status = 0;
4318   struct in_addr ip4;
4319   struct in6_addr ip6;
4320
4321   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4322   vec_add1 (status, 0);
4323
4324   vat_json_init_object (&node);
4325   vat_json_object_add_string_copy (&node, "status", status);
4326   if (mp->status)
4327     {
4328       if (mp->ip_address.af)
4329         {
4330           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4331           vat_json_object_add_ip6 (&node, "address", ip6);
4332         }
4333       else
4334         {
4335           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4336           vat_json_object_add_ip4 (&node, "address", ip4);
4337         }
4338     }
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_show_one_nsh_mapping_reply_t_handler
4351   (vl_api_show_one_nsh_mapping_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%-20s%-16s",
4359              mp->is_set ? "set" : "not-set",
4360              mp->is_set ? (char *) mp->locator_set_name : "");
4361     }
4362
4363   vam->retval = retval;
4364   vam->result_ready = 1;
4365 }
4366
4367 static void
4368   vl_api_show_one_nsh_mapping_reply_t_handler_json
4369   (vl_api_show_one_nsh_mapping_reply_t * mp)
4370 {
4371   vat_main_t *vam = &vat_main;
4372   vat_json_node_t node;
4373   u8 *status = 0;
4374
4375   status = format (0, "%s", mp->is_set ? "yes" : "no");
4376   vec_add1 (status, 0);
4377
4378   vat_json_init_object (&node);
4379   vat_json_object_add_string_copy (&node, "is_set", status);
4380   if (mp->is_set)
4381     {
4382       vat_json_object_add_string_copy (&node, "locator_set",
4383                                        mp->locator_set_name);
4384     }
4385
4386   vec_free (status);
4387
4388   vat_json_print (vam->ofp, &node);
4389   vat_json_free (&node);
4390
4391   vam->retval = ntohl (mp->retval);
4392   vam->result_ready = 1;
4393 }
4394
4395 static void
4396   vl_api_show_one_map_register_ttl_reply_t_handler
4397   (vl_api_show_one_map_register_ttl_reply_t * mp)
4398 {
4399   vat_main_t *vam = &vat_main;
4400   i32 retval = ntohl (mp->retval);
4401
4402   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4403
4404   if (0 <= retval)
4405     {
4406       print (vam->ofp, "ttl: %u", mp->ttl);
4407     }
4408
4409   vam->retval = retval;
4410   vam->result_ready = 1;
4411 }
4412
4413 static void
4414   vl_api_show_one_map_register_ttl_reply_t_handler_json
4415   (vl_api_show_one_map_register_ttl_reply_t * mp)
4416 {
4417   vat_main_t *vam = &vat_main;
4418   vat_json_node_t node;
4419
4420   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4421   vat_json_init_object (&node);
4422   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4423
4424   vat_json_print (vam->ofp, &node);
4425   vat_json_free (&node);
4426
4427   vam->retval = ntohl (mp->retval);
4428   vam->result_ready = 1;
4429 }
4430
4431 static void
4432 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   i32 retval = ntohl (mp->retval);
4436
4437   if (0 <= retval)
4438     {
4439       print (vam->ofp, "%-20s%-16s",
4440              mp->status ? "enabled" : "disabled",
4441              mp->status ? (char *) mp->locator_set_name : "");
4442     }
4443
4444   vam->retval = retval;
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4450 {
4451   vat_main_t *vam = &vat_main;
4452   vat_json_node_t node;
4453   u8 *status = 0;
4454
4455   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4456   vec_add1 (status, 0);
4457
4458   vat_json_init_object (&node);
4459   vat_json_object_add_string_copy (&node, "status", status);
4460   if (mp->status)
4461     {
4462       vat_json_object_add_string_copy (&node, "locator_set",
4463                                        mp->locator_set_name);
4464     }
4465
4466   vec_free (status);
4467
4468   vat_json_print (vam->ofp, &node);
4469   vat_json_free (&node);
4470
4471   vam->retval = ntohl (mp->retval);
4472   vam->result_ready = 1;
4473 }
4474
4475 static u8 *
4476 format_policer_type (u8 * s, va_list * va)
4477 {
4478   u32 i = va_arg (*va, u32);
4479
4480   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4481     s = format (s, "1r2c");
4482   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4483     s = format (s, "1r3c");
4484   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4485     s = format (s, "2r3c-2698");
4486   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4487     s = format (s, "2r3c-4115");
4488   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4489     s = format (s, "2r3c-mef5cf1");
4490   else
4491     s = format (s, "ILLEGAL");
4492   return s;
4493 }
4494
4495 static u8 *
4496 format_policer_rate_type (u8 * s, va_list * va)
4497 {
4498   u32 i = va_arg (*va, u32);
4499
4500   if (i == SSE2_QOS_RATE_KBPS)
4501     s = format (s, "kbps");
4502   else if (i == SSE2_QOS_RATE_PPS)
4503     s = format (s, "pps");
4504   else
4505     s = format (s, "ILLEGAL");
4506   return s;
4507 }
4508
4509 static u8 *
4510 format_policer_round_type (u8 * s, va_list * va)
4511 {
4512   u32 i = va_arg (*va, u32);
4513
4514   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4515     s = format (s, "closest");
4516   else if (i == SSE2_QOS_ROUND_TO_UP)
4517     s = format (s, "up");
4518   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4519     s = format (s, "down");
4520   else
4521     s = format (s, "ILLEGAL");
4522   return s;
4523 }
4524
4525 static u8 *
4526 format_policer_action_type (u8 * s, va_list * va)
4527 {
4528   u32 i = va_arg (*va, u32);
4529
4530   if (i == SSE2_QOS_ACTION_DROP)
4531     s = format (s, "drop");
4532   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4533     s = format (s, "transmit");
4534   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4535     s = format (s, "mark-and-transmit");
4536   else
4537     s = format (s, "ILLEGAL");
4538   return s;
4539 }
4540
4541 static u8 *
4542 format_dscp (u8 * s, va_list * va)
4543 {
4544   u32 i = va_arg (*va, u32);
4545   char *t = 0;
4546
4547   switch (i)
4548     {
4549 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4550       foreach_vnet_dscp
4551 #undef _
4552     default:
4553       return format (s, "ILLEGAL");
4554     }
4555   s = format (s, "%s", t);
4556   return s;
4557 }
4558
4559 static void
4560 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4561 {
4562   vat_main_t *vam = &vat_main;
4563   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4564
4565   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4566     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4567   else
4568     conform_dscp_str = format (0, "");
4569
4570   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4571     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4572   else
4573     exceed_dscp_str = format (0, "");
4574
4575   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4576     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4577   else
4578     violate_dscp_str = format (0, "");
4579
4580   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4581          "rate type %U, round type %U, %s rate, %s color-aware, "
4582          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4583          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4584          "conform action %U%s, exceed action %U%s, violate action %U%s",
4585          mp->name,
4586          format_policer_type, mp->type,
4587          ntohl (mp->cir),
4588          ntohl (mp->eir),
4589          clib_net_to_host_u64 (mp->cb),
4590          clib_net_to_host_u64 (mp->eb),
4591          format_policer_rate_type, mp->rate_type,
4592          format_policer_round_type, mp->round_type,
4593          mp->single_rate ? "single" : "dual",
4594          mp->color_aware ? "is" : "not",
4595          ntohl (mp->cir_tokens_per_period),
4596          ntohl (mp->pir_tokens_per_period),
4597          ntohl (mp->scale),
4598          ntohl (mp->current_limit),
4599          ntohl (mp->current_bucket),
4600          ntohl (mp->extended_limit),
4601          ntohl (mp->extended_bucket),
4602          clib_net_to_host_u64 (mp->last_update_time),
4603          format_policer_action_type, mp->conform_action.type,
4604          conform_dscp_str,
4605          format_policer_action_type, mp->exceed_action.type,
4606          exceed_dscp_str,
4607          format_policer_action_type, mp->violate_action.type,
4608          violate_dscp_str);
4609
4610   vec_free (conform_dscp_str);
4611   vec_free (exceed_dscp_str);
4612   vec_free (violate_dscp_str);
4613 }
4614
4615 static void vl_api_policer_details_t_handler_json
4616   (vl_api_policer_details_t * mp)
4617 {
4618   vat_main_t *vam = &vat_main;
4619   vat_json_node_t *node;
4620   u8 *rate_type_str, *round_type_str, *type_str;
4621   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4622
4623   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4624   round_type_str =
4625     format (0, "%U", format_policer_round_type, mp->round_type);
4626   type_str = format (0, "%U", format_policer_type, mp->type);
4627   conform_action_str = format (0, "%U", format_policer_action_type,
4628                                mp->conform_action.type);
4629   exceed_action_str = format (0, "%U", format_policer_action_type,
4630                               mp->exceed_action.type);
4631   violate_action_str = format (0, "%U", format_policer_action_type,
4632                                mp->violate_action.type);
4633
4634   if (VAT_JSON_ARRAY != vam->json_tree.type)
4635     {
4636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4637       vat_json_init_array (&vam->json_tree);
4638     }
4639   node = vat_json_array_add (&vam->json_tree);
4640
4641   vat_json_init_object (node);
4642   vat_json_object_add_string_copy (node, "name", mp->name);
4643   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4644   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4645   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4646   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4647   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4648   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4649   vat_json_object_add_string_copy (node, "type", type_str);
4650   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4651   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4652   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4653   vat_json_object_add_uint (node, "cir_tokens_per_period",
4654                             ntohl (mp->cir_tokens_per_period));
4655   vat_json_object_add_uint (node, "eir_tokens_per_period",
4656                             ntohl (mp->pir_tokens_per_period));
4657   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4658   vat_json_object_add_uint (node, "current_bucket",
4659                             ntohl (mp->current_bucket));
4660   vat_json_object_add_uint (node, "extended_limit",
4661                             ntohl (mp->extended_limit));
4662   vat_json_object_add_uint (node, "extended_bucket",
4663                             ntohl (mp->extended_bucket));
4664   vat_json_object_add_uint (node, "last_update_time",
4665                             ntohl (mp->last_update_time));
4666   vat_json_object_add_string_copy (node, "conform_action",
4667                                    conform_action_str);
4668   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4669     {
4670       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4671       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4672       vec_free (dscp_str);
4673     }
4674   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4675   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4676     {
4677       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4678       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4679       vec_free (dscp_str);
4680     }
4681   vat_json_object_add_string_copy (node, "violate_action",
4682                                    violate_action_str);
4683   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4684     {
4685       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4686       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4687       vec_free (dscp_str);
4688     }
4689
4690   vec_free (rate_type_str);
4691   vec_free (round_type_str);
4692   vec_free (type_str);
4693   vec_free (conform_action_str);
4694   vec_free (exceed_action_str);
4695   vec_free (violate_action_str);
4696 }
4697
4698 static void
4699 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4700                                            mp)
4701 {
4702   vat_main_t *vam = &vat_main;
4703   int i, count = ntohl (mp->count);
4704
4705   if (count > 0)
4706     print (vam->ofp, "classify table ids (%d) : ", count);
4707   for (i = 0; i < count; i++)
4708     {
4709       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4710       print (vam->ofp, (i < count - 1) ? "," : "");
4711     }
4712   vam->retval = ntohl (mp->retval);
4713   vam->result_ready = 1;
4714 }
4715
4716 static void
4717   vl_api_classify_table_ids_reply_t_handler_json
4718   (vl_api_classify_table_ids_reply_t * mp)
4719 {
4720   vat_main_t *vam = &vat_main;
4721   int i, count = ntohl (mp->count);
4722
4723   if (count > 0)
4724     {
4725       vat_json_node_t node;
4726
4727       vat_json_init_object (&node);
4728       for (i = 0; i < count; i++)
4729         {
4730           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4731         }
4732       vat_json_print (vam->ofp, &node);
4733       vat_json_free (&node);
4734     }
4735   vam->retval = ntohl (mp->retval);
4736   vam->result_ready = 1;
4737 }
4738
4739 static void
4740   vl_api_classify_table_by_interface_reply_t_handler
4741   (vl_api_classify_table_by_interface_reply_t * mp)
4742 {
4743   vat_main_t *vam = &vat_main;
4744   u32 table_id;
4745
4746   table_id = ntohl (mp->l2_table_id);
4747   if (table_id != ~0)
4748     print (vam->ofp, "l2 table id : %d", table_id);
4749   else
4750     print (vam->ofp, "l2 table id : No input ACL tables configured");
4751   table_id = ntohl (mp->ip4_table_id);
4752   if (table_id != ~0)
4753     print (vam->ofp, "ip4 table id : %d", table_id);
4754   else
4755     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4756   table_id = ntohl (mp->ip6_table_id);
4757   if (table_id != ~0)
4758     print (vam->ofp, "ip6 table id : %d", table_id);
4759   else
4760     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4761   vam->retval = ntohl (mp->retval);
4762   vam->result_ready = 1;
4763 }
4764
4765 static void
4766   vl_api_classify_table_by_interface_reply_t_handler_json
4767   (vl_api_classify_table_by_interface_reply_t * mp)
4768 {
4769   vat_main_t *vam = &vat_main;
4770   vat_json_node_t node;
4771
4772   vat_json_init_object (&node);
4773
4774   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4775   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4776   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4777
4778   vat_json_print (vam->ofp, &node);
4779   vat_json_free (&node);
4780
4781   vam->retval = ntohl (mp->retval);
4782   vam->result_ready = 1;
4783 }
4784
4785 static void vl_api_policer_add_del_reply_t_handler
4786   (vl_api_policer_add_del_reply_t * mp)
4787 {
4788   vat_main_t *vam = &vat_main;
4789   i32 retval = ntohl (mp->retval);
4790   if (vam->async_mode)
4791     {
4792       vam->async_errors += (retval < 0);
4793     }
4794   else
4795     {
4796       vam->retval = retval;
4797       vam->result_ready = 1;
4798       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4799         /*
4800          * Note: this is just barely thread-safe, depends on
4801          * the main thread spinning waiting for an answer...
4802          */
4803         errmsg ("policer index %d", ntohl (mp->policer_index));
4804     }
4805 }
4806
4807 static void vl_api_policer_add_del_reply_t_handler_json
4808   (vl_api_policer_add_del_reply_t * mp)
4809 {
4810   vat_main_t *vam = &vat_main;
4811   vat_json_node_t node;
4812
4813   vat_json_init_object (&node);
4814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4815   vat_json_object_add_uint (&node, "policer_index",
4816                             ntohl (mp->policer_index));
4817
4818   vat_json_print (vam->ofp, &node);
4819   vat_json_free (&node);
4820
4821   vam->retval = ntohl (mp->retval);
4822   vam->result_ready = 1;
4823 }
4824
4825 /* Format hex dump. */
4826 u8 *
4827 format_hex_bytes (u8 * s, va_list * va)
4828 {
4829   u8 *bytes = va_arg (*va, u8 *);
4830   int n_bytes = va_arg (*va, int);
4831   uword i;
4832
4833   /* Print short or long form depending on byte count. */
4834   uword short_form = n_bytes <= 32;
4835   u32 indent = format_get_indent (s);
4836
4837   if (n_bytes == 0)
4838     return s;
4839
4840   for (i = 0; i < n_bytes; i++)
4841     {
4842       if (!short_form && (i % 32) == 0)
4843         s = format (s, "%08x: ", i);
4844       s = format (s, "%02x", bytes[i]);
4845       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4846         s = format (s, "\n%U", format_white_space, indent);
4847     }
4848
4849   return s;
4850 }
4851
4852 static void
4853 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4854                                             * mp)
4855 {
4856   vat_main_t *vam = &vat_main;
4857   i32 retval = ntohl (mp->retval);
4858   if (retval == 0)
4859     {
4860       print (vam->ofp, "classify table info :");
4861       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4862              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4863              ntohl (mp->miss_next_index));
4864       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4865              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4866              ntohl (mp->match_n_vectors));
4867       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4868              ntohl (mp->mask_length));
4869     }
4870   vam->retval = retval;
4871   vam->result_ready = 1;
4872 }
4873
4874 static void
4875   vl_api_classify_table_info_reply_t_handler_json
4876   (vl_api_classify_table_info_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   vat_json_node_t node;
4880
4881   i32 retval = ntohl (mp->retval);
4882   if (retval == 0)
4883     {
4884       vat_json_init_object (&node);
4885
4886       vat_json_object_add_int (&node, "sessions",
4887                                ntohl (mp->active_sessions));
4888       vat_json_object_add_int (&node, "nexttbl",
4889                                ntohl (mp->next_table_index));
4890       vat_json_object_add_int (&node, "nextnode",
4891                                ntohl (mp->miss_next_index));
4892       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4893       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4894       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4895       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4896                       ntohl (mp->mask_length), 0);
4897       vat_json_object_add_string_copy (&node, "mask", s);
4898
4899       vat_json_print (vam->ofp, &node);
4900       vat_json_free (&node);
4901     }
4902   vam->retval = ntohl (mp->retval);
4903   vam->result_ready = 1;
4904 }
4905
4906 static void
4907 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4908                                            mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911
4912   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4913          ntohl (mp->hit_next_index), ntohl (mp->advance),
4914          ntohl (mp->opaque_index));
4915   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4916          ntohl (mp->match_length));
4917 }
4918
4919 static void
4920   vl_api_classify_session_details_t_handler_json
4921   (vl_api_classify_session_details_t * mp)
4922 {
4923   vat_main_t *vam = &vat_main;
4924   vat_json_node_t *node = NULL;
4925
4926   if (VAT_JSON_ARRAY != vam->json_tree.type)
4927     {
4928       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4929       vat_json_init_array (&vam->json_tree);
4930     }
4931   node = vat_json_array_add (&vam->json_tree);
4932
4933   vat_json_init_object (node);
4934   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4935   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4936   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4937   u8 *s =
4938     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4939             0);
4940   vat_json_object_add_string_copy (node, "match", s);
4941 }
4942
4943 static void vl_api_pg_create_interface_reply_t_handler
4944   (vl_api_pg_create_interface_reply_t * mp)
4945 {
4946   vat_main_t *vam = &vat_main;
4947
4948   vam->retval = ntohl (mp->retval);
4949   vam->result_ready = 1;
4950 }
4951
4952 static void vl_api_pg_create_interface_reply_t_handler_json
4953   (vl_api_pg_create_interface_reply_t * mp)
4954 {
4955   vat_main_t *vam = &vat_main;
4956   vat_json_node_t node;
4957
4958   i32 retval = ntohl (mp->retval);
4959   if (retval == 0)
4960     {
4961       vat_json_init_object (&node);
4962
4963       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4964
4965       vat_json_print (vam->ofp, &node);
4966       vat_json_free (&node);
4967     }
4968   vam->retval = ntohl (mp->retval);
4969   vam->result_ready = 1;
4970 }
4971
4972 static void vl_api_policer_classify_details_t_handler
4973   (vl_api_policer_classify_details_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976
4977   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4978          ntohl (mp->table_index));
4979 }
4980
4981 static void vl_api_policer_classify_details_t_handler_json
4982   (vl_api_policer_classify_details_t * mp)
4983 {
4984   vat_main_t *vam = &vat_main;
4985   vat_json_node_t *node;
4986
4987   if (VAT_JSON_ARRAY != vam->json_tree.type)
4988     {
4989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4990       vat_json_init_array (&vam->json_tree);
4991     }
4992   node = vat_json_array_add (&vam->json_tree);
4993
4994   vat_json_init_object (node);
4995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4996   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4997 }
4998
4999 static void vl_api_flow_classify_details_t_handler
5000   (vl_api_flow_classify_details_t * mp)
5001 {
5002   vat_main_t *vam = &vat_main;
5003
5004   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5005          ntohl (mp->table_index));
5006 }
5007
5008 static void vl_api_flow_classify_details_t_handler_json
5009   (vl_api_flow_classify_details_t * mp)
5010 {
5011   vat_main_t *vam = &vat_main;
5012   vat_json_node_t *node;
5013
5014   if (VAT_JSON_ARRAY != vam->json_tree.type)
5015     {
5016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5017       vat_json_init_array (&vam->json_tree);
5018     }
5019   node = vat_json_array_add (&vam->json_tree);
5020
5021   vat_json_init_object (node);
5022   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5023   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5024 }
5025
5026 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5027 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5028 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5029 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5030 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5031 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5032 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5033 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5034 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5035 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5036
5037 /*
5038  * Generate boilerplate reply handlers, which
5039  * dig the return value out of the xxx_reply_t API message,
5040  * stick it into vam->retval, and set vam->result_ready
5041  *
5042  * Could also do this by pointing N message decode slots at
5043  * a single function, but that could break in subtle ways.
5044  */
5045
5046 #define foreach_standard_reply_retval_handler           \
5047 _(sw_interface_set_flags_reply)                         \
5048 _(sw_interface_add_del_address_reply)                   \
5049 _(sw_interface_set_rx_mode_reply)                       \
5050 _(sw_interface_set_rx_placement_reply)                  \
5051 _(sw_interface_set_table_reply)                         \
5052 _(sw_interface_set_mpls_enable_reply)                   \
5053 _(sw_interface_set_vpath_reply)                         \
5054 _(sw_interface_set_vxlan_bypass_reply)                  \
5055 _(sw_interface_set_geneve_bypass_reply)                 \
5056 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5057 _(sw_interface_set_l2_bridge_reply)                     \
5058 _(sw_interface_set_bond_weight_reply)                   \
5059 _(bridge_domain_add_del_reply)                          \
5060 _(sw_interface_set_l2_xconnect_reply)                   \
5061 _(l2fib_add_del_reply)                                  \
5062 _(l2fib_flush_int_reply)                                \
5063 _(l2fib_flush_bd_reply)                                 \
5064 _(ip_route_add_del_reply)                               \
5065 _(ip_table_add_del_reply)                               \
5066 _(ip_table_replace_begin_reply)                         \
5067 _(ip_table_flush_reply)                                 \
5068 _(ip_table_replace_end_reply)                           \
5069 _(ip_mroute_add_del_reply)                              \
5070 _(mpls_route_add_del_reply)                             \
5071 _(mpls_table_add_del_reply)                             \
5072 _(mpls_ip_bind_unbind_reply)                            \
5073 _(bier_route_add_del_reply)                             \
5074 _(bier_table_add_del_reply)                             \
5075 _(sw_interface_set_unnumbered_reply)                    \
5076 _(set_ip_flow_hash_reply)                               \
5077 _(sw_interface_ip6_enable_disable_reply)                \
5078 _(l2_patch_add_del_reply)                               \
5079 _(sr_mpls_policy_add_reply)                             \
5080 _(sr_mpls_policy_mod_reply)                             \
5081 _(sr_mpls_policy_del_reply)                             \
5082 _(sr_policy_add_reply)                                  \
5083 _(sr_policy_mod_reply)                                  \
5084 _(sr_policy_del_reply)                                  \
5085 _(sr_localsid_add_del_reply)                            \
5086 _(sr_steering_add_del_reply)                            \
5087 _(classify_add_del_session_reply)                       \
5088 _(classify_set_interface_ip_table_reply)                \
5089 _(classify_set_interface_l2_tables_reply)               \
5090 _(l2tpv3_set_tunnel_cookies_reply)                      \
5091 _(l2tpv3_interface_enable_disable_reply)                \
5092 _(l2tpv3_set_lookup_key_reply)                          \
5093 _(l2_fib_clear_table_reply)                             \
5094 _(l2_interface_efp_filter_reply)                        \
5095 _(l2_interface_vlan_tag_rewrite_reply)                  \
5096 _(modify_vhost_user_if_reply)                           \
5097 _(delete_vhost_user_if_reply)                           \
5098 _(want_l2_macs_events_reply)                            \
5099 _(input_acl_set_interface_reply)                        \
5100 _(ipsec_spd_add_del_reply)                              \
5101 _(ipsec_interface_add_del_spd_reply)                    \
5102 _(ipsec_spd_entry_add_del_reply)                        \
5103 _(ipsec_sad_entry_add_del_reply)                        \
5104 _(ipsec_tunnel_if_add_del_reply)                        \
5105 _(ipsec_tunnel_if_set_sa_reply)                         \
5106 _(delete_loopback_reply)                                \
5107 _(bd_ip_mac_add_del_reply)                              \
5108 _(bd_ip_mac_flush_reply)                                \
5109 _(want_interface_events_reply)                          \
5110 _(cop_interface_enable_disable_reply)                   \
5111 _(cop_whitelist_enable_disable_reply)                   \
5112 _(sw_interface_clear_stats_reply)                       \
5113 _(ioam_enable_reply)                                    \
5114 _(ioam_disable_reply)                                   \
5115 _(one_add_del_locator_reply)                            \
5116 _(one_add_del_local_eid_reply)                          \
5117 _(one_add_del_remote_mapping_reply)                     \
5118 _(one_add_del_adjacency_reply)                          \
5119 _(one_add_del_map_resolver_reply)                       \
5120 _(one_add_del_map_server_reply)                         \
5121 _(one_enable_disable_reply)                             \
5122 _(one_rloc_probe_enable_disable_reply)                  \
5123 _(one_map_register_enable_disable_reply)                \
5124 _(one_map_register_set_ttl_reply)                       \
5125 _(one_set_transport_protocol_reply)                     \
5126 _(one_map_register_fallback_threshold_reply)            \
5127 _(one_pitr_set_locator_set_reply)                       \
5128 _(one_map_request_mode_reply)                           \
5129 _(one_add_del_map_request_itr_rlocs_reply)              \
5130 _(one_eid_table_add_del_map_reply)                      \
5131 _(one_use_petr_reply)                                   \
5132 _(one_stats_enable_disable_reply)                       \
5133 _(one_add_del_l2_arp_entry_reply)                       \
5134 _(one_add_del_ndp_entry_reply)                          \
5135 _(one_stats_flush_reply)                                \
5136 _(one_enable_disable_xtr_mode_reply)                    \
5137 _(one_enable_disable_pitr_mode_reply)                   \
5138 _(one_enable_disable_petr_mode_reply)                   \
5139 _(gpe_enable_disable_reply)                             \
5140 _(gpe_set_encap_mode_reply)                             \
5141 _(gpe_add_del_iface_reply)                              \
5142 _(gpe_add_del_native_fwd_rpath_reply)                   \
5143 _(af_packet_delete_reply)                               \
5144 _(policer_classify_set_interface_reply)                 \
5145 _(set_ipfix_exporter_reply)                             \
5146 _(set_ipfix_classify_stream_reply)                      \
5147 _(ipfix_classify_table_add_del_reply)                   \
5148 _(flow_classify_set_interface_reply)                    \
5149 _(sw_interface_span_enable_disable_reply)               \
5150 _(pg_capture_reply)                                     \
5151 _(pg_enable_disable_reply)                              \
5152 _(ip_source_and_port_range_check_add_del_reply)         \
5153 _(ip_source_and_port_range_check_interface_add_del_reply)\
5154 _(delete_subif_reply)                                   \
5155 _(l2_interface_pbb_tag_rewrite_reply)                   \
5156 _(set_punt_reply)                                       \
5157 _(feature_enable_disable_reply)                         \
5158 _(feature_gso_enable_disable_reply)                     \
5159 _(sw_interface_tag_add_del_reply)                       \
5160 _(sw_interface_add_del_mac_address_reply)               \
5161 _(hw_interface_set_mtu_reply)                           \
5162 _(p2p_ethernet_add_reply)                               \
5163 _(p2p_ethernet_del_reply)                               \
5164 _(lldp_config_reply)                                    \
5165 _(sw_interface_set_lldp_reply)                          \
5166 _(tcp_configure_src_addresses_reply)                    \
5167 _(session_rule_add_del_reply)                           \
5168 _(ip_container_proxy_add_del_reply)                     \
5169 _(output_acl_set_interface_reply)                       \
5170 _(qos_record_enable_disable_reply)
5171
5172 #define _(n)                                    \
5173     static void vl_api_##n##_t_handler          \
5174     (vl_api_##n##_t * mp)                       \
5175     {                                           \
5176         vat_main_t * vam = &vat_main;           \
5177         i32 retval = ntohl(mp->retval);         \
5178         if (vam->async_mode) {                  \
5179             vam->async_errors += (retval < 0);  \
5180         } else {                                \
5181             vam->retval = retval;               \
5182             vam->result_ready = 1;              \
5183         }                                       \
5184     }
5185 foreach_standard_reply_retval_handler;
5186 #undef _
5187
5188 #define _(n)                                    \
5189     static void vl_api_##n##_t_handler_json     \
5190     (vl_api_##n##_t * mp)                       \
5191     {                                           \
5192         vat_main_t * vam = &vat_main;           \
5193         vat_json_node_t node;                   \
5194         vat_json_init_object(&node);            \
5195         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5196         vat_json_print(vam->ofp, &node);        \
5197         vam->retval = ntohl(mp->retval);        \
5198         vam->result_ready = 1;                  \
5199     }
5200 foreach_standard_reply_retval_handler;
5201 #undef _
5202
5203 /*
5204  * Table of message reply handlers, must include boilerplate handlers
5205  * we just generated
5206  */
5207
5208 #define foreach_vpe_api_reply_msg                                       \
5209 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5210 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5211 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5212 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5213 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5214 _(CLI_REPLY, cli_reply)                                                 \
5215 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5216 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5217   sw_interface_add_del_address_reply)                                   \
5218 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5219 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5220 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5221 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5222 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5223 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5224 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5225 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5226 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5227 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5228   sw_interface_set_l2_xconnect_reply)                                   \
5229 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5230   sw_interface_set_l2_bridge_reply)                                     \
5231 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5232 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5233 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5234 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5235 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5236 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5237 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5238 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5239 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5240 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5241 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5242 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5243 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5244 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5245 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5246 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5247 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
5248 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
5249 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5250 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
5251 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
5252 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5253 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5254 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5255 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5256 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5257 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5258 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5259 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5260 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5261 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5262 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5263 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5264 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5265   sw_interface_set_unnumbered_reply)                                    \
5266 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5267 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5268 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5269 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5270   sw_interface_ip6_enable_disable_reply)                                \
5271 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5272 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5273 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5274 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5275 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5276 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5277 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5278 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5279 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5280 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5281 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5282 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5283 classify_set_interface_ip_table_reply)                                  \
5284 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5285   classify_set_interface_l2_tables_reply)                               \
5286 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5287 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5288 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5289 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5290 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5291   l2tpv3_interface_enable_disable_reply)                                \
5292 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5293 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5294 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5295 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5296 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5297 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5298 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5299 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5300 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5301 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5302 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5303 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5304 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5305 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5306 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5307 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5308 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5309 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5310 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5311 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5312 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5313 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5314 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5315 _(L2_MACS_EVENT, l2_macs_event)                                         \
5316 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5317 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5318 _(IP_DETAILS, ip_details)                                               \
5319 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5320 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5321 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5322 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5323 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5324 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5325 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5326 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5327 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5328 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5329 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5330 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5331 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5332 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5333 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5334 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5335 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5336 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5337 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5338 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5339 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5340 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5341 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5342 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5343 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5344 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5345 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5346 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5347   one_map_register_enable_disable_reply)                                \
5348 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5349 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5350 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5351 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5352   one_map_register_fallback_threshold_reply)                            \
5353 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5354   one_rloc_probe_enable_disable_reply)                                  \
5355 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5356 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5357 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5358 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5359 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5360 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5361 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5362 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5363 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5364 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5365 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5366 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5367 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5368 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5369 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5370 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5371   show_one_stats_enable_disable_reply)                                  \
5372 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5373 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5374 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5375 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5376 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5377 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5378 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5379 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5380   one_enable_disable_pitr_mode_reply)                                   \
5381 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5382   one_enable_disable_petr_mode_reply)                                   \
5383 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5384 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5385 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5386 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5387 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5388 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5389 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5390 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5391 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5392 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5393 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5394 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5395   gpe_add_del_native_fwd_rpath_reply)                                   \
5396 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5397   gpe_fwd_entry_path_details)                                           \
5398 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5399 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5400   one_add_del_map_request_itr_rlocs_reply)                              \
5401 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5402   one_get_map_request_itr_rlocs_reply)                                  \
5403 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5404 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5405 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5406 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5407 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5408 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5409   show_one_map_register_state_reply)                                    \
5410 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5411 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5412   show_one_map_register_fallback_threshold_reply)                       \
5413 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5414 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5415 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5416 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5417 _(POLICER_DETAILS, policer_details)                                     \
5418 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5419 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5420 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5421 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5422 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5423 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5424 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5425 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5426 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5427 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5428 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5429 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5430 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5431 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5432 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5433 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5434 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5435 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5436 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5437 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5438 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5439 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5440 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5441 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5442  ip_source_and_port_range_check_add_del_reply)                          \
5443 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5444  ip_source_and_port_range_check_interface_add_del_reply)                \
5445 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5446 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5447 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5448 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5449 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5450 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5451 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5452 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5453 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5454 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5455 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5456 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5457 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5458 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5459 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5460 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5461 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5462 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5463 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5464 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5465 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5466 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5467 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5468
5469 #define foreach_standalone_reply_msg                                    \
5470 _(SW_INTERFACE_EVENT, sw_interface_event)
5471
5472 typedef struct
5473 {
5474   u8 *name;
5475   u32 value;
5476 } name_sort_t;
5477
5478 #define STR_VTR_OP_CASE(op)     \
5479     case L2_VTR_ ## op:         \
5480         return "" # op;
5481
5482 static const char *
5483 str_vtr_op (u32 vtr_op)
5484 {
5485   switch (vtr_op)
5486     {
5487       STR_VTR_OP_CASE (DISABLED);
5488       STR_VTR_OP_CASE (PUSH_1);
5489       STR_VTR_OP_CASE (PUSH_2);
5490       STR_VTR_OP_CASE (POP_1);
5491       STR_VTR_OP_CASE (POP_2);
5492       STR_VTR_OP_CASE (TRANSLATE_1_1);
5493       STR_VTR_OP_CASE (TRANSLATE_1_2);
5494       STR_VTR_OP_CASE (TRANSLATE_2_1);
5495       STR_VTR_OP_CASE (TRANSLATE_2_2);
5496     }
5497
5498   return "UNKNOWN";
5499 }
5500
5501 static int
5502 dump_sub_interface_table (vat_main_t * vam)
5503 {
5504   const sw_interface_subif_t *sub = NULL;
5505
5506   if (vam->json_output)
5507     {
5508       clib_warning
5509         ("JSON output supported only for VPE API calls and dump_stats_table");
5510       return -99;
5511     }
5512
5513   print (vam->ofp,
5514          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5515          "Interface", "sw_if_index",
5516          "sub id", "dot1ad", "tags", "outer id",
5517          "inner id", "exact", "default", "outer any", "inner any");
5518
5519   vec_foreach (sub, vam->sw_if_subif_table)
5520   {
5521     print (vam->ofp,
5522            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5523            sub->interface_name,
5524            sub->sw_if_index,
5525            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5526            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5527            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5528            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5529     if (sub->vtr_op != L2_VTR_DISABLED)
5530       {
5531         print (vam->ofp,
5532                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5533                "tag1: %d tag2: %d ]",
5534                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5535                sub->vtr_tag1, sub->vtr_tag2);
5536       }
5537   }
5538
5539   return 0;
5540 }
5541
5542 static int
5543 name_sort_cmp (void *a1, void *a2)
5544 {
5545   name_sort_t *n1 = a1;
5546   name_sort_t *n2 = a2;
5547
5548   return strcmp ((char *) n1->name, (char *) n2->name);
5549 }
5550
5551 static int
5552 dump_interface_table (vat_main_t * vam)
5553 {
5554   hash_pair_t *p;
5555   name_sort_t *nses = 0, *ns;
5556
5557   if (vam->json_output)
5558     {
5559       clib_warning
5560         ("JSON output supported only for VPE API calls and dump_stats_table");
5561       return -99;
5562     }
5563
5564   /* *INDENT-OFF* */
5565   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5566   ({
5567     vec_add2 (nses, ns, 1);
5568     ns->name = (u8 *)(p->key);
5569     ns->value = (u32) p->value[0];
5570   }));
5571   /* *INDENT-ON* */
5572
5573   vec_sort_with_function (nses, name_sort_cmp);
5574
5575   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5576   vec_foreach (ns, nses)
5577   {
5578     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5579   }
5580   vec_free (nses);
5581   return 0;
5582 }
5583
5584 static int
5585 dump_ip_table (vat_main_t * vam, int is_ipv6)
5586 {
5587   const ip_details_t *det = NULL;
5588   const ip_address_details_t *address = NULL;
5589   u32 i = ~0;
5590
5591   print (vam->ofp, "%-12s", "sw_if_index");
5592
5593   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5594   {
5595     i++;
5596     if (!det->present)
5597       {
5598         continue;
5599       }
5600     print (vam->ofp, "%-12d", i);
5601     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5602     if (!det->addr)
5603       {
5604         continue;
5605       }
5606     vec_foreach (address, det->addr)
5607     {
5608       print (vam->ofp,
5609              "            %-30U%-13d",
5610              is_ipv6 ? format_ip6_address : format_ip4_address,
5611              address->ip, address->prefix_length);
5612     }
5613   }
5614
5615   return 0;
5616 }
5617
5618 static int
5619 dump_ipv4_table (vat_main_t * vam)
5620 {
5621   if (vam->json_output)
5622     {
5623       clib_warning
5624         ("JSON output supported only for VPE API calls and dump_stats_table");
5625       return -99;
5626     }
5627
5628   return dump_ip_table (vam, 0);
5629 }
5630
5631 static int
5632 dump_ipv6_table (vat_main_t * vam)
5633 {
5634   if (vam->json_output)
5635     {
5636       clib_warning
5637         ("JSON output supported only for VPE API calls and dump_stats_table");
5638       return -99;
5639     }
5640
5641   return dump_ip_table (vam, 1);
5642 }
5643
5644 /*
5645  * Pass CLI buffers directly in the CLI_INBAND API message,
5646  * instead of an additional shared memory area.
5647  */
5648 static int
5649 exec_inband (vat_main_t * vam)
5650 {
5651   vl_api_cli_inband_t *mp;
5652   unformat_input_t *i = vam->input;
5653   int ret;
5654
5655   if (vec_len (i->buffer) == 0)
5656     return -1;
5657
5658   if (vam->exec_mode == 0 && unformat (i, "mode"))
5659     {
5660       vam->exec_mode = 1;
5661       return 0;
5662     }
5663   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5664     {
5665       vam->exec_mode = 0;
5666       return 0;
5667     }
5668
5669   /*
5670    * In order for the CLI command to work, it
5671    * must be a vector ending in \n, not a C-string ending
5672    * in \n\0.
5673    */
5674   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5675   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5676
5677   S (mp);
5678   W (ret);
5679   /* json responses may or may not include a useful reply... */
5680   if (vec_len (vam->cmd_reply))
5681     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5682   return ret;
5683 }
5684
5685 int
5686 exec (vat_main_t * vam)
5687 {
5688   return exec_inband (vam);
5689 }
5690
5691 static int
5692 api_create_loopback (vat_main_t * vam)
5693 {
5694   unformat_input_t *i = vam->input;
5695   vl_api_create_loopback_t *mp;
5696   vl_api_create_loopback_instance_t *mp_lbi;
5697   u8 mac_address[6];
5698   u8 mac_set = 0;
5699   u8 is_specified = 0;
5700   u32 user_instance = 0;
5701   int ret;
5702
5703   clib_memset (mac_address, 0, sizeof (mac_address));
5704
5705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5706     {
5707       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5708         mac_set = 1;
5709       if (unformat (i, "instance %d", &user_instance))
5710         is_specified = 1;
5711       else
5712         break;
5713     }
5714
5715   if (is_specified)
5716     {
5717       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5718       mp_lbi->is_specified = is_specified;
5719       if (is_specified)
5720         mp_lbi->user_instance = htonl (user_instance);
5721       if (mac_set)
5722         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5723       S (mp_lbi);
5724     }
5725   else
5726     {
5727       /* Construct the API message */
5728       M (CREATE_LOOPBACK, mp);
5729       if (mac_set)
5730         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5731       S (mp);
5732     }
5733
5734   W (ret);
5735   return ret;
5736 }
5737
5738 static int
5739 api_delete_loopback (vat_main_t * vam)
5740 {
5741   unformat_input_t *i = vam->input;
5742   vl_api_delete_loopback_t *mp;
5743   u32 sw_if_index = ~0;
5744   int ret;
5745
5746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5747     {
5748       if (unformat (i, "sw_if_index %d", &sw_if_index))
5749         ;
5750       else
5751         break;
5752     }
5753
5754   if (sw_if_index == ~0)
5755     {
5756       errmsg ("missing sw_if_index");
5757       return -99;
5758     }
5759
5760   /* Construct the API message */
5761   M (DELETE_LOOPBACK, mp);
5762   mp->sw_if_index = ntohl (sw_if_index);
5763
5764   S (mp);
5765   W (ret);
5766   return ret;
5767 }
5768
5769 static int
5770 api_want_interface_events (vat_main_t * vam)
5771 {
5772   unformat_input_t *i = vam->input;
5773   vl_api_want_interface_events_t *mp;
5774   int enable = -1;
5775   int ret;
5776
5777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5778     {
5779       if (unformat (i, "enable"))
5780         enable = 1;
5781       else if (unformat (i, "disable"))
5782         enable = 0;
5783       else
5784         break;
5785     }
5786
5787   if (enable == -1)
5788     {
5789       errmsg ("missing enable|disable");
5790       return -99;
5791     }
5792
5793   M (WANT_INTERFACE_EVENTS, mp);
5794   mp->enable_disable = enable;
5795
5796   vam->interface_event_display = enable;
5797
5798   S (mp);
5799   W (ret);
5800   return ret;
5801 }
5802
5803
5804 /* Note: non-static, called once to set up the initial intfc table */
5805 int
5806 api_sw_interface_dump (vat_main_t * vam)
5807 {
5808   vl_api_sw_interface_dump_t *mp;
5809   vl_api_control_ping_t *mp_ping;
5810   hash_pair_t *p;
5811   name_sort_t *nses = 0, *ns;
5812   sw_interface_subif_t *sub = NULL;
5813   int ret;
5814
5815   /* Toss the old name table */
5816   /* *INDENT-OFF* */
5817   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5818   ({
5819     vec_add2 (nses, ns, 1);
5820     ns->name = (u8 *)(p->key);
5821     ns->value = (u32) p->value[0];
5822   }));
5823   /* *INDENT-ON* */
5824
5825   hash_free (vam->sw_if_index_by_interface_name);
5826
5827   vec_foreach (ns, nses) vec_free (ns->name);
5828
5829   vec_free (nses);
5830
5831   vec_foreach (sub, vam->sw_if_subif_table)
5832   {
5833     vec_free (sub->interface_name);
5834   }
5835   vec_free (vam->sw_if_subif_table);
5836
5837   /* recreate the interface name hash table */
5838   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5839
5840   /*
5841    * Ask for all interface names. Otherwise, the epic catalog of
5842    * name filters becomes ridiculously long, and vat ends up needing
5843    * to be taught about new interface types.
5844    */
5845   M (SW_INTERFACE_DUMP, mp);
5846   S (mp);
5847
5848   /* Use a control ping for synchronization */
5849   MPING (CONTROL_PING, mp_ping);
5850   S (mp_ping);
5851
5852   W (ret);
5853   return ret;
5854 }
5855
5856 static int
5857 api_sw_interface_set_flags (vat_main_t * vam)
5858 {
5859   unformat_input_t *i = vam->input;
5860   vl_api_sw_interface_set_flags_t *mp;
5861   u32 sw_if_index;
5862   u8 sw_if_index_set = 0;
5863   u8 admin_up = 0;
5864   int ret;
5865
5866   /* Parse args required to build the message */
5867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5868     {
5869       if (unformat (i, "admin-up"))
5870         admin_up = 1;
5871       else if (unformat (i, "admin-down"))
5872         admin_up = 0;
5873       else
5874         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5875         sw_if_index_set = 1;
5876       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5877         sw_if_index_set = 1;
5878       else
5879         break;
5880     }
5881
5882   if (sw_if_index_set == 0)
5883     {
5884       errmsg ("missing interface name or sw_if_index");
5885       return -99;
5886     }
5887
5888   /* Construct the API message */
5889   M (SW_INTERFACE_SET_FLAGS, mp);
5890   mp->sw_if_index = ntohl (sw_if_index);
5891   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5892
5893   /* send it... */
5894   S (mp);
5895
5896   /* Wait for a reply, return the good/bad news... */
5897   W (ret);
5898   return ret;
5899 }
5900
5901 static int
5902 api_sw_interface_set_rx_mode (vat_main_t * vam)
5903 {
5904   unformat_input_t *i = vam->input;
5905   vl_api_sw_interface_set_rx_mode_t *mp;
5906   u32 sw_if_index;
5907   u8 sw_if_index_set = 0;
5908   int ret;
5909   u8 queue_id_valid = 0;
5910   u32 queue_id;
5911   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5912
5913   /* Parse args required to build the message */
5914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5915     {
5916       if (unformat (i, "queue %d", &queue_id))
5917         queue_id_valid = 1;
5918       else if (unformat (i, "polling"))
5919         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5920       else if (unformat (i, "interrupt"))
5921         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5922       else if (unformat (i, "adaptive"))
5923         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5924       else
5925         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5926         sw_if_index_set = 1;
5927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5928         sw_if_index_set = 1;
5929       else
5930         break;
5931     }
5932
5933   if (sw_if_index_set == 0)
5934     {
5935       errmsg ("missing interface name or sw_if_index");
5936       return -99;
5937     }
5938   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5939     {
5940       errmsg ("missing rx-mode");
5941       return -99;
5942     }
5943
5944   /* Construct the API message */
5945   M (SW_INTERFACE_SET_RX_MODE, mp);
5946   mp->sw_if_index = ntohl (sw_if_index);
5947   mp->mode = (vl_api_rx_mode_t) mode;
5948   mp->queue_id_valid = queue_id_valid;
5949   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5950
5951   /* send it... */
5952   S (mp);
5953
5954   /* Wait for a reply, return the good/bad news... */
5955   W (ret);
5956   return ret;
5957 }
5958
5959 static int
5960 api_sw_interface_set_rx_placement (vat_main_t * vam)
5961 {
5962   unformat_input_t *i = vam->input;
5963   vl_api_sw_interface_set_rx_placement_t *mp;
5964   u32 sw_if_index;
5965   u8 sw_if_index_set = 0;
5966   int ret;
5967   u8 is_main = 0;
5968   u32 queue_id, thread_index;
5969
5970   /* Parse args required to build the message */
5971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5972     {
5973       if (unformat (i, "queue %d", &queue_id))
5974         ;
5975       else if (unformat (i, "main"))
5976         is_main = 1;
5977       else if (unformat (i, "worker %d", &thread_index))
5978         ;
5979       else
5980         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5981         sw_if_index_set = 1;
5982       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5983         sw_if_index_set = 1;
5984       else
5985         break;
5986     }
5987
5988   if (sw_if_index_set == 0)
5989     {
5990       errmsg ("missing interface name or sw_if_index");
5991       return -99;
5992     }
5993
5994   if (is_main)
5995     thread_index = 0;
5996   /* Construct the API message */
5997   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5998   mp->sw_if_index = ntohl (sw_if_index);
5999   mp->worker_id = ntohl (thread_index);
6000   mp->queue_id = ntohl (queue_id);
6001   mp->is_main = is_main;
6002
6003   /* send it... */
6004   S (mp);
6005   /* Wait for a reply, return the good/bad news... */
6006   W (ret);
6007   return ret;
6008 }
6009
6010 static void vl_api_sw_interface_rx_placement_details_t_handler
6011   (vl_api_sw_interface_rx_placement_details_t * mp)
6012 {
6013   vat_main_t *vam = &vat_main;
6014   u32 worker_id = ntohl (mp->worker_id);
6015
6016   print (vam->ofp,
6017          "\n%-11d %-11s %-6d %-5d %-9s",
6018          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6019          worker_id, ntohl (mp->queue_id),
6020          (mp->mode ==
6021           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6022 }
6023
6024 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6025   (vl_api_sw_interface_rx_placement_details_t * mp)
6026 {
6027   vat_main_t *vam = &vat_main;
6028   vat_json_node_t *node = NULL;
6029
6030   if (VAT_JSON_ARRAY != vam->json_tree.type)
6031     {
6032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6033       vat_json_init_array (&vam->json_tree);
6034     }
6035   node = vat_json_array_add (&vam->json_tree);
6036
6037   vat_json_init_object (node);
6038   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6039   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6040   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6041   vat_json_object_add_uint (node, "mode", mp->mode);
6042 }
6043
6044 static int
6045 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6046 {
6047   unformat_input_t *i = vam->input;
6048   vl_api_sw_interface_rx_placement_dump_t *mp;
6049   vl_api_control_ping_t *mp_ping;
6050   int ret;
6051   u32 sw_if_index;
6052   u8 sw_if_index_set = 0;
6053
6054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6055     {
6056       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6057         sw_if_index_set++;
6058       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6059         sw_if_index_set++;
6060       else
6061         break;
6062     }
6063
6064   print (vam->ofp,
6065          "\n%-11s %-11s %-6s %-5s %-4s",
6066          "sw_if_index", "main/worker", "thread", "queue", "mode");
6067
6068   /* Dump Interface rx placement */
6069   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6070
6071   if (sw_if_index_set)
6072     mp->sw_if_index = htonl (sw_if_index);
6073   else
6074     mp->sw_if_index = ~0;
6075
6076   S (mp);
6077
6078   /* Use a control ping for synchronization */
6079   MPING (CONTROL_PING, mp_ping);
6080   S (mp_ping);
6081
6082   W (ret);
6083   return ret;
6084 }
6085
6086 static int
6087 api_sw_interface_clear_stats (vat_main_t * vam)
6088 {
6089   unformat_input_t *i = vam->input;
6090   vl_api_sw_interface_clear_stats_t *mp;
6091   u32 sw_if_index;
6092   u8 sw_if_index_set = 0;
6093   int ret;
6094
6095   /* Parse args required to build the message */
6096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6097     {
6098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6099         sw_if_index_set = 1;
6100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6101         sw_if_index_set = 1;
6102       else
6103         break;
6104     }
6105
6106   /* Construct the API message */
6107   M (SW_INTERFACE_CLEAR_STATS, mp);
6108
6109   if (sw_if_index_set == 1)
6110     mp->sw_if_index = ntohl (sw_if_index);
6111   else
6112     mp->sw_if_index = ~0;
6113
6114   /* send it... */
6115   S (mp);
6116
6117   /* Wait for a reply, return the good/bad news... */
6118   W (ret);
6119   return ret;
6120 }
6121
6122 static int
6123 api_sw_interface_add_del_address (vat_main_t * vam)
6124 {
6125   unformat_input_t *i = vam->input;
6126   vl_api_sw_interface_add_del_address_t *mp;
6127   u32 sw_if_index;
6128   u8 sw_if_index_set = 0;
6129   u8 is_add = 1, del_all = 0;
6130   u32 address_length = 0;
6131   u8 v4_address_set = 0;
6132   u8 v6_address_set = 0;
6133   ip4_address_t v4address;
6134   ip6_address_t v6address;
6135   int ret;
6136
6137   /* Parse args required to build the message */
6138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6139     {
6140       if (unformat (i, "del-all"))
6141         del_all = 1;
6142       else if (unformat (i, "del"))
6143         is_add = 0;
6144       else
6145         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6146         sw_if_index_set = 1;
6147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6148         sw_if_index_set = 1;
6149       else if (unformat (i, "%U/%d",
6150                          unformat_ip4_address, &v4address, &address_length))
6151         v4_address_set = 1;
6152       else if (unformat (i, "%U/%d",
6153                          unformat_ip6_address, &v6address, &address_length))
6154         v6_address_set = 1;
6155       else
6156         break;
6157     }
6158
6159   if (sw_if_index_set == 0)
6160     {
6161       errmsg ("missing interface name or sw_if_index");
6162       return -99;
6163     }
6164   if (v4_address_set && v6_address_set)
6165     {
6166       errmsg ("both v4 and v6 addresses set");
6167       return -99;
6168     }
6169   if (!v4_address_set && !v6_address_set && !del_all)
6170     {
6171       errmsg ("no addresses set");
6172       return -99;
6173     }
6174
6175   /* Construct the API message */
6176   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6177
6178   mp->sw_if_index = ntohl (sw_if_index);
6179   mp->is_add = is_add;
6180   mp->del_all = del_all;
6181   if (v6_address_set)
6182     {
6183       mp->prefix.address.af = ADDRESS_IP6;
6184       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6185     }
6186   else
6187     {
6188       mp->prefix.address.af = ADDRESS_IP4;
6189       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6190     }
6191   mp->prefix.len = address_length;
6192
6193   /* send it... */
6194   S (mp);
6195
6196   /* Wait for a reply, return good/bad news  */
6197   W (ret);
6198   return ret;
6199 }
6200
6201 static int
6202 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6203 {
6204   unformat_input_t *i = vam->input;
6205   vl_api_sw_interface_set_mpls_enable_t *mp;
6206   u32 sw_if_index;
6207   u8 sw_if_index_set = 0;
6208   u8 enable = 1;
6209   int ret;
6210
6211   /* Parse args required to build the message */
6212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6213     {
6214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6215         sw_if_index_set = 1;
6216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6217         sw_if_index_set = 1;
6218       else if (unformat (i, "disable"))
6219         enable = 0;
6220       else if (unformat (i, "dis"))
6221         enable = 0;
6222       else
6223         break;
6224     }
6225
6226   if (sw_if_index_set == 0)
6227     {
6228       errmsg ("missing interface name or sw_if_index");
6229       return -99;
6230     }
6231
6232   /* Construct the API message */
6233   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6234
6235   mp->sw_if_index = ntohl (sw_if_index);
6236   mp->enable = enable;
6237
6238   /* send it... */
6239   S (mp);
6240
6241   /* Wait for a reply... */
6242   W (ret);
6243   return ret;
6244 }
6245
6246 static int
6247 api_sw_interface_set_table (vat_main_t * vam)
6248 {
6249   unformat_input_t *i = vam->input;
6250   vl_api_sw_interface_set_table_t *mp;
6251   u32 sw_if_index, vrf_id = 0;
6252   u8 sw_if_index_set = 0;
6253   u8 is_ipv6 = 0;
6254   int ret;
6255
6256   /* Parse args required to build the message */
6257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6258     {
6259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6260         sw_if_index_set = 1;
6261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "vrf %d", &vrf_id))
6264         ;
6265       else if (unformat (i, "ipv6"))
6266         is_ipv6 = 1;
6267       else
6268         break;
6269     }
6270
6271   if (sw_if_index_set == 0)
6272     {
6273       errmsg ("missing interface name or sw_if_index");
6274       return -99;
6275     }
6276
6277   /* Construct the API message */
6278   M (SW_INTERFACE_SET_TABLE, mp);
6279
6280   mp->sw_if_index = ntohl (sw_if_index);
6281   mp->is_ipv6 = is_ipv6;
6282   mp->vrf_id = ntohl (vrf_id);
6283
6284   /* send it... */
6285   S (mp);
6286
6287   /* Wait for a reply... */
6288   W (ret);
6289   return ret;
6290 }
6291
6292 static void vl_api_sw_interface_get_table_reply_t_handler
6293   (vl_api_sw_interface_get_table_reply_t * mp)
6294 {
6295   vat_main_t *vam = &vat_main;
6296
6297   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6298
6299   vam->retval = ntohl (mp->retval);
6300   vam->result_ready = 1;
6301
6302 }
6303
6304 static void vl_api_sw_interface_get_table_reply_t_handler_json
6305   (vl_api_sw_interface_get_table_reply_t * mp)
6306 {
6307   vat_main_t *vam = &vat_main;
6308   vat_json_node_t node;
6309
6310   vat_json_init_object (&node);
6311   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6312   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6313
6314   vat_json_print (vam->ofp, &node);
6315   vat_json_free (&node);
6316
6317   vam->retval = ntohl (mp->retval);
6318   vam->result_ready = 1;
6319 }
6320
6321 static int
6322 api_sw_interface_get_table (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   vl_api_sw_interface_get_table_t *mp;
6326   u32 sw_if_index;
6327   u8 sw_if_index_set = 0;
6328   u8 is_ipv6 = 0;
6329   int ret;
6330
6331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332     {
6333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6334         sw_if_index_set = 1;
6335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6336         sw_if_index_set = 1;
6337       else if (unformat (i, "ipv6"))
6338         is_ipv6 = 1;
6339       else
6340         break;
6341     }
6342
6343   if (sw_if_index_set == 0)
6344     {
6345       errmsg ("missing interface name or sw_if_index");
6346       return -99;
6347     }
6348
6349   M (SW_INTERFACE_GET_TABLE, mp);
6350   mp->sw_if_index = htonl (sw_if_index);
6351   mp->is_ipv6 = is_ipv6;
6352
6353   S (mp);
6354   W (ret);
6355   return ret;
6356 }
6357
6358 static int
6359 api_sw_interface_set_vpath (vat_main_t * vam)
6360 {
6361   unformat_input_t *i = vam->input;
6362   vl_api_sw_interface_set_vpath_t *mp;
6363   u32 sw_if_index = 0;
6364   u8 sw_if_index_set = 0;
6365   u8 is_enable = 0;
6366   int ret;
6367
6368   /* Parse args required to build the message */
6369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6370     {
6371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6372         sw_if_index_set = 1;
6373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6374         sw_if_index_set = 1;
6375       else if (unformat (i, "enable"))
6376         is_enable = 1;
6377       else if (unformat (i, "disable"))
6378         is_enable = 0;
6379       else
6380         break;
6381     }
6382
6383   if (sw_if_index_set == 0)
6384     {
6385       errmsg ("missing interface name or sw_if_index");
6386       return -99;
6387     }
6388
6389   /* Construct the API message */
6390   M (SW_INTERFACE_SET_VPATH, mp);
6391
6392   mp->sw_if_index = ntohl (sw_if_index);
6393   mp->enable = is_enable;
6394
6395   /* send it... */
6396   S (mp);
6397
6398   /* Wait for a reply... */
6399   W (ret);
6400   return ret;
6401 }
6402
6403 static int
6404 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6405 {
6406   unformat_input_t *i = vam->input;
6407   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6408   u32 sw_if_index = 0;
6409   u8 sw_if_index_set = 0;
6410   u8 is_enable = 1;
6411   u8 is_ipv6 = 0;
6412   int ret;
6413
6414   /* Parse args required to build the message */
6415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6416     {
6417       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6418         sw_if_index_set = 1;
6419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6420         sw_if_index_set = 1;
6421       else if (unformat (i, "enable"))
6422         is_enable = 1;
6423       else if (unformat (i, "disable"))
6424         is_enable = 0;
6425       else if (unformat (i, "ip4"))
6426         is_ipv6 = 0;
6427       else if (unformat (i, "ip6"))
6428         is_ipv6 = 1;
6429       else
6430         break;
6431     }
6432
6433   if (sw_if_index_set == 0)
6434     {
6435       errmsg ("missing interface name or sw_if_index");
6436       return -99;
6437     }
6438
6439   /* Construct the API message */
6440   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6441
6442   mp->sw_if_index = ntohl (sw_if_index);
6443   mp->enable = is_enable;
6444   mp->is_ipv6 = is_ipv6;
6445
6446   /* send it... */
6447   S (mp);
6448
6449   /* Wait for a reply... */
6450   W (ret);
6451   return ret;
6452 }
6453
6454 static int
6455 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6456 {
6457   unformat_input_t *i = vam->input;
6458   vl_api_sw_interface_set_geneve_bypass_t *mp;
6459   u32 sw_if_index = 0;
6460   u8 sw_if_index_set = 0;
6461   u8 is_enable = 1;
6462   u8 is_ipv6 = 0;
6463   int ret;
6464
6465   /* Parse args required to build the message */
6466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6467     {
6468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6469         sw_if_index_set = 1;
6470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6471         sw_if_index_set = 1;
6472       else if (unformat (i, "enable"))
6473         is_enable = 1;
6474       else if (unformat (i, "disable"))
6475         is_enable = 0;
6476       else if (unformat (i, "ip4"))
6477         is_ipv6 = 0;
6478       else if (unformat (i, "ip6"))
6479         is_ipv6 = 1;
6480       else
6481         break;
6482     }
6483
6484   if (sw_if_index_set == 0)
6485     {
6486       errmsg ("missing interface name or sw_if_index");
6487       return -99;
6488     }
6489
6490   /* Construct the API message */
6491   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6492
6493   mp->sw_if_index = ntohl (sw_if_index);
6494   mp->enable = is_enable;
6495   mp->is_ipv6 = is_ipv6;
6496
6497   /* send it... */
6498   S (mp);
6499
6500   /* Wait for a reply... */
6501   W (ret);
6502   return ret;
6503 }
6504
6505 static int
6506 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6507 {
6508   unformat_input_t *i = vam->input;
6509   vl_api_sw_interface_set_l2_xconnect_t *mp;
6510   u32 rx_sw_if_index;
6511   u8 rx_sw_if_index_set = 0;
6512   u32 tx_sw_if_index;
6513   u8 tx_sw_if_index_set = 0;
6514   u8 enable = 1;
6515   int ret;
6516
6517   /* Parse args required to build the message */
6518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6519     {
6520       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6521         rx_sw_if_index_set = 1;
6522       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6523         tx_sw_if_index_set = 1;
6524       else if (unformat (i, "rx"))
6525         {
6526           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6527             {
6528               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6529                             &rx_sw_if_index))
6530                 rx_sw_if_index_set = 1;
6531             }
6532           else
6533             break;
6534         }
6535       else if (unformat (i, "tx"))
6536         {
6537           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6538             {
6539               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6540                             &tx_sw_if_index))
6541                 tx_sw_if_index_set = 1;
6542             }
6543           else
6544             break;
6545         }
6546       else if (unformat (i, "enable"))
6547         enable = 1;
6548       else if (unformat (i, "disable"))
6549         enable = 0;
6550       else
6551         break;
6552     }
6553
6554   if (rx_sw_if_index_set == 0)
6555     {
6556       errmsg ("missing rx interface name or rx_sw_if_index");
6557       return -99;
6558     }
6559
6560   if (enable && (tx_sw_if_index_set == 0))
6561     {
6562       errmsg ("missing tx interface name or tx_sw_if_index");
6563       return -99;
6564     }
6565
6566   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6567
6568   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6569   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6570   mp->enable = enable;
6571
6572   S (mp);
6573   W (ret);
6574   return ret;
6575 }
6576
6577 static int
6578 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6579 {
6580   unformat_input_t *i = vam->input;
6581   vl_api_sw_interface_set_l2_bridge_t *mp;
6582   vl_api_l2_port_type_t port_type;
6583   u32 rx_sw_if_index;
6584   u8 rx_sw_if_index_set = 0;
6585   u32 bd_id;
6586   u8 bd_id_set = 0;
6587   u32 shg = 0;
6588   u8 enable = 1;
6589   int ret;
6590
6591   port_type = L2_API_PORT_TYPE_NORMAL;
6592
6593   /* Parse args required to build the message */
6594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6595     {
6596       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6597         rx_sw_if_index_set = 1;
6598       else if (unformat (i, "bd_id %d", &bd_id))
6599         bd_id_set = 1;
6600       else
6601         if (unformat
6602             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6603         rx_sw_if_index_set = 1;
6604       else if (unformat (i, "shg %d", &shg))
6605         ;
6606       else if (unformat (i, "bvi"))
6607         port_type = L2_API_PORT_TYPE_BVI;
6608       else if (unformat (i, "uu-fwd"))
6609         port_type = L2_API_PORT_TYPE_UU_FWD;
6610       else if (unformat (i, "enable"))
6611         enable = 1;
6612       else if (unformat (i, "disable"))
6613         enable = 0;
6614       else
6615         break;
6616     }
6617
6618   if (rx_sw_if_index_set == 0)
6619     {
6620       errmsg ("missing rx interface name or sw_if_index");
6621       return -99;
6622     }
6623
6624   if (enable && (bd_id_set == 0))
6625     {
6626       errmsg ("missing bridge domain");
6627       return -99;
6628     }
6629
6630   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6631
6632   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6633   mp->bd_id = ntohl (bd_id);
6634   mp->shg = (u8) shg;
6635   mp->port_type = ntohl (port_type);
6636   mp->enable = enable;
6637
6638   S (mp);
6639   W (ret);
6640   return ret;
6641 }
6642
6643 static int
6644 api_bridge_domain_dump (vat_main_t * vam)
6645 {
6646   unformat_input_t *i = vam->input;
6647   vl_api_bridge_domain_dump_t *mp;
6648   vl_api_control_ping_t *mp_ping;
6649   u32 bd_id = ~0;
6650   int ret;
6651
6652   /* Parse args required to build the message */
6653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6654     {
6655       if (unformat (i, "bd_id %d", &bd_id))
6656         ;
6657       else
6658         break;
6659     }
6660
6661   M (BRIDGE_DOMAIN_DUMP, mp);
6662   mp->bd_id = ntohl (bd_id);
6663   S (mp);
6664
6665   /* Use a control ping for synchronization */
6666   MPING (CONTROL_PING, mp_ping);
6667   S (mp_ping);
6668
6669   W (ret);
6670   return ret;
6671 }
6672
6673 static int
6674 api_bridge_domain_add_del (vat_main_t * vam)
6675 {
6676   unformat_input_t *i = vam->input;
6677   vl_api_bridge_domain_add_del_t *mp;
6678   u32 bd_id = ~0;
6679   u8 is_add = 1;
6680   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6681   u8 *bd_tag = NULL;
6682   u32 mac_age = 0;
6683   int ret;
6684
6685   /* Parse args required to build the message */
6686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6687     {
6688       if (unformat (i, "bd_id %d", &bd_id))
6689         ;
6690       else if (unformat (i, "flood %d", &flood))
6691         ;
6692       else if (unformat (i, "uu-flood %d", &uu_flood))
6693         ;
6694       else if (unformat (i, "forward %d", &forward))
6695         ;
6696       else if (unformat (i, "learn %d", &learn))
6697         ;
6698       else if (unformat (i, "arp-term %d", &arp_term))
6699         ;
6700       else if (unformat (i, "mac-age %d", &mac_age))
6701         ;
6702       else if (unformat (i, "bd-tag %s", &bd_tag))
6703         ;
6704       else if (unformat (i, "del"))
6705         {
6706           is_add = 0;
6707           flood = uu_flood = forward = learn = 0;
6708         }
6709       else
6710         break;
6711     }
6712
6713   if (bd_id == ~0)
6714     {
6715       errmsg ("missing bridge domain");
6716       ret = -99;
6717       goto done;
6718     }
6719
6720   if (mac_age > 255)
6721     {
6722       errmsg ("mac age must be less than 256 ");
6723       ret = -99;
6724       goto done;
6725     }
6726
6727   if ((bd_tag) && (vec_len (bd_tag) > 63))
6728     {
6729       errmsg ("bd-tag cannot be longer than 63");
6730       ret = -99;
6731       goto done;
6732     }
6733
6734   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6735
6736   mp->bd_id = ntohl (bd_id);
6737   mp->flood = flood;
6738   mp->uu_flood = uu_flood;
6739   mp->forward = forward;
6740   mp->learn = learn;
6741   mp->arp_term = arp_term;
6742   mp->is_add = is_add;
6743   mp->mac_age = (u8) mac_age;
6744   if (bd_tag)
6745     {
6746       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6747       mp->bd_tag[vec_len (bd_tag)] = 0;
6748     }
6749   S (mp);
6750   W (ret);
6751
6752 done:
6753   vec_free (bd_tag);
6754   return ret;
6755 }
6756
6757 static int
6758 api_l2fib_flush_bd (vat_main_t * vam)
6759 {
6760   unformat_input_t *i = vam->input;
6761   vl_api_l2fib_flush_bd_t *mp;
6762   u32 bd_id = ~0;
6763   int ret;
6764
6765   /* Parse args required to build the message */
6766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6767     {
6768       if (unformat (i, "bd_id %d", &bd_id));
6769       else
6770         break;
6771     }
6772
6773   if (bd_id == ~0)
6774     {
6775       errmsg ("missing bridge domain");
6776       return -99;
6777     }
6778
6779   M (L2FIB_FLUSH_BD, mp);
6780
6781   mp->bd_id = htonl (bd_id);
6782
6783   S (mp);
6784   W (ret);
6785   return ret;
6786 }
6787
6788 static int
6789 api_l2fib_flush_int (vat_main_t * vam)
6790 {
6791   unformat_input_t *i = vam->input;
6792   vl_api_l2fib_flush_int_t *mp;
6793   u32 sw_if_index = ~0;
6794   int ret;
6795
6796   /* Parse args required to build the message */
6797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6798     {
6799       if (unformat (i, "sw_if_index %d", &sw_if_index));
6800       else
6801         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6802       else
6803         break;
6804     }
6805
6806   if (sw_if_index == ~0)
6807     {
6808       errmsg ("missing interface name or sw_if_index");
6809       return -99;
6810     }
6811
6812   M (L2FIB_FLUSH_INT, mp);
6813
6814   mp->sw_if_index = ntohl (sw_if_index);
6815
6816   S (mp);
6817   W (ret);
6818   return ret;
6819 }
6820
6821 static int
6822 api_l2fib_add_del (vat_main_t * vam)
6823 {
6824   unformat_input_t *i = vam->input;
6825   vl_api_l2fib_add_del_t *mp;
6826   f64 timeout;
6827   u8 mac[6] = { 0 };
6828   u8 mac_set = 0;
6829   u32 bd_id;
6830   u8 bd_id_set = 0;
6831   u32 sw_if_index = 0;
6832   u8 sw_if_index_set = 0;
6833   u8 is_add = 1;
6834   u8 static_mac = 0;
6835   u8 filter_mac = 0;
6836   u8 bvi_mac = 0;
6837   int count = 1;
6838   f64 before = 0;
6839   int j;
6840
6841   /* Parse args required to build the message */
6842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6843     {
6844       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6845         mac_set = 1;
6846       else if (unformat (i, "bd_id %d", &bd_id))
6847         bd_id_set = 1;
6848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6849         sw_if_index_set = 1;
6850       else if (unformat (i, "sw_if"))
6851         {
6852           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6853             {
6854               if (unformat
6855                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6856                 sw_if_index_set = 1;
6857             }
6858           else
6859             break;
6860         }
6861       else if (unformat (i, "static"))
6862         static_mac = 1;
6863       else if (unformat (i, "filter"))
6864         {
6865           filter_mac = 1;
6866           static_mac = 1;
6867         }
6868       else if (unformat (i, "bvi"))
6869         {
6870           bvi_mac = 1;
6871           static_mac = 1;
6872         }
6873       else if (unformat (i, "del"))
6874         is_add = 0;
6875       else if (unformat (i, "count %d", &count))
6876         ;
6877       else
6878         break;
6879     }
6880
6881   if (mac_set == 0)
6882     {
6883       errmsg ("missing mac address");
6884       return -99;
6885     }
6886
6887   if (bd_id_set == 0)
6888     {
6889       errmsg ("missing bridge domain");
6890       return -99;
6891     }
6892
6893   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6894     {
6895       errmsg ("missing interface name or sw_if_index");
6896       return -99;
6897     }
6898
6899   if (count > 1)
6900     {
6901       /* Turn on async mode */
6902       vam->async_mode = 1;
6903       vam->async_errors = 0;
6904       before = vat_time_now (vam);
6905     }
6906
6907   for (j = 0; j < count; j++)
6908     {
6909       M (L2FIB_ADD_DEL, mp);
6910
6911       clib_memcpy (mp->mac, mac, 6);
6912       mp->bd_id = ntohl (bd_id);
6913       mp->is_add = is_add;
6914       mp->sw_if_index = ntohl (sw_if_index);
6915
6916       if (is_add)
6917         {
6918           mp->static_mac = static_mac;
6919           mp->filter_mac = filter_mac;
6920           mp->bvi_mac = bvi_mac;
6921         }
6922       increment_mac_address (mac);
6923       /* send it... */
6924       S (mp);
6925     }
6926
6927   if (count > 1)
6928     {
6929       vl_api_control_ping_t *mp_ping;
6930       f64 after;
6931
6932       /* Shut off async mode */
6933       vam->async_mode = 0;
6934
6935       MPING (CONTROL_PING, mp_ping);
6936       S (mp_ping);
6937
6938       timeout = vat_time_now (vam) + 1.0;
6939       while (vat_time_now (vam) < timeout)
6940         if (vam->result_ready == 1)
6941           goto out;
6942       vam->retval = -99;
6943
6944     out:
6945       if (vam->retval == -99)
6946         errmsg ("timeout");
6947
6948       if (vam->async_errors > 0)
6949         {
6950           errmsg ("%d asynchronous errors", vam->async_errors);
6951           vam->retval = -98;
6952         }
6953       vam->async_errors = 0;
6954       after = vat_time_now (vam);
6955
6956       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6957              count, after - before, count / (after - before));
6958     }
6959   else
6960     {
6961       int ret;
6962
6963       /* Wait for a reply... */
6964       W (ret);
6965       return ret;
6966     }
6967   /* Return the good/bad news */
6968   return (vam->retval);
6969 }
6970
6971 static int
6972 api_bridge_domain_set_mac_age (vat_main_t * vam)
6973 {
6974   unformat_input_t *i = vam->input;
6975   vl_api_bridge_domain_set_mac_age_t *mp;
6976   u32 bd_id = ~0;
6977   u32 mac_age = 0;
6978   int ret;
6979
6980   /* Parse args required to build the message */
6981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6982     {
6983       if (unformat (i, "bd_id %d", &bd_id));
6984       else if (unformat (i, "mac-age %d", &mac_age));
6985       else
6986         break;
6987     }
6988
6989   if (bd_id == ~0)
6990     {
6991       errmsg ("missing bridge domain");
6992       return -99;
6993     }
6994
6995   if (mac_age > 255)
6996     {
6997       errmsg ("mac age must be less than 256 ");
6998       return -99;
6999     }
7000
7001   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7002
7003   mp->bd_id = htonl (bd_id);
7004   mp->mac_age = (u8) mac_age;
7005
7006   S (mp);
7007   W (ret);
7008   return ret;
7009 }
7010
7011 static int
7012 api_l2_flags (vat_main_t * vam)
7013 {
7014   unformat_input_t *i = vam->input;
7015   vl_api_l2_flags_t *mp;
7016   u32 sw_if_index;
7017   u32 flags = 0;
7018   u8 sw_if_index_set = 0;
7019   u8 is_set = 0;
7020   int ret;
7021
7022   /* Parse args required to build the message */
7023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7024     {
7025       if (unformat (i, "sw_if_index %d", &sw_if_index))
7026         sw_if_index_set = 1;
7027       else if (unformat (i, "sw_if"))
7028         {
7029           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7030             {
7031               if (unformat
7032                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7033                 sw_if_index_set = 1;
7034             }
7035           else
7036             break;
7037         }
7038       else if (unformat (i, "learn"))
7039         flags |= L2_LEARN;
7040       else if (unformat (i, "forward"))
7041         flags |= L2_FWD;
7042       else if (unformat (i, "flood"))
7043         flags |= L2_FLOOD;
7044       else if (unformat (i, "uu-flood"))
7045         flags |= L2_UU_FLOOD;
7046       else if (unformat (i, "arp-term"))
7047         flags |= L2_ARP_TERM;
7048       else if (unformat (i, "off"))
7049         is_set = 0;
7050       else if (unformat (i, "disable"))
7051         is_set = 0;
7052       else
7053         break;
7054     }
7055
7056   if (sw_if_index_set == 0)
7057     {
7058       errmsg ("missing interface name or sw_if_index");
7059       return -99;
7060     }
7061
7062   M (L2_FLAGS, mp);
7063
7064   mp->sw_if_index = ntohl (sw_if_index);
7065   mp->feature_bitmap = ntohl (flags);
7066   mp->is_set = is_set;
7067
7068   S (mp);
7069   W (ret);
7070   return ret;
7071 }
7072
7073 static int
7074 api_bridge_flags (vat_main_t * vam)
7075 {
7076   unformat_input_t *i = vam->input;
7077   vl_api_bridge_flags_t *mp;
7078   u32 bd_id;
7079   u8 bd_id_set = 0;
7080   u8 is_set = 1;
7081   bd_flags_t flags = 0;
7082   int ret;
7083
7084   /* Parse args required to build the message */
7085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7086     {
7087       if (unformat (i, "bd_id %d", &bd_id))
7088         bd_id_set = 1;
7089       else if (unformat (i, "learn"))
7090         flags |= BRIDGE_API_FLAG_LEARN;
7091       else if (unformat (i, "forward"))
7092         flags |= BRIDGE_API_FLAG_FWD;
7093       else if (unformat (i, "flood"))
7094         flags |= BRIDGE_API_FLAG_FLOOD;
7095       else if (unformat (i, "uu-flood"))
7096         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7097       else if (unformat (i, "arp-term"))
7098         flags |= BRIDGE_API_FLAG_ARP_TERM;
7099       else if (unformat (i, "off"))
7100         is_set = 0;
7101       else if (unformat (i, "disable"))
7102         is_set = 0;
7103       else
7104         break;
7105     }
7106
7107   if (bd_id_set == 0)
7108     {
7109       errmsg ("missing bridge domain");
7110       return -99;
7111     }
7112
7113   M (BRIDGE_FLAGS, mp);
7114
7115   mp->bd_id = ntohl (bd_id);
7116   mp->flags = ntohl (flags);
7117   mp->is_set = is_set;
7118
7119   S (mp);
7120   W (ret);
7121   return ret;
7122 }
7123
7124 static int
7125 api_bd_ip_mac_add_del (vat_main_t * vam)
7126 {
7127   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7128   vl_api_mac_address_t mac = { 0 };
7129   unformat_input_t *i = vam->input;
7130   vl_api_bd_ip_mac_add_del_t *mp;
7131   u32 bd_id;
7132   u8 is_add = 1;
7133   u8 bd_id_set = 0;
7134   u8 ip_set = 0;
7135   u8 mac_set = 0;
7136   int ret;
7137
7138
7139   /* Parse args required to build the message */
7140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7141     {
7142       if (unformat (i, "bd_id %d", &bd_id))
7143         {
7144           bd_id_set++;
7145         }
7146       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7147         {
7148           ip_set++;
7149         }
7150       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7151         {
7152           mac_set++;
7153         }
7154       else if (unformat (i, "del"))
7155         is_add = 0;
7156       else
7157         break;
7158     }
7159
7160   if (bd_id_set == 0)
7161     {
7162       errmsg ("missing bridge domain");
7163       return -99;
7164     }
7165   else if (ip_set == 0)
7166     {
7167       errmsg ("missing IP address");
7168       return -99;
7169     }
7170   else if (mac_set == 0)
7171     {
7172       errmsg ("missing MAC address");
7173       return -99;
7174     }
7175
7176   M (BD_IP_MAC_ADD_DEL, mp);
7177
7178   mp->entry.bd_id = ntohl (bd_id);
7179   mp->is_add = is_add;
7180
7181   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7182   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7183
7184   S (mp);
7185   W (ret);
7186   return ret;
7187 }
7188
7189 static int
7190 api_bd_ip_mac_flush (vat_main_t * vam)
7191 {
7192   unformat_input_t *i = vam->input;
7193   vl_api_bd_ip_mac_flush_t *mp;
7194   u32 bd_id;
7195   u8 bd_id_set = 0;
7196   int ret;
7197
7198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7199     {
7200       if (unformat (i, "bd_id %d", &bd_id))
7201         {
7202           bd_id_set++;
7203         }
7204       else
7205         break;
7206     }
7207
7208   if (bd_id_set == 0)
7209     {
7210       errmsg ("missing bridge domain");
7211       return -99;
7212     }
7213
7214   M (BD_IP_MAC_FLUSH, mp);
7215
7216   mp->bd_id = ntohl (bd_id);
7217
7218   S (mp);
7219   W (ret);
7220   return ret;
7221 }
7222
7223 static void vl_api_bd_ip_mac_details_t_handler
7224   (vl_api_bd_ip_mac_details_t * mp)
7225 {
7226   vat_main_t *vam = &vat_main;
7227
7228   print (vam->ofp,
7229          "\n%-5d %U %U",
7230          ntohl (mp->entry.bd_id),
7231          format_vl_api_mac_address, mp->entry.mac,
7232          format_vl_api_address, &mp->entry.ip);
7233 }
7234
7235 static void vl_api_bd_ip_mac_details_t_handler_json
7236   (vl_api_bd_ip_mac_details_t * mp)
7237 {
7238   vat_main_t *vam = &vat_main;
7239   vat_json_node_t *node = NULL;
7240
7241   if (VAT_JSON_ARRAY != vam->json_tree.type)
7242     {
7243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7244       vat_json_init_array (&vam->json_tree);
7245     }
7246   node = vat_json_array_add (&vam->json_tree);
7247
7248   vat_json_init_object (node);
7249   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7250   vat_json_object_add_string_copy (node, "mac_address",
7251                                    format (0, "%U", format_vl_api_mac_address,
7252                                            &mp->entry.mac));
7253   u8 *ip = 0;
7254
7255   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7256   vat_json_object_add_string_copy (node, "ip_address", ip);
7257   vec_free (ip);
7258 }
7259
7260 static int
7261 api_bd_ip_mac_dump (vat_main_t * vam)
7262 {
7263   unformat_input_t *i = vam->input;
7264   vl_api_bd_ip_mac_dump_t *mp;
7265   vl_api_control_ping_t *mp_ping;
7266   int ret;
7267   u32 bd_id;
7268   u8 bd_id_set = 0;
7269
7270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7271     {
7272       if (unformat (i, "bd_id %d", &bd_id))
7273         {
7274           bd_id_set++;
7275         }
7276       else
7277         break;
7278     }
7279
7280   print (vam->ofp,
7281          "\n%-5s %-7s %-20s %-30s",
7282          "bd_id", "is_ipv6", "mac_address", "ip_address");
7283
7284   /* Dump Bridge Domain Ip to Mac entries */
7285   M (BD_IP_MAC_DUMP, mp);
7286
7287   if (bd_id_set)
7288     mp->bd_id = htonl (bd_id);
7289   else
7290     mp->bd_id = ~0;
7291
7292   S (mp);
7293
7294   /* Use a control ping for synchronization */
7295   MPING (CONTROL_PING, mp_ping);
7296   S (mp_ping);
7297
7298   W (ret);
7299   return ret;
7300 }
7301
7302 static int
7303 api_tap_create_v2 (vat_main_t * vam)
7304 {
7305   unformat_input_t *i = vam->input;
7306   vl_api_tap_create_v2_t *mp;
7307   u8 mac_address[6];
7308   u8 random_mac = 1;
7309   u32 id = ~0;
7310   u32 num_rx_queues = 0;
7311   u8 *host_if_name = 0;
7312   u8 host_if_name_set = 0;
7313   u8 *host_ns = 0;
7314   u8 host_ns_set = 0;
7315   u8 host_mac_addr[6];
7316   u8 host_mac_addr_set = 0;
7317   u8 *host_bridge = 0;
7318   u8 host_bridge_set = 0;
7319   u8 host_ip4_prefix_set = 0;
7320   u8 host_ip6_prefix_set = 0;
7321   ip4_address_t host_ip4_addr;
7322   ip4_address_t host_ip4_gw;
7323   u8 host_ip4_gw_set = 0;
7324   u32 host_ip4_prefix_len = 0;
7325   ip6_address_t host_ip6_addr;
7326   ip6_address_t host_ip6_gw;
7327   u8 host_ip6_gw_set = 0;
7328   u32 host_ip6_prefix_len = 0;
7329   u32 host_mtu_size = 0;
7330   u8 host_mtu_set = 0;
7331   u32 tap_flags = 0;
7332   int ret;
7333   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7334
7335   clib_memset (mac_address, 0, sizeof (mac_address));
7336
7337   /* Parse args required to build the message */
7338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7339     {
7340       if (unformat (i, "id %u", &id))
7341         ;
7342       else
7343         if (unformat
7344             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7345         random_mac = 0;
7346       else if (unformat (i, "host-if-name %s", &host_if_name))
7347         host_if_name_set = 1;
7348       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7349         ;
7350       else if (unformat (i, "host-ns %s", &host_ns))
7351         host_ns_set = 1;
7352       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7353                          host_mac_addr))
7354         host_mac_addr_set = 1;
7355       else if (unformat (i, "host-bridge %s", &host_bridge))
7356         host_bridge_set = 1;
7357       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7358                          &host_ip4_addr, &host_ip4_prefix_len))
7359         host_ip4_prefix_set = 1;
7360       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7361                          &host_ip6_addr, &host_ip6_prefix_len))
7362         host_ip6_prefix_set = 1;
7363       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7364                          &host_ip4_gw))
7365         host_ip4_gw_set = 1;
7366       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7367                          &host_ip6_gw))
7368         host_ip6_gw_set = 1;
7369       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7370         ;
7371       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7372         ;
7373       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7374         host_mtu_set = 1;
7375       else if (unformat (i, "no-gso"))
7376         tap_flags &= ~TAP_API_FLAG_GSO;
7377       else if (unformat (i, "gso"))
7378         tap_flags |= TAP_API_FLAG_GSO;
7379       else if (unformat (i, "csum-offload"))
7380         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7381       else if (unformat (i, "persist"))
7382         tap_flags |= TAP_API_FLAG_PERSIST;
7383       else if (unformat (i, "attach"))
7384         tap_flags |= TAP_API_FLAG_ATTACH;
7385       else if (unformat (i, "tun"))
7386         tap_flags |= TAP_API_FLAG_TUN;
7387       else if (unformat (i, "gro-coalesce"))
7388         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7389       else
7390         break;
7391     }
7392
7393   if (vec_len (host_if_name) > 63)
7394     {
7395       errmsg ("tap name too long. ");
7396       return -99;
7397     }
7398   if (vec_len (host_ns) > 63)
7399     {
7400       errmsg ("host name space too long. ");
7401       return -99;
7402     }
7403   if (vec_len (host_bridge) > 63)
7404     {
7405       errmsg ("host bridge name too long. ");
7406       return -99;
7407     }
7408   if (host_ip4_prefix_len > 32)
7409     {
7410       errmsg ("host ip4 prefix length not valid. ");
7411       return -99;
7412     }
7413   if (host_ip6_prefix_len > 128)
7414     {
7415       errmsg ("host ip6 prefix length not valid. ");
7416       return -99;
7417     }
7418   if (!is_pow2 (rx_ring_sz))
7419     {
7420       errmsg ("rx ring size must be power of 2. ");
7421       return -99;
7422     }
7423   if (rx_ring_sz > 32768)
7424     {
7425       errmsg ("rx ring size must be 32768 or lower. ");
7426       return -99;
7427     }
7428   if (!is_pow2 (tx_ring_sz))
7429     {
7430       errmsg ("tx ring size must be power of 2. ");
7431       return -99;
7432     }
7433   if (tx_ring_sz > 32768)
7434     {
7435       errmsg ("tx ring size must be 32768 or lower. ");
7436       return -99;
7437     }
7438   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7439     {
7440       errmsg ("host MTU size must be in between 64 and 65355. ");
7441       return -99;
7442     }
7443
7444   /* Construct the API message */
7445   M (TAP_CREATE_V2, mp);
7446
7447   mp->id = ntohl (id);
7448   mp->use_random_mac = random_mac;
7449   mp->num_rx_queues = (u8) num_rx_queues;
7450   mp->tx_ring_sz = ntohs (tx_ring_sz);
7451   mp->rx_ring_sz = ntohs (rx_ring_sz);
7452   mp->host_mtu_set = host_mtu_set;
7453   mp->host_mtu_size = ntohl (host_mtu_size);
7454   mp->host_mac_addr_set = host_mac_addr_set;
7455   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7456   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7457   mp->host_ip4_gw_set = host_ip4_gw_set;
7458   mp->host_ip6_gw_set = host_ip6_gw_set;
7459   mp->tap_flags = ntohl (tap_flags);
7460   mp->host_namespace_set = host_ns_set;
7461   mp->host_if_name_set = host_if_name_set;
7462   mp->host_bridge_set = host_bridge_set;
7463
7464   if (random_mac == 0)
7465     clib_memcpy (mp->mac_address, mac_address, 6);
7466   if (host_mac_addr_set)
7467     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7468   if (host_if_name_set)
7469     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7470   if (host_ns_set)
7471     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7472   if (host_bridge_set)
7473     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7474   if (host_ip4_prefix_set)
7475     {
7476       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7477       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7478     }
7479   if (host_ip6_prefix_set)
7480     {
7481       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7482       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7483     }
7484   if (host_ip4_gw_set)
7485     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7486   if (host_ip6_gw_set)
7487     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7488
7489   vec_free (host_ns);
7490   vec_free (host_if_name);
7491   vec_free (host_bridge);
7492
7493   /* send it... */
7494   S (mp);
7495
7496   /* Wait for a reply... */
7497   W (ret);
7498   return ret;
7499 }
7500
7501 static int
7502 api_tap_delete_v2 (vat_main_t * vam)
7503 {
7504   unformat_input_t *i = vam->input;
7505   vl_api_tap_delete_v2_t *mp;
7506   u32 sw_if_index = ~0;
7507   u8 sw_if_index_set = 0;
7508   int ret;
7509
7510   /* Parse args required to build the message */
7511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7512     {
7513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7514         sw_if_index_set = 1;
7515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7516         sw_if_index_set = 1;
7517       else
7518         break;
7519     }
7520
7521   if (sw_if_index_set == 0)
7522     {
7523       errmsg ("missing vpp interface name. ");
7524       return -99;
7525     }
7526
7527   /* Construct the API message */
7528   M (TAP_DELETE_V2, mp);
7529
7530   mp->sw_if_index = ntohl (sw_if_index);
7531
7532   /* send it... */
7533   S (mp);
7534
7535   /* Wait for a reply... */
7536   W (ret);
7537   return ret;
7538 }
7539
7540 uword
7541 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7542 {
7543   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7544   u32 x[4];
7545
7546   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7547     return 0;
7548
7549   addr->domain = x[0];
7550   addr->bus = x[1];
7551   addr->slot = x[2];
7552   addr->function = x[3];
7553
7554   return 1;
7555 }
7556
7557 static int
7558 api_virtio_pci_create (vat_main_t * vam)
7559 {
7560   unformat_input_t *i = vam->input;
7561   vl_api_virtio_pci_create_t *mp;
7562   u8 mac_address[6];
7563   u8 random_mac = 1;
7564   u8 gso_enabled = 0;
7565   u8 checksum_offload_enabled = 0;
7566   u32 pci_addr = 0;
7567   u64 features = (u64) ~ (0ULL);
7568   int ret;
7569
7570   clib_memset (mac_address, 0, sizeof (mac_address));
7571
7572   /* Parse args required to build the message */
7573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7574     {
7575       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7576         {
7577           random_mac = 0;
7578         }
7579       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7580         ;
7581       else if (unformat (i, "features 0x%llx", &features))
7582         ;
7583       else if (unformat (i, "gso-enabled"))
7584         gso_enabled = 1;
7585       else if (unformat (i, "csum-offload-enabled"))
7586         checksum_offload_enabled = 1;
7587       else
7588         break;
7589     }
7590
7591   if (pci_addr == 0)
7592     {
7593       errmsg ("pci address must be non zero. ");
7594       return -99;
7595     }
7596
7597   /* Construct the API message */
7598   M (VIRTIO_PCI_CREATE, mp);
7599
7600   mp->use_random_mac = random_mac;
7601
7602   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7603   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7604   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7605   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7606
7607   mp->features = clib_host_to_net_u64 (features);
7608   mp->gso_enabled = gso_enabled;
7609   mp->checksum_offload_enabled = checksum_offload_enabled;
7610
7611   if (random_mac == 0)
7612     clib_memcpy (mp->mac_address, mac_address, 6);
7613
7614   /* send it... */
7615   S (mp);
7616
7617   /* Wait for a reply... */
7618   W (ret);
7619   return ret;
7620 }
7621
7622 static int
7623 api_virtio_pci_delete (vat_main_t * vam)
7624 {
7625   unformat_input_t *i = vam->input;
7626   vl_api_virtio_pci_delete_t *mp;
7627   u32 sw_if_index = ~0;
7628   u8 sw_if_index_set = 0;
7629   int ret;
7630
7631   /* Parse args required to build the message */
7632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7633     {
7634       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7635         sw_if_index_set = 1;
7636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7637         sw_if_index_set = 1;
7638       else
7639         break;
7640     }
7641
7642   if (sw_if_index_set == 0)
7643     {
7644       errmsg ("missing vpp interface name. ");
7645       return -99;
7646     }
7647
7648   /* Construct the API message */
7649   M (VIRTIO_PCI_DELETE, mp);
7650
7651   mp->sw_if_index = htonl (sw_if_index);
7652
7653   /* send it... */
7654   S (mp);
7655
7656   /* Wait for a reply... */
7657   W (ret);
7658   return ret;
7659 }
7660
7661 static int
7662 api_bond_create (vat_main_t * vam)
7663 {
7664   unformat_input_t *i = vam->input;
7665   vl_api_bond_create_t *mp;
7666   u8 mac_address[6];
7667   u8 custom_mac = 0;
7668   int ret;
7669   u8 mode;
7670   u8 lb;
7671   u8 mode_is_set = 0;
7672   u32 id = ~0;
7673   u8 numa_only = 0;
7674
7675   clib_memset (mac_address, 0, sizeof (mac_address));
7676   lb = BOND_LB_L2;
7677
7678   /* Parse args required to build the message */
7679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7680     {
7681       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7682         mode_is_set = 1;
7683       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7684                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7685         ;
7686       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7687                          mac_address))
7688         custom_mac = 1;
7689       else if (unformat (i, "numa-only"))
7690         numa_only = 1;
7691       else if (unformat (i, "id %u", &id))
7692         ;
7693       else
7694         break;
7695     }
7696
7697   if (mode_is_set == 0)
7698     {
7699       errmsg ("Missing bond mode. ");
7700       return -99;
7701     }
7702
7703   /* Construct the API message */
7704   M (BOND_CREATE, mp);
7705
7706   mp->use_custom_mac = custom_mac;
7707
7708   mp->mode = htonl (mode);
7709   mp->lb = htonl (lb);
7710   mp->id = htonl (id);
7711   mp->numa_only = numa_only;
7712
7713   if (custom_mac)
7714     clib_memcpy (mp->mac_address, mac_address, 6);
7715
7716   /* send it... */
7717   S (mp);
7718
7719   /* Wait for a reply... */
7720   W (ret);
7721   return ret;
7722 }
7723
7724 static int
7725 api_bond_delete (vat_main_t * vam)
7726 {
7727   unformat_input_t *i = vam->input;
7728   vl_api_bond_delete_t *mp;
7729   u32 sw_if_index = ~0;
7730   u8 sw_if_index_set = 0;
7731   int ret;
7732
7733   /* Parse args required to build the message */
7734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7735     {
7736       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7737         sw_if_index_set = 1;
7738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7739         sw_if_index_set = 1;
7740       else
7741         break;
7742     }
7743
7744   if (sw_if_index_set == 0)
7745     {
7746       errmsg ("missing vpp interface name. ");
7747       return -99;
7748     }
7749
7750   /* Construct the API message */
7751   M (BOND_DELETE, mp);
7752
7753   mp->sw_if_index = ntohl (sw_if_index);
7754
7755   /* send it... */
7756   S (mp);
7757
7758   /* Wait for a reply... */
7759   W (ret);
7760   return ret;
7761 }
7762
7763 static int
7764 api_bond_add_member (vat_main_t * vam)
7765 {
7766   unformat_input_t *i = vam->input;
7767   vl_api_bond_add_member_t *mp;
7768   u32 bond_sw_if_index;
7769   int ret;
7770   u8 is_passive;
7771   u8 is_long_timeout;
7772   u32 bond_sw_if_index_is_set = 0;
7773   u32 sw_if_index;
7774   u8 sw_if_index_is_set = 0;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "sw_if_index %d", &sw_if_index))
7780         sw_if_index_is_set = 1;
7781       else if (unformat (i, "bond %u", &bond_sw_if_index))
7782         bond_sw_if_index_is_set = 1;
7783       else if (unformat (i, "passive %d", &is_passive))
7784         ;
7785       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7786         ;
7787       else
7788         break;
7789     }
7790
7791   if (bond_sw_if_index_is_set == 0)
7792     {
7793       errmsg ("Missing bond sw_if_index. ");
7794       return -99;
7795     }
7796   if (sw_if_index_is_set == 0)
7797     {
7798       errmsg ("Missing member sw_if_index. ");
7799       return -99;
7800     }
7801
7802   /* Construct the API message */
7803   M (BOND_ADD_MEMBER, mp);
7804
7805   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7806   mp->sw_if_index = ntohl (sw_if_index);
7807   mp->is_long_timeout = is_long_timeout;
7808   mp->is_passive = is_passive;
7809
7810   /* send it... */
7811   S (mp);
7812
7813   /* Wait for a reply... */
7814   W (ret);
7815   return ret;
7816 }
7817
7818 static int
7819 api_bond_detach_member (vat_main_t * vam)
7820 {
7821   unformat_input_t *i = vam->input;
7822   vl_api_bond_detach_member_t *mp;
7823   u32 sw_if_index = ~0;
7824   u8 sw_if_index_set = 0;
7825   int ret;
7826
7827   /* Parse args required to build the message */
7828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7829     {
7830       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7831         sw_if_index_set = 1;
7832       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7833         sw_if_index_set = 1;
7834       else
7835         break;
7836     }
7837
7838   if (sw_if_index_set == 0)
7839     {
7840       errmsg ("missing vpp interface name. ");
7841       return -99;
7842     }
7843
7844   /* Construct the API message */
7845   M (BOND_DETACH_MEMBER, mp);
7846
7847   mp->sw_if_index = ntohl (sw_if_index);
7848
7849   /* send it... */
7850   S (mp);
7851
7852   /* Wait for a reply... */
7853   W (ret);
7854   return ret;
7855 }
7856
7857 static int
7858 api_ip_table_add_del (vat_main_t * vam)
7859 {
7860   unformat_input_t *i = vam->input;
7861   vl_api_ip_table_add_del_t *mp;
7862   u32 table_id = ~0;
7863   u8 is_ipv6 = 0;
7864   u8 is_add = 1;
7865   int ret = 0;
7866
7867   /* Parse args required to build the message */
7868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (i, "ipv6"))
7871         is_ipv6 = 1;
7872       else if (unformat (i, "del"))
7873         is_add = 0;
7874       else if (unformat (i, "add"))
7875         is_add = 1;
7876       else if (unformat (i, "table %d", &table_id))
7877         ;
7878       else
7879         {
7880           clib_warning ("parse error '%U'", format_unformat_error, i);
7881           return -99;
7882         }
7883     }
7884
7885   if (~0 == table_id)
7886     {
7887       errmsg ("missing table-ID");
7888       return -99;
7889     }
7890
7891   /* Construct the API message */
7892   M (IP_TABLE_ADD_DEL, mp);
7893
7894   mp->table.table_id = ntohl (table_id);
7895   mp->table.is_ip6 = is_ipv6;
7896   mp->is_add = is_add;
7897
7898   /* send it... */
7899   S (mp);
7900
7901   /* Wait for a reply... */
7902   W (ret);
7903
7904   return ret;
7905 }
7906
7907 uword
7908 unformat_fib_path (unformat_input_t * input, va_list * args)
7909 {
7910   vat_main_t *vam = va_arg (*args, vat_main_t *);
7911   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7912   u32 weight, preference;
7913   mpls_label_t out_label;
7914
7915   clib_memset (path, 0, sizeof (*path));
7916   path->weight = 1;
7917   path->sw_if_index = ~0;
7918   path->rpf_id = ~0;
7919   path->n_labels = 0;
7920
7921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7922     {
7923       if (unformat (input, "%U %U",
7924                     unformat_vl_api_ip4_address,
7925                     &path->nh.address.ip4,
7926                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7927         {
7928           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7929         }
7930       else if (unformat (input, "%U %U",
7931                          unformat_vl_api_ip6_address,
7932                          &path->nh.address.ip6,
7933                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7934         {
7935           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7936         }
7937       else if (unformat (input, "weight %u", &weight))
7938         {
7939           path->weight = weight;
7940         }
7941       else if (unformat (input, "preference %u", &preference))
7942         {
7943           path->preference = preference;
7944         }
7945       else if (unformat (input, "%U next-hop-table %d",
7946                          unformat_vl_api_ip4_address,
7947                          &path->nh.address.ip4, &path->table_id))
7948         {
7949           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7950         }
7951       else if (unformat (input, "%U next-hop-table %d",
7952                          unformat_vl_api_ip6_address,
7953                          &path->nh.address.ip6, &path->table_id))
7954         {
7955           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7956         }
7957       else if (unformat (input, "%U",
7958                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7959         {
7960           /*
7961            * the recursive next-hops are by default in the default table
7962            */
7963           path->table_id = 0;
7964           path->sw_if_index = ~0;
7965           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7966         }
7967       else if (unformat (input, "%U",
7968                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7969         {
7970           /*
7971            * the recursive next-hops are by default in the default table
7972            */
7973           path->table_id = 0;
7974           path->sw_if_index = ~0;
7975           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7976         }
7977       else if (unformat (input, "resolve-via-host"))
7978         {
7979           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7980         }
7981       else if (unformat (input, "resolve-via-attached"))
7982         {
7983           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7984         }
7985       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7986         {
7987           path->type = FIB_API_PATH_TYPE_LOCAL;
7988           path->sw_if_index = ~0;
7989           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7990         }
7991       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7992         {
7993           path->type = FIB_API_PATH_TYPE_LOCAL;
7994           path->sw_if_index = ~0;
7995           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7996         }
7997       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7998         ;
7999       else if (unformat (input, "via-label %d", &path->nh.via_label))
8000         {
8001           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8002           path->sw_if_index = ~0;
8003         }
8004       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8005         {
8006           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8007           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8008         }
8009       else if (unformat (input, "local"))
8010         {
8011           path->type = FIB_API_PATH_TYPE_LOCAL;
8012         }
8013       else if (unformat (input, "out-labels"))
8014         {
8015           while (unformat (input, "%d", &out_label))
8016             {
8017               path->label_stack[path->n_labels].label = out_label;
8018               path->label_stack[path->n_labels].is_uniform = 0;
8019               path->label_stack[path->n_labels].ttl = 64;
8020               path->n_labels++;
8021             }
8022         }
8023       else if (unformat (input, "via"))
8024         {
8025           /* new path, back up and return */
8026           unformat_put_input (input);
8027           unformat_put_input (input);
8028           unformat_put_input (input);
8029           unformat_put_input (input);
8030           break;
8031         }
8032       else
8033         {
8034           return (0);
8035         }
8036     }
8037
8038   path->proto = ntohl (path->proto);
8039   path->type = ntohl (path->type);
8040   path->flags = ntohl (path->flags);
8041   path->table_id = ntohl (path->table_id);
8042   path->sw_if_index = ntohl (path->sw_if_index);
8043
8044   return (1);
8045 }
8046
8047 static int
8048 api_ip_route_add_del (vat_main_t * vam)
8049 {
8050   unformat_input_t *i = vam->input;
8051   vl_api_ip_route_add_del_t *mp;
8052   u32 vrf_id = 0;
8053   u8 is_add = 1;
8054   u8 is_multipath = 0;
8055   u8 prefix_set = 0;
8056   u8 path_count = 0;
8057   vl_api_prefix_t pfx = { };
8058   vl_api_fib_path_t paths[8];
8059   int count = 1;
8060   int j;
8061   f64 before = 0;
8062   u32 random_add_del = 0;
8063   u32 *random_vector = 0;
8064   u32 random_seed = 0xdeaddabe;
8065
8066   /* Parse args required to build the message */
8067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8068     {
8069       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8070         prefix_set = 1;
8071       else if (unformat (i, "del"))
8072         is_add = 0;
8073       else if (unformat (i, "add"))
8074         is_add = 1;
8075       else if (unformat (i, "vrf %d", &vrf_id))
8076         ;
8077       else if (unformat (i, "count %d", &count))
8078         ;
8079       else if (unformat (i, "random"))
8080         random_add_del = 1;
8081       else if (unformat (i, "multipath"))
8082         is_multipath = 1;
8083       else if (unformat (i, "seed %d", &random_seed))
8084         ;
8085       else
8086         if (unformat
8087             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8088         {
8089           path_count++;
8090           if (8 == path_count)
8091             {
8092               errmsg ("max 8 paths");
8093               return -99;
8094             }
8095         }
8096       else
8097         {
8098           clib_warning ("parse error '%U'", format_unformat_error, i);
8099           return -99;
8100         }
8101     }
8102
8103   if (!path_count)
8104     {
8105       errmsg ("specify a path; via ...");
8106       return -99;
8107     }
8108   if (prefix_set == 0)
8109     {
8110       errmsg ("missing prefix");
8111       return -99;
8112     }
8113
8114   /* Generate a pile of unique, random routes */
8115   if (random_add_del)
8116     {
8117       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8118       u32 this_random_address;
8119       uword *random_hash;
8120
8121       random_hash = hash_create (count, sizeof (uword));
8122
8123       hash_set (random_hash, i->as_u32, 1);
8124       for (j = 0; j <= count; j++)
8125         {
8126           do
8127             {
8128               this_random_address = random_u32 (&random_seed);
8129               this_random_address =
8130                 clib_host_to_net_u32 (this_random_address);
8131             }
8132           while (hash_get (random_hash, this_random_address));
8133           vec_add1 (random_vector, this_random_address);
8134           hash_set (random_hash, this_random_address, 1);
8135         }
8136       hash_free (random_hash);
8137       set_ip4_address (&pfx.address, random_vector[0]);
8138     }
8139
8140   if (count > 1)
8141     {
8142       /* Turn on async mode */
8143       vam->async_mode = 1;
8144       vam->async_errors = 0;
8145       before = vat_time_now (vam);
8146     }
8147
8148   for (j = 0; j < count; j++)
8149     {
8150       /* Construct the API message */
8151       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8152
8153       mp->is_add = is_add;
8154       mp->is_multipath = is_multipath;
8155
8156       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8157       mp->route.table_id = ntohl (vrf_id);
8158       mp->route.n_paths = path_count;
8159
8160       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8161
8162       if (random_add_del)
8163         set_ip4_address (&pfx.address, random_vector[j + 1]);
8164       else
8165         increment_address (&pfx.address);
8166       /* send it... */
8167       S (mp);
8168       /* If we receive SIGTERM, stop now... */
8169       if (vam->do_exit)
8170         break;
8171     }
8172
8173   /* When testing multiple add/del ops, use a control-ping to sync */
8174   if (count > 1)
8175     {
8176       vl_api_control_ping_t *mp_ping;
8177       f64 after;
8178       f64 timeout;
8179
8180       /* Shut off async mode */
8181       vam->async_mode = 0;
8182
8183       MPING (CONTROL_PING, mp_ping);
8184       S (mp_ping);
8185
8186       timeout = vat_time_now (vam) + 1.0;
8187       while (vat_time_now (vam) < timeout)
8188         if (vam->result_ready == 1)
8189           goto out;
8190       vam->retval = -99;
8191
8192     out:
8193       if (vam->retval == -99)
8194         errmsg ("timeout");
8195
8196       if (vam->async_errors > 0)
8197         {
8198           errmsg ("%d asynchronous errors", vam->async_errors);
8199           vam->retval = -98;
8200         }
8201       vam->async_errors = 0;
8202       after = vat_time_now (vam);
8203
8204       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8205       if (j > 0)
8206         count = j;
8207
8208       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8209              count, after - before, count / (after - before));
8210     }
8211   else
8212     {
8213       int ret;
8214
8215       /* Wait for a reply... */
8216       W (ret);
8217       return ret;
8218     }
8219
8220   /* Return the good/bad news */
8221   return (vam->retval);
8222 }
8223
8224 static int
8225 api_ip_mroute_add_del (vat_main_t * vam)
8226 {
8227   unformat_input_t *i = vam->input;
8228   u8 path_set = 0, prefix_set = 0, is_add = 1;
8229   vl_api_ip_mroute_add_del_t *mp;
8230   mfib_entry_flags_t eflags = 0;
8231   vl_api_mfib_path_t path;
8232   vl_api_mprefix_t pfx = { };
8233   u32 vrf_id = 0;
8234   int ret;
8235
8236   /* Parse args required to build the message */
8237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8238     {
8239       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8240         {
8241           prefix_set = 1;
8242           pfx.grp_address_length = htons (pfx.grp_address_length);
8243         }
8244       else if (unformat (i, "del"))
8245         is_add = 0;
8246       else if (unformat (i, "add"))
8247         is_add = 1;
8248       else if (unformat (i, "vrf %d", &vrf_id))
8249         ;
8250       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8251         path.itf_flags = htonl (path.itf_flags);
8252       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8253         ;
8254       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8255         path_set = 1;
8256       else
8257         {
8258           clib_warning ("parse error '%U'", format_unformat_error, i);
8259           return -99;
8260         }
8261     }
8262
8263   if (prefix_set == 0)
8264     {
8265       errmsg ("missing addresses\n");
8266       return -99;
8267     }
8268   if (path_set == 0)
8269     {
8270       errmsg ("missing path\n");
8271       return -99;
8272     }
8273
8274   /* Construct the API message */
8275   M (IP_MROUTE_ADD_DEL, mp);
8276
8277   mp->is_add = is_add;
8278   mp->is_multipath = 1;
8279
8280   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8281   mp->route.table_id = htonl (vrf_id);
8282   mp->route.n_paths = 1;
8283   mp->route.entry_flags = htonl (eflags);
8284
8285   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8286
8287   /* send it... */
8288   S (mp);
8289   /* Wait for a reply... */
8290   W (ret);
8291   return ret;
8292 }
8293
8294 static int
8295 api_mpls_table_add_del (vat_main_t * vam)
8296 {
8297   unformat_input_t *i = vam->input;
8298   vl_api_mpls_table_add_del_t *mp;
8299   u32 table_id = ~0;
8300   u8 is_add = 1;
8301   int ret = 0;
8302
8303   /* Parse args required to build the message */
8304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8305     {
8306       if (unformat (i, "table %d", &table_id))
8307         ;
8308       else if (unformat (i, "del"))
8309         is_add = 0;
8310       else if (unformat (i, "add"))
8311         is_add = 1;
8312       else
8313         {
8314           clib_warning ("parse error '%U'", format_unformat_error, i);
8315           return -99;
8316         }
8317     }
8318
8319   if (~0 == table_id)
8320     {
8321       errmsg ("missing table-ID");
8322       return -99;
8323     }
8324
8325   /* Construct the API message */
8326   M (MPLS_TABLE_ADD_DEL, mp);
8327
8328   mp->mt_table.mt_table_id = ntohl (table_id);
8329   mp->mt_is_add = is_add;
8330
8331   /* send it... */
8332   S (mp);
8333
8334   /* Wait for a reply... */
8335   W (ret);
8336
8337   return ret;
8338 }
8339
8340 static int
8341 api_mpls_route_add_del (vat_main_t * vam)
8342 {
8343   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8344   mpls_label_t local_label = MPLS_LABEL_INVALID;
8345   unformat_input_t *i = vam->input;
8346   vl_api_mpls_route_add_del_t *mp;
8347   vl_api_fib_path_t paths[8];
8348   int count = 1, j;
8349   f64 before = 0;
8350
8351   /* Parse args required to build the message */
8352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8353     {
8354       if (unformat (i, "%d", &local_label))
8355         ;
8356       else if (unformat (i, "eos"))
8357         is_eos = 1;
8358       else if (unformat (i, "non-eos"))
8359         is_eos = 0;
8360       else if (unformat (i, "del"))
8361         is_add = 0;
8362       else if (unformat (i, "add"))
8363         is_add = 1;
8364       else if (unformat (i, "multipath"))
8365         is_multipath = 1;
8366       else if (unformat (i, "count %d", &count))
8367         ;
8368       else
8369         if (unformat
8370             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8371         {
8372           path_count++;
8373           if (8 == path_count)
8374             {
8375               errmsg ("max 8 paths");
8376               return -99;
8377             }
8378         }
8379       else
8380         {
8381           clib_warning ("parse error '%U'", format_unformat_error, i);
8382           return -99;
8383         }
8384     }
8385
8386   if (!path_count)
8387     {
8388       errmsg ("specify a path; via ...");
8389       return -99;
8390     }
8391
8392   if (MPLS_LABEL_INVALID == local_label)
8393     {
8394       errmsg ("missing label");
8395       return -99;
8396     }
8397
8398   if (count > 1)
8399     {
8400       /* Turn on async mode */
8401       vam->async_mode = 1;
8402       vam->async_errors = 0;
8403       before = vat_time_now (vam);
8404     }
8405
8406   for (j = 0; j < count; j++)
8407     {
8408       /* Construct the API message */
8409       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8410
8411       mp->mr_is_add = is_add;
8412       mp->mr_is_multipath = is_multipath;
8413
8414       mp->mr_route.mr_label = local_label;
8415       mp->mr_route.mr_eos = is_eos;
8416       mp->mr_route.mr_table_id = 0;
8417       mp->mr_route.mr_n_paths = path_count;
8418
8419       clib_memcpy (&mp->mr_route.mr_paths, paths,
8420                    sizeof (paths[0]) * path_count);
8421
8422       local_label++;
8423
8424       /* send it... */
8425       S (mp);
8426       /* If we receive SIGTERM, stop now... */
8427       if (vam->do_exit)
8428         break;
8429     }
8430
8431   /* When testing multiple add/del ops, use a control-ping to sync */
8432   if (count > 1)
8433     {
8434       vl_api_control_ping_t *mp_ping;
8435       f64 after;
8436       f64 timeout;
8437
8438       /* Shut off async mode */
8439       vam->async_mode = 0;
8440
8441       MPING (CONTROL_PING, mp_ping);
8442       S (mp_ping);
8443
8444       timeout = vat_time_now (vam) + 1.0;
8445       while (vat_time_now (vam) < timeout)
8446         if (vam->result_ready == 1)
8447           goto out;
8448       vam->retval = -99;
8449
8450     out:
8451       if (vam->retval == -99)
8452         errmsg ("timeout");
8453
8454       if (vam->async_errors > 0)
8455         {
8456           errmsg ("%d asynchronous errors", vam->async_errors);
8457           vam->retval = -98;
8458         }
8459       vam->async_errors = 0;
8460       after = vat_time_now (vam);
8461
8462       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8463       if (j > 0)
8464         count = j;
8465
8466       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8467              count, after - before, count / (after - before));
8468     }
8469   else
8470     {
8471       int ret;
8472
8473       /* Wait for a reply... */
8474       W (ret);
8475       return ret;
8476     }
8477
8478   /* Return the good/bad news */
8479   return (vam->retval);
8480   return (0);
8481 }
8482
8483 static int
8484 api_mpls_ip_bind_unbind (vat_main_t * vam)
8485 {
8486   unformat_input_t *i = vam->input;
8487   vl_api_mpls_ip_bind_unbind_t *mp;
8488   u32 ip_table_id = 0;
8489   u8 is_bind = 1;
8490   vl_api_prefix_t pfx;
8491   u8 prefix_set = 0;
8492   mpls_label_t local_label = MPLS_LABEL_INVALID;
8493   int ret;
8494
8495   /* Parse args required to build the message */
8496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8497     {
8498       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8499         prefix_set = 1;
8500       else if (unformat (i, "%d", &local_label))
8501         ;
8502       else if (unformat (i, "table-id %d", &ip_table_id))
8503         ;
8504       else if (unformat (i, "unbind"))
8505         is_bind = 0;
8506       else if (unformat (i, "bind"))
8507         is_bind = 1;
8508       else
8509         {
8510           clib_warning ("parse error '%U'", format_unformat_error, i);
8511           return -99;
8512         }
8513     }
8514
8515   if (!prefix_set)
8516     {
8517       errmsg ("IP prefix not set");
8518       return -99;
8519     }
8520
8521   if (MPLS_LABEL_INVALID == local_label)
8522     {
8523       errmsg ("missing label");
8524       return -99;
8525     }
8526
8527   /* Construct the API message */
8528   M (MPLS_IP_BIND_UNBIND, mp);
8529
8530   mp->mb_is_bind = is_bind;
8531   mp->mb_ip_table_id = ntohl (ip_table_id);
8532   mp->mb_mpls_table_id = 0;
8533   mp->mb_label = ntohl (local_label);
8534   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8535
8536   /* send it... */
8537   S (mp);
8538
8539   /* Wait for a reply... */
8540   W (ret);
8541   return ret;
8542   return (0);
8543 }
8544
8545 static int
8546 api_sr_mpls_policy_add (vat_main_t * vam)
8547 {
8548   unformat_input_t *i = vam->input;
8549   vl_api_sr_mpls_policy_add_t *mp;
8550   u32 bsid = 0;
8551   u32 weight = 1;
8552   u8 type = 0;
8553   u8 n_segments = 0;
8554   u32 sid;
8555   u32 *segments = NULL;
8556   int ret;
8557
8558   /* Parse args required to build the message */
8559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8560     {
8561       if (unformat (i, "bsid %d", &bsid))
8562         ;
8563       else if (unformat (i, "weight %d", &weight))
8564         ;
8565       else if (unformat (i, "spray"))
8566         type = 1;
8567       else if (unformat (i, "next %d", &sid))
8568         {
8569           n_segments += 1;
8570           vec_add1 (segments, htonl (sid));
8571         }
8572       else
8573         {
8574           clib_warning ("parse error '%U'", format_unformat_error, i);
8575           return -99;
8576         }
8577     }
8578
8579   if (bsid == 0)
8580     {
8581       errmsg ("bsid not set");
8582       return -99;
8583     }
8584
8585   if (n_segments == 0)
8586     {
8587       errmsg ("no sid in segment stack");
8588       return -99;
8589     }
8590
8591   /* Construct the API message */
8592   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8593
8594   mp->bsid = htonl (bsid);
8595   mp->weight = htonl (weight);
8596   mp->is_spray = type;
8597   mp->n_segments = n_segments;
8598   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8599   vec_free (segments);
8600
8601   /* send it... */
8602   S (mp);
8603
8604   /* Wait for a reply... */
8605   W (ret);
8606   return ret;
8607 }
8608
8609 static int
8610 api_sr_mpls_policy_del (vat_main_t * vam)
8611 {
8612   unformat_input_t *i = vam->input;
8613   vl_api_sr_mpls_policy_del_t *mp;
8614   u32 bsid = 0;
8615   int ret;
8616
8617   /* Parse args required to build the message */
8618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8619     {
8620       if (unformat (i, "bsid %d", &bsid))
8621         ;
8622       else
8623         {
8624           clib_warning ("parse error '%U'", format_unformat_error, i);
8625           return -99;
8626         }
8627     }
8628
8629   if (bsid == 0)
8630     {
8631       errmsg ("bsid not set");
8632       return -99;
8633     }
8634
8635   /* Construct the API message */
8636   M (SR_MPLS_POLICY_DEL, mp);
8637
8638   mp->bsid = htonl (bsid);
8639
8640   /* send it... */
8641   S (mp);
8642
8643   /* Wait for a reply... */
8644   W (ret);
8645   return ret;
8646 }
8647
8648 static int
8649 api_bier_table_add_del (vat_main_t * vam)
8650 {
8651   unformat_input_t *i = vam->input;
8652   vl_api_bier_table_add_del_t *mp;
8653   u8 is_add = 1;
8654   u32 set = 0, sub_domain = 0, hdr_len = 3;
8655   mpls_label_t local_label = MPLS_LABEL_INVALID;
8656   int ret;
8657
8658   /* Parse args required to build the message */
8659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8660     {
8661       if (unformat (i, "sub-domain %d", &sub_domain))
8662         ;
8663       else if (unformat (i, "set %d", &set))
8664         ;
8665       else if (unformat (i, "label %d", &local_label))
8666         ;
8667       else if (unformat (i, "hdr-len %d", &hdr_len))
8668         ;
8669       else if (unformat (i, "add"))
8670         is_add = 1;
8671       else if (unformat (i, "del"))
8672         is_add = 0;
8673       else
8674         {
8675           clib_warning ("parse error '%U'", format_unformat_error, i);
8676           return -99;
8677         }
8678     }
8679
8680   if (MPLS_LABEL_INVALID == local_label)
8681     {
8682       errmsg ("missing label\n");
8683       return -99;
8684     }
8685
8686   /* Construct the API message */
8687   M (BIER_TABLE_ADD_DEL, mp);
8688
8689   mp->bt_is_add = is_add;
8690   mp->bt_label = ntohl (local_label);
8691   mp->bt_tbl_id.bt_set = set;
8692   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8693   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8694
8695   /* send it... */
8696   S (mp);
8697
8698   /* Wait for a reply... */
8699   W (ret);
8700
8701   return (ret);
8702 }
8703
8704 static int
8705 api_bier_route_add_del (vat_main_t * vam)
8706 {
8707   unformat_input_t *i = vam->input;
8708   vl_api_bier_route_add_del_t *mp;
8709   u8 is_add = 1;
8710   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8711   ip4_address_t v4_next_hop_address;
8712   ip6_address_t v6_next_hop_address;
8713   u8 next_hop_set = 0;
8714   u8 next_hop_proto_is_ip4 = 1;
8715   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8716   int ret;
8717
8718   /* Parse args required to build the message */
8719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8720     {
8721       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8722         {
8723           next_hop_proto_is_ip4 = 1;
8724           next_hop_set = 1;
8725         }
8726       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8727         {
8728           next_hop_proto_is_ip4 = 0;
8729           next_hop_set = 1;
8730         }
8731       if (unformat (i, "sub-domain %d", &sub_domain))
8732         ;
8733       else if (unformat (i, "set %d", &set))
8734         ;
8735       else if (unformat (i, "hdr-len %d", &hdr_len))
8736         ;
8737       else if (unformat (i, "bp %d", &bp))
8738         ;
8739       else if (unformat (i, "add"))
8740         is_add = 1;
8741       else if (unformat (i, "del"))
8742         is_add = 0;
8743       else if (unformat (i, "out-label %d", &next_hop_out_label))
8744         ;
8745       else
8746         {
8747           clib_warning ("parse error '%U'", format_unformat_error, i);
8748           return -99;
8749         }
8750     }
8751
8752   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8753     {
8754       errmsg ("next hop / label set\n");
8755       return -99;
8756     }
8757   if (0 == bp)
8758     {
8759       errmsg ("bit=position not set\n");
8760       return -99;
8761     }
8762
8763   /* Construct the API message */
8764   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8765
8766   mp->br_is_add = is_add;
8767   mp->br_route.br_tbl_id.bt_set = set;
8768   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8769   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8770   mp->br_route.br_bp = ntohs (bp);
8771   mp->br_route.br_n_paths = 1;
8772   mp->br_route.br_paths[0].n_labels = 1;
8773   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8774   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8775                                     FIB_API_PATH_NH_PROTO_IP4 :
8776                                     FIB_API_PATH_NH_PROTO_IP6);
8777
8778   if (next_hop_proto_is_ip4)
8779     {
8780       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8781                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8782     }
8783   else
8784     {
8785       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8786                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8787     }
8788
8789   /* send it... */
8790   S (mp);
8791
8792   /* Wait for a reply... */
8793   W (ret);
8794
8795   return (ret);
8796 }
8797
8798 static int
8799 api_mpls_tunnel_add_del (vat_main_t * vam)
8800 {
8801   unformat_input_t *i = vam->input;
8802   vl_api_mpls_tunnel_add_del_t *mp;
8803
8804   vl_api_fib_path_t paths[8];
8805   u32 sw_if_index = ~0;
8806   u8 path_count = 0;
8807   u8 l2_only = 0;
8808   u8 is_add = 1;
8809   int ret;
8810
8811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8812     {
8813       if (unformat (i, "add"))
8814         is_add = 1;
8815       else
8816         if (unformat
8817             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8818         is_add = 0;
8819       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8820         is_add = 0;
8821       else if (unformat (i, "l2-only"))
8822         l2_only = 1;
8823       else
8824         if (unformat
8825             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8826         {
8827           path_count++;
8828           if (8 == path_count)
8829             {
8830               errmsg ("max 8 paths");
8831               return -99;
8832             }
8833         }
8834       else
8835         {
8836           clib_warning ("parse error '%U'", format_unformat_error, i);
8837           return -99;
8838         }
8839     }
8840
8841   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8842
8843   mp->mt_is_add = is_add;
8844   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8845   mp->mt_tunnel.mt_l2_only = l2_only;
8846   mp->mt_tunnel.mt_is_multicast = 0;
8847   mp->mt_tunnel.mt_n_paths = path_count;
8848
8849   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8850                sizeof (paths[0]) * path_count);
8851
8852   S (mp);
8853   W (ret);
8854   return ret;
8855 }
8856
8857 static int
8858 api_sw_interface_set_unnumbered (vat_main_t * vam)
8859 {
8860   unformat_input_t *i = vam->input;
8861   vl_api_sw_interface_set_unnumbered_t *mp;
8862   u32 sw_if_index;
8863   u32 unnum_sw_index = ~0;
8864   u8 is_add = 1;
8865   u8 sw_if_index_set = 0;
8866   int ret;
8867
8868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8869     {
8870       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8871         sw_if_index_set = 1;
8872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8873         sw_if_index_set = 1;
8874       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8875         ;
8876       else if (unformat (i, "del"))
8877         is_add = 0;
8878       else
8879         {
8880           clib_warning ("parse error '%U'", format_unformat_error, i);
8881           return -99;
8882         }
8883     }
8884
8885   if (sw_if_index_set == 0)
8886     {
8887       errmsg ("missing interface name or sw_if_index");
8888       return -99;
8889     }
8890
8891   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8892
8893   mp->sw_if_index = ntohl (sw_if_index);
8894   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8895   mp->is_add = is_add;
8896
8897   S (mp);
8898   W (ret);
8899   return ret;
8900 }
8901
8902
8903 static int
8904 api_create_vlan_subif (vat_main_t * vam)
8905 {
8906   unformat_input_t *i = vam->input;
8907   vl_api_create_vlan_subif_t *mp;
8908   u32 sw_if_index;
8909   u8 sw_if_index_set = 0;
8910   u32 vlan_id;
8911   u8 vlan_id_set = 0;
8912   int ret;
8913
8914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8915     {
8916       if (unformat (i, "sw_if_index %d", &sw_if_index))
8917         sw_if_index_set = 1;
8918       else
8919         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8920         sw_if_index_set = 1;
8921       else if (unformat (i, "vlan %d", &vlan_id))
8922         vlan_id_set = 1;
8923       else
8924         {
8925           clib_warning ("parse error '%U'", format_unformat_error, i);
8926           return -99;
8927         }
8928     }
8929
8930   if (sw_if_index_set == 0)
8931     {
8932       errmsg ("missing interface name or sw_if_index");
8933       return -99;
8934     }
8935
8936   if (vlan_id_set == 0)
8937     {
8938       errmsg ("missing vlan_id");
8939       return -99;
8940     }
8941   M (CREATE_VLAN_SUBIF, mp);
8942
8943   mp->sw_if_index = ntohl (sw_if_index);
8944   mp->vlan_id = ntohl (vlan_id);
8945
8946   S (mp);
8947   W (ret);
8948   return ret;
8949 }
8950
8951 #define foreach_create_subif_bit                \
8952 _(no_tags)                                      \
8953 _(one_tag)                                      \
8954 _(two_tags)                                     \
8955 _(dot1ad)                                       \
8956 _(exact_match)                                  \
8957 _(default_sub)                                  \
8958 _(outer_vlan_id_any)                            \
8959 _(inner_vlan_id_any)
8960
8961 #define foreach_create_subif_flag               \
8962 _(0, "no_tags")                                 \
8963 _(1, "one_tag")                                 \
8964 _(2, "two_tags")                                \
8965 _(3, "dot1ad")                                  \
8966 _(4, "exact_match")                             \
8967 _(5, "default_sub")                             \
8968 _(6, "outer_vlan_id_any")                       \
8969 _(7, "inner_vlan_id_any")
8970
8971 static int
8972 api_create_subif (vat_main_t * vam)
8973 {
8974   unformat_input_t *i = vam->input;
8975   vl_api_create_subif_t *mp;
8976   u32 sw_if_index;
8977   u8 sw_if_index_set = 0;
8978   u32 sub_id;
8979   u8 sub_id_set = 0;
8980   u32 __attribute__ ((unused)) no_tags = 0;
8981   u32 __attribute__ ((unused)) one_tag = 0;
8982   u32 __attribute__ ((unused)) two_tags = 0;
8983   u32 __attribute__ ((unused)) dot1ad = 0;
8984   u32 __attribute__ ((unused)) exact_match = 0;
8985   u32 __attribute__ ((unused)) default_sub = 0;
8986   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8987   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8988   u32 tmp;
8989   u16 outer_vlan_id = 0;
8990   u16 inner_vlan_id = 0;
8991   int ret;
8992
8993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8994     {
8995       if (unformat (i, "sw_if_index %d", &sw_if_index))
8996         sw_if_index_set = 1;
8997       else
8998         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8999         sw_if_index_set = 1;
9000       else if (unformat (i, "sub_id %d", &sub_id))
9001         sub_id_set = 1;
9002       else if (unformat (i, "outer_vlan_id %d", &tmp))
9003         outer_vlan_id = tmp;
9004       else if (unformat (i, "inner_vlan_id %d", &tmp))
9005         inner_vlan_id = tmp;
9006
9007 #define _(a) else if (unformat (i, #a)) a = 1 ;
9008       foreach_create_subif_bit
9009 #undef _
9010         else
9011         {
9012           clib_warning ("parse error '%U'", format_unformat_error, i);
9013           return -99;
9014         }
9015     }
9016
9017   if (sw_if_index_set == 0)
9018     {
9019       errmsg ("missing interface name or sw_if_index");
9020       return -99;
9021     }
9022
9023   if (sub_id_set == 0)
9024     {
9025       errmsg ("missing sub_id");
9026       return -99;
9027     }
9028   M (CREATE_SUBIF, mp);
9029
9030   mp->sw_if_index = ntohl (sw_if_index);
9031   mp->sub_id = ntohl (sub_id);
9032
9033 #define _(a,b) mp->sub_if_flags |= (1 << a);
9034   foreach_create_subif_flag;
9035 #undef _
9036
9037   mp->outer_vlan_id = ntohs (outer_vlan_id);
9038   mp->inner_vlan_id = ntohs (inner_vlan_id);
9039
9040   S (mp);
9041   W (ret);
9042   return ret;
9043 }
9044
9045 static int
9046 api_ip_table_replace_begin (vat_main_t * vam)
9047 {
9048   unformat_input_t *i = vam->input;
9049   vl_api_ip_table_replace_begin_t *mp;
9050   u32 table_id = 0;
9051   u8 is_ipv6 = 0;
9052
9053   int ret;
9054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9055     {
9056       if (unformat (i, "table %d", &table_id))
9057         ;
9058       else if (unformat (i, "ipv6"))
9059         is_ipv6 = 1;
9060       else
9061         {
9062           clib_warning ("parse error '%U'", format_unformat_error, i);
9063           return -99;
9064         }
9065     }
9066
9067   M (IP_TABLE_REPLACE_BEGIN, mp);
9068
9069   mp->table.table_id = ntohl (table_id);
9070   mp->table.is_ip6 = is_ipv6;
9071
9072   S (mp);
9073   W (ret);
9074   return ret;
9075 }
9076
9077 static int
9078 api_ip_table_flush (vat_main_t * vam)
9079 {
9080   unformat_input_t *i = vam->input;
9081   vl_api_ip_table_flush_t *mp;
9082   u32 table_id = 0;
9083   u8 is_ipv6 = 0;
9084
9085   int ret;
9086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9087     {
9088       if (unformat (i, "table %d", &table_id))
9089         ;
9090       else if (unformat (i, "ipv6"))
9091         is_ipv6 = 1;
9092       else
9093         {
9094           clib_warning ("parse error '%U'", format_unformat_error, i);
9095           return -99;
9096         }
9097     }
9098
9099   M (IP_TABLE_FLUSH, mp);
9100
9101   mp->table.table_id = ntohl (table_id);
9102   mp->table.is_ip6 = is_ipv6;
9103
9104   S (mp);
9105   W (ret);
9106   return ret;
9107 }
9108
9109 static int
9110 api_ip_table_replace_end (vat_main_t * vam)
9111 {
9112   unformat_input_t *i = vam->input;
9113   vl_api_ip_table_replace_end_t *mp;
9114   u32 table_id = 0;
9115   u8 is_ipv6 = 0;
9116
9117   int ret;
9118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9119     {
9120       if (unformat (i, "table %d", &table_id))
9121         ;
9122       else if (unformat (i, "ipv6"))
9123         is_ipv6 = 1;
9124       else
9125         {
9126           clib_warning ("parse error '%U'", format_unformat_error, i);
9127           return -99;
9128         }
9129     }
9130
9131   M (IP_TABLE_REPLACE_END, mp);
9132
9133   mp->table.table_id = ntohl (table_id);
9134   mp->table.is_ip6 = is_ipv6;
9135
9136   S (mp);
9137   W (ret);
9138   return ret;
9139 }
9140
9141 static int
9142 api_set_ip_flow_hash (vat_main_t * vam)
9143 {
9144   unformat_input_t *i = vam->input;
9145   vl_api_set_ip_flow_hash_t *mp;
9146   u32 vrf_id = 0;
9147   u8 is_ipv6 = 0;
9148   u8 vrf_id_set = 0;
9149   u8 src = 0;
9150   u8 dst = 0;
9151   u8 sport = 0;
9152   u8 dport = 0;
9153   u8 proto = 0;
9154   u8 reverse = 0;
9155   int ret;
9156
9157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9158     {
9159       if (unformat (i, "vrf %d", &vrf_id))
9160         vrf_id_set = 1;
9161       else if (unformat (i, "ipv6"))
9162         is_ipv6 = 1;
9163       else if (unformat (i, "src"))
9164         src = 1;
9165       else if (unformat (i, "dst"))
9166         dst = 1;
9167       else if (unformat (i, "sport"))
9168         sport = 1;
9169       else if (unformat (i, "dport"))
9170         dport = 1;
9171       else if (unformat (i, "proto"))
9172         proto = 1;
9173       else if (unformat (i, "reverse"))
9174         reverse = 1;
9175
9176       else
9177         {
9178           clib_warning ("parse error '%U'", format_unformat_error, i);
9179           return -99;
9180         }
9181     }
9182
9183   if (vrf_id_set == 0)
9184     {
9185       errmsg ("missing vrf id");
9186       return -99;
9187     }
9188
9189   M (SET_IP_FLOW_HASH, mp);
9190   mp->src = src;
9191   mp->dst = dst;
9192   mp->sport = sport;
9193   mp->dport = dport;
9194   mp->proto = proto;
9195   mp->reverse = reverse;
9196   mp->vrf_id = ntohl (vrf_id);
9197   mp->is_ipv6 = is_ipv6;
9198
9199   S (mp);
9200   W (ret);
9201   return ret;
9202 }
9203
9204 static int
9205 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9206 {
9207   unformat_input_t *i = vam->input;
9208   vl_api_sw_interface_ip6_enable_disable_t *mp;
9209   u32 sw_if_index;
9210   u8 sw_if_index_set = 0;
9211   u8 enable = 0;
9212   int ret;
9213
9214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9215     {
9216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9217         sw_if_index_set = 1;
9218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9219         sw_if_index_set = 1;
9220       else if (unformat (i, "enable"))
9221         enable = 1;
9222       else if (unformat (i, "disable"))
9223         enable = 0;
9224       else
9225         {
9226           clib_warning ("parse error '%U'", format_unformat_error, i);
9227           return -99;
9228         }
9229     }
9230
9231   if (sw_if_index_set == 0)
9232     {
9233       errmsg ("missing interface name or sw_if_index");
9234       return -99;
9235     }
9236
9237   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9238
9239   mp->sw_if_index = ntohl (sw_if_index);
9240   mp->enable = enable;
9241
9242   S (mp);
9243   W (ret);
9244   return ret;
9245 }
9246
9247
9248 static int
9249 api_l2_patch_add_del (vat_main_t * vam)
9250 {
9251   unformat_input_t *i = vam->input;
9252   vl_api_l2_patch_add_del_t *mp;
9253   u32 rx_sw_if_index;
9254   u8 rx_sw_if_index_set = 0;
9255   u32 tx_sw_if_index;
9256   u8 tx_sw_if_index_set = 0;
9257   u8 is_add = 1;
9258   int ret;
9259
9260   /* Parse args required to build the message */
9261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9262     {
9263       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9264         rx_sw_if_index_set = 1;
9265       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9266         tx_sw_if_index_set = 1;
9267       else if (unformat (i, "rx"))
9268         {
9269           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9270             {
9271               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9272                             &rx_sw_if_index))
9273                 rx_sw_if_index_set = 1;
9274             }
9275           else
9276             break;
9277         }
9278       else if (unformat (i, "tx"))
9279         {
9280           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9281             {
9282               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9283                             &tx_sw_if_index))
9284                 tx_sw_if_index_set = 1;
9285             }
9286           else
9287             break;
9288         }
9289       else if (unformat (i, "del"))
9290         is_add = 0;
9291       else
9292         break;
9293     }
9294
9295   if (rx_sw_if_index_set == 0)
9296     {
9297       errmsg ("missing rx interface name or rx_sw_if_index");
9298       return -99;
9299     }
9300
9301   if (tx_sw_if_index_set == 0)
9302     {
9303       errmsg ("missing tx interface name or tx_sw_if_index");
9304       return -99;
9305     }
9306
9307   M (L2_PATCH_ADD_DEL, mp);
9308
9309   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9310   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9311   mp->is_add = is_add;
9312
9313   S (mp);
9314   W (ret);
9315   return ret;
9316 }
9317
9318 u8 is_del;
9319 u8 localsid_addr[16];
9320 u8 end_psp;
9321 u8 behavior;
9322 u32 sw_if_index;
9323 u32 vlan_index;
9324 u32 fib_table;
9325 u8 nh_addr[16];
9326
9327 static int
9328 api_sr_localsid_add_del (vat_main_t * vam)
9329 {
9330   unformat_input_t *i = vam->input;
9331   vl_api_sr_localsid_add_del_t *mp;
9332
9333   u8 is_del;
9334   ip6_address_t localsid;
9335   u8 end_psp = 0;
9336   u8 behavior = ~0;
9337   u32 sw_if_index;
9338   u32 fib_table = ~(u32) 0;
9339   ip46_address_t nh_addr;
9340   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9341
9342   bool nexthop_set = 0;
9343
9344   int ret;
9345
9346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9347     {
9348       if (unformat (i, "del"))
9349         is_del = 1;
9350       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9351       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9352         nexthop_set = 1;
9353       else if (unformat (i, "behavior %u", &behavior));
9354       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9355       else if (unformat (i, "fib-table %u", &fib_table));
9356       else if (unformat (i, "end.psp %u", &behavior));
9357       else
9358         break;
9359     }
9360
9361   M (SR_LOCALSID_ADD_DEL, mp);
9362
9363   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9364
9365   if (nexthop_set)
9366     {
9367       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9368     }
9369   mp->behavior = behavior;
9370   mp->sw_if_index = ntohl (sw_if_index);
9371   mp->fib_table = ntohl (fib_table);
9372   mp->end_psp = end_psp;
9373   mp->is_del = is_del;
9374
9375   S (mp);
9376   W (ret);
9377   return ret;
9378 }
9379
9380 static int
9381 api_ioam_enable (vat_main_t * vam)
9382 {
9383   unformat_input_t *input = vam->input;
9384   vl_api_ioam_enable_t *mp;
9385   u32 id = 0;
9386   int has_trace_option = 0;
9387   int has_pot_option = 0;
9388   int has_seqno_option = 0;
9389   int has_analyse_option = 0;
9390   int ret;
9391
9392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9393     {
9394       if (unformat (input, "trace"))
9395         has_trace_option = 1;
9396       else if (unformat (input, "pot"))
9397         has_pot_option = 1;
9398       else if (unformat (input, "seqno"))
9399         has_seqno_option = 1;
9400       else if (unformat (input, "analyse"))
9401         has_analyse_option = 1;
9402       else
9403         break;
9404     }
9405   M (IOAM_ENABLE, mp);
9406   mp->id = htons (id);
9407   mp->seqno = has_seqno_option;
9408   mp->analyse = has_analyse_option;
9409   mp->pot_enable = has_pot_option;
9410   mp->trace_enable = has_trace_option;
9411
9412   S (mp);
9413   W (ret);
9414   return ret;
9415 }
9416
9417
9418 static int
9419 api_ioam_disable (vat_main_t * vam)
9420 {
9421   vl_api_ioam_disable_t *mp;
9422   int ret;
9423
9424   M (IOAM_DISABLE, mp);
9425   S (mp);
9426   W (ret);
9427   return ret;
9428 }
9429
9430 #define foreach_tcp_proto_field                 \
9431 _(src_port)                                     \
9432 _(dst_port)
9433
9434 #define foreach_udp_proto_field                 \
9435 _(src_port)                                     \
9436 _(dst_port)
9437
9438 #define foreach_ip4_proto_field                 \
9439 _(src_address)                                  \
9440 _(dst_address)                                  \
9441 _(tos)                                          \
9442 _(length)                                       \
9443 _(fragment_id)                                  \
9444 _(ttl)                                          \
9445 _(protocol)                                     \
9446 _(checksum)
9447
9448 typedef struct
9449 {
9450   u16 src_port, dst_port;
9451 } tcpudp_header_t;
9452
9453 #if VPP_API_TEST_BUILTIN == 0
9454 uword
9455 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9456 {
9457   u8 **maskp = va_arg (*args, u8 **);
9458   u8 *mask = 0;
9459   u8 found_something = 0;
9460   tcp_header_t *tcp;
9461
9462 #define _(a) u8 a=0;
9463   foreach_tcp_proto_field;
9464 #undef _
9465
9466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9467     {
9468       if (0);
9469 #define _(a) else if (unformat (input, #a)) a=1;
9470       foreach_tcp_proto_field
9471 #undef _
9472         else
9473         break;
9474     }
9475
9476 #define _(a) found_something += a;
9477   foreach_tcp_proto_field;
9478 #undef _
9479
9480   if (found_something == 0)
9481     return 0;
9482
9483   vec_validate (mask, sizeof (*tcp) - 1);
9484
9485   tcp = (tcp_header_t *) mask;
9486
9487 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9488   foreach_tcp_proto_field;
9489 #undef _
9490
9491   *maskp = mask;
9492   return 1;
9493 }
9494
9495 uword
9496 unformat_udp_mask (unformat_input_t * input, va_list * args)
9497 {
9498   u8 **maskp = va_arg (*args, u8 **);
9499   u8 *mask = 0;
9500   u8 found_something = 0;
9501   udp_header_t *udp;
9502
9503 #define _(a) u8 a=0;
9504   foreach_udp_proto_field;
9505 #undef _
9506
9507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9508     {
9509       if (0);
9510 #define _(a) else if (unformat (input, #a)) a=1;
9511       foreach_udp_proto_field
9512 #undef _
9513         else
9514         break;
9515     }
9516
9517 #define _(a) found_something += a;
9518   foreach_udp_proto_field;
9519 #undef _
9520
9521   if (found_something == 0)
9522     return 0;
9523
9524   vec_validate (mask, sizeof (*udp) - 1);
9525
9526   udp = (udp_header_t *) mask;
9527
9528 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9529   foreach_udp_proto_field;
9530 #undef _
9531
9532   *maskp = mask;
9533   return 1;
9534 }
9535
9536 uword
9537 unformat_l4_mask (unformat_input_t * input, va_list * args)
9538 {
9539   u8 **maskp = va_arg (*args, u8 **);
9540   u16 src_port = 0, dst_port = 0;
9541   tcpudp_header_t *tcpudp;
9542
9543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9544     {
9545       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9546         return 1;
9547       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9548         return 1;
9549       else if (unformat (input, "src_port"))
9550         src_port = 0xFFFF;
9551       else if (unformat (input, "dst_port"))
9552         dst_port = 0xFFFF;
9553       else
9554         return 0;
9555     }
9556
9557   if (!src_port && !dst_port)
9558     return 0;
9559
9560   u8 *mask = 0;
9561   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9562
9563   tcpudp = (tcpudp_header_t *) mask;
9564   tcpudp->src_port = src_port;
9565   tcpudp->dst_port = dst_port;
9566
9567   *maskp = mask;
9568
9569   return 1;
9570 }
9571
9572 uword
9573 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9574 {
9575   u8 **maskp = va_arg (*args, u8 **);
9576   u8 *mask = 0;
9577   u8 found_something = 0;
9578   ip4_header_t *ip;
9579
9580 #define _(a) u8 a=0;
9581   foreach_ip4_proto_field;
9582 #undef _
9583   u8 version = 0;
9584   u8 hdr_length = 0;
9585
9586
9587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9588     {
9589       if (unformat (input, "version"))
9590         version = 1;
9591       else if (unformat (input, "hdr_length"))
9592         hdr_length = 1;
9593       else if (unformat (input, "src"))
9594         src_address = 1;
9595       else if (unformat (input, "dst"))
9596         dst_address = 1;
9597       else if (unformat (input, "proto"))
9598         protocol = 1;
9599
9600 #define _(a) else if (unformat (input, #a)) a=1;
9601       foreach_ip4_proto_field
9602 #undef _
9603         else
9604         break;
9605     }
9606
9607 #define _(a) found_something += a;
9608   foreach_ip4_proto_field;
9609 #undef _
9610
9611   if (found_something == 0)
9612     return 0;
9613
9614   vec_validate (mask, sizeof (*ip) - 1);
9615
9616   ip = (ip4_header_t *) mask;
9617
9618 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9619   foreach_ip4_proto_field;
9620 #undef _
9621
9622   ip->ip_version_and_header_length = 0;
9623
9624   if (version)
9625     ip->ip_version_and_header_length |= 0xF0;
9626
9627   if (hdr_length)
9628     ip->ip_version_and_header_length |= 0x0F;
9629
9630   *maskp = mask;
9631   return 1;
9632 }
9633
9634 #define foreach_ip6_proto_field                 \
9635 _(src_address)                                  \
9636 _(dst_address)                                  \
9637 _(payload_length)                               \
9638 _(hop_limit)                                    \
9639 _(protocol)
9640
9641 uword
9642 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9643 {
9644   u8 **maskp = va_arg (*args, u8 **);
9645   u8 *mask = 0;
9646   u8 found_something = 0;
9647   ip6_header_t *ip;
9648   u32 ip_version_traffic_class_and_flow_label;
9649
9650 #define _(a) u8 a=0;
9651   foreach_ip6_proto_field;
9652 #undef _
9653   u8 version = 0;
9654   u8 traffic_class = 0;
9655   u8 flow_label = 0;
9656
9657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9658     {
9659       if (unformat (input, "version"))
9660         version = 1;
9661       else if (unformat (input, "traffic-class"))
9662         traffic_class = 1;
9663       else if (unformat (input, "flow-label"))
9664         flow_label = 1;
9665       else if (unformat (input, "src"))
9666         src_address = 1;
9667       else if (unformat (input, "dst"))
9668         dst_address = 1;
9669       else if (unformat (input, "proto"))
9670         protocol = 1;
9671
9672 #define _(a) else if (unformat (input, #a)) a=1;
9673       foreach_ip6_proto_field
9674 #undef _
9675         else
9676         break;
9677     }
9678
9679 #define _(a) found_something += a;
9680   foreach_ip6_proto_field;
9681 #undef _
9682
9683   if (found_something == 0)
9684     return 0;
9685
9686   vec_validate (mask, sizeof (*ip) - 1);
9687
9688   ip = (ip6_header_t *) mask;
9689
9690 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9691   foreach_ip6_proto_field;
9692 #undef _
9693
9694   ip_version_traffic_class_and_flow_label = 0;
9695
9696   if (version)
9697     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9698
9699   if (traffic_class)
9700     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9701
9702   if (flow_label)
9703     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9704
9705   ip->ip_version_traffic_class_and_flow_label =
9706     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9707
9708   *maskp = mask;
9709   return 1;
9710 }
9711
9712 uword
9713 unformat_l3_mask (unformat_input_t * input, va_list * args)
9714 {
9715   u8 **maskp = va_arg (*args, u8 **);
9716
9717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9718     {
9719       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9720         return 1;
9721       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9722         return 1;
9723       else
9724         break;
9725     }
9726   return 0;
9727 }
9728
9729 uword
9730 unformat_l2_mask (unformat_input_t * input, va_list * args)
9731 {
9732   u8 **maskp = va_arg (*args, u8 **);
9733   u8 *mask = 0;
9734   u8 src = 0;
9735   u8 dst = 0;
9736   u8 proto = 0;
9737   u8 tag1 = 0;
9738   u8 tag2 = 0;
9739   u8 ignore_tag1 = 0;
9740   u8 ignore_tag2 = 0;
9741   u8 cos1 = 0;
9742   u8 cos2 = 0;
9743   u8 dot1q = 0;
9744   u8 dot1ad = 0;
9745   int len = 14;
9746
9747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9748     {
9749       if (unformat (input, "src"))
9750         src = 1;
9751       else if (unformat (input, "dst"))
9752         dst = 1;
9753       else if (unformat (input, "proto"))
9754         proto = 1;
9755       else if (unformat (input, "tag1"))
9756         tag1 = 1;
9757       else if (unformat (input, "tag2"))
9758         tag2 = 1;
9759       else if (unformat (input, "ignore-tag1"))
9760         ignore_tag1 = 1;
9761       else if (unformat (input, "ignore-tag2"))
9762         ignore_tag2 = 1;
9763       else if (unformat (input, "cos1"))
9764         cos1 = 1;
9765       else if (unformat (input, "cos2"))
9766         cos2 = 1;
9767       else if (unformat (input, "dot1q"))
9768         dot1q = 1;
9769       else if (unformat (input, "dot1ad"))
9770         dot1ad = 1;
9771       else
9772         break;
9773     }
9774   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9775        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9776     return 0;
9777
9778   if (tag1 || ignore_tag1 || cos1 || dot1q)
9779     len = 18;
9780   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9781     len = 22;
9782
9783   vec_validate (mask, len - 1);
9784
9785   if (dst)
9786     clib_memset (mask, 0xff, 6);
9787
9788   if (src)
9789     clib_memset (mask + 6, 0xff, 6);
9790
9791   if (tag2 || dot1ad)
9792     {
9793       /* inner vlan tag */
9794       if (tag2)
9795         {
9796           mask[19] = 0xff;
9797           mask[18] = 0x0f;
9798         }
9799       if (cos2)
9800         mask[18] |= 0xe0;
9801       if (proto)
9802         mask[21] = mask[20] = 0xff;
9803       if (tag1)
9804         {
9805           mask[15] = 0xff;
9806           mask[14] = 0x0f;
9807         }
9808       if (cos1)
9809         mask[14] |= 0xe0;
9810       *maskp = mask;
9811       return 1;
9812     }
9813   if (tag1 | dot1q)
9814     {
9815       if (tag1)
9816         {
9817           mask[15] = 0xff;
9818           mask[14] = 0x0f;
9819         }
9820       if (cos1)
9821         mask[14] |= 0xe0;
9822       if (proto)
9823         mask[16] = mask[17] = 0xff;
9824
9825       *maskp = mask;
9826       return 1;
9827     }
9828   if (cos2)
9829     mask[18] |= 0xe0;
9830   if (cos1)
9831     mask[14] |= 0xe0;
9832   if (proto)
9833     mask[12] = mask[13] = 0xff;
9834
9835   *maskp = mask;
9836   return 1;
9837 }
9838
9839 uword
9840 unformat_classify_mask (unformat_input_t * input, va_list * args)
9841 {
9842   u8 **maskp = va_arg (*args, u8 **);
9843   u32 *skipp = va_arg (*args, u32 *);
9844   u32 *matchp = va_arg (*args, u32 *);
9845   u32 match;
9846   u8 *mask = 0;
9847   u8 *l2 = 0;
9848   u8 *l3 = 0;
9849   u8 *l4 = 0;
9850   int i;
9851
9852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9853     {
9854       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9855         ;
9856       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9857         ;
9858       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9859         ;
9860       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9861         ;
9862       else
9863         break;
9864     }
9865
9866   if (l4 && !l3)
9867     {
9868       vec_free (mask);
9869       vec_free (l2);
9870       vec_free (l4);
9871       return 0;
9872     }
9873
9874   if (mask || l2 || l3 || l4)
9875     {
9876       if (l2 || l3 || l4)
9877         {
9878           /* "With a free Ethernet header in every package" */
9879           if (l2 == 0)
9880             vec_validate (l2, 13);
9881           mask = l2;
9882           if (vec_len (l3))
9883             {
9884               vec_append (mask, l3);
9885               vec_free (l3);
9886             }
9887           if (vec_len (l4))
9888             {
9889               vec_append (mask, l4);
9890               vec_free (l4);
9891             }
9892         }
9893
9894       /* Scan forward looking for the first significant mask octet */
9895       for (i = 0; i < vec_len (mask); i++)
9896         if (mask[i])
9897           break;
9898
9899       /* compute (skip, match) params */
9900       *skipp = i / sizeof (u32x4);
9901       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9902
9903       /* Pad mask to an even multiple of the vector size */
9904       while (vec_len (mask) % sizeof (u32x4))
9905         vec_add1 (mask, 0);
9906
9907       match = vec_len (mask) / sizeof (u32x4);
9908
9909       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9910         {
9911           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9912           if (*tmp || *(tmp + 1))
9913             break;
9914           match--;
9915         }
9916       if (match == 0)
9917         clib_warning ("BUG: match 0");
9918
9919       _vec_len (mask) = match * sizeof (u32x4);
9920
9921       *matchp = match;
9922       *maskp = mask;
9923
9924       return 1;
9925     }
9926
9927   return 0;
9928 }
9929 #endif /* VPP_API_TEST_BUILTIN */
9930
9931 #define foreach_l2_next                         \
9932 _(drop, DROP)                                   \
9933 _(ethernet, ETHERNET_INPUT)                     \
9934 _(ip4, IP4_INPUT)                               \
9935 _(ip6, IP6_INPUT)
9936
9937 uword
9938 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9939 {
9940   u32 *miss_next_indexp = va_arg (*args, u32 *);
9941   u32 next_index = 0;
9942   u32 tmp;
9943
9944 #define _(n,N) \
9945   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9946   foreach_l2_next;
9947 #undef _
9948
9949   if (unformat (input, "%d", &tmp))
9950     {
9951       next_index = tmp;
9952       goto out;
9953     }
9954
9955   return 0;
9956
9957 out:
9958   *miss_next_indexp = next_index;
9959   return 1;
9960 }
9961
9962 #define foreach_ip_next                         \
9963 _(drop, DROP)                                   \
9964 _(local, LOCAL)                                 \
9965 _(rewrite, REWRITE)
9966
9967 uword
9968 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9969 {
9970   u32 *miss_next_indexp = va_arg (*args, u32 *);
9971   u32 next_index = 0;
9972   u32 tmp;
9973
9974 #define _(n,N) \
9975   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9976   foreach_ip_next;
9977 #undef _
9978
9979   if (unformat (input, "%d", &tmp))
9980     {
9981       next_index = tmp;
9982       goto out;
9983     }
9984
9985   return 0;
9986
9987 out:
9988   *miss_next_indexp = next_index;
9989   return 1;
9990 }
9991
9992 #define foreach_acl_next                        \
9993 _(deny, DENY)
9994
9995 uword
9996 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9997 {
9998   u32 *miss_next_indexp = va_arg (*args, u32 *);
9999   u32 next_index = 0;
10000   u32 tmp;
10001
10002 #define _(n,N) \
10003   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10004   foreach_acl_next;
10005 #undef _
10006
10007   if (unformat (input, "permit"))
10008     {
10009       next_index = ~0;
10010       goto out;
10011     }
10012   else if (unformat (input, "%d", &tmp))
10013     {
10014       next_index = tmp;
10015       goto out;
10016     }
10017
10018   return 0;
10019
10020 out:
10021   *miss_next_indexp = next_index;
10022   return 1;
10023 }
10024
10025 uword
10026 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10027 {
10028   u32 *r = va_arg (*args, u32 *);
10029
10030   if (unformat (input, "conform-color"))
10031     *r = POLICE_CONFORM;
10032   else if (unformat (input, "exceed-color"))
10033     *r = POLICE_EXCEED;
10034   else
10035     return 0;
10036
10037   return 1;
10038 }
10039
10040 static int
10041 api_classify_add_del_table (vat_main_t * vam)
10042 {
10043   unformat_input_t *i = vam->input;
10044   vl_api_classify_add_del_table_t *mp;
10045
10046   u32 nbuckets = 2;
10047   u32 skip = ~0;
10048   u32 match = ~0;
10049   int is_add = 1;
10050   int del_chain = 0;
10051   u32 table_index = ~0;
10052   u32 next_table_index = ~0;
10053   u32 miss_next_index = ~0;
10054   u32 memory_size = 32 << 20;
10055   u8 *mask = 0;
10056   u32 current_data_flag = 0;
10057   int current_data_offset = 0;
10058   int ret;
10059
10060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10061     {
10062       if (unformat (i, "del"))
10063         is_add = 0;
10064       else if (unformat (i, "del-chain"))
10065         {
10066           is_add = 0;
10067           del_chain = 1;
10068         }
10069       else if (unformat (i, "buckets %d", &nbuckets))
10070         ;
10071       else if (unformat (i, "memory_size %d", &memory_size))
10072         ;
10073       else if (unformat (i, "skip %d", &skip))
10074         ;
10075       else if (unformat (i, "match %d", &match))
10076         ;
10077       else if (unformat (i, "table %d", &table_index))
10078         ;
10079       else if (unformat (i, "mask %U", unformat_classify_mask,
10080                          &mask, &skip, &match))
10081         ;
10082       else if (unformat (i, "next-table %d", &next_table_index))
10083         ;
10084       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10085                          &miss_next_index))
10086         ;
10087       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10088                          &miss_next_index))
10089         ;
10090       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10091                          &miss_next_index))
10092         ;
10093       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10094         ;
10095       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10096         ;
10097       else
10098         break;
10099     }
10100
10101   if (is_add && mask == 0)
10102     {
10103       errmsg ("Mask required");
10104       return -99;
10105     }
10106
10107   if (is_add && skip == ~0)
10108     {
10109       errmsg ("skip count required");
10110       return -99;
10111     }
10112
10113   if (is_add && match == ~0)
10114     {
10115       errmsg ("match count required");
10116       return -99;
10117     }
10118
10119   if (!is_add && table_index == ~0)
10120     {
10121       errmsg ("table index required for delete");
10122       return -99;
10123     }
10124
10125   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10126
10127   mp->is_add = is_add;
10128   mp->del_chain = del_chain;
10129   mp->table_index = ntohl (table_index);
10130   mp->nbuckets = ntohl (nbuckets);
10131   mp->memory_size = ntohl (memory_size);
10132   mp->skip_n_vectors = ntohl (skip);
10133   mp->match_n_vectors = ntohl (match);
10134   mp->next_table_index = ntohl (next_table_index);
10135   mp->miss_next_index = ntohl (miss_next_index);
10136   mp->current_data_flag = ntohl (current_data_flag);
10137   mp->current_data_offset = ntohl (current_data_offset);
10138   mp->mask_len = ntohl (vec_len (mask));
10139   clib_memcpy (mp->mask, mask, vec_len (mask));
10140
10141   vec_free (mask);
10142
10143   S (mp);
10144   W (ret);
10145   return ret;
10146 }
10147
10148 #if VPP_API_TEST_BUILTIN == 0
10149 uword
10150 unformat_l4_match (unformat_input_t * input, va_list * args)
10151 {
10152   u8 **matchp = va_arg (*args, u8 **);
10153
10154   u8 *proto_header = 0;
10155   int src_port = 0;
10156   int dst_port = 0;
10157
10158   tcpudp_header_t h;
10159
10160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10161     {
10162       if (unformat (input, "src_port %d", &src_port))
10163         ;
10164       else if (unformat (input, "dst_port %d", &dst_port))
10165         ;
10166       else
10167         return 0;
10168     }
10169
10170   h.src_port = clib_host_to_net_u16 (src_port);
10171   h.dst_port = clib_host_to_net_u16 (dst_port);
10172   vec_validate (proto_header, sizeof (h) - 1);
10173   memcpy (proto_header, &h, sizeof (h));
10174
10175   *matchp = proto_header;
10176
10177   return 1;
10178 }
10179
10180 uword
10181 unformat_ip4_match (unformat_input_t * input, va_list * args)
10182 {
10183   u8 **matchp = va_arg (*args, u8 **);
10184   u8 *match = 0;
10185   ip4_header_t *ip;
10186   int version = 0;
10187   u32 version_val;
10188   int hdr_length = 0;
10189   u32 hdr_length_val;
10190   int src = 0, dst = 0;
10191   ip4_address_t src_val, dst_val;
10192   int proto = 0;
10193   u32 proto_val;
10194   int tos = 0;
10195   u32 tos_val;
10196   int length = 0;
10197   u32 length_val;
10198   int fragment_id = 0;
10199   u32 fragment_id_val;
10200   int ttl = 0;
10201   int ttl_val;
10202   int checksum = 0;
10203   u32 checksum_val;
10204
10205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10206     {
10207       if (unformat (input, "version %d", &version_val))
10208         version = 1;
10209       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10210         hdr_length = 1;
10211       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10212         src = 1;
10213       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10214         dst = 1;
10215       else if (unformat (input, "proto %d", &proto_val))
10216         proto = 1;
10217       else if (unformat (input, "tos %d", &tos_val))
10218         tos = 1;
10219       else if (unformat (input, "length %d", &length_val))
10220         length = 1;
10221       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10222         fragment_id = 1;
10223       else if (unformat (input, "ttl %d", &ttl_val))
10224         ttl = 1;
10225       else if (unformat (input, "checksum %d", &checksum_val))
10226         checksum = 1;
10227       else
10228         break;
10229     }
10230
10231   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10232       + ttl + checksum == 0)
10233     return 0;
10234
10235   /*
10236    * Aligned because we use the real comparison functions
10237    */
10238   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10239
10240   ip = (ip4_header_t *) match;
10241
10242   /* These are realistically matched in practice */
10243   if (src)
10244     ip->src_address.as_u32 = src_val.as_u32;
10245
10246   if (dst)
10247     ip->dst_address.as_u32 = dst_val.as_u32;
10248
10249   if (proto)
10250     ip->protocol = proto_val;
10251
10252
10253   /* These are not, but they're included for completeness */
10254   if (version)
10255     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10256
10257   if (hdr_length)
10258     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10259
10260   if (tos)
10261     ip->tos = tos_val;
10262
10263   if (length)
10264     ip->length = clib_host_to_net_u16 (length_val);
10265
10266   if (ttl)
10267     ip->ttl = ttl_val;
10268
10269   if (checksum)
10270     ip->checksum = clib_host_to_net_u16 (checksum_val);
10271
10272   *matchp = match;
10273   return 1;
10274 }
10275
10276 uword
10277 unformat_ip6_match (unformat_input_t * input, va_list * args)
10278 {
10279   u8 **matchp = va_arg (*args, u8 **);
10280   u8 *match = 0;
10281   ip6_header_t *ip;
10282   int version = 0;
10283   u32 version_val;
10284   u8 traffic_class = 0;
10285   u32 traffic_class_val = 0;
10286   u8 flow_label = 0;
10287   u8 flow_label_val;
10288   int src = 0, dst = 0;
10289   ip6_address_t src_val, dst_val;
10290   int proto = 0;
10291   u32 proto_val;
10292   int payload_length = 0;
10293   u32 payload_length_val;
10294   int hop_limit = 0;
10295   int hop_limit_val;
10296   u32 ip_version_traffic_class_and_flow_label;
10297
10298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10299     {
10300       if (unformat (input, "version %d", &version_val))
10301         version = 1;
10302       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10303         traffic_class = 1;
10304       else if (unformat (input, "flow_label %d", &flow_label_val))
10305         flow_label = 1;
10306       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10307         src = 1;
10308       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10309         dst = 1;
10310       else if (unformat (input, "proto %d", &proto_val))
10311         proto = 1;
10312       else if (unformat (input, "payload_length %d", &payload_length_val))
10313         payload_length = 1;
10314       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10315         hop_limit = 1;
10316       else
10317         break;
10318     }
10319
10320   if (version + traffic_class + flow_label + src + dst + proto +
10321       payload_length + hop_limit == 0)
10322     return 0;
10323
10324   /*
10325    * Aligned because we use the real comparison functions
10326    */
10327   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10328
10329   ip = (ip6_header_t *) match;
10330
10331   if (src)
10332     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10333
10334   if (dst)
10335     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10336
10337   if (proto)
10338     ip->protocol = proto_val;
10339
10340   ip_version_traffic_class_and_flow_label = 0;
10341
10342   if (version)
10343     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10344
10345   if (traffic_class)
10346     ip_version_traffic_class_and_flow_label |=
10347       (traffic_class_val & 0xFF) << 20;
10348
10349   if (flow_label)
10350     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10351
10352   ip->ip_version_traffic_class_and_flow_label =
10353     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10354
10355   if (payload_length)
10356     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10357
10358   if (hop_limit)
10359     ip->hop_limit = hop_limit_val;
10360
10361   *matchp = match;
10362   return 1;
10363 }
10364
10365 uword
10366 unformat_l3_match (unformat_input_t * input, va_list * args)
10367 {
10368   u8 **matchp = va_arg (*args, u8 **);
10369
10370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10371     {
10372       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10373         return 1;
10374       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10375         return 1;
10376       else
10377         break;
10378     }
10379   return 0;
10380 }
10381
10382 uword
10383 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10384 {
10385   u8 *tagp = va_arg (*args, u8 *);
10386   u32 tag;
10387
10388   if (unformat (input, "%d", &tag))
10389     {
10390       tagp[0] = (tag >> 8) & 0x0F;
10391       tagp[1] = tag & 0xFF;
10392       return 1;
10393     }
10394
10395   return 0;
10396 }
10397
10398 uword
10399 unformat_l2_match (unformat_input_t * input, va_list * args)
10400 {
10401   u8 **matchp = va_arg (*args, u8 **);
10402   u8 *match = 0;
10403   u8 src = 0;
10404   u8 src_val[6];
10405   u8 dst = 0;
10406   u8 dst_val[6];
10407   u8 proto = 0;
10408   u16 proto_val;
10409   u8 tag1 = 0;
10410   u8 tag1_val[2];
10411   u8 tag2 = 0;
10412   u8 tag2_val[2];
10413   int len = 14;
10414   u8 ignore_tag1 = 0;
10415   u8 ignore_tag2 = 0;
10416   u8 cos1 = 0;
10417   u8 cos2 = 0;
10418   u32 cos1_val = 0;
10419   u32 cos2_val = 0;
10420
10421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10422     {
10423       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10424         src = 1;
10425       else
10426         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10427         dst = 1;
10428       else if (unformat (input, "proto %U",
10429                          unformat_ethernet_type_host_byte_order, &proto_val))
10430         proto = 1;
10431       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10432         tag1 = 1;
10433       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10434         tag2 = 1;
10435       else if (unformat (input, "ignore-tag1"))
10436         ignore_tag1 = 1;
10437       else if (unformat (input, "ignore-tag2"))
10438         ignore_tag2 = 1;
10439       else if (unformat (input, "cos1 %d", &cos1_val))
10440         cos1 = 1;
10441       else if (unformat (input, "cos2 %d", &cos2_val))
10442         cos2 = 1;
10443       else
10444         break;
10445     }
10446   if ((src + dst + proto + tag1 + tag2 +
10447        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10448     return 0;
10449
10450   if (tag1 || ignore_tag1 || cos1)
10451     len = 18;
10452   if (tag2 || ignore_tag2 || cos2)
10453     len = 22;
10454
10455   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10456
10457   if (dst)
10458     clib_memcpy (match, dst_val, 6);
10459
10460   if (src)
10461     clib_memcpy (match + 6, src_val, 6);
10462
10463   if (tag2)
10464     {
10465       /* inner vlan tag */
10466       match[19] = tag2_val[1];
10467       match[18] = tag2_val[0];
10468       if (cos2)
10469         match[18] |= (cos2_val & 0x7) << 5;
10470       if (proto)
10471         {
10472           match[21] = proto_val & 0xff;
10473           match[20] = proto_val >> 8;
10474         }
10475       if (tag1)
10476         {
10477           match[15] = tag1_val[1];
10478           match[14] = tag1_val[0];
10479         }
10480       if (cos1)
10481         match[14] |= (cos1_val & 0x7) << 5;
10482       *matchp = match;
10483       return 1;
10484     }
10485   if (tag1)
10486     {
10487       match[15] = tag1_val[1];
10488       match[14] = tag1_val[0];
10489       if (proto)
10490         {
10491           match[17] = proto_val & 0xff;
10492           match[16] = proto_val >> 8;
10493         }
10494       if (cos1)
10495         match[14] |= (cos1_val & 0x7) << 5;
10496
10497       *matchp = match;
10498       return 1;
10499     }
10500   if (cos2)
10501     match[18] |= (cos2_val & 0x7) << 5;
10502   if (cos1)
10503     match[14] |= (cos1_val & 0x7) << 5;
10504   if (proto)
10505     {
10506       match[13] = proto_val & 0xff;
10507       match[12] = proto_val >> 8;
10508     }
10509
10510   *matchp = match;
10511   return 1;
10512 }
10513
10514 uword
10515 unformat_qos_source (unformat_input_t * input, va_list * args)
10516 {
10517   int *qs = va_arg (*args, int *);
10518
10519   if (unformat (input, "ip"))
10520     *qs = QOS_SOURCE_IP;
10521   else if (unformat (input, "mpls"))
10522     *qs = QOS_SOURCE_MPLS;
10523   else if (unformat (input, "ext"))
10524     *qs = QOS_SOURCE_EXT;
10525   else if (unformat (input, "vlan"))
10526     *qs = QOS_SOURCE_VLAN;
10527   else
10528     return 0;
10529
10530   return 1;
10531 }
10532 #endif
10533
10534 uword
10535 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10536 {
10537   u8 **matchp = va_arg (*args, u8 **);
10538   u32 skip_n_vectors = va_arg (*args, u32);
10539   u32 match_n_vectors = va_arg (*args, u32);
10540
10541   u8 *match = 0;
10542   u8 *l2 = 0;
10543   u8 *l3 = 0;
10544   u8 *l4 = 0;
10545
10546   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10547     {
10548       if (unformat (input, "hex %U", unformat_hex_string, &match))
10549         ;
10550       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10551         ;
10552       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10553         ;
10554       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10555         ;
10556       else
10557         break;
10558     }
10559
10560   if (l4 && !l3)
10561     {
10562       vec_free (match);
10563       vec_free (l2);
10564       vec_free (l4);
10565       return 0;
10566     }
10567
10568   if (match || l2 || l3 || l4)
10569     {
10570       if (l2 || l3 || l4)
10571         {
10572           /* "Win a free Ethernet header in every packet" */
10573           if (l2 == 0)
10574             vec_validate_aligned (l2, 13, sizeof (u32x4));
10575           match = l2;
10576           if (vec_len (l3))
10577             {
10578               vec_append_aligned (match, l3, sizeof (u32x4));
10579               vec_free (l3);
10580             }
10581           if (vec_len (l4))
10582             {
10583               vec_append_aligned (match, l4, sizeof (u32x4));
10584               vec_free (l4);
10585             }
10586         }
10587
10588       /* Make sure the vector is big enough even if key is all 0's */
10589       vec_validate_aligned
10590         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10591          sizeof (u32x4));
10592
10593       /* Set size, include skipped vectors */
10594       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10595
10596       *matchp = match;
10597
10598       return 1;
10599     }
10600
10601   return 0;
10602 }
10603
10604 static int
10605 api_classify_add_del_session (vat_main_t * vam)
10606 {
10607   unformat_input_t *i = vam->input;
10608   vl_api_classify_add_del_session_t *mp;
10609   int is_add = 1;
10610   u32 table_index = ~0;
10611   u32 hit_next_index = ~0;
10612   u32 opaque_index = ~0;
10613   u8 *match = 0;
10614   i32 advance = 0;
10615   u32 skip_n_vectors = 0;
10616   u32 match_n_vectors = 0;
10617   u32 action = 0;
10618   u32 metadata = 0;
10619   int ret;
10620
10621   /*
10622    * Warning: you have to supply skip_n and match_n
10623    * because the API client cant simply look at the classify
10624    * table object.
10625    */
10626
10627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10628     {
10629       if (unformat (i, "del"))
10630         is_add = 0;
10631       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10632                          &hit_next_index))
10633         ;
10634       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10635                          &hit_next_index))
10636         ;
10637       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10638                          &hit_next_index))
10639         ;
10640       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10641         ;
10642       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10643         ;
10644       else if (unformat (i, "opaque-index %d", &opaque_index))
10645         ;
10646       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10647         ;
10648       else if (unformat (i, "match_n %d", &match_n_vectors))
10649         ;
10650       else if (unformat (i, "match %U", api_unformat_classify_match,
10651                          &match, skip_n_vectors, match_n_vectors))
10652         ;
10653       else if (unformat (i, "advance %d", &advance))
10654         ;
10655       else if (unformat (i, "table-index %d", &table_index))
10656         ;
10657       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10658         action = 1;
10659       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10660         action = 2;
10661       else if (unformat (i, "action %d", &action))
10662         ;
10663       else if (unformat (i, "metadata %d", &metadata))
10664         ;
10665       else
10666         break;
10667     }
10668
10669   if (table_index == ~0)
10670     {
10671       errmsg ("Table index required");
10672       return -99;
10673     }
10674
10675   if (is_add && match == 0)
10676     {
10677       errmsg ("Match value required");
10678       return -99;
10679     }
10680
10681   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10682
10683   mp->is_add = is_add;
10684   mp->table_index = ntohl (table_index);
10685   mp->hit_next_index = ntohl (hit_next_index);
10686   mp->opaque_index = ntohl (opaque_index);
10687   mp->advance = ntohl (advance);
10688   mp->action = action;
10689   mp->metadata = ntohl (metadata);
10690   mp->match_len = ntohl (vec_len (match));
10691   clib_memcpy (mp->match, match, vec_len (match));
10692   vec_free (match);
10693
10694   S (mp);
10695   W (ret);
10696   return ret;
10697 }
10698
10699 static int
10700 api_classify_set_interface_ip_table (vat_main_t * vam)
10701 {
10702   unformat_input_t *i = vam->input;
10703   vl_api_classify_set_interface_ip_table_t *mp;
10704   u32 sw_if_index;
10705   int sw_if_index_set;
10706   u32 table_index = ~0;
10707   u8 is_ipv6 = 0;
10708   int ret;
10709
10710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10711     {
10712       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10713         sw_if_index_set = 1;
10714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10715         sw_if_index_set = 1;
10716       else if (unformat (i, "table %d", &table_index))
10717         ;
10718       else
10719         {
10720           clib_warning ("parse error '%U'", format_unformat_error, i);
10721           return -99;
10722         }
10723     }
10724
10725   if (sw_if_index_set == 0)
10726     {
10727       errmsg ("missing interface name or sw_if_index");
10728       return -99;
10729     }
10730
10731
10732   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10733
10734   mp->sw_if_index = ntohl (sw_if_index);
10735   mp->table_index = ntohl (table_index);
10736   mp->is_ipv6 = is_ipv6;
10737
10738   S (mp);
10739   W (ret);
10740   return ret;
10741 }
10742
10743 static int
10744 api_classify_set_interface_l2_tables (vat_main_t * vam)
10745 {
10746   unformat_input_t *i = vam->input;
10747   vl_api_classify_set_interface_l2_tables_t *mp;
10748   u32 sw_if_index;
10749   int sw_if_index_set;
10750   u32 ip4_table_index = ~0;
10751   u32 ip6_table_index = ~0;
10752   u32 other_table_index = ~0;
10753   u32 is_input = 1;
10754   int ret;
10755
10756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10757     {
10758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10759         sw_if_index_set = 1;
10760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10761         sw_if_index_set = 1;
10762       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10763         ;
10764       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10765         ;
10766       else if (unformat (i, "other-table %d", &other_table_index))
10767         ;
10768       else if (unformat (i, "is-input %d", &is_input))
10769         ;
10770       else
10771         {
10772           clib_warning ("parse error '%U'", format_unformat_error, i);
10773           return -99;
10774         }
10775     }
10776
10777   if (sw_if_index_set == 0)
10778     {
10779       errmsg ("missing interface name or sw_if_index");
10780       return -99;
10781     }
10782
10783
10784   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10785
10786   mp->sw_if_index = ntohl (sw_if_index);
10787   mp->ip4_table_index = ntohl (ip4_table_index);
10788   mp->ip6_table_index = ntohl (ip6_table_index);
10789   mp->other_table_index = ntohl (other_table_index);
10790   mp->is_input = (u8) is_input;
10791
10792   S (mp);
10793   W (ret);
10794   return ret;
10795 }
10796
10797 static int
10798 api_set_ipfix_exporter (vat_main_t * vam)
10799 {
10800   unformat_input_t *i = vam->input;
10801   vl_api_set_ipfix_exporter_t *mp;
10802   ip4_address_t collector_address;
10803   u8 collector_address_set = 0;
10804   u32 collector_port = ~0;
10805   ip4_address_t src_address;
10806   u8 src_address_set = 0;
10807   u32 vrf_id = ~0;
10808   u32 path_mtu = ~0;
10809   u32 template_interval = ~0;
10810   u8 udp_checksum = 0;
10811   int ret;
10812
10813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10814     {
10815       if (unformat (i, "collector_address %U", unformat_ip4_address,
10816                     &collector_address))
10817         collector_address_set = 1;
10818       else if (unformat (i, "collector_port %d", &collector_port))
10819         ;
10820       else if (unformat (i, "src_address %U", unformat_ip4_address,
10821                          &src_address))
10822         src_address_set = 1;
10823       else if (unformat (i, "vrf_id %d", &vrf_id))
10824         ;
10825       else if (unformat (i, "path_mtu %d", &path_mtu))
10826         ;
10827       else if (unformat (i, "template_interval %d", &template_interval))
10828         ;
10829       else if (unformat (i, "udp_checksum"))
10830         udp_checksum = 1;
10831       else
10832         break;
10833     }
10834
10835   if (collector_address_set == 0)
10836     {
10837       errmsg ("collector_address required");
10838       return -99;
10839     }
10840
10841   if (src_address_set == 0)
10842     {
10843       errmsg ("src_address required");
10844       return -99;
10845     }
10846
10847   M (SET_IPFIX_EXPORTER, mp);
10848
10849   memcpy (mp->collector_address.un.ip4, collector_address.data,
10850           sizeof (collector_address.data));
10851   mp->collector_port = htons ((u16) collector_port);
10852   memcpy (mp->src_address.un.ip4, src_address.data,
10853           sizeof (src_address.data));
10854   mp->vrf_id = htonl (vrf_id);
10855   mp->path_mtu = htonl (path_mtu);
10856   mp->template_interval = htonl (template_interval);
10857   mp->udp_checksum = udp_checksum;
10858
10859   S (mp);
10860   W (ret);
10861   return ret;
10862 }
10863
10864 static int
10865 api_set_ipfix_classify_stream (vat_main_t * vam)
10866 {
10867   unformat_input_t *i = vam->input;
10868   vl_api_set_ipfix_classify_stream_t *mp;
10869   u32 domain_id = 0;
10870   u32 src_port = UDP_DST_PORT_ipfix;
10871   int ret;
10872
10873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10874     {
10875       if (unformat (i, "domain %d", &domain_id))
10876         ;
10877       else if (unformat (i, "src_port %d", &src_port))
10878         ;
10879       else
10880         {
10881           errmsg ("unknown input `%U'", format_unformat_error, i);
10882           return -99;
10883         }
10884     }
10885
10886   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10887
10888   mp->domain_id = htonl (domain_id);
10889   mp->src_port = htons ((u16) src_port);
10890
10891   S (mp);
10892   W (ret);
10893   return ret;
10894 }
10895
10896 static int
10897 api_ipfix_classify_table_add_del (vat_main_t * vam)
10898 {
10899   unformat_input_t *i = vam->input;
10900   vl_api_ipfix_classify_table_add_del_t *mp;
10901   int is_add = -1;
10902   u32 classify_table_index = ~0;
10903   u8 ip_version = 0;
10904   u8 transport_protocol = 255;
10905   int ret;
10906
10907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10908     {
10909       if (unformat (i, "add"))
10910         is_add = 1;
10911       else if (unformat (i, "del"))
10912         is_add = 0;
10913       else if (unformat (i, "table %d", &classify_table_index))
10914         ;
10915       else if (unformat (i, "ip4"))
10916         ip_version = 4;
10917       else if (unformat (i, "ip6"))
10918         ip_version = 6;
10919       else if (unformat (i, "tcp"))
10920         transport_protocol = 6;
10921       else if (unformat (i, "udp"))
10922         transport_protocol = 17;
10923       else
10924         {
10925           errmsg ("unknown input `%U'", format_unformat_error, i);
10926           return -99;
10927         }
10928     }
10929
10930   if (is_add == -1)
10931     {
10932       errmsg ("expecting: add|del");
10933       return -99;
10934     }
10935   if (classify_table_index == ~0)
10936     {
10937       errmsg ("classifier table not specified");
10938       return -99;
10939     }
10940   if (ip_version == 0)
10941     {
10942       errmsg ("IP version not specified");
10943       return -99;
10944     }
10945
10946   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10947
10948   mp->is_add = is_add;
10949   mp->table_id = htonl (classify_table_index);
10950   mp->ip_version = ip_version;
10951   mp->transport_protocol = transport_protocol;
10952
10953   S (mp);
10954   W (ret);
10955   return ret;
10956 }
10957
10958 static int
10959 api_get_node_index (vat_main_t * vam)
10960 {
10961   unformat_input_t *i = vam->input;
10962   vl_api_get_node_index_t *mp;
10963   u8 *name = 0;
10964   int ret;
10965
10966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10967     {
10968       if (unformat (i, "node %s", &name))
10969         ;
10970       else
10971         break;
10972     }
10973   if (name == 0)
10974     {
10975       errmsg ("node name required");
10976       return -99;
10977     }
10978   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10979     {
10980       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10981       return -99;
10982     }
10983
10984   M (GET_NODE_INDEX, mp);
10985   clib_memcpy (mp->node_name, name, vec_len (name));
10986   vec_free (name);
10987
10988   S (mp);
10989   W (ret);
10990   return ret;
10991 }
10992
10993 static int
10994 api_get_next_index (vat_main_t * vam)
10995 {
10996   unformat_input_t *i = vam->input;
10997   vl_api_get_next_index_t *mp;
10998   u8 *node_name = 0, *next_node_name = 0;
10999   int ret;
11000
11001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002     {
11003       if (unformat (i, "node-name %s", &node_name))
11004         ;
11005       else if (unformat (i, "next-node-name %s", &next_node_name))
11006         break;
11007     }
11008
11009   if (node_name == 0)
11010     {
11011       errmsg ("node name required");
11012       return -99;
11013     }
11014   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11015     {
11016       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11017       return -99;
11018     }
11019
11020   if (next_node_name == 0)
11021     {
11022       errmsg ("next node name required");
11023       return -99;
11024     }
11025   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11026     {
11027       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11028       return -99;
11029     }
11030
11031   M (GET_NEXT_INDEX, mp);
11032   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11033   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11034   vec_free (node_name);
11035   vec_free (next_node_name);
11036
11037   S (mp);
11038   W (ret);
11039   return ret;
11040 }
11041
11042 static int
11043 api_add_node_next (vat_main_t * vam)
11044 {
11045   unformat_input_t *i = vam->input;
11046   vl_api_add_node_next_t *mp;
11047   u8 *name = 0;
11048   u8 *next = 0;
11049   int ret;
11050
11051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11052     {
11053       if (unformat (i, "node %s", &name))
11054         ;
11055       else if (unformat (i, "next %s", &next))
11056         ;
11057       else
11058         break;
11059     }
11060   if (name == 0)
11061     {
11062       errmsg ("node name required");
11063       return -99;
11064     }
11065   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11066     {
11067       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11068       return -99;
11069     }
11070   if (next == 0)
11071     {
11072       errmsg ("next node required");
11073       return -99;
11074     }
11075   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11076     {
11077       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11078       return -99;
11079     }
11080
11081   M (ADD_NODE_NEXT, mp);
11082   clib_memcpy (mp->node_name, name, vec_len (name));
11083   clib_memcpy (mp->next_name, next, vec_len (next));
11084   vec_free (name);
11085   vec_free (next);
11086
11087   S (mp);
11088   W (ret);
11089   return ret;
11090 }
11091
11092 static int
11093 api_l2tpv3_create_tunnel (vat_main_t * vam)
11094 {
11095   unformat_input_t *i = vam->input;
11096   ip6_address_t client_address, our_address;
11097   int client_address_set = 0;
11098   int our_address_set = 0;
11099   u32 local_session_id = 0;
11100   u32 remote_session_id = 0;
11101   u64 local_cookie = 0;
11102   u64 remote_cookie = 0;
11103   u8 l2_sublayer_present = 0;
11104   vl_api_l2tpv3_create_tunnel_t *mp;
11105   int ret;
11106
11107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11108     {
11109       if (unformat (i, "client_address %U", unformat_ip6_address,
11110                     &client_address))
11111         client_address_set = 1;
11112       else if (unformat (i, "our_address %U", unformat_ip6_address,
11113                          &our_address))
11114         our_address_set = 1;
11115       else if (unformat (i, "local_session_id %d", &local_session_id))
11116         ;
11117       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11118         ;
11119       else if (unformat (i, "local_cookie %lld", &local_cookie))
11120         ;
11121       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11122         ;
11123       else if (unformat (i, "l2-sublayer-present"))
11124         l2_sublayer_present = 1;
11125       else
11126         break;
11127     }
11128
11129   if (client_address_set == 0)
11130     {
11131       errmsg ("client_address required");
11132       return -99;
11133     }
11134
11135   if (our_address_set == 0)
11136     {
11137       errmsg ("our_address required");
11138       return -99;
11139     }
11140
11141   M (L2TPV3_CREATE_TUNNEL, mp);
11142
11143   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11144                sizeof (ip6_address_t));
11145
11146   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11147                sizeof (ip6_address_t));
11148
11149   mp->local_session_id = ntohl (local_session_id);
11150   mp->remote_session_id = ntohl (remote_session_id);
11151   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11152   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11153   mp->l2_sublayer_present = l2_sublayer_present;
11154
11155   S (mp);
11156   W (ret);
11157   return ret;
11158 }
11159
11160 static int
11161 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11162 {
11163   unformat_input_t *i = vam->input;
11164   u32 sw_if_index;
11165   u8 sw_if_index_set = 0;
11166   u64 new_local_cookie = 0;
11167   u64 new_remote_cookie = 0;
11168   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11169   int ret;
11170
11171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11172     {
11173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11174         sw_if_index_set = 1;
11175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11176         sw_if_index_set = 1;
11177       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11178         ;
11179       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11180         ;
11181       else
11182         break;
11183     }
11184
11185   if (sw_if_index_set == 0)
11186     {
11187       errmsg ("missing interface name or sw_if_index");
11188       return -99;
11189     }
11190
11191   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11192
11193   mp->sw_if_index = ntohl (sw_if_index);
11194   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11195   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11196
11197   S (mp);
11198   W (ret);
11199   return ret;
11200 }
11201
11202 static int
11203 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11204 {
11205   unformat_input_t *i = vam->input;
11206   vl_api_l2tpv3_interface_enable_disable_t *mp;
11207   u32 sw_if_index;
11208   u8 sw_if_index_set = 0;
11209   u8 enable_disable = 1;
11210   int ret;
11211
11212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11213     {
11214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11215         sw_if_index_set = 1;
11216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11217         sw_if_index_set = 1;
11218       else if (unformat (i, "enable"))
11219         enable_disable = 1;
11220       else if (unformat (i, "disable"))
11221         enable_disable = 0;
11222       else
11223         break;
11224     }
11225
11226   if (sw_if_index_set == 0)
11227     {
11228       errmsg ("missing interface name or sw_if_index");
11229       return -99;
11230     }
11231
11232   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11233
11234   mp->sw_if_index = ntohl (sw_if_index);
11235   mp->enable_disable = enable_disable;
11236
11237   S (mp);
11238   W (ret);
11239   return ret;
11240 }
11241
11242 static int
11243 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11244 {
11245   unformat_input_t *i = vam->input;
11246   vl_api_l2tpv3_set_lookup_key_t *mp;
11247   u8 key = ~0;
11248   int ret;
11249
11250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11251     {
11252       if (unformat (i, "lookup_v6_src"))
11253         key = L2T_LOOKUP_SRC_ADDRESS;
11254       else if (unformat (i, "lookup_v6_dst"))
11255         key = L2T_LOOKUP_DST_ADDRESS;
11256       else if (unformat (i, "lookup_session_id"))
11257         key = L2T_LOOKUP_SESSION_ID;
11258       else
11259         break;
11260     }
11261
11262   if (key == (u8) ~ 0)
11263     {
11264       errmsg ("l2tp session lookup key unset");
11265       return -99;
11266     }
11267
11268   M (L2TPV3_SET_LOOKUP_KEY, mp);
11269
11270   mp->key = key;
11271
11272   S (mp);
11273   W (ret);
11274   return ret;
11275 }
11276
11277 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11278   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11279 {
11280   vat_main_t *vam = &vat_main;
11281
11282   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11283          format_ip6_address, mp->our_address,
11284          format_ip6_address, mp->client_address,
11285          clib_net_to_host_u32 (mp->sw_if_index));
11286
11287   print (vam->ofp,
11288          "   local cookies %016llx %016llx remote cookie %016llx",
11289          clib_net_to_host_u64 (mp->local_cookie[0]),
11290          clib_net_to_host_u64 (mp->local_cookie[1]),
11291          clib_net_to_host_u64 (mp->remote_cookie));
11292
11293   print (vam->ofp, "   local session-id %d remote session-id %d",
11294          clib_net_to_host_u32 (mp->local_session_id),
11295          clib_net_to_host_u32 (mp->remote_session_id));
11296
11297   print (vam->ofp, "   l2 specific sublayer %s\n",
11298          mp->l2_sublayer_present ? "preset" : "absent");
11299
11300 }
11301
11302 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11303   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11304 {
11305   vat_main_t *vam = &vat_main;
11306   vat_json_node_t *node = NULL;
11307   struct in6_addr addr;
11308
11309   if (VAT_JSON_ARRAY != vam->json_tree.type)
11310     {
11311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11312       vat_json_init_array (&vam->json_tree);
11313     }
11314   node = vat_json_array_add (&vam->json_tree);
11315
11316   vat_json_init_object (node);
11317
11318   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11319   vat_json_object_add_ip6 (node, "our_address", addr);
11320   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11321   vat_json_object_add_ip6 (node, "client_address", addr);
11322
11323   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11324   vat_json_init_array (lc);
11325   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11326   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11327   vat_json_object_add_uint (node, "remote_cookie",
11328                             clib_net_to_host_u64 (mp->remote_cookie));
11329
11330   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11331   vat_json_object_add_uint (node, "local_session_id",
11332                             clib_net_to_host_u32 (mp->local_session_id));
11333   vat_json_object_add_uint (node, "remote_session_id",
11334                             clib_net_to_host_u32 (mp->remote_session_id));
11335   vat_json_object_add_string_copy (node, "l2_sublayer",
11336                                    mp->l2_sublayer_present ? (u8 *) "present"
11337                                    : (u8 *) "absent");
11338 }
11339
11340 static int
11341 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11342 {
11343   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11344   vl_api_control_ping_t *mp_ping;
11345   int ret;
11346
11347   /* Get list of l2tpv3-tunnel interfaces */
11348   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11349   S (mp);
11350
11351   /* Use a control ping for synchronization */
11352   MPING (CONTROL_PING, mp_ping);
11353   S (mp_ping);
11354
11355   W (ret);
11356   return ret;
11357 }
11358
11359
11360 static void vl_api_sw_interface_tap_v2_details_t_handler
11361   (vl_api_sw_interface_tap_v2_details_t * mp)
11362 {
11363   vat_main_t *vam = &vat_main;
11364
11365   u8 *ip4 =
11366     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11367             mp->host_ip4_prefix.len);
11368   u8 *ip6 =
11369     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11370             mp->host_ip6_prefix.len);
11371
11372   print (vam->ofp,
11373          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11374          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11375          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11376          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11377          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11378
11379   vec_free (ip4);
11380   vec_free (ip6);
11381 }
11382
11383 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11384   (vl_api_sw_interface_tap_v2_details_t * mp)
11385 {
11386   vat_main_t *vam = &vat_main;
11387   vat_json_node_t *node = NULL;
11388
11389   if (VAT_JSON_ARRAY != vam->json_tree.type)
11390     {
11391       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11392       vat_json_init_array (&vam->json_tree);
11393     }
11394   node = vat_json_array_add (&vam->json_tree);
11395
11396   vat_json_init_object (node);
11397   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11398   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11399   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11400   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11401   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11402   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11403   vat_json_object_add_string_copy (node, "host_mac_addr",
11404                                    format (0, "%U", format_ethernet_address,
11405                                            &mp->host_mac_addr));
11406   vat_json_object_add_string_copy (node, "host_namespace",
11407                                    mp->host_namespace);
11408   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11409   vat_json_object_add_string_copy (node, "host_ip4_addr",
11410                                    format (0, "%U/%d", format_ip4_address,
11411                                            mp->host_ip4_prefix.address,
11412                                            mp->host_ip4_prefix.len));
11413   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11414                                    format (0, "%U/%d", format_ip6_address,
11415                                            mp->host_ip6_prefix.address,
11416                                            mp->host_ip6_prefix.len));
11417
11418 }
11419
11420 static int
11421 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11422 {
11423   vl_api_sw_interface_tap_v2_dump_t *mp;
11424   vl_api_control_ping_t *mp_ping;
11425   int ret;
11426
11427   print (vam->ofp,
11428          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11429          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11430          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11431          "host_ip6_addr");
11432
11433   /* Get list of tap interfaces */
11434   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11435   S (mp);
11436
11437   /* Use a control ping for synchronization */
11438   MPING (CONTROL_PING, mp_ping);
11439   S (mp_ping);
11440
11441   W (ret);
11442   return ret;
11443 }
11444
11445 static void vl_api_sw_interface_virtio_pci_details_t_handler
11446   (vl_api_sw_interface_virtio_pci_details_t * mp)
11447 {
11448   vat_main_t *vam = &vat_main;
11449
11450   typedef union
11451   {
11452     struct
11453     {
11454       u16 domain;
11455       u8 bus;
11456       u8 slot:5;
11457       u8 function:3;
11458     };
11459     u32 as_u32;
11460   } pci_addr_t;
11461   pci_addr_t addr;
11462
11463   addr.domain = ntohs (mp->pci_addr.domain);
11464   addr.bus = mp->pci_addr.bus;
11465   addr.slot = mp->pci_addr.slot;
11466   addr.function = mp->pci_addr.function;
11467
11468   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11469                          addr.slot, addr.function);
11470
11471   print (vam->ofp,
11472          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11473          pci_addr, ntohl (mp->sw_if_index),
11474          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11475          format_ethernet_address, mp->mac_addr,
11476          clib_net_to_host_u64 (mp->features));
11477   vec_free (pci_addr);
11478 }
11479
11480 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11481   (vl_api_sw_interface_virtio_pci_details_t * mp)
11482 {
11483   vat_main_t *vam = &vat_main;
11484   vat_json_node_t *node = NULL;
11485   vlib_pci_addr_t pci_addr;
11486
11487   if (VAT_JSON_ARRAY != vam->json_tree.type)
11488     {
11489       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11490       vat_json_init_array (&vam->json_tree);
11491     }
11492   node = vat_json_array_add (&vam->json_tree);
11493
11494   pci_addr.domain = ntohs (mp->pci_addr.domain);
11495   pci_addr.bus = mp->pci_addr.bus;
11496   pci_addr.slot = mp->pci_addr.slot;
11497   pci_addr.function = mp->pci_addr.function;
11498
11499   vat_json_init_object (node);
11500   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11501   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11502   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11503   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11504   vat_json_object_add_uint (node, "features",
11505                             clib_net_to_host_u64 (mp->features));
11506   vat_json_object_add_string_copy (node, "mac_addr",
11507                                    format (0, "%U", format_ethernet_address,
11508                                            &mp->mac_addr));
11509 }
11510
11511 static int
11512 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11513 {
11514   vl_api_sw_interface_virtio_pci_dump_t *mp;
11515   vl_api_control_ping_t *mp_ping;
11516   int ret;
11517
11518   print (vam->ofp,
11519          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11520          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11521          "mac_addr", "features");
11522
11523   /* Get list of tap interfaces */
11524   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11525   S (mp);
11526
11527   /* Use a control ping for synchronization */
11528   MPING (CONTROL_PING, mp_ping);
11529   S (mp_ping);
11530
11531   W (ret);
11532   return ret;
11533 }
11534
11535 static int
11536 api_vxlan_offload_rx (vat_main_t * vam)
11537 {
11538   unformat_input_t *line_input = vam->input;
11539   vl_api_vxlan_offload_rx_t *mp;
11540   u32 hw_if_index = ~0, rx_if_index = ~0;
11541   u8 is_add = 1;
11542   int ret;
11543
11544   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11545     {
11546       if (unformat (line_input, "del"))
11547         is_add = 0;
11548       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11549                          &hw_if_index))
11550         ;
11551       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11552         ;
11553       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11554                          &rx_if_index))
11555         ;
11556       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11557         ;
11558       else
11559         {
11560           errmsg ("parse error '%U'", format_unformat_error, line_input);
11561           return -99;
11562         }
11563     }
11564
11565   if (hw_if_index == ~0)
11566     {
11567       errmsg ("no hw interface");
11568       return -99;
11569     }
11570
11571   if (rx_if_index == ~0)
11572     {
11573       errmsg ("no rx tunnel");
11574       return -99;
11575     }
11576
11577   M (VXLAN_OFFLOAD_RX, mp);
11578
11579   mp->hw_if_index = ntohl (hw_if_index);
11580   mp->sw_if_index = ntohl (rx_if_index);
11581   mp->enable = is_add;
11582
11583   S (mp);
11584   W (ret);
11585   return ret;
11586 }
11587
11588 static uword unformat_vxlan_decap_next
11589   (unformat_input_t * input, va_list * args)
11590 {
11591   u32 *result = va_arg (*args, u32 *);
11592   u32 tmp;
11593
11594   if (unformat (input, "l2"))
11595     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11596   else if (unformat (input, "%d", &tmp))
11597     *result = tmp;
11598   else
11599     return 0;
11600   return 1;
11601 }
11602
11603 static int
11604 api_vxlan_add_del_tunnel (vat_main_t * vam)
11605 {
11606   unformat_input_t *line_input = vam->input;
11607   vl_api_vxlan_add_del_tunnel_t *mp;
11608   ip46_address_t src, dst;
11609   u8 is_add = 1;
11610   u8 ipv4_set = 0, ipv6_set = 0;
11611   u8 src_set = 0;
11612   u8 dst_set = 0;
11613   u8 grp_set = 0;
11614   u32 instance = ~0;
11615   u32 mcast_sw_if_index = ~0;
11616   u32 encap_vrf_id = 0;
11617   u32 decap_next_index = ~0;
11618   u32 vni = 0;
11619   int ret;
11620
11621   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11622   clib_memset (&src, 0, sizeof src);
11623   clib_memset (&dst, 0, sizeof dst);
11624
11625   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11626     {
11627       if (unformat (line_input, "del"))
11628         is_add = 0;
11629       else if (unformat (line_input, "instance %d", &instance))
11630         ;
11631       else
11632         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11633         {
11634           ipv4_set = 1;
11635           src_set = 1;
11636         }
11637       else
11638         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11639         {
11640           ipv4_set = 1;
11641           dst_set = 1;
11642         }
11643       else
11644         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11645         {
11646           ipv6_set = 1;
11647           src_set = 1;
11648         }
11649       else
11650         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11651         {
11652           ipv6_set = 1;
11653           dst_set = 1;
11654         }
11655       else if (unformat (line_input, "group %U %U",
11656                          unformat_ip4_address, &dst.ip4,
11657                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11658         {
11659           grp_set = dst_set = 1;
11660           ipv4_set = 1;
11661         }
11662       else if (unformat (line_input, "group %U",
11663                          unformat_ip4_address, &dst.ip4))
11664         {
11665           grp_set = dst_set = 1;
11666           ipv4_set = 1;
11667         }
11668       else if (unformat (line_input, "group %U %U",
11669                          unformat_ip6_address, &dst.ip6,
11670                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11671         {
11672           grp_set = dst_set = 1;
11673           ipv6_set = 1;
11674         }
11675       else if (unformat (line_input, "group %U",
11676                          unformat_ip6_address, &dst.ip6))
11677         {
11678           grp_set = dst_set = 1;
11679           ipv6_set = 1;
11680         }
11681       else
11682         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11683         ;
11684       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11685         ;
11686       else if (unformat (line_input, "decap-next %U",
11687                          unformat_vxlan_decap_next, &decap_next_index))
11688         ;
11689       else if (unformat (line_input, "vni %d", &vni))
11690         ;
11691       else
11692         {
11693           errmsg ("parse error '%U'", format_unformat_error, line_input);
11694           return -99;
11695         }
11696     }
11697
11698   if (src_set == 0)
11699     {
11700       errmsg ("tunnel src address not specified");
11701       return -99;
11702     }
11703   if (dst_set == 0)
11704     {
11705       errmsg ("tunnel dst address not specified");
11706       return -99;
11707     }
11708
11709   if (grp_set && !ip46_address_is_multicast (&dst))
11710     {
11711       errmsg ("tunnel group address not multicast");
11712       return -99;
11713     }
11714   if (grp_set && mcast_sw_if_index == ~0)
11715     {
11716       errmsg ("tunnel nonexistent multicast device");
11717       return -99;
11718     }
11719   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11720     {
11721       errmsg ("tunnel dst address must be unicast");
11722       return -99;
11723     }
11724
11725
11726   if (ipv4_set && ipv6_set)
11727     {
11728       errmsg ("both IPv4 and IPv6 addresses specified");
11729       return -99;
11730     }
11731
11732   if ((vni == 0) || (vni >> 24))
11733     {
11734       errmsg ("vni not specified or out of range");
11735       return -99;
11736     }
11737
11738   M (VXLAN_ADD_DEL_TUNNEL, mp);
11739
11740   if (ipv6_set)
11741     {
11742       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11743       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11744     }
11745   else
11746     {
11747       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11748       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11749     }
11750   mp->src_address.af = ipv6_set;
11751   mp->dst_address.af = ipv6_set;
11752
11753   mp->instance = htonl (instance);
11754   mp->encap_vrf_id = ntohl (encap_vrf_id);
11755   mp->decap_next_index = ntohl (decap_next_index);
11756   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11757   mp->vni = ntohl (vni);
11758   mp->is_add = is_add;
11759
11760   S (mp);
11761   W (ret);
11762   return ret;
11763 }
11764
11765 static void vl_api_vxlan_tunnel_details_t_handler
11766   (vl_api_vxlan_tunnel_details_t * mp)
11767 {
11768   vat_main_t *vam = &vat_main;
11769   ip46_address_t src =
11770     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11771   ip46_address_t dst =
11772     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11773
11774   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11775          ntohl (mp->sw_if_index),
11776          ntohl (mp->instance),
11777          format_ip46_address, &src, IP46_TYPE_ANY,
11778          format_ip46_address, &dst, IP46_TYPE_ANY,
11779          ntohl (mp->encap_vrf_id),
11780          ntohl (mp->decap_next_index), ntohl (mp->vni),
11781          ntohl (mp->mcast_sw_if_index));
11782 }
11783
11784 static void vl_api_vxlan_tunnel_details_t_handler_json
11785   (vl_api_vxlan_tunnel_details_t * mp)
11786 {
11787   vat_main_t *vam = &vat_main;
11788   vat_json_node_t *node = NULL;
11789
11790   if (VAT_JSON_ARRAY != vam->json_tree.type)
11791     {
11792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11793       vat_json_init_array (&vam->json_tree);
11794     }
11795   node = vat_json_array_add (&vam->json_tree);
11796
11797   vat_json_init_object (node);
11798   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11799
11800   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11801
11802   if (mp->src_address.af)
11803     {
11804       struct in6_addr ip6;
11805
11806       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11807       vat_json_object_add_ip6 (node, "src_address", ip6);
11808       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11809       vat_json_object_add_ip6 (node, "dst_address", ip6);
11810     }
11811   else
11812     {
11813       struct in_addr ip4;
11814
11815       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11816       vat_json_object_add_ip4 (node, "src_address", ip4);
11817       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11818       vat_json_object_add_ip4 (node, "dst_address", ip4);
11819     }
11820   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11821   vat_json_object_add_uint (node, "decap_next_index",
11822                             ntohl (mp->decap_next_index));
11823   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11824   vat_json_object_add_uint (node, "mcast_sw_if_index",
11825                             ntohl (mp->mcast_sw_if_index));
11826 }
11827
11828 static int
11829 api_vxlan_tunnel_dump (vat_main_t * vam)
11830 {
11831   unformat_input_t *i = vam->input;
11832   vl_api_vxlan_tunnel_dump_t *mp;
11833   vl_api_control_ping_t *mp_ping;
11834   u32 sw_if_index;
11835   u8 sw_if_index_set = 0;
11836   int ret;
11837
11838   /* Parse args required to build the message */
11839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11840     {
11841       if (unformat (i, "sw_if_index %d", &sw_if_index))
11842         sw_if_index_set = 1;
11843       else
11844         break;
11845     }
11846
11847   if (sw_if_index_set == 0)
11848     {
11849       sw_if_index = ~0;
11850     }
11851
11852   if (!vam->json_output)
11853     {
11854       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11855              "sw_if_index", "instance", "src_address", "dst_address",
11856              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11857     }
11858
11859   /* Get list of vxlan-tunnel interfaces */
11860   M (VXLAN_TUNNEL_DUMP, mp);
11861
11862   mp->sw_if_index = htonl (sw_if_index);
11863
11864   S (mp);
11865
11866   /* Use a control ping for synchronization */
11867   MPING (CONTROL_PING, mp_ping);
11868   S (mp_ping);
11869
11870   W (ret);
11871   return ret;
11872 }
11873
11874 static uword unformat_geneve_decap_next
11875   (unformat_input_t * input, va_list * args)
11876 {
11877   u32 *result = va_arg (*args, u32 *);
11878   u32 tmp;
11879
11880   if (unformat (input, "l2"))
11881     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11882   else if (unformat (input, "%d", &tmp))
11883     *result = tmp;
11884   else
11885     return 0;
11886   return 1;
11887 }
11888
11889 static int
11890 api_geneve_add_del_tunnel (vat_main_t * vam)
11891 {
11892   unformat_input_t *line_input = vam->input;
11893   vl_api_geneve_add_del_tunnel_t *mp;
11894   ip46_address_t src, dst;
11895   u8 is_add = 1;
11896   u8 ipv4_set = 0, ipv6_set = 0;
11897   u8 src_set = 0;
11898   u8 dst_set = 0;
11899   u8 grp_set = 0;
11900   u32 mcast_sw_if_index = ~0;
11901   u32 encap_vrf_id = 0;
11902   u32 decap_next_index = ~0;
11903   u32 vni = 0;
11904   int ret;
11905
11906   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11907   clib_memset (&src, 0, sizeof src);
11908   clib_memset (&dst, 0, sizeof dst);
11909
11910   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11911     {
11912       if (unformat (line_input, "del"))
11913         is_add = 0;
11914       else
11915         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11916         {
11917           ipv4_set = 1;
11918           src_set = 1;
11919         }
11920       else
11921         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11922         {
11923           ipv4_set = 1;
11924           dst_set = 1;
11925         }
11926       else
11927         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11928         {
11929           ipv6_set = 1;
11930           src_set = 1;
11931         }
11932       else
11933         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11934         {
11935           ipv6_set = 1;
11936           dst_set = 1;
11937         }
11938       else if (unformat (line_input, "group %U %U",
11939                          unformat_ip4_address, &dst.ip4,
11940                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11941         {
11942           grp_set = dst_set = 1;
11943           ipv4_set = 1;
11944         }
11945       else if (unformat (line_input, "group %U",
11946                          unformat_ip4_address, &dst.ip4))
11947         {
11948           grp_set = dst_set = 1;
11949           ipv4_set = 1;
11950         }
11951       else if (unformat (line_input, "group %U %U",
11952                          unformat_ip6_address, &dst.ip6,
11953                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11954         {
11955           grp_set = dst_set = 1;
11956           ipv6_set = 1;
11957         }
11958       else if (unformat (line_input, "group %U",
11959                          unformat_ip6_address, &dst.ip6))
11960         {
11961           grp_set = dst_set = 1;
11962           ipv6_set = 1;
11963         }
11964       else
11965         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11966         ;
11967       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11968         ;
11969       else if (unformat (line_input, "decap-next %U",
11970                          unformat_geneve_decap_next, &decap_next_index))
11971         ;
11972       else if (unformat (line_input, "vni %d", &vni))
11973         ;
11974       else
11975         {
11976           errmsg ("parse error '%U'", format_unformat_error, line_input);
11977           return -99;
11978         }
11979     }
11980
11981   if (src_set == 0)
11982     {
11983       errmsg ("tunnel src address not specified");
11984       return -99;
11985     }
11986   if (dst_set == 0)
11987     {
11988       errmsg ("tunnel dst address not specified");
11989       return -99;
11990     }
11991
11992   if (grp_set && !ip46_address_is_multicast (&dst))
11993     {
11994       errmsg ("tunnel group address not multicast");
11995       return -99;
11996     }
11997   if (grp_set && mcast_sw_if_index == ~0)
11998     {
11999       errmsg ("tunnel nonexistent multicast device");
12000       return -99;
12001     }
12002   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12003     {
12004       errmsg ("tunnel dst address must be unicast");
12005       return -99;
12006     }
12007
12008
12009   if (ipv4_set && ipv6_set)
12010     {
12011       errmsg ("both IPv4 and IPv6 addresses specified");
12012       return -99;
12013     }
12014
12015   if ((vni == 0) || (vni >> 24))
12016     {
12017       errmsg ("vni not specified or out of range");
12018       return -99;
12019     }
12020
12021   M (GENEVE_ADD_DEL_TUNNEL, mp);
12022
12023   if (ipv6_set)
12024     {
12025       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12026       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12027     }
12028   else
12029     {
12030       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12031       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12032     }
12033   mp->encap_vrf_id = ntohl (encap_vrf_id);
12034   mp->decap_next_index = ntohl (decap_next_index);
12035   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12036   mp->vni = ntohl (vni);
12037   mp->is_add = is_add;
12038
12039   S (mp);
12040   W (ret);
12041   return ret;
12042 }
12043
12044 static void vl_api_geneve_tunnel_details_t_handler
12045   (vl_api_geneve_tunnel_details_t * mp)
12046 {
12047   vat_main_t *vam = &vat_main;
12048   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12049   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12050
12051   if (mp->src_address.af == ADDRESS_IP6)
12052     {
12053       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12054       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12055     }
12056   else
12057     {
12058       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12059       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12060     }
12061
12062   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12063          ntohl (mp->sw_if_index),
12064          format_ip46_address, &src, IP46_TYPE_ANY,
12065          format_ip46_address, &dst, IP46_TYPE_ANY,
12066          ntohl (mp->encap_vrf_id),
12067          ntohl (mp->decap_next_index), ntohl (mp->vni),
12068          ntohl (mp->mcast_sw_if_index));
12069 }
12070
12071 static void vl_api_geneve_tunnel_details_t_handler_json
12072   (vl_api_geneve_tunnel_details_t * mp)
12073 {
12074   vat_main_t *vam = &vat_main;
12075   vat_json_node_t *node = NULL;
12076   bool is_ipv6;
12077
12078   if (VAT_JSON_ARRAY != vam->json_tree.type)
12079     {
12080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12081       vat_json_init_array (&vam->json_tree);
12082     }
12083   node = vat_json_array_add (&vam->json_tree);
12084
12085   vat_json_init_object (node);
12086   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12087   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12088   if (is_ipv6)
12089     {
12090       struct in6_addr ip6;
12091
12092       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12093       vat_json_object_add_ip6 (node, "src_address", ip6);
12094       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12095       vat_json_object_add_ip6 (node, "dst_address", ip6);
12096     }
12097   else
12098     {
12099       struct in_addr ip4;
12100
12101       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12102       vat_json_object_add_ip4 (node, "src_address", ip4);
12103       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12104       vat_json_object_add_ip4 (node, "dst_address", ip4);
12105     }
12106   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12107   vat_json_object_add_uint (node, "decap_next_index",
12108                             ntohl (mp->decap_next_index));
12109   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12110   vat_json_object_add_uint (node, "mcast_sw_if_index",
12111                             ntohl (mp->mcast_sw_if_index));
12112 }
12113
12114 static int
12115 api_geneve_tunnel_dump (vat_main_t * vam)
12116 {
12117   unformat_input_t *i = vam->input;
12118   vl_api_geneve_tunnel_dump_t *mp;
12119   vl_api_control_ping_t *mp_ping;
12120   u32 sw_if_index;
12121   u8 sw_if_index_set = 0;
12122   int ret;
12123
12124   /* Parse args required to build the message */
12125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12126     {
12127       if (unformat (i, "sw_if_index %d", &sw_if_index))
12128         sw_if_index_set = 1;
12129       else
12130         break;
12131     }
12132
12133   if (sw_if_index_set == 0)
12134     {
12135       sw_if_index = ~0;
12136     }
12137
12138   if (!vam->json_output)
12139     {
12140       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12141              "sw_if_index", "local_address", "remote_address",
12142              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12143     }
12144
12145   /* Get list of geneve-tunnel interfaces */
12146   M (GENEVE_TUNNEL_DUMP, mp);
12147
12148   mp->sw_if_index = htonl (sw_if_index);
12149
12150   S (mp);
12151
12152   /* Use a control ping for synchronization */
12153   M (CONTROL_PING, mp_ping);
12154   S (mp_ping);
12155
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static int
12161 api_gre_tunnel_add_del (vat_main_t * vam)
12162 {
12163   unformat_input_t *line_input = vam->input;
12164   vl_api_address_t src = { }, dst =
12165   {
12166   };
12167   vl_api_gre_tunnel_add_del_t *mp;
12168   vl_api_gre_tunnel_type_t t_type;
12169   u8 is_add = 1;
12170   u8 src_set = 0;
12171   u8 dst_set = 0;
12172   u32 outer_table_id = 0;
12173   u32 session_id = 0;
12174   u32 instance = ~0;
12175   int ret;
12176
12177   t_type = GRE_API_TUNNEL_TYPE_L3;
12178
12179   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12180     {
12181       if (unformat (line_input, "del"))
12182         is_add = 0;
12183       else if (unformat (line_input, "instance %d", &instance))
12184         ;
12185       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12186         {
12187           src_set = 1;
12188         }
12189       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12190         {
12191           dst_set = 1;
12192         }
12193       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12194         ;
12195       else if (unformat (line_input, "teb"))
12196         t_type = GRE_API_TUNNEL_TYPE_TEB;
12197       else if (unformat (line_input, "erspan %d", &session_id))
12198         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12199       else
12200         {
12201           errmsg ("parse error '%U'", format_unformat_error, line_input);
12202           return -99;
12203         }
12204     }
12205
12206   if (src_set == 0)
12207     {
12208       errmsg ("tunnel src address not specified");
12209       return -99;
12210     }
12211   if (dst_set == 0)
12212     {
12213       errmsg ("tunnel dst address not specified");
12214       return -99;
12215     }
12216
12217   M (GRE_TUNNEL_ADD_DEL, mp);
12218
12219   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12220   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12221
12222   mp->tunnel.instance = htonl (instance);
12223   mp->tunnel.outer_table_id = htonl (outer_table_id);
12224   mp->is_add = is_add;
12225   mp->tunnel.session_id = htons ((u16) session_id);
12226   mp->tunnel.type = htonl (t_type);
12227
12228   S (mp);
12229   W (ret);
12230   return ret;
12231 }
12232
12233 static void vl_api_gre_tunnel_details_t_handler
12234   (vl_api_gre_tunnel_details_t * mp)
12235 {
12236   vat_main_t *vam = &vat_main;
12237
12238   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12239          ntohl (mp->tunnel.sw_if_index),
12240          ntohl (mp->tunnel.instance),
12241          format_vl_api_address, &mp->tunnel.src,
12242          format_vl_api_address, &mp->tunnel.dst,
12243          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12244          ntohl (mp->tunnel.session_id));
12245 }
12246
12247 static void vl_api_gre_tunnel_details_t_handler_json
12248   (vl_api_gre_tunnel_details_t * mp)
12249 {
12250   vat_main_t *vam = &vat_main;
12251   vat_json_node_t *node = NULL;
12252
12253   if (VAT_JSON_ARRAY != vam->json_tree.type)
12254     {
12255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12256       vat_json_init_array (&vam->json_tree);
12257     }
12258   node = vat_json_array_add (&vam->json_tree);
12259
12260   vat_json_init_object (node);
12261   vat_json_object_add_uint (node, "sw_if_index",
12262                             ntohl (mp->tunnel.sw_if_index));
12263   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12264
12265   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12266   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12267   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12268   vat_json_object_add_uint (node, "outer_table_id",
12269                             ntohl (mp->tunnel.outer_table_id));
12270   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12271 }
12272
12273 static int
12274 api_gre_tunnel_dump (vat_main_t * vam)
12275 {
12276   unformat_input_t *i = vam->input;
12277   vl_api_gre_tunnel_dump_t *mp;
12278   vl_api_control_ping_t *mp_ping;
12279   u32 sw_if_index;
12280   u8 sw_if_index_set = 0;
12281   int ret;
12282
12283   /* Parse args required to build the message */
12284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12285     {
12286       if (unformat (i, "sw_if_index %d", &sw_if_index))
12287         sw_if_index_set = 1;
12288       else
12289         break;
12290     }
12291
12292   if (sw_if_index_set == 0)
12293     {
12294       sw_if_index = ~0;
12295     }
12296
12297   if (!vam->json_output)
12298     {
12299       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12300              "sw_if_index", "instance", "src_address", "dst_address",
12301              "tunnel_type", "outer_fib_id", "session_id");
12302     }
12303
12304   /* Get list of gre-tunnel interfaces */
12305   M (GRE_TUNNEL_DUMP, mp);
12306
12307   mp->sw_if_index = htonl (sw_if_index);
12308
12309   S (mp);
12310
12311   /* Use a control ping for synchronization */
12312   MPING (CONTROL_PING, mp_ping);
12313   S (mp_ping);
12314
12315   W (ret);
12316   return ret;
12317 }
12318
12319 static int
12320 api_l2_fib_clear_table (vat_main_t * vam)
12321 {
12322 //  unformat_input_t * i = vam->input;
12323   vl_api_l2_fib_clear_table_t *mp;
12324   int ret;
12325
12326   M (L2_FIB_CLEAR_TABLE, mp);
12327
12328   S (mp);
12329   W (ret);
12330   return ret;
12331 }
12332
12333 static int
12334 api_l2_interface_efp_filter (vat_main_t * vam)
12335 {
12336   unformat_input_t *i = vam->input;
12337   vl_api_l2_interface_efp_filter_t *mp;
12338   u32 sw_if_index;
12339   u8 enable = 1;
12340   u8 sw_if_index_set = 0;
12341   int ret;
12342
12343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12344     {
12345       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12346         sw_if_index_set = 1;
12347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12348         sw_if_index_set = 1;
12349       else if (unformat (i, "enable"))
12350         enable = 1;
12351       else if (unformat (i, "disable"))
12352         enable = 0;
12353       else
12354         {
12355           clib_warning ("parse error '%U'", format_unformat_error, i);
12356           return -99;
12357         }
12358     }
12359
12360   if (sw_if_index_set == 0)
12361     {
12362       errmsg ("missing sw_if_index");
12363       return -99;
12364     }
12365
12366   M (L2_INTERFACE_EFP_FILTER, mp);
12367
12368   mp->sw_if_index = ntohl (sw_if_index);
12369   mp->enable_disable = enable;
12370
12371   S (mp);
12372   W (ret);
12373   return ret;
12374 }
12375
12376 #define foreach_vtr_op                          \
12377 _("disable",  L2_VTR_DISABLED)                  \
12378 _("push-1",  L2_VTR_PUSH_1)                     \
12379 _("push-2",  L2_VTR_PUSH_2)                     \
12380 _("pop-1",  L2_VTR_POP_1)                       \
12381 _("pop-2",  L2_VTR_POP_2)                       \
12382 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12383 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12384 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12385 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12386
12387 static int
12388 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12389 {
12390   unformat_input_t *i = vam->input;
12391   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12392   u32 sw_if_index;
12393   u8 sw_if_index_set = 0;
12394   u8 vtr_op_set = 0;
12395   u32 vtr_op = 0;
12396   u32 push_dot1q = 1;
12397   u32 tag1 = ~0;
12398   u32 tag2 = ~0;
12399   int ret;
12400
12401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12402     {
12403       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12404         sw_if_index_set = 1;
12405       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12406         sw_if_index_set = 1;
12407       else if (unformat (i, "vtr_op %d", &vtr_op))
12408         vtr_op_set = 1;
12409 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12410       foreach_vtr_op
12411 #undef _
12412         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12413         ;
12414       else if (unformat (i, "tag1 %d", &tag1))
12415         ;
12416       else if (unformat (i, "tag2 %d", &tag2))
12417         ;
12418       else
12419         {
12420           clib_warning ("parse error '%U'", format_unformat_error, i);
12421           return -99;
12422         }
12423     }
12424
12425   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12426     {
12427       errmsg ("missing vtr operation or sw_if_index");
12428       return -99;
12429     }
12430
12431   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12432   mp->sw_if_index = ntohl (sw_if_index);
12433   mp->vtr_op = ntohl (vtr_op);
12434   mp->push_dot1q = ntohl (push_dot1q);
12435   mp->tag1 = ntohl (tag1);
12436   mp->tag2 = ntohl (tag2);
12437
12438   S (mp);
12439   W (ret);
12440   return ret;
12441 }
12442
12443 static int
12444 api_create_vhost_user_if (vat_main_t * vam)
12445 {
12446   unformat_input_t *i = vam->input;
12447   vl_api_create_vhost_user_if_t *mp;
12448   u8 *file_name;
12449   u8 is_server = 0;
12450   u8 file_name_set = 0;
12451   u32 custom_dev_instance = ~0;
12452   u8 hwaddr[6];
12453   u8 use_custom_mac = 0;
12454   u8 disable_mrg_rxbuf = 0;
12455   u8 disable_indirect_desc = 0;
12456   u8 *tag = 0;
12457   u8 enable_gso = 0;
12458   u8 enable_packed = 0;
12459   int ret;
12460
12461   /* Shut up coverity */
12462   clib_memset (hwaddr, 0, sizeof (hwaddr));
12463
12464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12465     {
12466       if (unformat (i, "socket %s", &file_name))
12467         {
12468           file_name_set = 1;
12469         }
12470       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12471         ;
12472       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12473         use_custom_mac = 1;
12474       else if (unformat (i, "server"))
12475         is_server = 1;
12476       else if (unformat (i, "disable_mrg_rxbuf"))
12477         disable_mrg_rxbuf = 1;
12478       else if (unformat (i, "disable_indirect_desc"))
12479         disable_indirect_desc = 1;
12480       else if (unformat (i, "gso"))
12481         enable_gso = 1;
12482       else if (unformat (i, "packed"))
12483         enable_packed = 1;
12484       else if (unformat (i, "tag %s", &tag))
12485         ;
12486       else
12487         break;
12488     }
12489
12490   if (file_name_set == 0)
12491     {
12492       errmsg ("missing socket file name");
12493       return -99;
12494     }
12495
12496   if (vec_len (file_name) > 255)
12497     {
12498       errmsg ("socket file name too long");
12499       return -99;
12500     }
12501   vec_add1 (file_name, 0);
12502
12503   M (CREATE_VHOST_USER_IF, mp);
12504
12505   mp->is_server = is_server;
12506   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12507   mp->disable_indirect_desc = disable_indirect_desc;
12508   mp->enable_gso = enable_gso;
12509   mp->enable_packed = enable_packed;
12510   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12511   vec_free (file_name);
12512   if (custom_dev_instance != ~0)
12513     {
12514       mp->renumber = 1;
12515       mp->custom_dev_instance = ntohl (custom_dev_instance);
12516     }
12517
12518   mp->use_custom_mac = use_custom_mac;
12519   clib_memcpy (mp->mac_address, hwaddr, 6);
12520   if (tag)
12521     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12522   vec_free (tag);
12523
12524   S (mp);
12525   W (ret);
12526   return ret;
12527 }
12528
12529 static int
12530 api_modify_vhost_user_if (vat_main_t * vam)
12531 {
12532   unformat_input_t *i = vam->input;
12533   vl_api_modify_vhost_user_if_t *mp;
12534   u8 *file_name;
12535   u8 is_server = 0;
12536   u8 file_name_set = 0;
12537   u32 custom_dev_instance = ~0;
12538   u8 sw_if_index_set = 0;
12539   u32 sw_if_index = (u32) ~ 0;
12540   u8 enable_gso = 0;
12541   u8 enable_packed = 0;
12542   int ret;
12543
12544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12545     {
12546       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12547         sw_if_index_set = 1;
12548       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12549         sw_if_index_set = 1;
12550       else if (unformat (i, "socket %s", &file_name))
12551         {
12552           file_name_set = 1;
12553         }
12554       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12555         ;
12556       else if (unformat (i, "server"))
12557         is_server = 1;
12558       else if (unformat (i, "gso"))
12559         enable_gso = 1;
12560       else if (unformat (i, "packed"))
12561         enable_packed = 1;
12562       else
12563         break;
12564     }
12565
12566   if (sw_if_index_set == 0)
12567     {
12568       errmsg ("missing sw_if_index or interface name");
12569       return -99;
12570     }
12571
12572   if (file_name_set == 0)
12573     {
12574       errmsg ("missing socket file name");
12575       return -99;
12576     }
12577
12578   if (vec_len (file_name) > 255)
12579     {
12580       errmsg ("socket file name too long");
12581       return -99;
12582     }
12583   vec_add1 (file_name, 0);
12584
12585   M (MODIFY_VHOST_USER_IF, mp);
12586
12587   mp->sw_if_index = ntohl (sw_if_index);
12588   mp->is_server = is_server;
12589   mp->enable_gso = enable_gso;
12590   mp->enable_packed = enable_packed;
12591   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12592   vec_free (file_name);
12593   if (custom_dev_instance != ~0)
12594     {
12595       mp->renumber = 1;
12596       mp->custom_dev_instance = ntohl (custom_dev_instance);
12597     }
12598
12599   S (mp);
12600   W (ret);
12601   return ret;
12602 }
12603
12604 static int
12605 api_delete_vhost_user_if (vat_main_t * vam)
12606 {
12607   unformat_input_t *i = vam->input;
12608   vl_api_delete_vhost_user_if_t *mp;
12609   u32 sw_if_index = ~0;
12610   u8 sw_if_index_set = 0;
12611   int ret;
12612
12613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12614     {
12615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12616         sw_if_index_set = 1;
12617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12618         sw_if_index_set = 1;
12619       else
12620         break;
12621     }
12622
12623   if (sw_if_index_set == 0)
12624     {
12625       errmsg ("missing sw_if_index or interface name");
12626       return -99;
12627     }
12628
12629
12630   M (DELETE_VHOST_USER_IF, mp);
12631
12632   mp->sw_if_index = ntohl (sw_if_index);
12633
12634   S (mp);
12635   W (ret);
12636   return ret;
12637 }
12638
12639 static void vl_api_sw_interface_vhost_user_details_t_handler
12640   (vl_api_sw_interface_vhost_user_details_t * mp)
12641 {
12642   vat_main_t *vam = &vat_main;
12643   u64 features;
12644
12645   features =
12646     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12647                                                     clib_net_to_host_u32
12648                                                     (mp->features_last_32) <<
12649                                                     32);
12650
12651   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12652          (char *) mp->interface_name,
12653          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12654          features, mp->is_server,
12655          ntohl (mp->num_regions), (char *) mp->sock_filename);
12656   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12657 }
12658
12659 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12660   (vl_api_sw_interface_vhost_user_details_t * mp)
12661 {
12662   vat_main_t *vam = &vat_main;
12663   vat_json_node_t *node = NULL;
12664
12665   if (VAT_JSON_ARRAY != vam->json_tree.type)
12666     {
12667       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12668       vat_json_init_array (&vam->json_tree);
12669     }
12670   node = vat_json_array_add (&vam->json_tree);
12671
12672   vat_json_init_object (node);
12673   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12674   vat_json_object_add_string_copy (node, "interface_name",
12675                                    mp->interface_name);
12676   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12677                             ntohl (mp->virtio_net_hdr_sz));
12678   vat_json_object_add_uint (node, "features_first_32",
12679                             clib_net_to_host_u32 (mp->features_first_32));
12680   vat_json_object_add_uint (node, "features_last_32",
12681                             clib_net_to_host_u32 (mp->features_last_32));
12682   vat_json_object_add_uint (node, "is_server", mp->is_server);
12683   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12684   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12685   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12686 }
12687
12688 static int
12689 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12690 {
12691   unformat_input_t *i = vam->input;
12692   vl_api_sw_interface_vhost_user_dump_t *mp;
12693   vl_api_control_ping_t *mp_ping;
12694   int ret;
12695   u32 sw_if_index = ~0;
12696
12697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12698     {
12699       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12700         ;
12701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12702         ;
12703       else
12704         break;
12705     }
12706
12707   print (vam->ofp,
12708          "Interface name            idx hdr_sz features server regions filename");
12709
12710   /* Get list of vhost-user interfaces */
12711   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12712   mp->sw_if_index = ntohl (sw_if_index);
12713   S (mp);
12714
12715   /* Use a control ping for synchronization */
12716   MPING (CONTROL_PING, mp_ping);
12717   S (mp_ping);
12718
12719   W (ret);
12720   return ret;
12721 }
12722
12723 static int
12724 api_show_version (vat_main_t * vam)
12725 {
12726   vl_api_show_version_t *mp;
12727   int ret;
12728
12729   M (SHOW_VERSION, mp);
12730
12731   S (mp);
12732   W (ret);
12733   return ret;
12734 }
12735
12736
12737 static int
12738 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12739 {
12740   unformat_input_t *line_input = vam->input;
12741   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12742   ip46_address_t local, remote;
12743   u8 is_add = 1;
12744   u8 local_set = 0;
12745   u8 remote_set = 0;
12746   u8 grp_set = 0;
12747   u32 mcast_sw_if_index = ~0;
12748   u32 encap_vrf_id = 0;
12749   u32 decap_vrf_id = 0;
12750   u8 protocol = ~0;
12751   u32 vni;
12752   u8 vni_set = 0;
12753   int ret;
12754
12755   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12756     {
12757       if (unformat (line_input, "del"))
12758         is_add = 0;
12759       else if (unformat (line_input, "local %U",
12760                          unformat_ip46_address, &local))
12761         {
12762           local_set = 1;
12763         }
12764       else if (unformat (line_input, "remote %U",
12765                          unformat_ip46_address, &remote))
12766         {
12767           remote_set = 1;
12768         }
12769       else if (unformat (line_input, "group %U %U",
12770                          unformat_ip46_address, &remote,
12771                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12772         {
12773           grp_set = remote_set = 1;
12774         }
12775       else if (unformat (line_input, "group %U",
12776                          unformat_ip46_address, &remote))
12777         {
12778           grp_set = remote_set = 1;
12779         }
12780       else
12781         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12782         ;
12783       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12784         ;
12785       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12786         ;
12787       else if (unformat (line_input, "vni %d", &vni))
12788         vni_set = 1;
12789       else if (unformat (line_input, "next-ip4"))
12790         protocol = 1;
12791       else if (unformat (line_input, "next-ip6"))
12792         protocol = 2;
12793       else if (unformat (line_input, "next-ethernet"))
12794         protocol = 3;
12795       else if (unformat (line_input, "next-nsh"))
12796         protocol = 4;
12797       else
12798         {
12799           errmsg ("parse error '%U'", format_unformat_error, line_input);
12800           return -99;
12801         }
12802     }
12803
12804   if (local_set == 0)
12805     {
12806       errmsg ("tunnel local address not specified");
12807       return -99;
12808     }
12809   if (remote_set == 0)
12810     {
12811       errmsg ("tunnel remote address not specified");
12812       return -99;
12813     }
12814   if (grp_set && mcast_sw_if_index == ~0)
12815     {
12816       errmsg ("tunnel nonexistent multicast device");
12817       return -99;
12818     }
12819   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12820     {
12821       errmsg ("both IPv4 and IPv6 addresses specified");
12822       return -99;
12823     }
12824
12825   if (vni_set == 0)
12826     {
12827       errmsg ("vni not specified");
12828       return -99;
12829     }
12830
12831   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12832
12833   ip_address_encode (&local,
12834                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12835                      IP46_TYPE_IP6, &mp->local);
12836   ip_address_encode (&remote,
12837                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12838                      IP46_TYPE_IP6, &mp->remote);
12839
12840   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12841   mp->encap_vrf_id = ntohl (encap_vrf_id);
12842   mp->decap_vrf_id = ntohl (decap_vrf_id);
12843   mp->protocol = protocol;
12844   mp->vni = ntohl (vni);
12845   mp->is_add = is_add;
12846
12847   S (mp);
12848   W (ret);
12849   return ret;
12850 }
12851
12852 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12853   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12854 {
12855   vat_main_t *vam = &vat_main;
12856   ip46_address_t local, remote;
12857
12858   ip_address_decode (&mp->local, &local);
12859   ip_address_decode (&mp->remote, &remote);
12860
12861   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12862          ntohl (mp->sw_if_index),
12863          format_ip46_address, &local, IP46_TYPE_ANY,
12864          format_ip46_address, &remote, IP46_TYPE_ANY,
12865          ntohl (mp->vni), mp->protocol,
12866          ntohl (mp->mcast_sw_if_index),
12867          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12868 }
12869
12870
12871 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12872   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12873 {
12874   vat_main_t *vam = &vat_main;
12875   vat_json_node_t *node = NULL;
12876   struct in_addr ip4;
12877   struct in6_addr ip6;
12878   ip46_address_t local, remote;
12879
12880   ip_address_decode (&mp->local, &local);
12881   ip_address_decode (&mp->remote, &remote);
12882
12883   if (VAT_JSON_ARRAY != vam->json_tree.type)
12884     {
12885       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12886       vat_json_init_array (&vam->json_tree);
12887     }
12888   node = vat_json_array_add (&vam->json_tree);
12889
12890   vat_json_init_object (node);
12891   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12892   if (ip46_address_is_ip4 (&local))
12893     {
12894       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12895       vat_json_object_add_ip4 (node, "local", ip4);
12896       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12897       vat_json_object_add_ip4 (node, "remote", ip4);
12898     }
12899   else
12900     {
12901       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12902       vat_json_object_add_ip6 (node, "local", ip6);
12903       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12904       vat_json_object_add_ip6 (node, "remote", ip6);
12905     }
12906   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12907   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12908   vat_json_object_add_uint (node, "mcast_sw_if_index",
12909                             ntohl (mp->mcast_sw_if_index));
12910   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12911   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12912   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12913 }
12914
12915 static int
12916 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12917 {
12918   unformat_input_t *i = vam->input;
12919   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12920   vl_api_control_ping_t *mp_ping;
12921   u32 sw_if_index;
12922   u8 sw_if_index_set = 0;
12923   int ret;
12924
12925   /* Parse args required to build the message */
12926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12927     {
12928       if (unformat (i, "sw_if_index %d", &sw_if_index))
12929         sw_if_index_set = 1;
12930       else
12931         break;
12932     }
12933
12934   if (sw_if_index_set == 0)
12935     {
12936       sw_if_index = ~0;
12937     }
12938
12939   if (!vam->json_output)
12940     {
12941       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12942              "sw_if_index", "local", "remote", "vni",
12943              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12944     }
12945
12946   /* Get list of vxlan-tunnel interfaces */
12947   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12948
12949   mp->sw_if_index = htonl (sw_if_index);
12950
12951   S (mp);
12952
12953   /* Use a control ping for synchronization */
12954   MPING (CONTROL_PING, mp_ping);
12955   S (mp_ping);
12956
12957   W (ret);
12958   return ret;
12959 }
12960
12961 static void vl_api_l2_fib_table_details_t_handler
12962   (vl_api_l2_fib_table_details_t * mp)
12963 {
12964   vat_main_t *vam = &vat_main;
12965
12966   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12967          "       %d       %d     %d",
12968          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12969          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12970          mp->bvi_mac);
12971 }
12972
12973 static void vl_api_l2_fib_table_details_t_handler_json
12974   (vl_api_l2_fib_table_details_t * mp)
12975 {
12976   vat_main_t *vam = &vat_main;
12977   vat_json_node_t *node = NULL;
12978
12979   if (VAT_JSON_ARRAY != vam->json_tree.type)
12980     {
12981       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12982       vat_json_init_array (&vam->json_tree);
12983     }
12984   node = vat_json_array_add (&vam->json_tree);
12985
12986   vat_json_init_object (node);
12987   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12988   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12989   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12990   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12991   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12992   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12993 }
12994
12995 static int
12996 api_l2_fib_table_dump (vat_main_t * vam)
12997 {
12998   unformat_input_t *i = vam->input;
12999   vl_api_l2_fib_table_dump_t *mp;
13000   vl_api_control_ping_t *mp_ping;
13001   u32 bd_id;
13002   u8 bd_id_set = 0;
13003   int ret;
13004
13005   /* Parse args required to build the message */
13006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13007     {
13008       if (unformat (i, "bd_id %d", &bd_id))
13009         bd_id_set = 1;
13010       else
13011         break;
13012     }
13013
13014   if (bd_id_set == 0)
13015     {
13016       errmsg ("missing bridge domain");
13017       return -99;
13018     }
13019
13020   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13021
13022   /* Get list of l2 fib entries */
13023   M (L2_FIB_TABLE_DUMP, mp);
13024
13025   mp->bd_id = ntohl (bd_id);
13026   S (mp);
13027
13028   /* Use a control ping for synchronization */
13029   MPING (CONTROL_PING, mp_ping);
13030   S (mp_ping);
13031
13032   W (ret);
13033   return ret;
13034 }
13035
13036
13037 static int
13038 api_interface_name_renumber (vat_main_t * vam)
13039 {
13040   unformat_input_t *line_input = vam->input;
13041   vl_api_interface_name_renumber_t *mp;
13042   u32 sw_if_index = ~0;
13043   u32 new_show_dev_instance = ~0;
13044   int ret;
13045
13046   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13047     {
13048       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13049                     &sw_if_index))
13050         ;
13051       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13052         ;
13053       else if (unformat (line_input, "new_show_dev_instance %d",
13054                          &new_show_dev_instance))
13055         ;
13056       else
13057         break;
13058     }
13059
13060   if (sw_if_index == ~0)
13061     {
13062       errmsg ("missing interface name or sw_if_index");
13063       return -99;
13064     }
13065
13066   if (new_show_dev_instance == ~0)
13067     {
13068       errmsg ("missing new_show_dev_instance");
13069       return -99;
13070     }
13071
13072   M (INTERFACE_NAME_RENUMBER, mp);
13073
13074   mp->sw_if_index = ntohl (sw_if_index);
13075   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13076
13077   S (mp);
13078   W (ret);
13079   return ret;
13080 }
13081
13082 static int
13083 api_want_l2_macs_events (vat_main_t * vam)
13084 {
13085   unformat_input_t *line_input = vam->input;
13086   vl_api_want_l2_macs_events_t *mp;
13087   u8 enable_disable = 1;
13088   u32 scan_delay = 0;
13089   u32 max_macs_in_event = 0;
13090   u32 learn_limit = 0;
13091   int ret;
13092
13093   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13094     {
13095       if (unformat (line_input, "learn-limit %d", &learn_limit))
13096         ;
13097       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13098         ;
13099       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13100         ;
13101       else if (unformat (line_input, "disable"))
13102         enable_disable = 0;
13103       else
13104         break;
13105     }
13106
13107   M (WANT_L2_MACS_EVENTS, mp);
13108   mp->enable_disable = enable_disable;
13109   mp->pid = htonl (getpid ());
13110   mp->learn_limit = htonl (learn_limit);
13111   mp->scan_delay = (u8) scan_delay;
13112   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13113   S (mp);
13114   W (ret);
13115   return ret;
13116 }
13117
13118 static int
13119 api_input_acl_set_interface (vat_main_t * vam)
13120 {
13121   unformat_input_t *i = vam->input;
13122   vl_api_input_acl_set_interface_t *mp;
13123   u32 sw_if_index;
13124   int sw_if_index_set;
13125   u32 ip4_table_index = ~0;
13126   u32 ip6_table_index = ~0;
13127   u32 l2_table_index = ~0;
13128   u8 is_add = 1;
13129   int ret;
13130
13131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13132     {
13133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13134         sw_if_index_set = 1;
13135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13136         sw_if_index_set = 1;
13137       else if (unformat (i, "del"))
13138         is_add = 0;
13139       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13140         ;
13141       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13142         ;
13143       else if (unformat (i, "l2-table %d", &l2_table_index))
13144         ;
13145       else
13146         {
13147           clib_warning ("parse error '%U'", format_unformat_error, i);
13148           return -99;
13149         }
13150     }
13151
13152   if (sw_if_index_set == 0)
13153     {
13154       errmsg ("missing interface name or sw_if_index");
13155       return -99;
13156     }
13157
13158   M (INPUT_ACL_SET_INTERFACE, mp);
13159
13160   mp->sw_if_index = ntohl (sw_if_index);
13161   mp->ip4_table_index = ntohl (ip4_table_index);
13162   mp->ip6_table_index = ntohl (ip6_table_index);
13163   mp->l2_table_index = ntohl (l2_table_index);
13164   mp->is_add = is_add;
13165
13166   S (mp);
13167   W (ret);
13168   return ret;
13169 }
13170
13171 static int
13172 api_output_acl_set_interface (vat_main_t * vam)
13173 {
13174   unformat_input_t *i = vam->input;
13175   vl_api_output_acl_set_interface_t *mp;
13176   u32 sw_if_index;
13177   int sw_if_index_set;
13178   u32 ip4_table_index = ~0;
13179   u32 ip6_table_index = ~0;
13180   u32 l2_table_index = ~0;
13181   u8 is_add = 1;
13182   int ret;
13183
13184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13185     {
13186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13187         sw_if_index_set = 1;
13188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13189         sw_if_index_set = 1;
13190       else if (unformat (i, "del"))
13191         is_add = 0;
13192       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13193         ;
13194       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13195         ;
13196       else if (unformat (i, "l2-table %d", &l2_table_index))
13197         ;
13198       else
13199         {
13200           clib_warning ("parse error '%U'", format_unformat_error, i);
13201           return -99;
13202         }
13203     }
13204
13205   if (sw_if_index_set == 0)
13206     {
13207       errmsg ("missing interface name or sw_if_index");
13208       return -99;
13209     }
13210
13211   M (OUTPUT_ACL_SET_INTERFACE, mp);
13212
13213   mp->sw_if_index = ntohl (sw_if_index);
13214   mp->ip4_table_index = ntohl (ip4_table_index);
13215   mp->ip6_table_index = ntohl (ip6_table_index);
13216   mp->l2_table_index = ntohl (l2_table_index);
13217   mp->is_add = is_add;
13218
13219   S (mp);
13220   W (ret);
13221   return ret;
13222 }
13223
13224 static int
13225 api_ip_address_dump (vat_main_t * vam)
13226 {
13227   unformat_input_t *i = vam->input;
13228   vl_api_ip_address_dump_t *mp;
13229   vl_api_control_ping_t *mp_ping;
13230   u32 sw_if_index = ~0;
13231   u8 sw_if_index_set = 0;
13232   u8 ipv4_set = 0;
13233   u8 ipv6_set = 0;
13234   int ret;
13235
13236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13237     {
13238       if (unformat (i, "sw_if_index %d", &sw_if_index))
13239         sw_if_index_set = 1;
13240       else
13241         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13242         sw_if_index_set = 1;
13243       else if (unformat (i, "ipv4"))
13244         ipv4_set = 1;
13245       else if (unformat (i, "ipv6"))
13246         ipv6_set = 1;
13247       else
13248         break;
13249     }
13250
13251   if (ipv4_set && ipv6_set)
13252     {
13253       errmsg ("ipv4 and ipv6 flags cannot be both set");
13254       return -99;
13255     }
13256
13257   if ((!ipv4_set) && (!ipv6_set))
13258     {
13259       errmsg ("no ipv4 nor ipv6 flag set");
13260       return -99;
13261     }
13262
13263   if (sw_if_index_set == 0)
13264     {
13265       errmsg ("missing interface name or sw_if_index");
13266       return -99;
13267     }
13268
13269   vam->current_sw_if_index = sw_if_index;
13270   vam->is_ipv6 = ipv6_set;
13271
13272   M (IP_ADDRESS_DUMP, mp);
13273   mp->sw_if_index = ntohl (sw_if_index);
13274   mp->is_ipv6 = ipv6_set;
13275   S (mp);
13276
13277   /* Use a control ping for synchronization */
13278   MPING (CONTROL_PING, mp_ping);
13279   S (mp_ping);
13280
13281   W (ret);
13282   return ret;
13283 }
13284
13285 static int
13286 api_ip_dump (vat_main_t * vam)
13287 {
13288   vl_api_ip_dump_t *mp;
13289   vl_api_control_ping_t *mp_ping;
13290   unformat_input_t *in = vam->input;
13291   int ipv4_set = 0;
13292   int ipv6_set = 0;
13293   int is_ipv6;
13294   int i;
13295   int ret;
13296
13297   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13298     {
13299       if (unformat (in, "ipv4"))
13300         ipv4_set = 1;
13301       else if (unformat (in, "ipv6"))
13302         ipv6_set = 1;
13303       else
13304         break;
13305     }
13306
13307   if (ipv4_set && ipv6_set)
13308     {
13309       errmsg ("ipv4 and ipv6 flags cannot be both set");
13310       return -99;
13311     }
13312
13313   if ((!ipv4_set) && (!ipv6_set))
13314     {
13315       errmsg ("no ipv4 nor ipv6 flag set");
13316       return -99;
13317     }
13318
13319   is_ipv6 = ipv6_set;
13320   vam->is_ipv6 = is_ipv6;
13321
13322   /* free old data */
13323   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13324     {
13325       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13326     }
13327   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13328
13329   M (IP_DUMP, mp);
13330   mp->is_ipv6 = ipv6_set;
13331   S (mp);
13332
13333   /* Use a control ping for synchronization */
13334   MPING (CONTROL_PING, mp_ping);
13335   S (mp_ping);
13336
13337   W (ret);
13338   return ret;
13339 }
13340
13341 static int
13342 api_ipsec_spd_add_del (vat_main_t * vam)
13343 {
13344   unformat_input_t *i = vam->input;
13345   vl_api_ipsec_spd_add_del_t *mp;
13346   u32 spd_id = ~0;
13347   u8 is_add = 1;
13348   int ret;
13349
13350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13351     {
13352       if (unformat (i, "spd_id %d", &spd_id))
13353         ;
13354       else if (unformat (i, "del"))
13355         is_add = 0;
13356       else
13357         {
13358           clib_warning ("parse error '%U'", format_unformat_error, i);
13359           return -99;
13360         }
13361     }
13362   if (spd_id == ~0)
13363     {
13364       errmsg ("spd_id must be set");
13365       return -99;
13366     }
13367
13368   M (IPSEC_SPD_ADD_DEL, mp);
13369
13370   mp->spd_id = ntohl (spd_id);
13371   mp->is_add = is_add;
13372
13373   S (mp);
13374   W (ret);
13375   return ret;
13376 }
13377
13378 static int
13379 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13380 {
13381   unformat_input_t *i = vam->input;
13382   vl_api_ipsec_interface_add_del_spd_t *mp;
13383   u32 sw_if_index;
13384   u8 sw_if_index_set = 0;
13385   u32 spd_id = (u32) ~ 0;
13386   u8 is_add = 1;
13387   int ret;
13388
13389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13390     {
13391       if (unformat (i, "del"))
13392         is_add = 0;
13393       else if (unformat (i, "spd_id %d", &spd_id))
13394         ;
13395       else
13396         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13397         sw_if_index_set = 1;
13398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13399         sw_if_index_set = 1;
13400       else
13401         {
13402           clib_warning ("parse error '%U'", format_unformat_error, i);
13403           return -99;
13404         }
13405
13406     }
13407
13408   if (spd_id == (u32) ~ 0)
13409     {
13410       errmsg ("spd_id must be 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   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13421
13422   mp->spd_id = ntohl (spd_id);
13423   mp->sw_if_index = ntohl (sw_if_index);
13424   mp->is_add = is_add;
13425
13426   S (mp);
13427   W (ret);
13428   return ret;
13429 }
13430
13431 static int
13432 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13433 {
13434   unformat_input_t *i = vam->input;
13435   vl_api_ipsec_spd_entry_add_del_t *mp;
13436   u8 is_add = 1, is_outbound = 0;
13437   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13438   i32 priority = 0;
13439   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13440   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13441   vl_api_address_t laddr_start = { }, laddr_stop =
13442   {
13443   }, raddr_start =
13444   {
13445   }, raddr_stop =
13446   {
13447   };
13448   int ret;
13449
13450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13451     {
13452       if (unformat (i, "del"))
13453         is_add = 0;
13454       if (unformat (i, "outbound"))
13455         is_outbound = 1;
13456       if (unformat (i, "inbound"))
13457         is_outbound = 0;
13458       else if (unformat (i, "spd_id %d", &spd_id))
13459         ;
13460       else if (unformat (i, "sa_id %d", &sa_id))
13461         ;
13462       else if (unformat (i, "priority %d", &priority))
13463         ;
13464       else if (unformat (i, "protocol %d", &protocol))
13465         ;
13466       else if (unformat (i, "lport_start %d", &lport_start))
13467         ;
13468       else if (unformat (i, "lport_stop %d", &lport_stop))
13469         ;
13470       else if (unformat (i, "rport_start %d", &rport_start))
13471         ;
13472       else if (unformat (i, "rport_stop %d", &rport_stop))
13473         ;
13474       else if (unformat (i, "laddr_start %U",
13475                          unformat_vl_api_address, &laddr_start))
13476         ;
13477       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13478                          &laddr_stop))
13479         ;
13480       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13481                          &raddr_start))
13482         ;
13483       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13484                          &raddr_stop))
13485         ;
13486       else
13487         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13488         {
13489           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13490             {
13491               clib_warning ("unsupported action: 'resolve'");
13492               return -99;
13493             }
13494         }
13495       else
13496         {
13497           clib_warning ("parse error '%U'", format_unformat_error, i);
13498           return -99;
13499         }
13500
13501     }
13502
13503   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13504
13505   mp->is_add = is_add;
13506
13507   mp->entry.spd_id = ntohl (spd_id);
13508   mp->entry.priority = ntohl (priority);
13509   mp->entry.is_outbound = is_outbound;
13510
13511   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13512                sizeof (vl_api_address_t));
13513   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13514                sizeof (vl_api_address_t));
13515   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13516                sizeof (vl_api_address_t));
13517   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13518                sizeof (vl_api_address_t));
13519
13520   mp->entry.protocol = (u8) protocol;
13521   mp->entry.local_port_start = ntohs ((u16) lport_start);
13522   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13523   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13524   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13525   mp->entry.policy = (u8) policy;
13526   mp->entry.sa_id = ntohl (sa_id);
13527
13528   S (mp);
13529   W (ret);
13530   return ret;
13531 }
13532
13533 static int
13534 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13535 {
13536   unformat_input_t *i = vam->input;
13537   vl_api_ipsec_sad_entry_add_del_t *mp;
13538   u32 sad_id = 0, spi = 0;
13539   u8 *ck = 0, *ik = 0;
13540   u8 is_add = 1;
13541
13542   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13543   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13544   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13545   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13546   vl_api_address_t tun_src, tun_dst;
13547   int ret;
13548
13549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13550     {
13551       if (unformat (i, "del"))
13552         is_add = 0;
13553       else if (unformat (i, "sad_id %d", &sad_id))
13554         ;
13555       else if (unformat (i, "spi %d", &spi))
13556         ;
13557       else if (unformat (i, "esp"))
13558         protocol = IPSEC_API_PROTO_ESP;
13559       else
13560         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13561         {
13562           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13563           if (ADDRESS_IP6 == tun_src.af)
13564             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13565         }
13566       else
13567         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13568         {
13569           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13570           if (ADDRESS_IP6 == tun_src.af)
13571             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13572         }
13573       else
13574         if (unformat (i, "crypto_alg %U",
13575                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13576         ;
13577       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13578         ;
13579       else if (unformat (i, "integ_alg %U",
13580                          unformat_ipsec_api_integ_alg, &integ_alg))
13581         ;
13582       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13583         ;
13584       else
13585         {
13586           clib_warning ("parse error '%U'", format_unformat_error, i);
13587           return -99;
13588         }
13589
13590     }
13591
13592   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13593
13594   mp->is_add = is_add;
13595   mp->entry.sad_id = ntohl (sad_id);
13596   mp->entry.protocol = protocol;
13597   mp->entry.spi = ntohl (spi);
13598   mp->entry.flags = flags;
13599
13600   mp->entry.crypto_algorithm = crypto_alg;
13601   mp->entry.integrity_algorithm = integ_alg;
13602   mp->entry.crypto_key.length = vec_len (ck);
13603   mp->entry.integrity_key.length = vec_len (ik);
13604
13605   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13606     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13607
13608   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13609     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13610
13611   if (ck)
13612     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13613   if (ik)
13614     clib_memcpy (mp->entry.integrity_key.data, ik,
13615                  mp->entry.integrity_key.length);
13616
13617   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13618     {
13619       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13620                    sizeof (mp->entry.tunnel_src));
13621       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13622                    sizeof (mp->entry.tunnel_dst));
13623     }
13624
13625   S (mp);
13626   W (ret);
13627   return ret;
13628 }
13629
13630 static int
13631 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13632 {
13633   unformat_input_t *i = vam->input;
13634   vl_api_ipsec_tunnel_if_add_del_t *mp;
13635   u32 local_spi = 0, remote_spi = 0;
13636   u32 crypto_alg = 0, integ_alg = 0;
13637   u8 *lck = NULL, *rck = NULL;
13638   u8 *lik = NULL, *rik = NULL;
13639   vl_api_address_t local_ip = { 0 };
13640   vl_api_address_t remote_ip = { 0 };
13641   f64 before = 0;
13642   u8 is_add = 1;
13643   u8 esn = 0;
13644   u8 anti_replay = 0;
13645   u8 renumber = 0;
13646   u32 instance = ~0;
13647   u32 count = 1, jj;
13648   int ret = -1;
13649
13650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13651     {
13652       if (unformat (i, "del"))
13653         is_add = 0;
13654       else if (unformat (i, "esn"))
13655         esn = 1;
13656       else if (unformat (i, "anti-replay"))
13657         anti_replay = 1;
13658       else if (unformat (i, "count %d", &count))
13659         ;
13660       else if (unformat (i, "local_spi %d", &local_spi))
13661         ;
13662       else if (unformat (i, "remote_spi %d", &remote_spi))
13663         ;
13664       else
13665         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13666         ;
13667       else
13668         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13669         ;
13670       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13671         ;
13672       else
13673         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13674         ;
13675       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13676         ;
13677       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13678         ;
13679       else
13680         if (unformat
13681             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13682         {
13683           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13684             {
13685               errmsg ("unsupported crypto-alg: '%U'\n",
13686                       format_ipsec_crypto_alg, crypto_alg);
13687               return -99;
13688             }
13689         }
13690       else
13691         if (unformat
13692             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13693         {
13694           if (integ_alg >= IPSEC_INTEG_N_ALG)
13695             {
13696               errmsg ("unsupported integ-alg: '%U'\n",
13697                       format_ipsec_integ_alg, integ_alg);
13698               return -99;
13699             }
13700         }
13701       else if (unformat (i, "instance %u", &instance))
13702         renumber = 1;
13703       else
13704         {
13705           errmsg ("parse error '%U'\n", format_unformat_error, i);
13706           return -99;
13707         }
13708     }
13709
13710   if (count > 1)
13711     {
13712       /* Turn on async mode */
13713       vam->async_mode = 1;
13714       vam->async_errors = 0;
13715       before = vat_time_now (vam);
13716     }
13717
13718   for (jj = 0; jj < count; jj++)
13719     {
13720       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13721
13722       mp->is_add = is_add;
13723       mp->esn = esn;
13724       mp->anti_replay = anti_replay;
13725
13726       if (jj > 0)
13727         increment_address (&remote_ip);
13728
13729       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13730       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13731
13732       mp->local_spi = htonl (local_spi + jj);
13733       mp->remote_spi = htonl (remote_spi + jj);
13734       mp->crypto_alg = (u8) crypto_alg;
13735
13736       mp->local_crypto_key_len = 0;
13737       if (lck)
13738         {
13739           mp->local_crypto_key_len = vec_len (lck);
13740           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13741             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13742           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13743         }
13744
13745       mp->remote_crypto_key_len = 0;
13746       if (rck)
13747         {
13748           mp->remote_crypto_key_len = vec_len (rck);
13749           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13750             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13751           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13752         }
13753
13754       mp->integ_alg = (u8) integ_alg;
13755
13756       mp->local_integ_key_len = 0;
13757       if (lik)
13758         {
13759           mp->local_integ_key_len = vec_len (lik);
13760           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13761             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13762           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13763         }
13764
13765       mp->remote_integ_key_len = 0;
13766       if (rik)
13767         {
13768           mp->remote_integ_key_len = vec_len (rik);
13769           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13770             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13771           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13772         }
13773
13774       if (renumber)
13775         {
13776           mp->renumber = renumber;
13777           mp->show_instance = ntohl (instance);
13778         }
13779       S (mp);
13780     }
13781
13782   /* When testing multiple add/del ops, use a control-ping to sync */
13783   if (count > 1)
13784     {
13785       vl_api_control_ping_t *mp_ping;
13786       f64 after;
13787       f64 timeout;
13788
13789       /* Shut off async mode */
13790       vam->async_mode = 0;
13791
13792       MPING (CONTROL_PING, mp_ping);
13793       S (mp_ping);
13794
13795       timeout = vat_time_now (vam) + 1.0;
13796       while (vat_time_now (vam) < timeout)
13797         if (vam->result_ready == 1)
13798           goto out;
13799       vam->retval = -99;
13800
13801     out:
13802       if (vam->retval == -99)
13803         errmsg ("timeout");
13804
13805       if (vam->async_errors > 0)
13806         {
13807           errmsg ("%d asynchronous errors", vam->async_errors);
13808           vam->retval = -98;
13809         }
13810       vam->async_errors = 0;
13811       after = vat_time_now (vam);
13812
13813       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13814       if (jj > 0)
13815         count = jj;
13816
13817       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13818              count, after - before, count / (after - before));
13819     }
13820   else
13821     {
13822       /* Wait for a reply... */
13823       W (ret);
13824       return ret;
13825     }
13826
13827   return ret;
13828 }
13829
13830 static void
13831 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13832 {
13833   vat_main_t *vam = &vat_main;
13834
13835   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13836          "crypto_key %U integ_alg %u integ_key %U flags %x "
13837          "tunnel_src_addr %U tunnel_dst_addr %U "
13838          "salt %u seq_outbound %lu last_seq_inbound %lu "
13839          "replay_window %lu stat_index %u\n",
13840          ntohl (mp->entry.sad_id),
13841          ntohl (mp->sw_if_index),
13842          ntohl (mp->entry.spi),
13843          ntohl (mp->entry.protocol),
13844          ntohl (mp->entry.crypto_algorithm),
13845          format_hex_bytes, mp->entry.crypto_key.data,
13846          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13847          format_hex_bytes, mp->entry.integrity_key.data,
13848          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13849          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13850          &mp->entry.tunnel_dst, ntohl (mp->salt),
13851          clib_net_to_host_u64 (mp->seq_outbound),
13852          clib_net_to_host_u64 (mp->last_seq_inbound),
13853          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13854 }
13855
13856 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13857 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13858
13859 static void vl_api_ipsec_sa_details_t_handler_json
13860   (vl_api_ipsec_sa_details_t * mp)
13861 {
13862   vat_main_t *vam = &vat_main;
13863   vat_json_node_t *node = NULL;
13864   vl_api_ipsec_sad_flags_t flags;
13865
13866   if (VAT_JSON_ARRAY != vam->json_tree.type)
13867     {
13868       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13869       vat_json_init_array (&vam->json_tree);
13870     }
13871   node = vat_json_array_add (&vam->json_tree);
13872
13873   vat_json_init_object (node);
13874   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13875   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13876   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13877   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13878   vat_json_object_add_uint (node, "crypto_alg",
13879                             ntohl (mp->entry.crypto_algorithm));
13880   vat_json_object_add_uint (node, "integ_alg",
13881                             ntohl (mp->entry.integrity_algorithm));
13882   flags = ntohl (mp->entry.flags);
13883   vat_json_object_add_uint (node, "use_esn",
13884                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13885   vat_json_object_add_uint (node, "use_anti_replay",
13886                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13887   vat_json_object_add_uint (node, "is_tunnel",
13888                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13889   vat_json_object_add_uint (node, "is_tunnel_ip6",
13890                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13891   vat_json_object_add_uint (node, "udp_encap",
13892                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13893   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13894                              mp->entry.crypto_key.length);
13895   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13896                              mp->entry.integrity_key.length);
13897   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13898   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13899   vat_json_object_add_uint (node, "replay_window",
13900                             clib_net_to_host_u64 (mp->replay_window));
13901   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13902 }
13903
13904 static int
13905 api_ipsec_sa_dump (vat_main_t * vam)
13906 {
13907   unformat_input_t *i = vam->input;
13908   vl_api_ipsec_sa_dump_t *mp;
13909   vl_api_control_ping_t *mp_ping;
13910   u32 sa_id = ~0;
13911   int ret;
13912
13913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13914     {
13915       if (unformat (i, "sa_id %d", &sa_id))
13916         ;
13917       else
13918         {
13919           clib_warning ("parse error '%U'", format_unformat_error, i);
13920           return -99;
13921         }
13922     }
13923
13924   M (IPSEC_SA_DUMP, mp);
13925
13926   mp->sa_id = ntohl (sa_id);
13927
13928   S (mp);
13929
13930   /* Use a control ping for synchronization */
13931   M (CONTROL_PING, mp_ping);
13932   S (mp_ping);
13933
13934   W (ret);
13935   return ret;
13936 }
13937
13938 static int
13939 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13940 {
13941   unformat_input_t *i = vam->input;
13942   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13943   u32 sw_if_index = ~0;
13944   u32 sa_id = ~0;
13945   u8 is_outbound = (u8) ~ 0;
13946   int ret;
13947
13948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13949     {
13950       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13951         ;
13952       else if (unformat (i, "sa_id %d", &sa_id))
13953         ;
13954       else if (unformat (i, "outbound"))
13955         is_outbound = 1;
13956       else if (unformat (i, "inbound"))
13957         is_outbound = 0;
13958       else
13959         {
13960           clib_warning ("parse error '%U'", format_unformat_error, i);
13961           return -99;
13962         }
13963     }
13964
13965   if (sw_if_index == ~0)
13966     {
13967       errmsg ("interface must be specified");
13968       return -99;
13969     }
13970
13971   if (sa_id == ~0)
13972     {
13973       errmsg ("SA ID must be specified");
13974       return -99;
13975     }
13976
13977   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13978
13979   mp->sw_if_index = htonl (sw_if_index);
13980   mp->sa_id = htonl (sa_id);
13981   mp->is_outbound = is_outbound;
13982
13983   S (mp);
13984   W (ret);
13985
13986   return ret;
13987 }
13988
13989 static int
13990 api_get_first_msg_id (vat_main_t * vam)
13991 {
13992   vl_api_get_first_msg_id_t *mp;
13993   unformat_input_t *i = vam->input;
13994   u8 *name;
13995   u8 name_set = 0;
13996   int ret;
13997
13998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13999     {
14000       if (unformat (i, "client %s", &name))
14001         name_set = 1;
14002       else
14003         break;
14004     }
14005
14006   if (name_set == 0)
14007     {
14008       errmsg ("missing client name");
14009       return -99;
14010     }
14011   vec_add1 (name, 0);
14012
14013   if (vec_len (name) > 63)
14014     {
14015       errmsg ("client name too long");
14016       return -99;
14017     }
14018
14019   M (GET_FIRST_MSG_ID, mp);
14020   clib_memcpy (mp->name, name, vec_len (name));
14021   S (mp);
14022   W (ret);
14023   return ret;
14024 }
14025
14026 static int
14027 api_cop_interface_enable_disable (vat_main_t * vam)
14028 {
14029   unformat_input_t *line_input = vam->input;
14030   vl_api_cop_interface_enable_disable_t *mp;
14031   u32 sw_if_index = ~0;
14032   u8 enable_disable = 1;
14033   int ret;
14034
14035   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14036     {
14037       if (unformat (line_input, "disable"))
14038         enable_disable = 0;
14039       if (unformat (line_input, "enable"))
14040         enable_disable = 1;
14041       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14042                          vam, &sw_if_index))
14043         ;
14044       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14045         ;
14046       else
14047         break;
14048     }
14049
14050   if (sw_if_index == ~0)
14051     {
14052       errmsg ("missing interface name or sw_if_index");
14053       return -99;
14054     }
14055
14056   /* Construct the API message */
14057   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14058   mp->sw_if_index = ntohl (sw_if_index);
14059   mp->enable_disable = enable_disable;
14060
14061   /* send it... */
14062   S (mp);
14063   /* Wait for the reply */
14064   W (ret);
14065   return ret;
14066 }
14067
14068 static int
14069 api_cop_whitelist_enable_disable (vat_main_t * vam)
14070 {
14071   unformat_input_t *line_input = vam->input;
14072   vl_api_cop_whitelist_enable_disable_t *mp;
14073   u32 sw_if_index = ~0;
14074   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14075   u32 fib_id = 0;
14076   int ret;
14077
14078   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14079     {
14080       if (unformat (line_input, "ip4"))
14081         ip4 = 1;
14082       else if (unformat (line_input, "ip6"))
14083         ip6 = 1;
14084       else if (unformat (line_input, "default"))
14085         default_cop = 1;
14086       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14087                          vam, &sw_if_index))
14088         ;
14089       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14090         ;
14091       else if (unformat (line_input, "fib-id %d", &fib_id))
14092         ;
14093       else
14094         break;
14095     }
14096
14097   if (sw_if_index == ~0)
14098     {
14099       errmsg ("missing interface name or sw_if_index");
14100       return -99;
14101     }
14102
14103   /* Construct the API message */
14104   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14105   mp->sw_if_index = ntohl (sw_if_index);
14106   mp->fib_id = ntohl (fib_id);
14107   mp->ip4 = ip4;
14108   mp->ip6 = ip6;
14109   mp->default_cop = default_cop;
14110
14111   /* send it... */
14112   S (mp);
14113   /* Wait for the reply */
14114   W (ret);
14115   return ret;
14116 }
14117
14118 static int
14119 api_get_node_graph (vat_main_t * vam)
14120 {
14121   vl_api_get_node_graph_t *mp;
14122   int ret;
14123
14124   M (GET_NODE_GRAPH, mp);
14125
14126   /* send it... */
14127   S (mp);
14128   /* Wait for the reply */
14129   W (ret);
14130   return ret;
14131 }
14132
14133 /* *INDENT-OFF* */
14134 /** Used for parsing LISP eids */
14135 typedef CLIB_PACKED(struct{
14136   union {
14137           ip46_address_t ip;
14138           mac_address_t mac;
14139           lisp_nsh_api_t nsh;
14140   } addr;
14141   u32 len;       /**< prefix length if IP */
14142   u8 type;      /**< type of eid */
14143 }) lisp_eid_vat_t;
14144 /* *INDENT-ON* */
14145
14146 static uword
14147 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14148 {
14149   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14150
14151   clib_memset (a, 0, sizeof (a[0]));
14152
14153   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14154     {
14155       a->type = 0;              /* ip prefix type */
14156     }
14157   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14158     {
14159       a->type = 1;              /* mac type */
14160     }
14161   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14162     {
14163       a->type = 2;              /* NSH type */
14164       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14165     }
14166   else
14167     {
14168       return 0;
14169     }
14170
14171   if (a->type == 0)
14172     {
14173       if (ip46_address_is_ip4 (&a->addr.ip))
14174         return a->len > 32 ? 1 : 0;
14175       else
14176         return a->len > 128 ? 1 : 0;
14177     }
14178
14179   return 1;
14180 }
14181
14182 static void
14183 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14184 {
14185   eid->type = vat_eid->type;
14186   switch (eid->type)
14187     {
14188     case EID_TYPE_API_PREFIX:
14189       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14190         {
14191           clib_memcpy (&eid->address.prefix.address.un.ip4,
14192                        &vat_eid->addr.ip.ip4, 4);
14193           eid->address.prefix.address.af = ADDRESS_IP4;
14194           eid->address.prefix.len = vat_eid->len;
14195         }
14196       else
14197         {
14198           clib_memcpy (&eid->address.prefix.address.un.ip6,
14199                        &vat_eid->addr.ip.ip6, 16);
14200           eid->address.prefix.address.af = ADDRESS_IP6;
14201           eid->address.prefix.len = vat_eid->len;
14202         }
14203       return;
14204     case EID_TYPE_API_MAC:
14205       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14206                    sizeof (eid->address.mac));
14207       return;
14208     case EID_TYPE_API_NSH:
14209       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14210                    sizeof (eid->address.nsh));
14211       return;
14212     default:
14213       ASSERT (0);
14214       return;
14215     }
14216 }
14217
14218 static int
14219 api_one_add_del_locator_set (vat_main_t * vam)
14220 {
14221   unformat_input_t *input = vam->input;
14222   vl_api_one_add_del_locator_set_t *mp;
14223   u8 is_add = 1;
14224   u8 *locator_set_name = NULL;
14225   u8 locator_set_name_set = 0;
14226   vl_api_local_locator_t locator, *locators = 0;
14227   u32 sw_if_index, priority, weight;
14228   u32 data_len = 0;
14229
14230   int ret;
14231   /* Parse args required to build the message */
14232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14233     {
14234       if (unformat (input, "del"))
14235         {
14236           is_add = 0;
14237         }
14238       else if (unformat (input, "locator-set %s", &locator_set_name))
14239         {
14240           locator_set_name_set = 1;
14241         }
14242       else if (unformat (input, "sw_if_index %u p %u w %u",
14243                          &sw_if_index, &priority, &weight))
14244         {
14245           locator.sw_if_index = htonl (sw_if_index);
14246           locator.priority = priority;
14247           locator.weight = weight;
14248           vec_add1 (locators, locator);
14249         }
14250       else
14251         if (unformat
14252             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14253              &sw_if_index, &priority, &weight))
14254         {
14255           locator.sw_if_index = htonl (sw_if_index);
14256           locator.priority = priority;
14257           locator.weight = weight;
14258           vec_add1 (locators, locator);
14259         }
14260       else
14261         break;
14262     }
14263
14264   if (locator_set_name_set == 0)
14265     {
14266       errmsg ("missing locator-set name");
14267       vec_free (locators);
14268       return -99;
14269     }
14270
14271   if (vec_len (locator_set_name) > 64)
14272     {
14273       errmsg ("locator-set name too long");
14274       vec_free (locator_set_name);
14275       vec_free (locators);
14276       return -99;
14277     }
14278   vec_add1 (locator_set_name, 0);
14279
14280   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14281
14282   /* Construct the API message */
14283   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14284
14285   mp->is_add = is_add;
14286   clib_memcpy (mp->locator_set_name, locator_set_name,
14287                vec_len (locator_set_name));
14288   vec_free (locator_set_name);
14289
14290   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14291   if (locators)
14292     clib_memcpy (mp->locators, locators, data_len);
14293   vec_free (locators);
14294
14295   /* send it... */
14296   S (mp);
14297
14298   /* Wait for a reply... */
14299   W (ret);
14300   return ret;
14301 }
14302
14303 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14304
14305 static int
14306 api_one_add_del_locator (vat_main_t * vam)
14307 {
14308   unformat_input_t *input = vam->input;
14309   vl_api_one_add_del_locator_t *mp;
14310   u32 tmp_if_index = ~0;
14311   u32 sw_if_index = ~0;
14312   u8 sw_if_index_set = 0;
14313   u8 sw_if_index_if_name_set = 0;
14314   u32 priority = ~0;
14315   u8 priority_set = 0;
14316   u32 weight = ~0;
14317   u8 weight_set = 0;
14318   u8 is_add = 1;
14319   u8 *locator_set_name = NULL;
14320   u8 locator_set_name_set = 0;
14321   int ret;
14322
14323   /* Parse args required to build the message */
14324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14325     {
14326       if (unformat (input, "del"))
14327         {
14328           is_add = 0;
14329         }
14330       else if (unformat (input, "locator-set %s", &locator_set_name))
14331         {
14332           locator_set_name_set = 1;
14333         }
14334       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14335                          &tmp_if_index))
14336         {
14337           sw_if_index_if_name_set = 1;
14338           sw_if_index = tmp_if_index;
14339         }
14340       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14341         {
14342           sw_if_index_set = 1;
14343           sw_if_index = tmp_if_index;
14344         }
14345       else if (unformat (input, "p %d", &priority))
14346         {
14347           priority_set = 1;
14348         }
14349       else if (unformat (input, "w %d", &weight))
14350         {
14351           weight_set = 1;
14352         }
14353       else
14354         break;
14355     }
14356
14357   if (locator_set_name_set == 0)
14358     {
14359       errmsg ("missing locator-set name");
14360       return -99;
14361     }
14362
14363   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14364     {
14365       errmsg ("missing sw_if_index");
14366       vec_free (locator_set_name);
14367       return -99;
14368     }
14369
14370   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14371     {
14372       errmsg ("cannot use both params interface name and sw_if_index");
14373       vec_free (locator_set_name);
14374       return -99;
14375     }
14376
14377   if (priority_set == 0)
14378     {
14379       errmsg ("missing locator-set priority");
14380       vec_free (locator_set_name);
14381       return -99;
14382     }
14383
14384   if (weight_set == 0)
14385     {
14386       errmsg ("missing locator-set weight");
14387       vec_free (locator_set_name);
14388       return -99;
14389     }
14390
14391   if (vec_len (locator_set_name) > 64)
14392     {
14393       errmsg ("locator-set name too long");
14394       vec_free (locator_set_name);
14395       return -99;
14396     }
14397   vec_add1 (locator_set_name, 0);
14398
14399   /* Construct the API message */
14400   M (ONE_ADD_DEL_LOCATOR, mp);
14401
14402   mp->is_add = is_add;
14403   mp->sw_if_index = ntohl (sw_if_index);
14404   mp->priority = priority;
14405   mp->weight = weight;
14406   clib_memcpy (mp->locator_set_name, locator_set_name,
14407                vec_len (locator_set_name));
14408   vec_free (locator_set_name);
14409
14410   /* send it... */
14411   S (mp);
14412
14413   /* Wait for a reply... */
14414   W (ret);
14415   return ret;
14416 }
14417
14418 #define api_lisp_add_del_locator api_one_add_del_locator
14419
14420 uword
14421 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14422 {
14423   u32 *key_id = va_arg (*args, u32 *);
14424   u8 *s = 0;
14425
14426   if (unformat (input, "%s", &s))
14427     {
14428       if (!strcmp ((char *) s, "sha1"))
14429         key_id[0] = HMAC_SHA_1_96;
14430       else if (!strcmp ((char *) s, "sha256"))
14431         key_id[0] = HMAC_SHA_256_128;
14432       else
14433         {
14434           clib_warning ("invalid key_id: '%s'", s);
14435           key_id[0] = HMAC_NO_KEY;
14436         }
14437     }
14438   else
14439     return 0;
14440
14441   vec_free (s);
14442   return 1;
14443 }
14444
14445 static int
14446 api_one_add_del_local_eid (vat_main_t * vam)
14447 {
14448   unformat_input_t *input = vam->input;
14449   vl_api_one_add_del_local_eid_t *mp;
14450   u8 is_add = 1;
14451   u8 eid_set = 0;
14452   lisp_eid_vat_t _eid, *eid = &_eid;
14453   u8 *locator_set_name = 0;
14454   u8 locator_set_name_set = 0;
14455   u32 vni = 0;
14456   u16 key_id = 0;
14457   u8 *key = 0;
14458   int ret;
14459
14460   /* Parse args required to build the message */
14461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14462     {
14463       if (unformat (input, "del"))
14464         {
14465           is_add = 0;
14466         }
14467       else if (unformat (input, "vni %d", &vni))
14468         {
14469           ;
14470         }
14471       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14472         {
14473           eid_set = 1;
14474         }
14475       else if (unformat (input, "locator-set %s", &locator_set_name))
14476         {
14477           locator_set_name_set = 1;
14478         }
14479       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14480         ;
14481       else if (unformat (input, "secret-key %_%v%_", &key))
14482         ;
14483       else
14484         break;
14485     }
14486
14487   if (locator_set_name_set == 0)
14488     {
14489       errmsg ("missing locator-set name");
14490       return -99;
14491     }
14492
14493   if (0 == eid_set)
14494     {
14495       errmsg ("EID address not set!");
14496       vec_free (locator_set_name);
14497       return -99;
14498     }
14499
14500   if (key && (0 == key_id))
14501     {
14502       errmsg ("invalid key_id!");
14503       return -99;
14504     }
14505
14506   if (vec_len (key) > 64)
14507     {
14508       errmsg ("key too long");
14509       vec_free (key);
14510       return -99;
14511     }
14512
14513   if (vec_len (locator_set_name) > 64)
14514     {
14515       errmsg ("locator-set name too long");
14516       vec_free (locator_set_name);
14517       return -99;
14518     }
14519   vec_add1 (locator_set_name, 0);
14520
14521   /* Construct the API message */
14522   M (ONE_ADD_DEL_LOCAL_EID, mp);
14523
14524   mp->is_add = is_add;
14525   lisp_eid_put_vat (&mp->eid, eid);
14526   mp->vni = clib_host_to_net_u32 (vni);
14527   mp->key.id = key_id;
14528   clib_memcpy (mp->locator_set_name, locator_set_name,
14529                vec_len (locator_set_name));
14530   clib_memcpy (mp->key.key, key, vec_len (key));
14531
14532   vec_free (locator_set_name);
14533   vec_free (key);
14534
14535   /* send it... */
14536   S (mp);
14537
14538   /* Wait for a reply... */
14539   W (ret);
14540   return ret;
14541 }
14542
14543 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14544
14545 static int
14546 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14547 {
14548   u32 dp_table = 0, vni = 0;;
14549   unformat_input_t *input = vam->input;
14550   vl_api_gpe_add_del_fwd_entry_t *mp;
14551   u8 is_add = 1;
14552   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14553   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14554   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14555   u32 action = ~0, w;
14556   ip4_address_t rmt_rloc4, lcl_rloc4;
14557   ip6_address_t rmt_rloc6, lcl_rloc6;
14558   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14559   int ret;
14560
14561   clib_memset (&rloc, 0, sizeof (rloc));
14562
14563   /* Parse args required to build the message */
14564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14565     {
14566       if (unformat (input, "del"))
14567         is_add = 0;
14568       else if (unformat (input, "add"))
14569         is_add = 1;
14570       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14571         {
14572           rmt_eid_set = 1;
14573         }
14574       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14575         {
14576           lcl_eid_set = 1;
14577         }
14578       else if (unformat (input, "vrf %d", &dp_table))
14579         ;
14580       else if (unformat (input, "bd %d", &dp_table))
14581         ;
14582       else if (unformat (input, "vni %d", &vni))
14583         ;
14584       else if (unformat (input, "w %d", &w))
14585         {
14586           if (!curr_rloc)
14587             {
14588               errmsg ("No RLOC configured for setting priority/weight!");
14589               return -99;
14590             }
14591           curr_rloc->weight = w;
14592         }
14593       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14594                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14595         {
14596           rloc.addr.af = 0;
14597           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14598           rloc.weight = 0;
14599           vec_add1 (lcl_locs, rloc);
14600
14601           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14602           vec_add1 (rmt_locs, rloc);
14603           /* weight saved in rmt loc */
14604           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14605         }
14606       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14607                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14608         {
14609           rloc.addr.af = 1;
14610           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14611           rloc.weight = 0;
14612           vec_add1 (lcl_locs, rloc);
14613
14614           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14615           vec_add1 (rmt_locs, rloc);
14616           /* weight saved in rmt loc */
14617           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14618         }
14619       else if (unformat (input, "action %d", &action))
14620         {
14621           ;
14622         }
14623       else
14624         {
14625           clib_warning ("parse error '%U'", format_unformat_error, input);
14626           return -99;
14627         }
14628     }
14629
14630   if (!rmt_eid_set)
14631     {
14632       errmsg ("remote eid addresses not set");
14633       return -99;
14634     }
14635
14636   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14637     {
14638       errmsg ("eid types don't match");
14639       return -99;
14640     }
14641
14642   if (0 == rmt_locs && (u32) ~ 0 == action)
14643     {
14644       errmsg ("action not set for negative mapping");
14645       return -99;
14646     }
14647
14648   /* Construct the API message */
14649   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14650       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14651
14652   mp->is_add = is_add;
14653   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14654   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14655   mp->dp_table = clib_host_to_net_u32 (dp_table);
14656   mp->vni = clib_host_to_net_u32 (vni);
14657   mp->action = action;
14658
14659   if (0 != rmt_locs && 0 != lcl_locs)
14660     {
14661       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14662       clib_memcpy (mp->locs, lcl_locs,
14663                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14664
14665       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14666       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14667                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14668     }
14669   vec_free (lcl_locs);
14670   vec_free (rmt_locs);
14671
14672   /* send it... */
14673   S (mp);
14674
14675   /* Wait for a reply... */
14676   W (ret);
14677   return ret;
14678 }
14679
14680 static int
14681 api_one_add_del_map_server (vat_main_t * vam)
14682 {
14683   unformat_input_t *input = vam->input;
14684   vl_api_one_add_del_map_server_t *mp;
14685   u8 is_add = 1;
14686   u8 ipv4_set = 0;
14687   u8 ipv6_set = 0;
14688   ip4_address_t ipv4;
14689   ip6_address_t ipv6;
14690   int ret;
14691
14692   /* Parse args required to build the message */
14693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14694     {
14695       if (unformat (input, "del"))
14696         {
14697           is_add = 0;
14698         }
14699       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14700         {
14701           ipv4_set = 1;
14702         }
14703       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14704         {
14705           ipv6_set = 1;
14706         }
14707       else
14708         break;
14709     }
14710
14711   if (ipv4_set && ipv6_set)
14712     {
14713       errmsg ("both eid v4 and v6 addresses set");
14714       return -99;
14715     }
14716
14717   if (!ipv4_set && !ipv6_set)
14718     {
14719       errmsg ("eid addresses not set");
14720       return -99;
14721     }
14722
14723   /* Construct the API message */
14724   M (ONE_ADD_DEL_MAP_SERVER, mp);
14725
14726   mp->is_add = is_add;
14727   if (ipv6_set)
14728     {
14729       mp->ip_address.af = 1;
14730       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14731     }
14732   else
14733     {
14734       mp->ip_address.af = 0;
14735       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14736     }
14737
14738   /* send it... */
14739   S (mp);
14740
14741   /* Wait for a reply... */
14742   W (ret);
14743   return ret;
14744 }
14745
14746 #define api_lisp_add_del_map_server api_one_add_del_map_server
14747
14748 static int
14749 api_one_add_del_map_resolver (vat_main_t * vam)
14750 {
14751   unformat_input_t *input = vam->input;
14752   vl_api_one_add_del_map_resolver_t *mp;
14753   u8 is_add = 1;
14754   u8 ipv4_set = 0;
14755   u8 ipv6_set = 0;
14756   ip4_address_t ipv4;
14757   ip6_address_t ipv6;
14758   int ret;
14759
14760   /* Parse args required to build the message */
14761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14762     {
14763       if (unformat (input, "del"))
14764         {
14765           is_add = 0;
14766         }
14767       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14768         {
14769           ipv4_set = 1;
14770         }
14771       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14772         {
14773           ipv6_set = 1;
14774         }
14775       else
14776         break;
14777     }
14778
14779   if (ipv4_set && ipv6_set)
14780     {
14781       errmsg ("both eid v4 and v6 addresses set");
14782       return -99;
14783     }
14784
14785   if (!ipv4_set && !ipv6_set)
14786     {
14787       errmsg ("eid addresses not set");
14788       return -99;
14789     }
14790
14791   /* Construct the API message */
14792   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14793
14794   mp->is_add = is_add;
14795   if (ipv6_set)
14796     {
14797       mp->ip_address.af = 1;
14798       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14799     }
14800   else
14801     {
14802       mp->ip_address.af = 0;
14803       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14804     }
14805
14806   /* send it... */
14807   S (mp);
14808
14809   /* Wait for a reply... */
14810   W (ret);
14811   return ret;
14812 }
14813
14814 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14815
14816 static int
14817 api_lisp_gpe_enable_disable (vat_main_t * vam)
14818 {
14819   unformat_input_t *input = vam->input;
14820   vl_api_gpe_enable_disable_t *mp;
14821   u8 is_set = 0;
14822   u8 is_enable = 1;
14823   int ret;
14824
14825   /* Parse args required to build the message */
14826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14827     {
14828       if (unformat (input, "enable"))
14829         {
14830           is_set = 1;
14831           is_enable = 1;
14832         }
14833       else if (unformat (input, "disable"))
14834         {
14835           is_set = 1;
14836           is_enable = 0;
14837         }
14838       else
14839         break;
14840     }
14841
14842   if (is_set == 0)
14843     {
14844       errmsg ("Value not set");
14845       return -99;
14846     }
14847
14848   /* Construct the API message */
14849   M (GPE_ENABLE_DISABLE, mp);
14850
14851   mp->is_enable = is_enable;
14852
14853   /* send it... */
14854   S (mp);
14855
14856   /* Wait for a reply... */
14857   W (ret);
14858   return ret;
14859 }
14860
14861 static int
14862 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14863 {
14864   unformat_input_t *input = vam->input;
14865   vl_api_one_rloc_probe_enable_disable_t *mp;
14866   u8 is_set = 0;
14867   u8 is_enable = 0;
14868   int ret;
14869
14870   /* Parse args required to build the message */
14871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14872     {
14873       if (unformat (input, "enable"))
14874         {
14875           is_set = 1;
14876           is_enable = 1;
14877         }
14878       else if (unformat (input, "disable"))
14879         is_set = 1;
14880       else
14881         break;
14882     }
14883
14884   if (!is_set)
14885     {
14886       errmsg ("Value not set");
14887       return -99;
14888     }
14889
14890   /* Construct the API message */
14891   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14892
14893   mp->is_enable = is_enable;
14894
14895   /* send it... */
14896   S (mp);
14897
14898   /* Wait for a reply... */
14899   W (ret);
14900   return ret;
14901 }
14902
14903 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14904
14905 static int
14906 api_one_map_register_enable_disable (vat_main_t * vam)
14907 {
14908   unformat_input_t *input = vam->input;
14909   vl_api_one_map_register_enable_disable_t *mp;
14910   u8 is_set = 0;
14911   u8 is_enable = 0;
14912   int ret;
14913
14914   /* Parse args required to build the message */
14915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14916     {
14917       if (unformat (input, "enable"))
14918         {
14919           is_set = 1;
14920           is_enable = 1;
14921         }
14922       else if (unformat (input, "disable"))
14923         is_set = 1;
14924       else
14925         break;
14926     }
14927
14928   if (!is_set)
14929     {
14930       errmsg ("Value not set");
14931       return -99;
14932     }
14933
14934   /* Construct the API message */
14935   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14936
14937   mp->is_enable = is_enable;
14938
14939   /* send it... */
14940   S (mp);
14941
14942   /* Wait for a reply... */
14943   W (ret);
14944   return ret;
14945 }
14946
14947 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14948
14949 static int
14950 api_one_enable_disable (vat_main_t * vam)
14951 {
14952   unformat_input_t *input = vam->input;
14953   vl_api_one_enable_disable_t *mp;
14954   u8 is_set = 0;
14955   u8 is_enable = 0;
14956   int ret;
14957
14958   /* Parse args required to build the message */
14959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14960     {
14961       if (unformat (input, "enable"))
14962         {
14963           is_set = 1;
14964           is_enable = 1;
14965         }
14966       else if (unformat (input, "disable"))
14967         {
14968           is_set = 1;
14969         }
14970       else
14971         break;
14972     }
14973
14974   if (!is_set)
14975     {
14976       errmsg ("Value not set");
14977       return -99;
14978     }
14979
14980   /* Construct the API message */
14981   M (ONE_ENABLE_DISABLE, mp);
14982
14983   mp->is_enable = is_enable;
14984
14985   /* send it... */
14986   S (mp);
14987
14988   /* Wait for a reply... */
14989   W (ret);
14990   return ret;
14991 }
14992
14993 #define api_lisp_enable_disable api_one_enable_disable
14994
14995 static int
14996 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14997 {
14998   unformat_input_t *input = vam->input;
14999   vl_api_one_enable_disable_xtr_mode_t *mp;
15000   u8 is_set = 0;
15001   u8 is_enable = 0;
15002   int ret;
15003
15004   /* Parse args required to build the message */
15005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15006     {
15007       if (unformat (input, "enable"))
15008         {
15009           is_set = 1;
15010           is_enable = 1;
15011         }
15012       else if (unformat (input, "disable"))
15013         {
15014           is_set = 1;
15015         }
15016       else
15017         break;
15018     }
15019
15020   if (!is_set)
15021     {
15022       errmsg ("Value not set");
15023       return -99;
15024     }
15025
15026   /* Construct the API message */
15027   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15028
15029   mp->is_enable = is_enable;
15030
15031   /* send it... */
15032   S (mp);
15033
15034   /* Wait for a reply... */
15035   W (ret);
15036   return ret;
15037 }
15038
15039 static int
15040 api_one_show_xtr_mode (vat_main_t * vam)
15041 {
15042   vl_api_one_show_xtr_mode_t *mp;
15043   int ret;
15044
15045   /* Construct the API message */
15046   M (ONE_SHOW_XTR_MODE, mp);
15047
15048   /* send it... */
15049   S (mp);
15050
15051   /* Wait for a reply... */
15052   W (ret);
15053   return ret;
15054 }
15055
15056 static int
15057 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15058 {
15059   unformat_input_t *input = vam->input;
15060   vl_api_one_enable_disable_pitr_mode_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         {
15075           is_set = 1;
15076         }
15077       else
15078         break;
15079     }
15080
15081   if (!is_set)
15082     {
15083       errmsg ("Value not set");
15084       return -99;
15085     }
15086
15087   /* Construct the API message */
15088   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15089
15090   mp->is_enable = is_enable;
15091
15092   /* send it... */
15093   S (mp);
15094
15095   /* Wait for a reply... */
15096   W (ret);
15097   return ret;
15098 }
15099
15100 static int
15101 api_one_show_pitr_mode (vat_main_t * vam)
15102 {
15103   vl_api_one_show_pitr_mode_t *mp;
15104   int ret;
15105
15106   /* Construct the API message */
15107   M (ONE_SHOW_PITR_MODE, mp);
15108
15109   /* send it... */
15110   S (mp);
15111
15112   /* Wait for a reply... */
15113   W (ret);
15114   return ret;
15115 }
15116
15117 static int
15118 api_one_enable_disable_petr_mode (vat_main_t * vam)
15119 {
15120   unformat_input_t *input = vam->input;
15121   vl_api_one_enable_disable_petr_mode_t *mp;
15122   u8 is_set = 0;
15123   u8 is_enable = 0;
15124   int ret;
15125
15126   /* Parse args required to build the message */
15127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15128     {
15129       if (unformat (input, "enable"))
15130         {
15131           is_set = 1;
15132           is_enable = 1;
15133         }
15134       else if (unformat (input, "disable"))
15135         {
15136           is_set = 1;
15137         }
15138       else
15139         break;
15140     }
15141
15142   if (!is_set)
15143     {
15144       errmsg ("Value not set");
15145       return -99;
15146     }
15147
15148   /* Construct the API message */
15149   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15150
15151   mp->is_enable = is_enable;
15152
15153   /* send it... */
15154   S (mp);
15155
15156   /* Wait for a reply... */
15157   W (ret);
15158   return ret;
15159 }
15160
15161 static int
15162 api_one_show_petr_mode (vat_main_t * vam)
15163 {
15164   vl_api_one_show_petr_mode_t *mp;
15165   int ret;
15166
15167   /* Construct the API message */
15168   M (ONE_SHOW_PETR_MODE, mp);
15169
15170   /* send it... */
15171   S (mp);
15172
15173   /* Wait for a reply... */
15174   W (ret);
15175   return ret;
15176 }
15177
15178 static int
15179 api_show_one_map_register_state (vat_main_t * vam)
15180 {
15181   vl_api_show_one_map_register_state_t *mp;
15182   int ret;
15183
15184   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15185
15186   /* send */
15187   S (mp);
15188
15189   /* wait for reply */
15190   W (ret);
15191   return ret;
15192 }
15193
15194 #define api_show_lisp_map_register_state api_show_one_map_register_state
15195
15196 static int
15197 api_show_one_rloc_probe_state (vat_main_t * vam)
15198 {
15199   vl_api_show_one_rloc_probe_state_t *mp;
15200   int ret;
15201
15202   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15203
15204   /* send */
15205   S (mp);
15206
15207   /* wait for reply */
15208   W (ret);
15209   return ret;
15210 }
15211
15212 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15213
15214 static int
15215 api_one_add_del_ndp_entry (vat_main_t * vam)
15216 {
15217   vl_api_one_add_del_ndp_entry_t *mp;
15218   unformat_input_t *input = vam->input;
15219   u8 is_add = 1;
15220   u8 mac_set = 0;
15221   u8 bd_set = 0;
15222   u8 ip_set = 0;
15223   u8 mac[6] = { 0, };
15224   u8 ip6[16] = { 0, };
15225   u32 bd = ~0;
15226   int ret;
15227
15228   /* Parse args required to build the message */
15229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15230     {
15231       if (unformat (input, "del"))
15232         is_add = 0;
15233       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15234         mac_set = 1;
15235       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15236         ip_set = 1;
15237       else if (unformat (input, "bd %d", &bd))
15238         bd_set = 1;
15239       else
15240         {
15241           errmsg ("parse error '%U'", format_unformat_error, input);
15242           return -99;
15243         }
15244     }
15245
15246   if (!bd_set || !ip_set || (!mac_set && is_add))
15247     {
15248       errmsg ("Missing BD, IP or MAC!");
15249       return -99;
15250     }
15251
15252   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15253   mp->is_add = is_add;
15254   clib_memcpy (&mp->entry.mac, mac, 6);
15255   mp->bd = clib_host_to_net_u32 (bd);
15256   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15257
15258   /* send */
15259   S (mp);
15260
15261   /* wait for reply */
15262   W (ret);
15263   return ret;
15264 }
15265
15266 static int
15267 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15268 {
15269   vl_api_one_add_del_l2_arp_entry_t *mp;
15270   unformat_input_t *input = vam->input;
15271   u8 is_add = 1;
15272   u8 mac_set = 0;
15273   u8 bd_set = 0;
15274   u8 ip_set = 0;
15275   u8 mac[6] = { 0, };
15276   u32 ip4 = 0, bd = ~0;
15277   int ret;
15278
15279   /* Parse args required to build the message */
15280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15281     {
15282       if (unformat (input, "del"))
15283         is_add = 0;
15284       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15285         mac_set = 1;
15286       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15287         ip_set = 1;
15288       else if (unformat (input, "bd %d", &bd))
15289         bd_set = 1;
15290       else
15291         {
15292           errmsg ("parse error '%U'", format_unformat_error, input);
15293           return -99;
15294         }
15295     }
15296
15297   if (!bd_set || !ip_set || (!mac_set && is_add))
15298     {
15299       errmsg ("Missing BD, IP or MAC!");
15300       return -99;
15301     }
15302
15303   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15304   mp->is_add = is_add;
15305   clib_memcpy (&mp->entry.mac, mac, 6);
15306   mp->bd = clib_host_to_net_u32 (bd);
15307   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15308
15309   /* send */
15310   S (mp);
15311
15312   /* wait for reply */
15313   W (ret);
15314   return ret;
15315 }
15316
15317 static int
15318 api_one_ndp_bd_get (vat_main_t * vam)
15319 {
15320   vl_api_one_ndp_bd_get_t *mp;
15321   int ret;
15322
15323   M (ONE_NDP_BD_GET, mp);
15324
15325   /* send */
15326   S (mp);
15327
15328   /* wait for reply */
15329   W (ret);
15330   return ret;
15331 }
15332
15333 static int
15334 api_one_ndp_entries_get (vat_main_t * vam)
15335 {
15336   vl_api_one_ndp_entries_get_t *mp;
15337   unformat_input_t *input = vam->input;
15338   u8 bd_set = 0;
15339   u32 bd = ~0;
15340   int ret;
15341
15342   /* Parse args required to build the message */
15343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15344     {
15345       if (unformat (input, "bd %d", &bd))
15346         bd_set = 1;
15347       else
15348         {
15349           errmsg ("parse error '%U'", format_unformat_error, input);
15350           return -99;
15351         }
15352     }
15353
15354   if (!bd_set)
15355     {
15356       errmsg ("Expected bridge domain!");
15357       return -99;
15358     }
15359
15360   M (ONE_NDP_ENTRIES_GET, mp);
15361   mp->bd = clib_host_to_net_u32 (bd);
15362
15363   /* send */
15364   S (mp);
15365
15366   /* wait for reply */
15367   W (ret);
15368   return ret;
15369 }
15370
15371 static int
15372 api_one_l2_arp_bd_get (vat_main_t * vam)
15373 {
15374   vl_api_one_l2_arp_bd_get_t *mp;
15375   int ret;
15376
15377   M (ONE_L2_ARP_BD_GET, mp);
15378
15379   /* send */
15380   S (mp);
15381
15382   /* wait for reply */
15383   W (ret);
15384   return ret;
15385 }
15386
15387 static int
15388 api_one_l2_arp_entries_get (vat_main_t * vam)
15389 {
15390   vl_api_one_l2_arp_entries_get_t *mp;
15391   unformat_input_t *input = vam->input;
15392   u8 bd_set = 0;
15393   u32 bd = ~0;
15394   int ret;
15395
15396   /* Parse args required to build the message */
15397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15398     {
15399       if (unformat (input, "bd %d", &bd))
15400         bd_set = 1;
15401       else
15402         {
15403           errmsg ("parse error '%U'", format_unformat_error, input);
15404           return -99;
15405         }
15406     }
15407
15408   if (!bd_set)
15409     {
15410       errmsg ("Expected bridge domain!");
15411       return -99;
15412     }
15413
15414   M (ONE_L2_ARP_ENTRIES_GET, mp);
15415   mp->bd = clib_host_to_net_u32 (bd);
15416
15417   /* send */
15418   S (mp);
15419
15420   /* wait for reply */
15421   W (ret);
15422   return ret;
15423 }
15424
15425 static int
15426 api_one_stats_enable_disable (vat_main_t * vam)
15427 {
15428   vl_api_one_stats_enable_disable_t *mp;
15429   unformat_input_t *input = vam->input;
15430   u8 is_set = 0;
15431   u8 is_enable = 0;
15432   int ret;
15433
15434   /* Parse args required to build the message */
15435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15436     {
15437       if (unformat (input, "enable"))
15438         {
15439           is_set = 1;
15440           is_enable = 1;
15441         }
15442       else if (unformat (input, "disable"))
15443         {
15444           is_set = 1;
15445         }
15446       else
15447         break;
15448     }
15449
15450   if (!is_set)
15451     {
15452       errmsg ("Value not set");
15453       return -99;
15454     }
15455
15456   M (ONE_STATS_ENABLE_DISABLE, mp);
15457   mp->is_enable = is_enable;
15458
15459   /* send */
15460   S (mp);
15461
15462   /* wait for reply */
15463   W (ret);
15464   return ret;
15465 }
15466
15467 static int
15468 api_show_one_stats_enable_disable (vat_main_t * vam)
15469 {
15470   vl_api_show_one_stats_enable_disable_t *mp;
15471   int ret;
15472
15473   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15474
15475   /* send */
15476   S (mp);
15477
15478   /* wait for reply */
15479   W (ret);
15480   return ret;
15481 }
15482
15483 static int
15484 api_show_one_map_request_mode (vat_main_t * vam)
15485 {
15486   vl_api_show_one_map_request_mode_t *mp;
15487   int ret;
15488
15489   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15490
15491   /* send */
15492   S (mp);
15493
15494   /* wait for reply */
15495   W (ret);
15496   return ret;
15497 }
15498
15499 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15500
15501 static int
15502 api_one_map_request_mode (vat_main_t * vam)
15503 {
15504   unformat_input_t *input = vam->input;
15505   vl_api_one_map_request_mode_t *mp;
15506   u8 mode = 0;
15507   int ret;
15508
15509   /* Parse args required to build the message */
15510   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15511     {
15512       if (unformat (input, "dst-only"))
15513         mode = 0;
15514       else if (unformat (input, "src-dst"))
15515         mode = 1;
15516       else
15517         {
15518           errmsg ("parse error '%U'", format_unformat_error, input);
15519           return -99;
15520         }
15521     }
15522
15523   M (ONE_MAP_REQUEST_MODE, mp);
15524
15525   mp->mode = mode;
15526
15527   /* send */
15528   S (mp);
15529
15530   /* wait for reply */
15531   W (ret);
15532   return ret;
15533 }
15534
15535 #define api_lisp_map_request_mode api_one_map_request_mode
15536
15537 /**
15538  * Enable/disable ONE proxy ITR.
15539  *
15540  * @param vam vpp API test context
15541  * @return return code
15542  */
15543 static int
15544 api_one_pitr_set_locator_set (vat_main_t * vam)
15545 {
15546   u8 ls_name_set = 0;
15547   unformat_input_t *input = vam->input;
15548   vl_api_one_pitr_set_locator_set_t *mp;
15549   u8 is_add = 1;
15550   u8 *ls_name = 0;
15551   int ret;
15552
15553   /* Parse args required to build the message */
15554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15555     {
15556       if (unformat (input, "del"))
15557         is_add = 0;
15558       else if (unformat (input, "locator-set %s", &ls_name))
15559         ls_name_set = 1;
15560       else
15561         {
15562           errmsg ("parse error '%U'", format_unformat_error, input);
15563           return -99;
15564         }
15565     }
15566
15567   if (!ls_name_set)
15568     {
15569       errmsg ("locator-set name not set!");
15570       return -99;
15571     }
15572
15573   M (ONE_PITR_SET_LOCATOR_SET, mp);
15574
15575   mp->is_add = is_add;
15576   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15577   vec_free (ls_name);
15578
15579   /* send */
15580   S (mp);
15581
15582   /* wait for reply */
15583   W (ret);
15584   return ret;
15585 }
15586
15587 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15588
15589 static int
15590 api_one_nsh_set_locator_set (vat_main_t * vam)
15591 {
15592   u8 ls_name_set = 0;
15593   unformat_input_t *input = vam->input;
15594   vl_api_one_nsh_set_locator_set_t *mp;
15595   u8 is_add = 1;
15596   u8 *ls_name = 0;
15597   int ret;
15598
15599   /* Parse args required to build the message */
15600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15601     {
15602       if (unformat (input, "del"))
15603         is_add = 0;
15604       else if (unformat (input, "ls %s", &ls_name))
15605         ls_name_set = 1;
15606       else
15607         {
15608           errmsg ("parse error '%U'", format_unformat_error, input);
15609           return -99;
15610         }
15611     }
15612
15613   if (!ls_name_set && is_add)
15614     {
15615       errmsg ("locator-set name not set!");
15616       return -99;
15617     }
15618
15619   M (ONE_NSH_SET_LOCATOR_SET, mp);
15620
15621   mp->is_add = is_add;
15622   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15623   vec_free (ls_name);
15624
15625   /* send */
15626   S (mp);
15627
15628   /* wait for reply */
15629   W (ret);
15630   return ret;
15631 }
15632
15633 static int
15634 api_show_one_pitr (vat_main_t * vam)
15635 {
15636   vl_api_show_one_pitr_t *mp;
15637   int ret;
15638
15639   if (!vam->json_output)
15640     {
15641       print (vam->ofp, "%=20s", "lisp status:");
15642     }
15643
15644   M (SHOW_ONE_PITR, mp);
15645   /* send it... */
15646   S (mp);
15647
15648   /* Wait for a reply... */
15649   W (ret);
15650   return ret;
15651 }
15652
15653 #define api_show_lisp_pitr api_show_one_pitr
15654
15655 static int
15656 api_one_use_petr (vat_main_t * vam)
15657 {
15658   unformat_input_t *input = vam->input;
15659   vl_api_one_use_petr_t *mp;
15660   u8 is_add = 0;
15661   ip_address_t ip;
15662   int ret;
15663
15664   clib_memset (&ip, 0, sizeof (ip));
15665
15666   /* Parse args required to build the message */
15667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15668     {
15669       if (unformat (input, "disable"))
15670         is_add = 0;
15671       else
15672         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15673         {
15674           is_add = 1;
15675           ip_addr_version (&ip) = AF_IP4;
15676         }
15677       else
15678         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15679         {
15680           is_add = 1;
15681           ip_addr_version (&ip) = AF_IP6;
15682         }
15683       else
15684         {
15685           errmsg ("parse error '%U'", format_unformat_error, input);
15686           return -99;
15687         }
15688     }
15689
15690   M (ONE_USE_PETR, mp);
15691
15692   mp->is_add = is_add;
15693   if (is_add)
15694     {
15695       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15696       if (mp->ip_address.af)
15697         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15698       else
15699         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15700     }
15701
15702   /* send */
15703   S (mp);
15704
15705   /* wait for reply */
15706   W (ret);
15707   return ret;
15708 }
15709
15710 #define api_lisp_use_petr api_one_use_petr
15711
15712 static int
15713 api_show_one_nsh_mapping (vat_main_t * vam)
15714 {
15715   vl_api_show_one_use_petr_t *mp;
15716   int ret;
15717
15718   if (!vam->json_output)
15719     {
15720       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15721     }
15722
15723   M (SHOW_ONE_NSH_MAPPING, mp);
15724   /* send it... */
15725   S (mp);
15726
15727   /* Wait for a reply... */
15728   W (ret);
15729   return ret;
15730 }
15731
15732 static int
15733 api_show_one_use_petr (vat_main_t * vam)
15734 {
15735   vl_api_show_one_use_petr_t *mp;
15736   int ret;
15737
15738   if (!vam->json_output)
15739     {
15740       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15741     }
15742
15743   M (SHOW_ONE_USE_PETR, mp);
15744   /* send it... */
15745   S (mp);
15746
15747   /* Wait for a reply... */
15748   W (ret);
15749   return ret;
15750 }
15751
15752 #define api_show_lisp_use_petr api_show_one_use_petr
15753
15754 /**
15755  * Add/delete mapping between vni and vrf
15756  */
15757 static int
15758 api_one_eid_table_add_del_map (vat_main_t * vam)
15759 {
15760   unformat_input_t *input = vam->input;
15761   vl_api_one_eid_table_add_del_map_t *mp;
15762   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15763   u32 vni, vrf, bd_index;
15764   int ret;
15765
15766   /* Parse args required to build the message */
15767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15768     {
15769       if (unformat (input, "del"))
15770         is_add = 0;
15771       else if (unformat (input, "vrf %d", &vrf))
15772         vrf_set = 1;
15773       else if (unformat (input, "bd_index %d", &bd_index))
15774         bd_index_set = 1;
15775       else if (unformat (input, "vni %d", &vni))
15776         vni_set = 1;
15777       else
15778         break;
15779     }
15780
15781   if (!vni_set || (!vrf_set && !bd_index_set))
15782     {
15783       errmsg ("missing arguments!");
15784       return -99;
15785     }
15786
15787   if (vrf_set && bd_index_set)
15788     {
15789       errmsg ("error: both vrf and bd entered!");
15790       return -99;
15791     }
15792
15793   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15794
15795   mp->is_add = is_add;
15796   mp->vni = htonl (vni);
15797   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15798   mp->is_l2 = bd_index_set;
15799
15800   /* send */
15801   S (mp);
15802
15803   /* wait for reply */
15804   W (ret);
15805   return ret;
15806 }
15807
15808 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15809
15810 uword
15811 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15812 {
15813   u32 *action = va_arg (*args, u32 *);
15814   u8 *s = 0;
15815
15816   if (unformat (input, "%s", &s))
15817     {
15818       if (!strcmp ((char *) s, "no-action"))
15819         action[0] = 0;
15820       else if (!strcmp ((char *) s, "natively-forward"))
15821         action[0] = 1;
15822       else if (!strcmp ((char *) s, "send-map-request"))
15823         action[0] = 2;
15824       else if (!strcmp ((char *) s, "drop"))
15825         action[0] = 3;
15826       else
15827         {
15828           clib_warning ("invalid action: '%s'", s);
15829           action[0] = 3;
15830         }
15831     }
15832   else
15833     return 0;
15834
15835   vec_free (s);
15836   return 1;
15837 }
15838
15839 /**
15840  * Add/del remote mapping to/from ONE control plane
15841  *
15842  * @param vam vpp API test context
15843  * @return return code
15844  */
15845 static int
15846 api_one_add_del_remote_mapping (vat_main_t * vam)
15847 {
15848   unformat_input_t *input = vam->input;
15849   vl_api_one_add_del_remote_mapping_t *mp;
15850   u32 vni = 0;
15851   lisp_eid_vat_t _eid, *eid = &_eid;
15852   lisp_eid_vat_t _seid, *seid = &_seid;
15853   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15854   u32 action = ~0, p, w, data_len;
15855   ip4_address_t rloc4;
15856   ip6_address_t rloc6;
15857   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15858   int ret;
15859
15860   clib_memset (&rloc, 0, sizeof (rloc));
15861
15862   /* Parse args required to build the message */
15863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15864     {
15865       if (unformat (input, "del-all"))
15866         {
15867           del_all = 1;
15868         }
15869       else if (unformat (input, "del"))
15870         {
15871           is_add = 0;
15872         }
15873       else if (unformat (input, "add"))
15874         {
15875           is_add = 1;
15876         }
15877       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15878         {
15879           eid_set = 1;
15880         }
15881       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15882         {
15883           seid_set = 1;
15884         }
15885       else if (unformat (input, "vni %d", &vni))
15886         {
15887           ;
15888         }
15889       else if (unformat (input, "p %d w %d", &p, &w))
15890         {
15891           if (!curr_rloc)
15892             {
15893               errmsg ("No RLOC configured for setting priority/weight!");
15894               return -99;
15895             }
15896           curr_rloc->priority = p;
15897           curr_rloc->weight = w;
15898         }
15899       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15900         {
15901           rloc.ip_address.af = 0;
15902           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15903           vec_add1 (rlocs, rloc);
15904           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15905         }
15906       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15907         {
15908           rloc.ip_address.af = 1;
15909           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15910           vec_add1 (rlocs, rloc);
15911           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15912         }
15913       else if (unformat (input, "action %U",
15914                          unformat_negative_mapping_action, &action))
15915         {
15916           ;
15917         }
15918       else
15919         {
15920           clib_warning ("parse error '%U'", format_unformat_error, input);
15921           return -99;
15922         }
15923     }
15924
15925   if (0 == eid_set)
15926     {
15927       errmsg ("missing params!");
15928       return -99;
15929     }
15930
15931   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15932     {
15933       errmsg ("no action set for negative map-reply!");
15934       return -99;
15935     }
15936
15937   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15938
15939   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15940   mp->is_add = is_add;
15941   mp->vni = htonl (vni);
15942   mp->action = (u8) action;
15943   mp->is_src_dst = seid_set;
15944   mp->del_all = del_all;
15945   lisp_eid_put_vat (&mp->deid, eid);
15946   lisp_eid_put_vat (&mp->seid, seid);
15947
15948   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15949   clib_memcpy (mp->rlocs, rlocs, data_len);
15950   vec_free (rlocs);
15951
15952   /* send it... */
15953   S (mp);
15954
15955   /* Wait for a reply... */
15956   W (ret);
15957   return ret;
15958 }
15959
15960 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15961
15962 /**
15963  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15964  * forwarding entries in data-plane accordingly.
15965  *
15966  * @param vam vpp API test context
15967  * @return return code
15968  */
15969 static int
15970 api_one_add_del_adjacency (vat_main_t * vam)
15971 {
15972   unformat_input_t *input = vam->input;
15973   vl_api_one_add_del_adjacency_t *mp;
15974   u32 vni = 0;
15975   u8 is_add = 1;
15976   int ret;
15977   lisp_eid_vat_t leid, reid;
15978
15979   leid.type = reid.type = (u8) ~ 0;
15980
15981   /* Parse args required to build the message */
15982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15983     {
15984       if (unformat (input, "del"))
15985         {
15986           is_add = 0;
15987         }
15988       else if (unformat (input, "add"))
15989         {
15990           is_add = 1;
15991         }
15992       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15993                          &reid.addr.ip, &reid.len))
15994         {
15995           reid.type = 0;        /* ipv4 */
15996         }
15997       else if (unformat (input, "reid %U", unformat_ethernet_address,
15998                          &reid.addr.mac))
15999         {
16000           reid.type = 1;        /* mac */
16001         }
16002       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
16003                          &leid.addr.ip, &leid.len))
16004         {
16005           leid.type = 0;        /* ipv4 */
16006         }
16007       else if (unformat (input, "leid %U", unformat_ethernet_address,
16008                          &leid.addr.mac))
16009         {
16010           leid.type = 1;        /* mac */
16011         }
16012       else if (unformat (input, "vni %d", &vni))
16013         {
16014           ;
16015         }
16016       else
16017         {
16018           errmsg ("parse error '%U'", format_unformat_error, input);
16019           return -99;
16020         }
16021     }
16022
16023   if ((u8) ~ 0 == reid.type)
16024     {
16025       errmsg ("missing params!");
16026       return -99;
16027     }
16028
16029   if (leid.type != reid.type)
16030     {
16031       errmsg ("remote and local EIDs are of different types!");
16032       return -99;
16033     }
16034
16035   M (ONE_ADD_DEL_ADJACENCY, mp);
16036   mp->is_add = is_add;
16037   mp->vni = htonl (vni);
16038   lisp_eid_put_vat (&mp->leid, &leid);
16039   lisp_eid_put_vat (&mp->reid, &reid);
16040
16041   /* send it... */
16042   S (mp);
16043
16044   /* Wait for a reply... */
16045   W (ret);
16046   return ret;
16047 }
16048
16049 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16050
16051 uword
16052 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16053 {
16054   u32 *mode = va_arg (*args, u32 *);
16055
16056   if (unformat (input, "lisp"))
16057     *mode = 0;
16058   else if (unformat (input, "vxlan"))
16059     *mode = 1;
16060   else
16061     return 0;
16062
16063   return 1;
16064 }
16065
16066 static int
16067 api_gpe_get_encap_mode (vat_main_t * vam)
16068 {
16069   vl_api_gpe_get_encap_mode_t *mp;
16070   int ret;
16071
16072   /* Construct the API message */
16073   M (GPE_GET_ENCAP_MODE, mp);
16074
16075   /* send it... */
16076   S (mp);
16077
16078   /* Wait for a reply... */
16079   W (ret);
16080   return ret;
16081 }
16082
16083 static int
16084 api_gpe_set_encap_mode (vat_main_t * vam)
16085 {
16086   unformat_input_t *input = vam->input;
16087   vl_api_gpe_set_encap_mode_t *mp;
16088   int ret;
16089   u32 mode = 0;
16090
16091   /* Parse args required to build the message */
16092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16093     {
16094       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16095         ;
16096       else
16097         break;
16098     }
16099
16100   /* Construct the API message */
16101   M (GPE_SET_ENCAP_MODE, mp);
16102
16103   mp->is_vxlan = mode;
16104
16105   /* send it... */
16106   S (mp);
16107
16108   /* Wait for a reply... */
16109   W (ret);
16110   return ret;
16111 }
16112
16113 static int
16114 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16115 {
16116   unformat_input_t *input = vam->input;
16117   vl_api_gpe_add_del_iface_t *mp;
16118   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16119   u32 dp_table = 0, vni = 0;
16120   int ret;
16121
16122   /* Parse args required to build the message */
16123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16124     {
16125       if (unformat (input, "up"))
16126         {
16127           action_set = 1;
16128           is_add = 1;
16129         }
16130       else if (unformat (input, "down"))
16131         {
16132           action_set = 1;
16133           is_add = 0;
16134         }
16135       else if (unformat (input, "table_id %d", &dp_table))
16136         {
16137           dp_table_set = 1;
16138         }
16139       else if (unformat (input, "bd_id %d", &dp_table))
16140         {
16141           dp_table_set = 1;
16142           is_l2 = 1;
16143         }
16144       else if (unformat (input, "vni %d", &vni))
16145         {
16146           vni_set = 1;
16147         }
16148       else
16149         break;
16150     }
16151
16152   if (action_set == 0)
16153     {
16154       errmsg ("Action not set");
16155       return -99;
16156     }
16157   if (dp_table_set == 0 || vni_set == 0)
16158     {
16159       errmsg ("vni and dp_table must be set");
16160       return -99;
16161     }
16162
16163   /* Construct the API message */
16164   M (GPE_ADD_DEL_IFACE, mp);
16165
16166   mp->is_add = is_add;
16167   mp->dp_table = clib_host_to_net_u32 (dp_table);
16168   mp->is_l2 = is_l2;
16169   mp->vni = clib_host_to_net_u32 (vni);
16170
16171   /* send it... */
16172   S (mp);
16173
16174   /* Wait for a reply... */
16175   W (ret);
16176   return ret;
16177 }
16178
16179 static int
16180 api_one_map_register_fallback_threshold (vat_main_t * vam)
16181 {
16182   unformat_input_t *input = vam->input;
16183   vl_api_one_map_register_fallback_threshold_t *mp;
16184   u32 value = 0;
16185   u8 is_set = 0;
16186   int ret;
16187
16188   /* Parse args required to build the message */
16189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16190     {
16191       if (unformat (input, "%u", &value))
16192         is_set = 1;
16193       else
16194         {
16195           clib_warning ("parse error '%U'", format_unformat_error, input);
16196           return -99;
16197         }
16198     }
16199
16200   if (!is_set)
16201     {
16202       errmsg ("fallback threshold value is missing!");
16203       return -99;
16204     }
16205
16206   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16207   mp->value = clib_host_to_net_u32 (value);
16208
16209   /* send it... */
16210   S (mp);
16211
16212   /* Wait for a reply... */
16213   W (ret);
16214   return ret;
16215 }
16216
16217 static int
16218 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16219 {
16220   vl_api_show_one_map_register_fallback_threshold_t *mp;
16221   int ret;
16222
16223   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16224
16225   /* send it... */
16226   S (mp);
16227
16228   /* Wait for a reply... */
16229   W (ret);
16230   return ret;
16231 }
16232
16233 uword
16234 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16235 {
16236   u32 *proto = va_arg (*args, u32 *);
16237
16238   if (unformat (input, "udp"))
16239     *proto = 1;
16240   else if (unformat (input, "api"))
16241     *proto = 2;
16242   else
16243     return 0;
16244
16245   return 1;
16246 }
16247
16248 static int
16249 api_one_set_transport_protocol (vat_main_t * vam)
16250 {
16251   unformat_input_t *input = vam->input;
16252   vl_api_one_set_transport_protocol_t *mp;
16253   u8 is_set = 0;
16254   u32 protocol = 0;
16255   int ret;
16256
16257   /* Parse args required to build the message */
16258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16259     {
16260       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16261         is_set = 1;
16262       else
16263         {
16264           clib_warning ("parse error '%U'", format_unformat_error, input);
16265           return -99;
16266         }
16267     }
16268
16269   if (!is_set)
16270     {
16271       errmsg ("Transport protocol missing!");
16272       return -99;
16273     }
16274
16275   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16276   mp->protocol = (u8) protocol;
16277
16278   /* send it... */
16279   S (mp);
16280
16281   /* Wait for a reply... */
16282   W (ret);
16283   return ret;
16284 }
16285
16286 static int
16287 api_one_get_transport_protocol (vat_main_t * vam)
16288 {
16289   vl_api_one_get_transport_protocol_t *mp;
16290   int ret;
16291
16292   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16293
16294   /* send it... */
16295   S (mp);
16296
16297   /* Wait for a reply... */
16298   W (ret);
16299   return ret;
16300 }
16301
16302 static int
16303 api_one_map_register_set_ttl (vat_main_t * vam)
16304 {
16305   unformat_input_t *input = vam->input;
16306   vl_api_one_map_register_set_ttl_t *mp;
16307   u32 ttl = 0;
16308   u8 is_set = 0;
16309   int ret;
16310
16311   /* Parse args required to build the message */
16312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16313     {
16314       if (unformat (input, "%u", &ttl))
16315         is_set = 1;
16316       else
16317         {
16318           clib_warning ("parse error '%U'", format_unformat_error, input);
16319           return -99;
16320         }
16321     }
16322
16323   if (!is_set)
16324     {
16325       errmsg ("TTL value missing!");
16326       return -99;
16327     }
16328
16329   M (ONE_MAP_REGISTER_SET_TTL, mp);
16330   mp->ttl = clib_host_to_net_u32 (ttl);
16331
16332   /* send it... */
16333   S (mp);
16334
16335   /* Wait for a reply... */
16336   W (ret);
16337   return ret;
16338 }
16339
16340 static int
16341 api_show_one_map_register_ttl (vat_main_t * vam)
16342 {
16343   vl_api_show_one_map_register_ttl_t *mp;
16344   int ret;
16345
16346   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16347
16348   /* send it... */
16349   S (mp);
16350
16351   /* Wait for a reply... */
16352   W (ret);
16353   return ret;
16354 }
16355
16356 /**
16357  * Add/del map request itr rlocs from ONE control plane and updates
16358  *
16359  * @param vam vpp API test context
16360  * @return return code
16361  */
16362 static int
16363 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16364 {
16365   unformat_input_t *input = vam->input;
16366   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16367   u8 *locator_set_name = 0;
16368   u8 locator_set_name_set = 0;
16369   u8 is_add = 1;
16370   int ret;
16371
16372   /* Parse args required to build the message */
16373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16374     {
16375       if (unformat (input, "del"))
16376         {
16377           is_add = 0;
16378         }
16379       else if (unformat (input, "%_%v%_", &locator_set_name))
16380         {
16381           locator_set_name_set = 1;
16382         }
16383       else
16384         {
16385           clib_warning ("parse error '%U'", format_unformat_error, input);
16386           return -99;
16387         }
16388     }
16389
16390   if (is_add && !locator_set_name_set)
16391     {
16392       errmsg ("itr-rloc is not set!");
16393       return -99;
16394     }
16395
16396   if (is_add && vec_len (locator_set_name) > 64)
16397     {
16398       errmsg ("itr-rloc locator-set name too long");
16399       vec_free (locator_set_name);
16400       return -99;
16401     }
16402
16403   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16404   mp->is_add = is_add;
16405   if (is_add)
16406     {
16407       clib_memcpy (mp->locator_set_name, locator_set_name,
16408                    vec_len (locator_set_name));
16409     }
16410   else
16411     {
16412       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16413     }
16414   vec_free (locator_set_name);
16415
16416   /* send it... */
16417   S (mp);
16418
16419   /* Wait for a reply... */
16420   W (ret);
16421   return ret;
16422 }
16423
16424 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16425
16426 static int
16427 api_one_locator_dump (vat_main_t * vam)
16428 {
16429   unformat_input_t *input = vam->input;
16430   vl_api_one_locator_dump_t *mp;
16431   vl_api_control_ping_t *mp_ping;
16432   u8 is_index_set = 0, is_name_set = 0;
16433   u8 *ls_name = 0;
16434   u32 ls_index = ~0;
16435   int ret;
16436
16437   /* Parse args required to build the message */
16438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16439     {
16440       if (unformat (input, "ls_name %_%v%_", &ls_name))
16441         {
16442           is_name_set = 1;
16443         }
16444       else if (unformat (input, "ls_index %d", &ls_index))
16445         {
16446           is_index_set = 1;
16447         }
16448       else
16449         {
16450           errmsg ("parse error '%U'", format_unformat_error, input);
16451           return -99;
16452         }
16453     }
16454
16455   if (!is_index_set && !is_name_set)
16456     {
16457       errmsg ("error: expected one of index or name!");
16458       return -99;
16459     }
16460
16461   if (is_index_set && is_name_set)
16462     {
16463       errmsg ("error: only one param expected!");
16464       return -99;
16465     }
16466
16467   if (vec_len (ls_name) > 62)
16468     {
16469       errmsg ("error: locator set name too long!");
16470       return -99;
16471     }
16472
16473   if (!vam->json_output)
16474     {
16475       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16476     }
16477
16478   M (ONE_LOCATOR_DUMP, mp);
16479   mp->is_index_set = is_index_set;
16480
16481   if (is_index_set)
16482     mp->ls_index = clib_host_to_net_u32 (ls_index);
16483   else
16484     {
16485       vec_add1 (ls_name, 0);
16486       strncpy ((char *) mp->ls_name, (char *) ls_name,
16487                sizeof (mp->ls_name) - 1);
16488     }
16489
16490   /* send it... */
16491   S (mp);
16492
16493   /* Use a control ping for synchronization */
16494   MPING (CONTROL_PING, mp_ping);
16495   S (mp_ping);
16496
16497   /* Wait for a reply... */
16498   W (ret);
16499   return ret;
16500 }
16501
16502 #define api_lisp_locator_dump api_one_locator_dump
16503
16504 static int
16505 api_one_locator_set_dump (vat_main_t * vam)
16506 {
16507   vl_api_one_locator_set_dump_t *mp;
16508   vl_api_control_ping_t *mp_ping;
16509   unformat_input_t *input = vam->input;
16510   u8 filter = 0;
16511   int ret;
16512
16513   /* Parse args required to build the message */
16514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16515     {
16516       if (unformat (input, "local"))
16517         {
16518           filter = 1;
16519         }
16520       else if (unformat (input, "remote"))
16521         {
16522           filter = 2;
16523         }
16524       else
16525         {
16526           errmsg ("parse error '%U'", format_unformat_error, input);
16527           return -99;
16528         }
16529     }
16530
16531   if (!vam->json_output)
16532     {
16533       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16534     }
16535
16536   M (ONE_LOCATOR_SET_DUMP, mp);
16537
16538   mp->filter = filter;
16539
16540   /* send it... */
16541   S (mp);
16542
16543   /* Use a control ping for synchronization */
16544   MPING (CONTROL_PING, mp_ping);
16545   S (mp_ping);
16546
16547   /* Wait for a reply... */
16548   W (ret);
16549   return ret;
16550 }
16551
16552 #define api_lisp_locator_set_dump api_one_locator_set_dump
16553
16554 static int
16555 api_one_eid_table_map_dump (vat_main_t * vam)
16556 {
16557   u8 is_l2 = 0;
16558   u8 mode_set = 0;
16559   unformat_input_t *input = vam->input;
16560   vl_api_one_eid_table_map_dump_t *mp;
16561   vl_api_control_ping_t *mp_ping;
16562   int ret;
16563
16564   /* Parse args required to build the message */
16565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16566     {
16567       if (unformat (input, "l2"))
16568         {
16569           is_l2 = 1;
16570           mode_set = 1;
16571         }
16572       else if (unformat (input, "l3"))
16573         {
16574           is_l2 = 0;
16575           mode_set = 1;
16576         }
16577       else
16578         {
16579           errmsg ("parse error '%U'", format_unformat_error, input);
16580           return -99;
16581         }
16582     }
16583
16584   if (!mode_set)
16585     {
16586       errmsg ("expected one of 'l2' or 'l3' parameter!");
16587       return -99;
16588     }
16589
16590   if (!vam->json_output)
16591     {
16592       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16593     }
16594
16595   M (ONE_EID_TABLE_MAP_DUMP, mp);
16596   mp->is_l2 = is_l2;
16597
16598   /* send it... */
16599   S (mp);
16600
16601   /* Use a control ping for synchronization */
16602   MPING (CONTROL_PING, mp_ping);
16603   S (mp_ping);
16604
16605   /* Wait for a reply... */
16606   W (ret);
16607   return ret;
16608 }
16609
16610 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16611
16612 static int
16613 api_one_eid_table_vni_dump (vat_main_t * vam)
16614 {
16615   vl_api_one_eid_table_vni_dump_t *mp;
16616   vl_api_control_ping_t *mp_ping;
16617   int ret;
16618
16619   if (!vam->json_output)
16620     {
16621       print (vam->ofp, "VNI");
16622     }
16623
16624   M (ONE_EID_TABLE_VNI_DUMP, mp);
16625
16626   /* send it... */
16627   S (mp);
16628
16629   /* Use a control ping for synchronization */
16630   MPING (CONTROL_PING, mp_ping);
16631   S (mp_ping);
16632
16633   /* Wait for a reply... */
16634   W (ret);
16635   return ret;
16636 }
16637
16638 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16639
16640 static int
16641 api_one_eid_table_dump (vat_main_t * vam)
16642 {
16643   unformat_input_t *i = vam->input;
16644   vl_api_one_eid_table_dump_t *mp;
16645   vl_api_control_ping_t *mp_ping;
16646   u8 filter = 0;
16647   int ret;
16648   u32 vni, t = 0;
16649   lisp_eid_vat_t eid;
16650   u8 eid_set = 0;
16651
16652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16653     {
16654       if (unformat
16655           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16656         {
16657           eid_set = 1;
16658           eid.type = 0;
16659         }
16660       else
16661         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16662         {
16663           eid_set = 1;
16664           eid.type = 1;
16665         }
16666       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16667         {
16668           eid_set = 1;
16669           eid.type = 2;
16670         }
16671       else if (unformat (i, "vni %d", &t))
16672         {
16673           vni = t;
16674         }
16675       else if (unformat (i, "local"))
16676         {
16677           filter = 1;
16678         }
16679       else if (unformat (i, "remote"))
16680         {
16681           filter = 2;
16682         }
16683       else
16684         {
16685           errmsg ("parse error '%U'", format_unformat_error, i);
16686           return -99;
16687         }
16688     }
16689
16690   if (!vam->json_output)
16691     {
16692       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16693              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16694     }
16695
16696   M (ONE_EID_TABLE_DUMP, mp);
16697
16698   mp->filter = filter;
16699   if (eid_set)
16700     {
16701       mp->eid_set = 1;
16702       mp->vni = htonl (vni);
16703       lisp_eid_put_vat (&mp->eid, &eid);
16704     }
16705
16706   /* send it... */
16707   S (mp);
16708
16709   /* Use a control ping for synchronization */
16710   MPING (CONTROL_PING, mp_ping);
16711   S (mp_ping);
16712
16713   /* Wait for a reply... */
16714   W (ret);
16715   return ret;
16716 }
16717
16718 #define api_lisp_eid_table_dump api_one_eid_table_dump
16719
16720 static int
16721 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16722 {
16723   unformat_input_t *i = vam->input;
16724   vl_api_gpe_fwd_entries_get_t *mp;
16725   u8 vni_set = 0;
16726   u32 vni = ~0;
16727   int ret;
16728
16729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16730     {
16731       if (unformat (i, "vni %d", &vni))
16732         {
16733           vni_set = 1;
16734         }
16735       else
16736         {
16737           errmsg ("parse error '%U'", format_unformat_error, i);
16738           return -99;
16739         }
16740     }
16741
16742   if (!vni_set)
16743     {
16744       errmsg ("vni not set!");
16745       return -99;
16746     }
16747
16748   if (!vam->json_output)
16749     {
16750       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16751              "leid", "reid");
16752     }
16753
16754   M (GPE_FWD_ENTRIES_GET, mp);
16755   mp->vni = clib_host_to_net_u32 (vni);
16756
16757   /* send it... */
16758   S (mp);
16759
16760   /* Wait for a reply... */
16761   W (ret);
16762   return ret;
16763 }
16764
16765 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16766 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16767 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16768 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16769 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16770 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16771 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16772 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16773
16774 static int
16775 api_one_adjacencies_get (vat_main_t * vam)
16776 {
16777   unformat_input_t *i = vam->input;
16778   vl_api_one_adjacencies_get_t *mp;
16779   u8 vni_set = 0;
16780   u32 vni = ~0;
16781   int ret;
16782
16783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16784     {
16785       if (unformat (i, "vni %d", &vni))
16786         {
16787           vni_set = 1;
16788         }
16789       else
16790         {
16791           errmsg ("parse error '%U'", format_unformat_error, i);
16792           return -99;
16793         }
16794     }
16795
16796   if (!vni_set)
16797     {
16798       errmsg ("vni not set!");
16799       return -99;
16800     }
16801
16802   if (!vam->json_output)
16803     {
16804       print (vam->ofp, "%s %40s", "leid", "reid");
16805     }
16806
16807   M (ONE_ADJACENCIES_GET, mp);
16808   mp->vni = clib_host_to_net_u32 (vni);
16809
16810   /* send it... */
16811   S (mp);
16812
16813   /* Wait for a reply... */
16814   W (ret);
16815   return ret;
16816 }
16817
16818 #define api_lisp_adjacencies_get api_one_adjacencies_get
16819
16820 static int
16821 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16822 {
16823   unformat_input_t *i = vam->input;
16824   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16825   int ret;
16826   u8 ip_family_set = 0, is_ip4 = 1;
16827
16828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16829     {
16830       if (unformat (i, "ip4"))
16831         {
16832           ip_family_set = 1;
16833           is_ip4 = 1;
16834         }
16835       else if (unformat (i, "ip6"))
16836         {
16837           ip_family_set = 1;
16838           is_ip4 = 0;
16839         }
16840       else
16841         {
16842           errmsg ("parse error '%U'", format_unformat_error, i);
16843           return -99;
16844         }
16845     }
16846
16847   if (!ip_family_set)
16848     {
16849       errmsg ("ip family not set!");
16850       return -99;
16851     }
16852
16853   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16854   mp->is_ip4 = is_ip4;
16855
16856   /* send it... */
16857   S (mp);
16858
16859   /* Wait for a reply... */
16860   W (ret);
16861   return ret;
16862 }
16863
16864 static int
16865 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16866 {
16867   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16868   int ret;
16869
16870   if (!vam->json_output)
16871     {
16872       print (vam->ofp, "VNIs");
16873     }
16874
16875   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16876
16877   /* send it... */
16878   S (mp);
16879
16880   /* Wait for a reply... */
16881   W (ret);
16882   return ret;
16883 }
16884
16885 static int
16886 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16887 {
16888   unformat_input_t *i = vam->input;
16889   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16890   int ret = 0;
16891   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16892   struct in_addr ip4;
16893   struct in6_addr ip6;
16894   u32 table_id = 0, nh_sw_if_index = ~0;
16895
16896   clib_memset (&ip4, 0, sizeof (ip4));
16897   clib_memset (&ip6, 0, sizeof (ip6));
16898
16899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16900     {
16901       if (unformat (i, "del"))
16902         is_add = 0;
16903       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16904                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16905         {
16906           ip_set = 1;
16907           is_ip4 = 1;
16908         }
16909       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16910                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16911         {
16912           ip_set = 1;
16913           is_ip4 = 0;
16914         }
16915       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16916         {
16917           ip_set = 1;
16918           is_ip4 = 1;
16919           nh_sw_if_index = ~0;
16920         }
16921       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16922         {
16923           ip_set = 1;
16924           is_ip4 = 0;
16925           nh_sw_if_index = ~0;
16926         }
16927       else if (unformat (i, "table %d", &table_id))
16928         ;
16929       else
16930         {
16931           errmsg ("parse error '%U'", format_unformat_error, i);
16932           return -99;
16933         }
16934     }
16935
16936   if (!ip_set)
16937     {
16938       errmsg ("nh addr not set!");
16939       return -99;
16940     }
16941
16942   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16943   mp->is_add = is_add;
16944   mp->table_id = clib_host_to_net_u32 (table_id);
16945   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16946   mp->nh_addr.af = is_ip4 ? 0 : 1;
16947   if (is_ip4)
16948     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16949   else
16950     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16951
16952   /* send it... */
16953   S (mp);
16954
16955   /* Wait for a reply... */
16956   W (ret);
16957   return ret;
16958 }
16959
16960 static int
16961 api_one_map_server_dump (vat_main_t * vam)
16962 {
16963   vl_api_one_map_server_dump_t *mp;
16964   vl_api_control_ping_t *mp_ping;
16965   int ret;
16966
16967   if (!vam->json_output)
16968     {
16969       print (vam->ofp, "%=20s", "Map server");
16970     }
16971
16972   M (ONE_MAP_SERVER_DUMP, mp);
16973   /* send it... */
16974   S (mp);
16975
16976   /* Use a control ping for synchronization */
16977   MPING (CONTROL_PING, mp_ping);
16978   S (mp_ping);
16979
16980   /* Wait for a reply... */
16981   W (ret);
16982   return ret;
16983 }
16984
16985 #define api_lisp_map_server_dump api_one_map_server_dump
16986
16987 static int
16988 api_one_map_resolver_dump (vat_main_t * vam)
16989 {
16990   vl_api_one_map_resolver_dump_t *mp;
16991   vl_api_control_ping_t *mp_ping;
16992   int ret;
16993
16994   if (!vam->json_output)
16995     {
16996       print (vam->ofp, "%=20s", "Map resolver");
16997     }
16998
16999   M (ONE_MAP_RESOLVER_DUMP, mp);
17000   /* send it... */
17001   S (mp);
17002
17003   /* Use a control ping for synchronization */
17004   MPING (CONTROL_PING, mp_ping);
17005   S (mp_ping);
17006
17007   /* Wait for a reply... */
17008   W (ret);
17009   return ret;
17010 }
17011
17012 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17013
17014 static int
17015 api_one_stats_flush (vat_main_t * vam)
17016 {
17017   vl_api_one_stats_flush_t *mp;
17018   int ret = 0;
17019
17020   M (ONE_STATS_FLUSH, mp);
17021   S (mp);
17022   W (ret);
17023   return ret;
17024 }
17025
17026 static int
17027 api_one_stats_dump (vat_main_t * vam)
17028 {
17029   vl_api_one_stats_dump_t *mp;
17030   vl_api_control_ping_t *mp_ping;
17031   int ret;
17032
17033   M (ONE_STATS_DUMP, mp);
17034   /* send it... */
17035   S (mp);
17036
17037   /* Use a control ping for synchronization */
17038   MPING (CONTROL_PING, mp_ping);
17039   S (mp_ping);
17040
17041   /* Wait for a reply... */
17042   W (ret);
17043   return ret;
17044 }
17045
17046 static int
17047 api_show_one_status (vat_main_t * vam)
17048 {
17049   vl_api_show_one_status_t *mp;
17050   int ret;
17051
17052   if (!vam->json_output)
17053     {
17054       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17055     }
17056
17057   M (SHOW_ONE_STATUS, mp);
17058   /* send it... */
17059   S (mp);
17060   /* Wait for a reply... */
17061   W (ret);
17062   return ret;
17063 }
17064
17065 #define api_show_lisp_status api_show_one_status
17066
17067 static int
17068 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17069 {
17070   vl_api_gpe_fwd_entry_path_dump_t *mp;
17071   vl_api_control_ping_t *mp_ping;
17072   unformat_input_t *i = vam->input;
17073   u32 fwd_entry_index = ~0;
17074   int ret;
17075
17076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17077     {
17078       if (unformat (i, "index %d", &fwd_entry_index))
17079         ;
17080       else
17081         break;
17082     }
17083
17084   if (~0 == fwd_entry_index)
17085     {
17086       errmsg ("no index specified!");
17087       return -99;
17088     }
17089
17090   if (!vam->json_output)
17091     {
17092       print (vam->ofp, "first line");
17093     }
17094
17095   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17096
17097   /* send it... */
17098   S (mp);
17099   /* Use a control ping for synchronization */
17100   MPING (CONTROL_PING, mp_ping);
17101   S (mp_ping);
17102
17103   /* Wait for a reply... */
17104   W (ret);
17105   return ret;
17106 }
17107
17108 static int
17109 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17110 {
17111   vl_api_one_get_map_request_itr_rlocs_t *mp;
17112   int ret;
17113
17114   if (!vam->json_output)
17115     {
17116       print (vam->ofp, "%=20s", "itr-rlocs:");
17117     }
17118
17119   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17120   /* send it... */
17121   S (mp);
17122   /* Wait for a reply... */
17123   W (ret);
17124   return ret;
17125 }
17126
17127 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17128
17129 static int
17130 api_af_packet_create (vat_main_t * vam)
17131 {
17132   unformat_input_t *i = vam->input;
17133   vl_api_af_packet_create_t *mp;
17134   u8 *host_if_name = 0;
17135   u8 hw_addr[6];
17136   u8 random_hw_addr = 1;
17137   int ret;
17138
17139   clib_memset (hw_addr, 0, sizeof (hw_addr));
17140
17141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17142     {
17143       if (unformat (i, "name %s", &host_if_name))
17144         vec_add1 (host_if_name, 0);
17145       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17146         random_hw_addr = 0;
17147       else
17148         break;
17149     }
17150
17151   if (!vec_len (host_if_name))
17152     {
17153       errmsg ("host-interface name must be specified");
17154       return -99;
17155     }
17156
17157   if (vec_len (host_if_name) > 64)
17158     {
17159       errmsg ("host-interface name too long");
17160       return -99;
17161     }
17162
17163   M (AF_PACKET_CREATE, mp);
17164
17165   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17166   clib_memcpy (mp->hw_addr, hw_addr, 6);
17167   mp->use_random_hw_addr = random_hw_addr;
17168   vec_free (host_if_name);
17169
17170   S (mp);
17171
17172   /* *INDENT-OFF* */
17173   W2 (ret,
17174       ({
17175         if (ret == 0)
17176           fprintf (vam->ofp ? vam->ofp : stderr,
17177                    " new sw_if_index = %d\n", vam->sw_if_index);
17178       }));
17179   /* *INDENT-ON* */
17180   return ret;
17181 }
17182
17183 static int
17184 api_af_packet_delete (vat_main_t * vam)
17185 {
17186   unformat_input_t *i = vam->input;
17187   vl_api_af_packet_delete_t *mp;
17188   u8 *host_if_name = 0;
17189   int ret;
17190
17191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17192     {
17193       if (unformat (i, "name %s", &host_if_name))
17194         vec_add1 (host_if_name, 0);
17195       else
17196         break;
17197     }
17198
17199   if (!vec_len (host_if_name))
17200     {
17201       errmsg ("host-interface name must be specified");
17202       return -99;
17203     }
17204
17205   if (vec_len (host_if_name) > 64)
17206     {
17207       errmsg ("host-interface name too long");
17208       return -99;
17209     }
17210
17211   M (AF_PACKET_DELETE, mp);
17212
17213   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17214   vec_free (host_if_name);
17215
17216   S (mp);
17217   W (ret);
17218   return ret;
17219 }
17220
17221 static void vl_api_af_packet_details_t_handler
17222   (vl_api_af_packet_details_t * mp)
17223 {
17224   vat_main_t *vam = &vat_main;
17225
17226   print (vam->ofp, "%-16s %d",
17227          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17228 }
17229
17230 static void vl_api_af_packet_details_t_handler_json
17231   (vl_api_af_packet_details_t * mp)
17232 {
17233   vat_main_t *vam = &vat_main;
17234   vat_json_node_t *node = NULL;
17235
17236   if (VAT_JSON_ARRAY != vam->json_tree.type)
17237     {
17238       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17239       vat_json_init_array (&vam->json_tree);
17240     }
17241   node = vat_json_array_add (&vam->json_tree);
17242
17243   vat_json_init_object (node);
17244   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17245   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17246 }
17247
17248 static int
17249 api_af_packet_dump (vat_main_t * vam)
17250 {
17251   vl_api_af_packet_dump_t *mp;
17252   vl_api_control_ping_t *mp_ping;
17253   int ret;
17254
17255   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17256   /* Get list of tap interfaces */
17257   M (AF_PACKET_DUMP, mp);
17258   S (mp);
17259
17260   /* Use a control ping for synchronization */
17261   MPING (CONTROL_PING, mp_ping);
17262   S (mp_ping);
17263
17264   W (ret);
17265   return ret;
17266 }
17267
17268 static int
17269 api_policer_add_del (vat_main_t * vam)
17270 {
17271   unformat_input_t *i = vam->input;
17272   vl_api_policer_add_del_t *mp;
17273   u8 is_add = 1;
17274   u8 *name = 0;
17275   u32 cir = 0;
17276   u32 eir = 0;
17277   u64 cb = 0;
17278   u64 eb = 0;
17279   u8 rate_type = 0;
17280   u8 round_type = 0;
17281   u8 type = 0;
17282   u8 color_aware = 0;
17283   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17284   int ret;
17285
17286   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17287   conform_action.dscp = 0;
17288   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17289   exceed_action.dscp = 0;
17290   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17291   violate_action.dscp = 0;
17292
17293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17294     {
17295       if (unformat (i, "del"))
17296         is_add = 0;
17297       else if (unformat (i, "name %s", &name))
17298         vec_add1 (name, 0);
17299       else if (unformat (i, "cir %u", &cir))
17300         ;
17301       else if (unformat (i, "eir %u", &eir))
17302         ;
17303       else if (unformat (i, "cb %u", &cb))
17304         ;
17305       else if (unformat (i, "eb %u", &eb))
17306         ;
17307       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17308                          &rate_type))
17309         ;
17310       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17311                          &round_type))
17312         ;
17313       else if (unformat (i, "type %U", unformat_policer_type, &type))
17314         ;
17315       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17316                          &conform_action))
17317         ;
17318       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17319                          &exceed_action))
17320         ;
17321       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17322                          &violate_action))
17323         ;
17324       else if (unformat (i, "color-aware"))
17325         color_aware = 1;
17326       else
17327         break;
17328     }
17329
17330   if (!vec_len (name))
17331     {
17332       errmsg ("policer name must be specified");
17333       return -99;
17334     }
17335
17336   if (vec_len (name) > 64)
17337     {
17338       errmsg ("policer name too long");
17339       return -99;
17340     }
17341
17342   M (POLICER_ADD_DEL, mp);
17343
17344   clib_memcpy (mp->name, name, vec_len (name));
17345   vec_free (name);
17346   mp->is_add = is_add;
17347   mp->cir = ntohl (cir);
17348   mp->eir = ntohl (eir);
17349   mp->cb = clib_net_to_host_u64 (cb);
17350   mp->eb = clib_net_to_host_u64 (eb);
17351   mp->rate_type = rate_type;
17352   mp->round_type = round_type;
17353   mp->type = type;
17354   mp->conform_action.type = conform_action.action_type;
17355   mp->conform_action.dscp = conform_action.dscp;
17356   mp->exceed_action.type = exceed_action.action_type;
17357   mp->exceed_action.dscp = exceed_action.dscp;
17358   mp->violate_action.type = violate_action.action_type;
17359   mp->violate_action.dscp = violate_action.dscp;
17360   mp->color_aware = color_aware;
17361
17362   S (mp);
17363   W (ret);
17364   return ret;
17365 }
17366
17367 static int
17368 api_policer_dump (vat_main_t * vam)
17369 {
17370   unformat_input_t *i = vam->input;
17371   vl_api_policer_dump_t *mp;
17372   vl_api_control_ping_t *mp_ping;
17373   u8 *match_name = 0;
17374   u8 match_name_valid = 0;
17375   int ret;
17376
17377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17378     {
17379       if (unformat (i, "name %s", &match_name))
17380         {
17381           vec_add1 (match_name, 0);
17382           match_name_valid = 1;
17383         }
17384       else
17385         break;
17386     }
17387
17388   M (POLICER_DUMP, mp);
17389   mp->match_name_valid = match_name_valid;
17390   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17391   vec_free (match_name);
17392   /* send it... */
17393   S (mp);
17394
17395   /* Use a control ping for synchronization */
17396   MPING (CONTROL_PING, mp_ping);
17397   S (mp_ping);
17398
17399   /* Wait for a reply... */
17400   W (ret);
17401   return ret;
17402 }
17403
17404 static int
17405 api_policer_classify_set_interface (vat_main_t * vam)
17406 {
17407   unformat_input_t *i = vam->input;
17408   vl_api_policer_classify_set_interface_t *mp;
17409   u32 sw_if_index;
17410   int sw_if_index_set;
17411   u32 ip4_table_index = ~0;
17412   u32 ip6_table_index = ~0;
17413   u32 l2_table_index = ~0;
17414   u8 is_add = 1;
17415   int ret;
17416
17417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17418     {
17419       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17420         sw_if_index_set = 1;
17421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17422         sw_if_index_set = 1;
17423       else if (unformat (i, "del"))
17424         is_add = 0;
17425       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17426         ;
17427       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17428         ;
17429       else if (unformat (i, "l2-table %d", &l2_table_index))
17430         ;
17431       else
17432         {
17433           clib_warning ("parse error '%U'", format_unformat_error, i);
17434           return -99;
17435         }
17436     }
17437
17438   if (sw_if_index_set == 0)
17439     {
17440       errmsg ("missing interface name or sw_if_index");
17441       return -99;
17442     }
17443
17444   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17445
17446   mp->sw_if_index = ntohl (sw_if_index);
17447   mp->ip4_table_index = ntohl (ip4_table_index);
17448   mp->ip6_table_index = ntohl (ip6_table_index);
17449   mp->l2_table_index = ntohl (l2_table_index);
17450   mp->is_add = is_add;
17451
17452   S (mp);
17453   W (ret);
17454   return ret;
17455 }
17456
17457 static int
17458 api_policer_classify_dump (vat_main_t * vam)
17459 {
17460   unformat_input_t *i = vam->input;
17461   vl_api_policer_classify_dump_t *mp;
17462   vl_api_control_ping_t *mp_ping;
17463   u8 type = POLICER_CLASSIFY_N_TABLES;
17464   int ret;
17465
17466   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17467     ;
17468   else
17469     {
17470       errmsg ("classify table type must be specified");
17471       return -99;
17472     }
17473
17474   if (!vam->json_output)
17475     {
17476       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17477     }
17478
17479   M (POLICER_CLASSIFY_DUMP, mp);
17480   mp->type = type;
17481   /* send it... */
17482   S (mp);
17483
17484   /* Use a control ping for synchronization */
17485   MPING (CONTROL_PING, mp_ping);
17486   S (mp_ping);
17487
17488   /* Wait for a reply... */
17489   W (ret);
17490   return ret;
17491 }
17492
17493 static u8 *
17494 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17495 {
17496   vl_api_fib_path_nh_proto_t proto =
17497     va_arg (*args, vl_api_fib_path_nh_proto_t);
17498
17499   switch (proto)
17500     {
17501     case FIB_API_PATH_NH_PROTO_IP4:
17502       s = format (s, "ip4");
17503       break;
17504     case FIB_API_PATH_NH_PROTO_IP6:
17505       s = format (s, "ip6");
17506       break;
17507     case FIB_API_PATH_NH_PROTO_MPLS:
17508       s = format (s, "mpls");
17509       break;
17510     case FIB_API_PATH_NH_PROTO_BIER:
17511       s = format (s, "bier");
17512       break;
17513     case FIB_API_PATH_NH_PROTO_ETHERNET:
17514       s = format (s, "ethernet");
17515       break;
17516     }
17517
17518   return (s);
17519 }
17520
17521 static u8 *
17522 format_vl_api_ip_address_union (u8 * s, va_list * args)
17523 {
17524   vl_api_address_family_t af = va_arg (*args, int);
17525   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17526
17527   switch (af)
17528     {
17529     case ADDRESS_IP4:
17530       s = format (s, "%U", format_ip4_address, u->ip4);
17531       break;
17532     case ADDRESS_IP6:
17533       s = format (s, "%U", format_ip6_address, u->ip6);
17534       break;
17535     }
17536   return (s);
17537 }
17538
17539 static u8 *
17540 format_vl_api_fib_path_type (u8 * s, va_list * args)
17541 {
17542   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17543
17544   switch (t)
17545     {
17546     case FIB_API_PATH_TYPE_NORMAL:
17547       s = format (s, "normal");
17548       break;
17549     case FIB_API_PATH_TYPE_LOCAL:
17550       s = format (s, "local");
17551       break;
17552     case FIB_API_PATH_TYPE_DROP:
17553       s = format (s, "drop");
17554       break;
17555     case FIB_API_PATH_TYPE_UDP_ENCAP:
17556       s = format (s, "udp-encap");
17557       break;
17558     case FIB_API_PATH_TYPE_BIER_IMP:
17559       s = format (s, "bier-imp");
17560       break;
17561     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17562       s = format (s, "unreach");
17563       break;
17564     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17565       s = format (s, "prohibit");
17566       break;
17567     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17568       s = format (s, "src-lookup");
17569       break;
17570     case FIB_API_PATH_TYPE_DVR:
17571       s = format (s, "dvr");
17572       break;
17573     case FIB_API_PATH_TYPE_INTERFACE_RX:
17574       s = format (s, "interface-rx");
17575       break;
17576     case FIB_API_PATH_TYPE_CLASSIFY:
17577       s = format (s, "classify");
17578       break;
17579     }
17580
17581   return (s);
17582 }
17583
17584 static void
17585 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17586 {
17587   print (vam->ofp,
17588          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17589          ntohl (fp->weight), ntohl (fp->sw_if_index),
17590          format_vl_api_fib_path_type, fp->type,
17591          format_fib_api_path_nh_proto, fp->proto,
17592          format_vl_api_ip_address_union, &fp->nh.address);
17593 }
17594
17595 static void
17596 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17597                                  vl_api_fib_path_t * fp)
17598 {
17599   struct in_addr ip4;
17600   struct in6_addr ip6;
17601
17602   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17603   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17604   vat_json_object_add_uint (node, "type", fp->type);
17605   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17606   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17607     {
17608       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17609       vat_json_object_add_ip4 (node, "next_hop", ip4);
17610     }
17611   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17612     {
17613       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17614       vat_json_object_add_ip6 (node, "next_hop", ip6);
17615     }
17616 }
17617
17618 static void
17619 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17620 {
17621   vat_main_t *vam = &vat_main;
17622   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17623   vl_api_fib_path_t *fp;
17624   i32 i;
17625
17626   print (vam->ofp, "sw_if_index %d via:",
17627          ntohl (mp->mt_tunnel.mt_sw_if_index));
17628   fp = mp->mt_tunnel.mt_paths;
17629   for (i = 0; i < count; i++)
17630     {
17631       vl_api_fib_path_print (vam, fp);
17632       fp++;
17633     }
17634
17635   print (vam->ofp, "");
17636 }
17637
17638 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17639 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17640
17641 static void
17642 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17643 {
17644   vat_main_t *vam = &vat_main;
17645   vat_json_node_t *node = NULL;
17646   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17647   vl_api_fib_path_t *fp;
17648   i32 i;
17649
17650   if (VAT_JSON_ARRAY != vam->json_tree.type)
17651     {
17652       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17653       vat_json_init_array (&vam->json_tree);
17654     }
17655   node = vat_json_array_add (&vam->json_tree);
17656
17657   vat_json_init_object (node);
17658   vat_json_object_add_uint (node, "sw_if_index",
17659                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17660
17661   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17662
17663   fp = mp->mt_tunnel.mt_paths;
17664   for (i = 0; i < count; i++)
17665     {
17666       vl_api_mpls_fib_path_json_print (node, fp);
17667       fp++;
17668     }
17669 }
17670
17671 static int
17672 api_mpls_tunnel_dump (vat_main_t * vam)
17673 {
17674   vl_api_mpls_tunnel_dump_t *mp;
17675   vl_api_control_ping_t *mp_ping;
17676   int ret;
17677
17678   M (MPLS_TUNNEL_DUMP, mp);
17679
17680   S (mp);
17681
17682   /* Use a control ping for synchronization */
17683   MPING (CONTROL_PING, mp_ping);
17684   S (mp_ping);
17685
17686   W (ret);
17687   return ret;
17688 }
17689
17690 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17691 #define vl_api_mpls_table_details_t_print vl_noop_handler
17692
17693
17694 static void
17695 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17696 {
17697   vat_main_t *vam = &vat_main;
17698
17699   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17700 }
17701
17702 static void vl_api_mpls_table_details_t_handler_json
17703   (vl_api_mpls_table_details_t * mp)
17704 {
17705   vat_main_t *vam = &vat_main;
17706   vat_json_node_t *node = NULL;
17707
17708   if (VAT_JSON_ARRAY != vam->json_tree.type)
17709     {
17710       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17711       vat_json_init_array (&vam->json_tree);
17712     }
17713   node = vat_json_array_add (&vam->json_tree);
17714
17715   vat_json_init_object (node);
17716   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17717 }
17718
17719 static int
17720 api_mpls_table_dump (vat_main_t * vam)
17721 {
17722   vl_api_mpls_table_dump_t *mp;
17723   vl_api_control_ping_t *mp_ping;
17724   int ret;
17725
17726   M (MPLS_TABLE_DUMP, mp);
17727   S (mp);
17728
17729   /* Use a control ping for synchronization */
17730   MPING (CONTROL_PING, mp_ping);
17731   S (mp_ping);
17732
17733   W (ret);
17734   return ret;
17735 }
17736
17737 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17738 #define vl_api_mpls_route_details_t_print vl_noop_handler
17739
17740 static void
17741 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17742 {
17743   vat_main_t *vam = &vat_main;
17744   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17745   vl_api_fib_path_t *fp;
17746   int i;
17747
17748   print (vam->ofp,
17749          "table-id %d, label %u, ess_bit %u",
17750          ntohl (mp->mr_route.mr_table_id),
17751          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17752   fp = mp->mr_route.mr_paths;
17753   for (i = 0; i < count; i++)
17754     {
17755       vl_api_fib_path_print (vam, fp);
17756       fp++;
17757     }
17758 }
17759
17760 static void vl_api_mpls_route_details_t_handler_json
17761   (vl_api_mpls_route_details_t * mp)
17762 {
17763   vat_main_t *vam = &vat_main;
17764   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17765   vat_json_node_t *node = NULL;
17766   vl_api_fib_path_t *fp;
17767   int i;
17768
17769   if (VAT_JSON_ARRAY != vam->json_tree.type)
17770     {
17771       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17772       vat_json_init_array (&vam->json_tree);
17773     }
17774   node = vat_json_array_add (&vam->json_tree);
17775
17776   vat_json_init_object (node);
17777   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17778   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17779   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17780   vat_json_object_add_uint (node, "path_count", count);
17781   fp = mp->mr_route.mr_paths;
17782   for (i = 0; i < count; i++)
17783     {
17784       vl_api_mpls_fib_path_json_print (node, fp);
17785       fp++;
17786     }
17787 }
17788
17789 static int
17790 api_mpls_route_dump (vat_main_t * vam)
17791 {
17792   unformat_input_t *input = vam->input;
17793   vl_api_mpls_route_dump_t *mp;
17794   vl_api_control_ping_t *mp_ping;
17795   u32 table_id;
17796   int ret;
17797
17798   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17799     {
17800       if (unformat (input, "table_id %d", &table_id))
17801         ;
17802       else
17803         break;
17804     }
17805   if (table_id == ~0)
17806     {
17807       errmsg ("missing table id");
17808       return -99;
17809     }
17810
17811   M (MPLS_ROUTE_DUMP, mp);
17812
17813   mp->table.mt_table_id = ntohl (table_id);
17814   S (mp);
17815
17816   /* Use a control ping for synchronization */
17817   MPING (CONTROL_PING, mp_ping);
17818   S (mp_ping);
17819
17820   W (ret);
17821   return ret;
17822 }
17823
17824 #define vl_api_ip_table_details_t_endian vl_noop_handler
17825 #define vl_api_ip_table_details_t_print vl_noop_handler
17826
17827 static void
17828 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17829 {
17830   vat_main_t *vam = &vat_main;
17831
17832   print (vam->ofp,
17833          "%s; table-id %d, prefix %U/%d",
17834          mp->table.name, ntohl (mp->table.table_id));
17835 }
17836
17837
17838 static void vl_api_ip_table_details_t_handler_json
17839   (vl_api_ip_table_details_t * mp)
17840 {
17841   vat_main_t *vam = &vat_main;
17842   vat_json_node_t *node = NULL;
17843
17844   if (VAT_JSON_ARRAY != vam->json_tree.type)
17845     {
17846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17847       vat_json_init_array (&vam->json_tree);
17848     }
17849   node = vat_json_array_add (&vam->json_tree);
17850
17851   vat_json_init_object (node);
17852   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17853 }
17854
17855 static int
17856 api_ip_table_dump (vat_main_t * vam)
17857 {
17858   vl_api_ip_table_dump_t *mp;
17859   vl_api_control_ping_t *mp_ping;
17860   int ret;
17861
17862   M (IP_TABLE_DUMP, mp);
17863   S (mp);
17864
17865   /* Use a control ping for synchronization */
17866   MPING (CONTROL_PING, mp_ping);
17867   S (mp_ping);
17868
17869   W (ret);
17870   return ret;
17871 }
17872
17873 static int
17874 api_ip_mtable_dump (vat_main_t * vam)
17875 {
17876   vl_api_ip_mtable_dump_t *mp;
17877   vl_api_control_ping_t *mp_ping;
17878   int ret;
17879
17880   M (IP_MTABLE_DUMP, mp);
17881   S (mp);
17882
17883   /* Use a control ping for synchronization */
17884   MPING (CONTROL_PING, mp_ping);
17885   S (mp_ping);
17886
17887   W (ret);
17888   return ret;
17889 }
17890
17891 static int
17892 api_ip_mroute_dump (vat_main_t * vam)
17893 {
17894   unformat_input_t *input = vam->input;
17895   vl_api_control_ping_t *mp_ping;
17896   vl_api_ip_mroute_dump_t *mp;
17897   int ret, is_ip6;
17898   u32 table_id;
17899
17900   is_ip6 = 0;
17901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17902     {
17903       if (unformat (input, "table_id %d", &table_id))
17904         ;
17905       else if (unformat (input, "ip6"))
17906         is_ip6 = 1;
17907       else if (unformat (input, "ip4"))
17908         is_ip6 = 0;
17909       else
17910         break;
17911     }
17912   if (table_id == ~0)
17913     {
17914       errmsg ("missing table id");
17915       return -99;
17916     }
17917
17918   M (IP_MROUTE_DUMP, mp);
17919   mp->table.table_id = table_id;
17920   mp->table.is_ip6 = is_ip6;
17921   S (mp);
17922
17923   /* Use a control ping for synchronization */
17924   MPING (CONTROL_PING, mp_ping);
17925   S (mp_ping);
17926
17927   W (ret);
17928   return ret;
17929 }
17930
17931 #define vl_api_ip_route_details_t_endian vl_noop_handler
17932 #define vl_api_ip_route_details_t_print vl_noop_handler
17933
17934 static void
17935 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17936 {
17937   vat_main_t *vam = &vat_main;
17938   u8 count = mp->route.n_paths;
17939   vl_api_fib_path_t *fp;
17940   int i;
17941
17942   print (vam->ofp,
17943          "table-id %d, prefix %U/%d",
17944          ntohl (mp->route.table_id),
17945          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17946   for (i = 0; i < count; i++)
17947     {
17948       fp = &mp->route.paths[i];
17949
17950       vl_api_fib_path_print (vam, fp);
17951       fp++;
17952     }
17953 }
17954
17955 static void vl_api_ip_route_details_t_handler_json
17956   (vl_api_ip_route_details_t * mp)
17957 {
17958   vat_main_t *vam = &vat_main;
17959   u8 count = mp->route.n_paths;
17960   vat_json_node_t *node = NULL;
17961   struct in_addr ip4;
17962   struct in6_addr ip6;
17963   vl_api_fib_path_t *fp;
17964   int i;
17965
17966   if (VAT_JSON_ARRAY != vam->json_tree.type)
17967     {
17968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17969       vat_json_init_array (&vam->json_tree);
17970     }
17971   node = vat_json_array_add (&vam->json_tree);
17972
17973   vat_json_init_object (node);
17974   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17975   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17976     {
17977       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17978       vat_json_object_add_ip6 (node, "prefix", ip6);
17979     }
17980   else
17981     {
17982       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17983       vat_json_object_add_ip4 (node, "prefix", ip4);
17984     }
17985   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17986   vat_json_object_add_uint (node, "path_count", count);
17987   for (i = 0; i < count; i++)
17988     {
17989       fp = &mp->route.paths[i];
17990       vl_api_mpls_fib_path_json_print (node, fp);
17991     }
17992 }
17993
17994 static int
17995 api_ip_route_dump (vat_main_t * vam)
17996 {
17997   unformat_input_t *input = vam->input;
17998   vl_api_ip_route_dump_t *mp;
17999   vl_api_control_ping_t *mp_ping;
18000   u32 table_id;
18001   u8 is_ip6;
18002   int ret;
18003
18004   is_ip6 = 0;
18005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18006     {
18007       if (unformat (input, "table_id %d", &table_id))
18008         ;
18009       else if (unformat (input, "ip6"))
18010         is_ip6 = 1;
18011       else if (unformat (input, "ip4"))
18012         is_ip6 = 0;
18013       else
18014         break;
18015     }
18016   if (table_id == ~0)
18017     {
18018       errmsg ("missing table id");
18019       return -99;
18020     }
18021
18022   M (IP_ROUTE_DUMP, mp);
18023
18024   mp->table.table_id = table_id;
18025   mp->table.is_ip6 = is_ip6;
18026
18027   S (mp);
18028
18029   /* Use a control ping for synchronization */
18030   MPING (CONTROL_PING, mp_ping);
18031   S (mp_ping);
18032
18033   W (ret);
18034   return ret;
18035 }
18036
18037 int
18038 api_classify_table_ids (vat_main_t * vam)
18039 {
18040   vl_api_classify_table_ids_t *mp;
18041   int ret;
18042
18043   /* Construct the API message */
18044   M (CLASSIFY_TABLE_IDS, mp);
18045   mp->context = 0;
18046
18047   S (mp);
18048   W (ret);
18049   return ret;
18050 }
18051
18052 int
18053 api_classify_table_by_interface (vat_main_t * vam)
18054 {
18055   unformat_input_t *input = vam->input;
18056   vl_api_classify_table_by_interface_t *mp;
18057
18058   u32 sw_if_index = ~0;
18059   int ret;
18060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18061     {
18062       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18063         ;
18064       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18065         ;
18066       else
18067         break;
18068     }
18069   if (sw_if_index == ~0)
18070     {
18071       errmsg ("missing interface name or sw_if_index");
18072       return -99;
18073     }
18074
18075   /* Construct the API message */
18076   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18077   mp->context = 0;
18078   mp->sw_if_index = ntohl (sw_if_index);
18079
18080   S (mp);
18081   W (ret);
18082   return ret;
18083 }
18084
18085 int
18086 api_classify_table_info (vat_main_t * vam)
18087 {
18088   unformat_input_t *input = vam->input;
18089   vl_api_classify_table_info_t *mp;
18090
18091   u32 table_id = ~0;
18092   int ret;
18093   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18094     {
18095       if (unformat (input, "table_id %d", &table_id))
18096         ;
18097       else
18098         break;
18099     }
18100   if (table_id == ~0)
18101     {
18102       errmsg ("missing table id");
18103       return -99;
18104     }
18105
18106   /* Construct the API message */
18107   M (CLASSIFY_TABLE_INFO, mp);
18108   mp->context = 0;
18109   mp->table_id = ntohl (table_id);
18110
18111   S (mp);
18112   W (ret);
18113   return ret;
18114 }
18115
18116 int
18117 api_classify_session_dump (vat_main_t * vam)
18118 {
18119   unformat_input_t *input = vam->input;
18120   vl_api_classify_session_dump_t *mp;
18121   vl_api_control_ping_t *mp_ping;
18122
18123   u32 table_id = ~0;
18124   int ret;
18125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18126     {
18127       if (unformat (input, "table_id %d", &table_id))
18128         ;
18129       else
18130         break;
18131     }
18132   if (table_id == ~0)
18133     {
18134       errmsg ("missing table id");
18135       return -99;
18136     }
18137
18138   /* Construct the API message */
18139   M (CLASSIFY_SESSION_DUMP, mp);
18140   mp->context = 0;
18141   mp->table_id = ntohl (table_id);
18142   S (mp);
18143
18144   /* Use a control ping for synchronization */
18145   MPING (CONTROL_PING, mp_ping);
18146   S (mp_ping);
18147
18148   W (ret);
18149   return ret;
18150 }
18151
18152 static void
18153 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18154 {
18155   vat_main_t *vam = &vat_main;
18156
18157   print (vam->ofp, "collector_address %U, collector_port %d, "
18158          "src_address %U, vrf_id %d, path_mtu %u, "
18159          "template_interval %u, udp_checksum %d",
18160          format_ip4_address, mp->collector_address,
18161          ntohs (mp->collector_port),
18162          format_ip4_address, mp->src_address,
18163          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18164          ntohl (mp->template_interval), mp->udp_checksum);
18165
18166   vam->retval = 0;
18167   vam->result_ready = 1;
18168 }
18169
18170 static void
18171   vl_api_ipfix_exporter_details_t_handler_json
18172   (vl_api_ipfix_exporter_details_t * mp)
18173 {
18174   vat_main_t *vam = &vat_main;
18175   vat_json_node_t node;
18176   struct in_addr collector_address;
18177   struct in_addr src_address;
18178
18179   vat_json_init_object (&node);
18180   clib_memcpy (&collector_address, &mp->collector_address,
18181                sizeof (collector_address));
18182   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18183   vat_json_object_add_uint (&node, "collector_port",
18184                             ntohs (mp->collector_port));
18185   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18186   vat_json_object_add_ip4 (&node, "src_address", src_address);
18187   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18188   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18189   vat_json_object_add_uint (&node, "template_interval",
18190                             ntohl (mp->template_interval));
18191   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18192
18193   vat_json_print (vam->ofp, &node);
18194   vat_json_free (&node);
18195   vam->retval = 0;
18196   vam->result_ready = 1;
18197 }
18198
18199 int
18200 api_ipfix_exporter_dump (vat_main_t * vam)
18201 {
18202   vl_api_ipfix_exporter_dump_t *mp;
18203   int ret;
18204
18205   /* Construct the API message */
18206   M (IPFIX_EXPORTER_DUMP, mp);
18207   mp->context = 0;
18208
18209   S (mp);
18210   W (ret);
18211   return ret;
18212 }
18213
18214 static int
18215 api_ipfix_classify_stream_dump (vat_main_t * vam)
18216 {
18217   vl_api_ipfix_classify_stream_dump_t *mp;
18218   int ret;
18219
18220   /* Construct the API message */
18221   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18222   mp->context = 0;
18223
18224   S (mp);
18225   W (ret);
18226   return ret;
18227   /* NOTREACHED */
18228   return 0;
18229 }
18230
18231 static void
18232   vl_api_ipfix_classify_stream_details_t_handler
18233   (vl_api_ipfix_classify_stream_details_t * mp)
18234 {
18235   vat_main_t *vam = &vat_main;
18236   print (vam->ofp, "domain_id %d, src_port %d",
18237          ntohl (mp->domain_id), ntohs (mp->src_port));
18238   vam->retval = 0;
18239   vam->result_ready = 1;
18240 }
18241
18242 static void
18243   vl_api_ipfix_classify_stream_details_t_handler_json
18244   (vl_api_ipfix_classify_stream_details_t * mp)
18245 {
18246   vat_main_t *vam = &vat_main;
18247   vat_json_node_t node;
18248
18249   vat_json_init_object (&node);
18250   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18251   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18252
18253   vat_json_print (vam->ofp, &node);
18254   vat_json_free (&node);
18255   vam->retval = 0;
18256   vam->result_ready = 1;
18257 }
18258
18259 static int
18260 api_ipfix_classify_table_dump (vat_main_t * vam)
18261 {
18262   vl_api_ipfix_classify_table_dump_t *mp;
18263   vl_api_control_ping_t *mp_ping;
18264   int ret;
18265
18266   if (!vam->json_output)
18267     {
18268       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18269              "transport_protocol");
18270     }
18271
18272   /* Construct the API message */
18273   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18274
18275   /* send it... */
18276   S (mp);
18277
18278   /* Use a control ping for synchronization */
18279   MPING (CONTROL_PING, mp_ping);
18280   S (mp_ping);
18281
18282   W (ret);
18283   return ret;
18284 }
18285
18286 static void
18287   vl_api_ipfix_classify_table_details_t_handler
18288   (vl_api_ipfix_classify_table_details_t * mp)
18289 {
18290   vat_main_t *vam = &vat_main;
18291   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18292          mp->transport_protocol);
18293 }
18294
18295 static void
18296   vl_api_ipfix_classify_table_details_t_handler_json
18297   (vl_api_ipfix_classify_table_details_t * mp)
18298 {
18299   vat_json_node_t *node = NULL;
18300   vat_main_t *vam = &vat_main;
18301
18302   if (VAT_JSON_ARRAY != vam->json_tree.type)
18303     {
18304       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18305       vat_json_init_array (&vam->json_tree);
18306     }
18307
18308   node = vat_json_array_add (&vam->json_tree);
18309   vat_json_init_object (node);
18310
18311   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18312   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18313   vat_json_object_add_uint (node, "transport_protocol",
18314                             mp->transport_protocol);
18315 }
18316
18317 static int
18318 api_sw_interface_span_enable_disable (vat_main_t * vam)
18319 {
18320   unformat_input_t *i = vam->input;
18321   vl_api_sw_interface_span_enable_disable_t *mp;
18322   u32 src_sw_if_index = ~0;
18323   u32 dst_sw_if_index = ~0;
18324   u8 state = 3;
18325   int ret;
18326   u8 is_l2 = 0;
18327
18328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18329     {
18330       if (unformat
18331           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18332         ;
18333       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18334         ;
18335       else
18336         if (unformat
18337             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18338         ;
18339       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18340         ;
18341       else if (unformat (i, "disable"))
18342         state = 0;
18343       else if (unformat (i, "rx"))
18344         state = 1;
18345       else if (unformat (i, "tx"))
18346         state = 2;
18347       else if (unformat (i, "both"))
18348         state = 3;
18349       else if (unformat (i, "l2"))
18350         is_l2 = 1;
18351       else
18352         break;
18353     }
18354
18355   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18356
18357   mp->sw_if_index_from = htonl (src_sw_if_index);
18358   mp->sw_if_index_to = htonl (dst_sw_if_index);
18359   mp->state = state;
18360   mp->is_l2 = is_l2;
18361
18362   S (mp);
18363   W (ret);
18364   return ret;
18365 }
18366
18367 static void
18368 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18369                                             * mp)
18370 {
18371   vat_main_t *vam = &vat_main;
18372   u8 *sw_if_from_name = 0;
18373   u8 *sw_if_to_name = 0;
18374   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18375   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18376   char *states[] = { "none", "rx", "tx", "both" };
18377   hash_pair_t *p;
18378
18379   /* *INDENT-OFF* */
18380   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18381   ({
18382     if ((u32) p->value[0] == sw_if_index_from)
18383       {
18384         sw_if_from_name = (u8 *)(p->key);
18385         if (sw_if_to_name)
18386           break;
18387       }
18388     if ((u32) p->value[0] == sw_if_index_to)
18389       {
18390         sw_if_to_name = (u8 *)(p->key);
18391         if (sw_if_from_name)
18392           break;
18393       }
18394   }));
18395   /* *INDENT-ON* */
18396   print (vam->ofp, "%20s => %20s (%s) %s",
18397          sw_if_from_name, sw_if_to_name, states[mp->state],
18398          mp->is_l2 ? "l2" : "device");
18399 }
18400
18401 static void
18402   vl_api_sw_interface_span_details_t_handler_json
18403   (vl_api_sw_interface_span_details_t * mp)
18404 {
18405   vat_main_t *vam = &vat_main;
18406   vat_json_node_t *node = NULL;
18407   u8 *sw_if_from_name = 0;
18408   u8 *sw_if_to_name = 0;
18409   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18410   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18411   hash_pair_t *p;
18412
18413   /* *INDENT-OFF* */
18414   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18415   ({
18416     if ((u32) p->value[0] == sw_if_index_from)
18417       {
18418         sw_if_from_name = (u8 *)(p->key);
18419         if (sw_if_to_name)
18420           break;
18421       }
18422     if ((u32) p->value[0] == sw_if_index_to)
18423       {
18424         sw_if_to_name = (u8 *)(p->key);
18425         if (sw_if_from_name)
18426           break;
18427       }
18428   }));
18429   /* *INDENT-ON* */
18430
18431   if (VAT_JSON_ARRAY != vam->json_tree.type)
18432     {
18433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18434       vat_json_init_array (&vam->json_tree);
18435     }
18436   node = vat_json_array_add (&vam->json_tree);
18437
18438   vat_json_init_object (node);
18439   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18440   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18441   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18442   if (0 != sw_if_to_name)
18443     {
18444       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18445     }
18446   vat_json_object_add_uint (node, "state", mp->state);
18447   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18448 }
18449
18450 static int
18451 api_sw_interface_span_dump (vat_main_t * vam)
18452 {
18453   unformat_input_t *input = vam->input;
18454   vl_api_sw_interface_span_dump_t *mp;
18455   vl_api_control_ping_t *mp_ping;
18456   u8 is_l2 = 0;
18457   int ret;
18458
18459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18460     {
18461       if (unformat (input, "l2"))
18462         is_l2 = 1;
18463       else
18464         break;
18465     }
18466
18467   M (SW_INTERFACE_SPAN_DUMP, mp);
18468   mp->is_l2 = is_l2;
18469   S (mp);
18470
18471   /* Use a control ping for synchronization */
18472   MPING (CONTROL_PING, mp_ping);
18473   S (mp_ping);
18474
18475   W (ret);
18476   return ret;
18477 }
18478
18479 int
18480 api_pg_create_interface (vat_main_t * vam)
18481 {
18482   unformat_input_t *input = vam->input;
18483   vl_api_pg_create_interface_t *mp;
18484
18485   u32 if_id = ~0, gso_size = 0;
18486   u8 gso_enabled = 0;
18487   int ret;
18488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18489     {
18490       if (unformat (input, "if_id %d", &if_id))
18491         ;
18492       else if (unformat (input, "gso-enabled"))
18493         {
18494           gso_enabled = 1;
18495           if (unformat (input, "gso-size %u", &gso_size))
18496             ;
18497           else
18498             {
18499               errmsg ("missing gso-size");
18500               return -99;
18501             }
18502         }
18503       else
18504         break;
18505     }
18506   if (if_id == ~0)
18507     {
18508       errmsg ("missing pg interface index");
18509       return -99;
18510     }
18511
18512   /* Construct the API message */
18513   M (PG_CREATE_INTERFACE, mp);
18514   mp->context = 0;
18515   mp->interface_id = ntohl (if_id);
18516   mp->gso_enabled = gso_enabled;
18517
18518   S (mp);
18519   W (ret);
18520   return ret;
18521 }
18522
18523 int
18524 api_pg_capture (vat_main_t * vam)
18525 {
18526   unformat_input_t *input = vam->input;
18527   vl_api_pg_capture_t *mp;
18528
18529   u32 if_id = ~0;
18530   u8 enable = 1;
18531   u32 count = 1;
18532   u8 pcap_file_set = 0;
18533   u8 *pcap_file = 0;
18534   int ret;
18535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18536     {
18537       if (unformat (input, "if_id %d", &if_id))
18538         ;
18539       else if (unformat (input, "pcap %s", &pcap_file))
18540         pcap_file_set = 1;
18541       else if (unformat (input, "count %d", &count))
18542         ;
18543       else if (unformat (input, "disable"))
18544         enable = 0;
18545       else
18546         break;
18547     }
18548   if (if_id == ~0)
18549     {
18550       errmsg ("missing pg interface index");
18551       return -99;
18552     }
18553   if (pcap_file_set > 0)
18554     {
18555       if (vec_len (pcap_file) > 255)
18556         {
18557           errmsg ("pcap file name is too long");
18558           return -99;
18559         }
18560     }
18561
18562   /* Construct the API message */
18563   M (PG_CAPTURE, mp);
18564   mp->context = 0;
18565   mp->interface_id = ntohl (if_id);
18566   mp->is_enabled = enable;
18567   mp->count = ntohl (count);
18568   if (pcap_file_set != 0)
18569     {
18570       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18571     }
18572   vec_free (pcap_file);
18573
18574   S (mp);
18575   W (ret);
18576   return ret;
18577 }
18578
18579 int
18580 api_pg_enable_disable (vat_main_t * vam)
18581 {
18582   unformat_input_t *input = vam->input;
18583   vl_api_pg_enable_disable_t *mp;
18584
18585   u8 enable = 1;
18586   u8 stream_name_set = 0;
18587   u8 *stream_name = 0;
18588   int ret;
18589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18590     {
18591       if (unformat (input, "stream %s", &stream_name))
18592         stream_name_set = 1;
18593       else if (unformat (input, "disable"))
18594         enable = 0;
18595       else
18596         break;
18597     }
18598
18599   if (stream_name_set > 0)
18600     {
18601       if (vec_len (stream_name) > 255)
18602         {
18603           errmsg ("stream name too long");
18604           return -99;
18605         }
18606     }
18607
18608   /* Construct the API message */
18609   M (PG_ENABLE_DISABLE, mp);
18610   mp->context = 0;
18611   mp->is_enabled = enable;
18612   if (stream_name_set != 0)
18613     {
18614       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18615     }
18616   vec_free (stream_name);
18617
18618   S (mp);
18619   W (ret);
18620   return ret;
18621 }
18622
18623 int
18624 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18625 {
18626   unformat_input_t *input = vam->input;
18627   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18628
18629   u16 *low_ports = 0;
18630   u16 *high_ports = 0;
18631   u16 this_low;
18632   u16 this_hi;
18633   vl_api_prefix_t prefix;
18634   u32 tmp, tmp2;
18635   u8 prefix_set = 0;
18636   u32 vrf_id = ~0;
18637   u8 is_add = 1;
18638   int ret;
18639
18640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18641     {
18642       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18643         prefix_set = 1;
18644       else if (unformat (input, "vrf %d", &vrf_id))
18645         ;
18646       else if (unformat (input, "del"))
18647         is_add = 0;
18648       else if (unformat (input, "port %d", &tmp))
18649         {
18650           if (tmp == 0 || tmp > 65535)
18651             {
18652               errmsg ("port %d out of range", tmp);
18653               return -99;
18654             }
18655           this_low = tmp;
18656           this_hi = this_low + 1;
18657           vec_add1 (low_ports, this_low);
18658           vec_add1 (high_ports, this_hi);
18659         }
18660       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18661         {
18662           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18663             {
18664               errmsg ("incorrect range parameters");
18665               return -99;
18666             }
18667           this_low = tmp;
18668           /* Note: in debug CLI +1 is added to high before
18669              passing to real fn that does "the work"
18670              (ip_source_and_port_range_check_add_del).
18671              This fn is a wrapper around the binary API fn a
18672              control plane will call, which expects this increment
18673              to have occurred. Hence letting the binary API control
18674              plane fn do the increment for consistency between VAT
18675              and other control planes.
18676            */
18677           this_hi = tmp2;
18678           vec_add1 (low_ports, this_low);
18679           vec_add1 (high_ports, this_hi);
18680         }
18681       else
18682         break;
18683     }
18684
18685   if (prefix_set == 0)
18686     {
18687       errmsg ("<address>/<mask> not specified");
18688       return -99;
18689     }
18690
18691   if (vrf_id == ~0)
18692     {
18693       errmsg ("VRF ID required, not specified");
18694       return -99;
18695     }
18696
18697   if (vrf_id == 0)
18698     {
18699       errmsg
18700         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18701       return -99;
18702     }
18703
18704   if (vec_len (low_ports) == 0)
18705     {
18706       errmsg ("At least one port or port range required");
18707       return -99;
18708     }
18709
18710   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18711
18712   mp->is_add = is_add;
18713
18714   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18715
18716   mp->number_of_ranges = vec_len (low_ports);
18717
18718   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18719   vec_free (low_ports);
18720
18721   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18722   vec_free (high_ports);
18723
18724   mp->vrf_id = ntohl (vrf_id);
18725
18726   S (mp);
18727   W (ret);
18728   return ret;
18729 }
18730
18731 int
18732 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18733 {
18734   unformat_input_t *input = vam->input;
18735   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18736   u32 sw_if_index = ~0;
18737   int vrf_set = 0;
18738   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18739   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18740   u8 is_add = 1;
18741   int ret;
18742
18743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18744     {
18745       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18746         ;
18747       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18748         ;
18749       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18750         vrf_set = 1;
18751       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18752         vrf_set = 1;
18753       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18754         vrf_set = 1;
18755       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18756         vrf_set = 1;
18757       else if (unformat (input, "del"))
18758         is_add = 0;
18759       else
18760         break;
18761     }
18762
18763   if (sw_if_index == ~0)
18764     {
18765       errmsg ("Interface required but not specified");
18766       return -99;
18767     }
18768
18769   if (vrf_set == 0)
18770     {
18771       errmsg ("VRF ID required but not specified");
18772       return -99;
18773     }
18774
18775   if (tcp_out_vrf_id == 0
18776       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18777     {
18778       errmsg
18779         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18780       return -99;
18781     }
18782
18783   /* Construct the API message */
18784   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18785
18786   mp->sw_if_index = ntohl (sw_if_index);
18787   mp->is_add = is_add;
18788   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18789   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18790   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18791   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18792
18793   /* send it... */
18794   S (mp);
18795
18796   /* Wait for a reply... */
18797   W (ret);
18798   return ret;
18799 }
18800
18801 static int
18802 api_set_punt (vat_main_t * vam)
18803 {
18804   unformat_input_t *i = vam->input;
18805   vl_api_address_family_t af;
18806   vl_api_set_punt_t *mp;
18807   u32 protocol = ~0;
18808   u32 port = ~0;
18809   int is_add = 1;
18810   int ret;
18811
18812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18813     {
18814       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18815         ;
18816       else if (unformat (i, "protocol %d", &protocol))
18817         ;
18818       else if (unformat (i, "port %d", &port))
18819         ;
18820       else if (unformat (i, "del"))
18821         is_add = 0;
18822       else
18823         {
18824           clib_warning ("parse error '%U'", format_unformat_error, i);
18825           return -99;
18826         }
18827     }
18828
18829   M (SET_PUNT, mp);
18830
18831   mp->is_add = (u8) is_add;
18832   mp->punt.type = PUNT_API_TYPE_L4;
18833   mp->punt.punt.l4.af = af;
18834   mp->punt.punt.l4.protocol = (u8) protocol;
18835   mp->punt.punt.l4.port = htons ((u16) port);
18836
18837   S (mp);
18838   W (ret);
18839   return ret;
18840 }
18841
18842 static int
18843 api_delete_subif (vat_main_t * vam)
18844 {
18845   unformat_input_t *i = vam->input;
18846   vl_api_delete_subif_t *mp;
18847   u32 sw_if_index = ~0;
18848   int ret;
18849
18850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18851     {
18852       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18853         ;
18854       if (unformat (i, "sw_if_index %d", &sw_if_index))
18855         ;
18856       else
18857         break;
18858     }
18859
18860   if (sw_if_index == ~0)
18861     {
18862       errmsg ("missing sw_if_index");
18863       return -99;
18864     }
18865
18866   /* Construct the API message */
18867   M (DELETE_SUBIF, mp);
18868   mp->sw_if_index = ntohl (sw_if_index);
18869
18870   S (mp);
18871   W (ret);
18872   return ret;
18873 }
18874
18875 #define foreach_pbb_vtr_op      \
18876 _("disable",  L2_VTR_DISABLED)  \
18877 _("pop",  L2_VTR_POP_2)         \
18878 _("push",  L2_VTR_PUSH_2)
18879
18880 static int
18881 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18882 {
18883   unformat_input_t *i = vam->input;
18884   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18885   u32 sw_if_index = ~0, vtr_op = ~0;
18886   u16 outer_tag = ~0;
18887   u8 dmac[6], smac[6];
18888   u8 dmac_set = 0, smac_set = 0;
18889   u16 vlanid = 0;
18890   u32 sid = ~0;
18891   u32 tmp;
18892   int ret;
18893
18894   /* Shut up coverity */
18895   clib_memset (dmac, 0, sizeof (dmac));
18896   clib_memset (smac, 0, sizeof (smac));
18897
18898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18899     {
18900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18901         ;
18902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18903         ;
18904       else if (unformat (i, "vtr_op %d", &vtr_op))
18905         ;
18906 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18907       foreach_pbb_vtr_op
18908 #undef _
18909         else if (unformat (i, "translate_pbb_stag"))
18910         {
18911           if (unformat (i, "%d", &tmp))
18912             {
18913               vtr_op = L2_VTR_TRANSLATE_2_1;
18914               outer_tag = tmp;
18915             }
18916           else
18917             {
18918               errmsg
18919                 ("translate_pbb_stag operation requires outer tag definition");
18920               return -99;
18921             }
18922         }
18923       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18924         dmac_set++;
18925       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18926         smac_set++;
18927       else if (unformat (i, "sid %d", &sid))
18928         ;
18929       else if (unformat (i, "vlanid %d", &tmp))
18930         vlanid = tmp;
18931       else
18932         {
18933           clib_warning ("parse error '%U'", format_unformat_error, i);
18934           return -99;
18935         }
18936     }
18937
18938   if ((sw_if_index == ~0) || (vtr_op == ~0))
18939     {
18940       errmsg ("missing sw_if_index or vtr operation");
18941       return -99;
18942     }
18943   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18944       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18945     {
18946       errmsg
18947         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18948       return -99;
18949     }
18950
18951   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18952   mp->sw_if_index = ntohl (sw_if_index);
18953   mp->vtr_op = ntohl (vtr_op);
18954   mp->outer_tag = ntohs (outer_tag);
18955   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18956   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18957   mp->b_vlanid = ntohs (vlanid);
18958   mp->i_sid = ntohl (sid);
18959
18960   S (mp);
18961   W (ret);
18962   return ret;
18963 }
18964
18965 static int
18966 api_flow_classify_set_interface (vat_main_t * vam)
18967 {
18968   unformat_input_t *i = vam->input;
18969   vl_api_flow_classify_set_interface_t *mp;
18970   u32 sw_if_index;
18971   int sw_if_index_set;
18972   u32 ip4_table_index = ~0;
18973   u32 ip6_table_index = ~0;
18974   u8 is_add = 1;
18975   int ret;
18976
18977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18978     {
18979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18980         sw_if_index_set = 1;
18981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18982         sw_if_index_set = 1;
18983       else if (unformat (i, "del"))
18984         is_add = 0;
18985       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18986         ;
18987       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18988         ;
18989       else
18990         {
18991           clib_warning ("parse error '%U'", format_unformat_error, i);
18992           return -99;
18993         }
18994     }
18995
18996   if (sw_if_index_set == 0)
18997     {
18998       errmsg ("missing interface name or sw_if_index");
18999       return -99;
19000     }
19001
19002   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19003
19004   mp->sw_if_index = ntohl (sw_if_index);
19005   mp->ip4_table_index = ntohl (ip4_table_index);
19006   mp->ip6_table_index = ntohl (ip6_table_index);
19007   mp->is_add = is_add;
19008
19009   S (mp);
19010   W (ret);
19011   return ret;
19012 }
19013
19014 static int
19015 api_flow_classify_dump (vat_main_t * vam)
19016 {
19017   unformat_input_t *i = vam->input;
19018   vl_api_flow_classify_dump_t *mp;
19019   vl_api_control_ping_t *mp_ping;
19020   u8 type = FLOW_CLASSIFY_N_TABLES;
19021   int ret;
19022
19023   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19024     ;
19025   else
19026     {
19027       errmsg ("classify table type must be specified");
19028       return -99;
19029     }
19030
19031   if (!vam->json_output)
19032     {
19033       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19034     }
19035
19036   M (FLOW_CLASSIFY_DUMP, mp);
19037   mp->type = type;
19038   /* send it... */
19039   S (mp);
19040
19041   /* Use a control ping for synchronization */
19042   MPING (CONTROL_PING, mp_ping);
19043   S (mp_ping);
19044
19045   /* Wait for a reply... */
19046   W (ret);
19047   return ret;
19048 }
19049
19050 static int
19051 api_feature_enable_disable (vat_main_t * vam)
19052 {
19053   unformat_input_t *i = vam->input;
19054   vl_api_feature_enable_disable_t *mp;
19055   u8 *arc_name = 0;
19056   u8 *feature_name = 0;
19057   u32 sw_if_index = ~0;
19058   u8 enable = 1;
19059   int ret;
19060
19061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19062     {
19063       if (unformat (i, "arc_name %s", &arc_name))
19064         ;
19065       else if (unformat (i, "feature_name %s", &feature_name))
19066         ;
19067       else
19068         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19069         ;
19070       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19071         ;
19072       else if (unformat (i, "disable"))
19073         enable = 0;
19074       else
19075         break;
19076     }
19077
19078   if (arc_name == 0)
19079     {
19080       errmsg ("missing arc name");
19081       return -99;
19082     }
19083   if (vec_len (arc_name) > 63)
19084     {
19085       errmsg ("arc name too long");
19086     }
19087
19088   if (feature_name == 0)
19089     {
19090       errmsg ("missing feature name");
19091       return -99;
19092     }
19093   if (vec_len (feature_name) > 63)
19094     {
19095       errmsg ("feature name too long");
19096     }
19097
19098   if (sw_if_index == ~0)
19099     {
19100       errmsg ("missing interface name or sw_if_index");
19101       return -99;
19102     }
19103
19104   /* Construct the API message */
19105   M (FEATURE_ENABLE_DISABLE, mp);
19106   mp->sw_if_index = ntohl (sw_if_index);
19107   mp->enable = enable;
19108   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19109   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19110   vec_free (arc_name);
19111   vec_free (feature_name);
19112
19113   S (mp);
19114   W (ret);
19115   return ret;
19116 }
19117
19118 static int
19119 api_feature_gso_enable_disable (vat_main_t * vam)
19120 {
19121   unformat_input_t *i = vam->input;
19122   vl_api_feature_gso_enable_disable_t *mp;
19123   u32 sw_if_index = ~0;
19124   u8 enable = 1;
19125   int ret;
19126
19127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19128     {
19129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19130         ;
19131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19132         ;
19133       else if (unformat (i, "enable"))
19134         enable = 1;
19135       else if (unformat (i, "disable"))
19136         enable = 0;
19137       else
19138         break;
19139     }
19140
19141   if (sw_if_index == ~0)
19142     {
19143       errmsg ("missing interface name or sw_if_index");
19144       return -99;
19145     }
19146
19147   /* Construct the API message */
19148   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19149   mp->sw_if_index = ntohl (sw_if_index);
19150   mp->enable_disable = enable;
19151
19152   S (mp);
19153   W (ret);
19154   return ret;
19155 }
19156
19157 static int
19158 api_sw_interface_tag_add_del (vat_main_t * vam)
19159 {
19160   unformat_input_t *i = vam->input;
19161   vl_api_sw_interface_tag_add_del_t *mp;
19162   u32 sw_if_index = ~0;
19163   u8 *tag = 0;
19164   u8 enable = 1;
19165   int ret;
19166
19167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19168     {
19169       if (unformat (i, "tag %s", &tag))
19170         ;
19171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19172         ;
19173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19174         ;
19175       else if (unformat (i, "del"))
19176         enable = 0;
19177       else
19178         break;
19179     }
19180
19181   if (sw_if_index == ~0)
19182     {
19183       errmsg ("missing interface name or sw_if_index");
19184       return -99;
19185     }
19186
19187   if (enable && (tag == 0))
19188     {
19189       errmsg ("no tag specified");
19190       return -99;
19191     }
19192
19193   /* Construct the API message */
19194   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19195   mp->sw_if_index = ntohl (sw_if_index);
19196   mp->is_add = enable;
19197   if (enable)
19198     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19199   vec_free (tag);
19200
19201   S (mp);
19202   W (ret);
19203   return ret;
19204 }
19205
19206 static int
19207 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19208 {
19209   unformat_input_t *i = vam->input;
19210   vl_api_mac_address_t mac = { 0 };
19211   vl_api_sw_interface_add_del_mac_address_t *mp;
19212   u32 sw_if_index = ~0;
19213   u8 is_add = 1;
19214   u8 mac_set = 0;
19215   int ret;
19216
19217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19218     {
19219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19220         ;
19221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19222         ;
19223       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19224         mac_set++;
19225       else if (unformat (i, "del"))
19226         is_add = 0;
19227       else
19228         break;
19229     }
19230
19231   if (sw_if_index == ~0)
19232     {
19233       errmsg ("missing interface name or sw_if_index");
19234       return -99;
19235     }
19236
19237   if (!mac_set)
19238     {
19239       errmsg ("missing MAC address");
19240       return -99;
19241     }
19242
19243   /* Construct the API message */
19244   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19245   mp->sw_if_index = ntohl (sw_if_index);
19246   mp->is_add = is_add;
19247   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19248
19249   S (mp);
19250   W (ret);
19251   return ret;
19252 }
19253
19254 static void vl_api_l2_xconnect_details_t_handler
19255   (vl_api_l2_xconnect_details_t * mp)
19256 {
19257   vat_main_t *vam = &vat_main;
19258
19259   print (vam->ofp, "%15d%15d",
19260          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19261 }
19262
19263 static void vl_api_l2_xconnect_details_t_handler_json
19264   (vl_api_l2_xconnect_details_t * mp)
19265 {
19266   vat_main_t *vam = &vat_main;
19267   vat_json_node_t *node = NULL;
19268
19269   if (VAT_JSON_ARRAY != vam->json_tree.type)
19270     {
19271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19272       vat_json_init_array (&vam->json_tree);
19273     }
19274   node = vat_json_array_add (&vam->json_tree);
19275
19276   vat_json_init_object (node);
19277   vat_json_object_add_uint (node, "rx_sw_if_index",
19278                             ntohl (mp->rx_sw_if_index));
19279   vat_json_object_add_uint (node, "tx_sw_if_index",
19280                             ntohl (mp->tx_sw_if_index));
19281 }
19282
19283 static int
19284 api_l2_xconnect_dump (vat_main_t * vam)
19285 {
19286   vl_api_l2_xconnect_dump_t *mp;
19287   vl_api_control_ping_t *mp_ping;
19288   int ret;
19289
19290   if (!vam->json_output)
19291     {
19292       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19293     }
19294
19295   M (L2_XCONNECT_DUMP, mp);
19296
19297   S (mp);
19298
19299   /* Use a control ping for synchronization */
19300   MPING (CONTROL_PING, mp_ping);
19301   S (mp_ping);
19302
19303   W (ret);
19304   return ret;
19305 }
19306
19307 static int
19308 api_hw_interface_set_mtu (vat_main_t * vam)
19309 {
19310   unformat_input_t *i = vam->input;
19311   vl_api_hw_interface_set_mtu_t *mp;
19312   u32 sw_if_index = ~0;
19313   u32 mtu = 0;
19314   int ret;
19315
19316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19317     {
19318       if (unformat (i, "mtu %d", &mtu))
19319         ;
19320       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19321         ;
19322       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19323         ;
19324       else
19325         break;
19326     }
19327
19328   if (sw_if_index == ~0)
19329     {
19330       errmsg ("missing interface name or sw_if_index");
19331       return -99;
19332     }
19333
19334   if (mtu == 0)
19335     {
19336       errmsg ("no mtu specified");
19337       return -99;
19338     }
19339
19340   /* Construct the API message */
19341   M (HW_INTERFACE_SET_MTU, mp);
19342   mp->sw_if_index = ntohl (sw_if_index);
19343   mp->mtu = ntohs ((u16) mtu);
19344
19345   S (mp);
19346   W (ret);
19347   return ret;
19348 }
19349
19350 static int
19351 api_p2p_ethernet_add (vat_main_t * vam)
19352 {
19353   unformat_input_t *i = vam->input;
19354   vl_api_p2p_ethernet_add_t *mp;
19355   u32 parent_if_index = ~0;
19356   u32 sub_id = ~0;
19357   u8 remote_mac[6];
19358   u8 mac_set = 0;
19359   int ret;
19360
19361   clib_memset (remote_mac, 0, sizeof (remote_mac));
19362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19363     {
19364       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19365         ;
19366       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19367         ;
19368       else
19369         if (unformat
19370             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19371         mac_set++;
19372       else if (unformat (i, "sub_id %d", &sub_id))
19373         ;
19374       else
19375         {
19376           clib_warning ("parse error '%U'", format_unformat_error, i);
19377           return -99;
19378         }
19379     }
19380
19381   if (parent_if_index == ~0)
19382     {
19383       errmsg ("missing interface name or sw_if_index");
19384       return -99;
19385     }
19386   if (mac_set == 0)
19387     {
19388       errmsg ("missing remote mac address");
19389       return -99;
19390     }
19391   if (sub_id == ~0)
19392     {
19393       errmsg ("missing sub-interface id");
19394       return -99;
19395     }
19396
19397   M (P2P_ETHERNET_ADD, mp);
19398   mp->parent_if_index = ntohl (parent_if_index);
19399   mp->subif_id = ntohl (sub_id);
19400   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19401
19402   S (mp);
19403   W (ret);
19404   return ret;
19405 }
19406
19407 static int
19408 api_p2p_ethernet_del (vat_main_t * vam)
19409 {
19410   unformat_input_t *i = vam->input;
19411   vl_api_p2p_ethernet_del_t *mp;
19412   u32 parent_if_index = ~0;
19413   u8 remote_mac[6];
19414   u8 mac_set = 0;
19415   int ret;
19416
19417   clib_memset (remote_mac, 0, sizeof (remote_mac));
19418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19419     {
19420       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19421         ;
19422       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19423         ;
19424       else
19425         if (unformat
19426             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19427         mac_set++;
19428       else
19429         {
19430           clib_warning ("parse error '%U'", format_unformat_error, i);
19431           return -99;
19432         }
19433     }
19434
19435   if (parent_if_index == ~0)
19436     {
19437       errmsg ("missing interface name or sw_if_index");
19438       return -99;
19439     }
19440   if (mac_set == 0)
19441     {
19442       errmsg ("missing remote mac address");
19443       return -99;
19444     }
19445
19446   M (P2P_ETHERNET_DEL, mp);
19447   mp->parent_if_index = ntohl (parent_if_index);
19448   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19449
19450   S (mp);
19451   W (ret);
19452   return ret;
19453 }
19454
19455 static int
19456 api_lldp_config (vat_main_t * vam)
19457 {
19458   unformat_input_t *i = vam->input;
19459   vl_api_lldp_config_t *mp;
19460   int tx_hold = 0;
19461   int tx_interval = 0;
19462   u8 *sys_name = NULL;
19463   int ret;
19464
19465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19466     {
19467       if (unformat (i, "system-name %s", &sys_name))
19468         ;
19469       else if (unformat (i, "tx-hold %d", &tx_hold))
19470         ;
19471       else if (unformat (i, "tx-interval %d", &tx_interval))
19472         ;
19473       else
19474         {
19475           clib_warning ("parse error '%U'", format_unformat_error, i);
19476           return -99;
19477         }
19478     }
19479
19480   vec_add1 (sys_name, 0);
19481
19482   M (LLDP_CONFIG, mp);
19483   mp->tx_hold = htonl (tx_hold);
19484   mp->tx_interval = htonl (tx_interval);
19485   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19486   vec_free (sys_name);
19487
19488   S (mp);
19489   W (ret);
19490   return ret;
19491 }
19492
19493 static int
19494 api_sw_interface_set_lldp (vat_main_t * vam)
19495 {
19496   unformat_input_t *i = vam->input;
19497   vl_api_sw_interface_set_lldp_t *mp;
19498   u32 sw_if_index = ~0;
19499   u32 enable = 1;
19500   u8 *port_desc = NULL, *mgmt_oid = NULL;
19501   ip4_address_t ip4_addr;
19502   ip6_address_t ip6_addr;
19503   int ret;
19504
19505   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19506   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19507
19508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19509     {
19510       if (unformat (i, "disable"))
19511         enable = 0;
19512       else
19513         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19514         ;
19515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19516         ;
19517       else if (unformat (i, "port-desc %s", &port_desc))
19518         ;
19519       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19520         ;
19521       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19522         ;
19523       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19524         ;
19525       else
19526         break;
19527     }
19528
19529   if (sw_if_index == ~0)
19530     {
19531       errmsg ("missing interface name or sw_if_index");
19532       return -99;
19533     }
19534
19535   /* Construct the API message */
19536   vec_add1 (port_desc, 0);
19537   vec_add1 (mgmt_oid, 0);
19538   M (SW_INTERFACE_SET_LLDP, mp);
19539   mp->sw_if_index = ntohl (sw_if_index);
19540   mp->enable = enable;
19541   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19542   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19543   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19544   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19545   vec_free (port_desc);
19546   vec_free (mgmt_oid);
19547
19548   S (mp);
19549   W (ret);
19550   return ret;
19551 }
19552
19553 static int
19554 api_tcp_configure_src_addresses (vat_main_t * vam)
19555 {
19556   vl_api_tcp_configure_src_addresses_t *mp;
19557   unformat_input_t *i = vam->input;
19558   vl_api_address_t first, last;
19559   u8 range_set = 0;
19560   u32 vrf_id = 0;
19561   int ret;
19562
19563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19564     {
19565       if (unformat (i, "%U - %U",
19566                     unformat_vl_api_address, &first,
19567                     unformat_vl_api_address, &last))
19568         {
19569           if (range_set)
19570             {
19571               errmsg ("one range per message (range already set)");
19572               return -99;
19573             }
19574           range_set = 1;
19575         }
19576       else if (unformat (i, "vrf %d", &vrf_id))
19577         ;
19578       else
19579         break;
19580     }
19581
19582   if (range_set == 0)
19583     {
19584       errmsg ("address range not set");
19585       return -99;
19586     }
19587
19588   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19589
19590   mp->vrf_id = ntohl (vrf_id);
19591   clib_memcpy (&mp->first_address, &first, sizeof (first));
19592   clib_memcpy (&mp->last_address, &last, sizeof (last));
19593
19594   S (mp);
19595   W (ret);
19596   return ret;
19597 }
19598
19599 static void vl_api_app_namespace_add_del_reply_t_handler
19600   (vl_api_app_namespace_add_del_reply_t * mp)
19601 {
19602   vat_main_t *vam = &vat_main;
19603   i32 retval = ntohl (mp->retval);
19604   if (vam->async_mode)
19605     {
19606       vam->async_errors += (retval < 0);
19607     }
19608   else
19609     {
19610       vam->retval = retval;
19611       if (retval == 0)
19612         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19613       vam->result_ready = 1;
19614     }
19615 }
19616
19617 static void vl_api_app_namespace_add_del_reply_t_handler_json
19618   (vl_api_app_namespace_add_del_reply_t * mp)
19619 {
19620   vat_main_t *vam = &vat_main;
19621   vat_json_node_t node;
19622
19623   vat_json_init_object (&node);
19624   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19625   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19626
19627   vat_json_print (vam->ofp, &node);
19628   vat_json_free (&node);
19629
19630   vam->retval = ntohl (mp->retval);
19631   vam->result_ready = 1;
19632 }
19633
19634 static int
19635 api_app_namespace_add_del (vat_main_t * vam)
19636 {
19637   vl_api_app_namespace_add_del_t *mp;
19638   unformat_input_t *i = vam->input;
19639   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19640   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19641   u64 secret;
19642   int ret;
19643
19644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19645     {
19646       if (unformat (i, "id %_%v%_", &ns_id))
19647         ;
19648       else if (unformat (i, "secret %lu", &secret))
19649         secret_set = 1;
19650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19651         sw_if_index_set = 1;
19652       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19653         ;
19654       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19655         ;
19656       else
19657         break;
19658     }
19659   if (!ns_id || !secret_set || !sw_if_index_set)
19660     {
19661       errmsg ("namespace id, secret and sw_if_index must be set");
19662       return -99;
19663     }
19664   if (vec_len (ns_id) > 64)
19665     {
19666       errmsg ("namespace id too long");
19667       return -99;
19668     }
19669   M (APP_NAMESPACE_ADD_DEL, mp);
19670
19671   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19672   mp->secret = clib_host_to_net_u64 (secret);
19673   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19674   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19675   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19676   vec_free (ns_id);
19677   S (mp);
19678   W (ret);
19679   return ret;
19680 }
19681
19682 static int
19683 api_sock_init_shm (vat_main_t * vam)
19684 {
19685 #if VPP_API_TEST_BUILTIN == 0
19686   unformat_input_t *i = vam->input;
19687   vl_api_shm_elem_config_t *config = 0;
19688   u64 size = 64 << 20;
19689   int rv;
19690
19691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19692     {
19693       if (unformat (i, "size %U", unformat_memory_size, &size))
19694         ;
19695       else
19696         break;
19697     }
19698
19699   /*
19700    * Canned custom ring allocator config.
19701    * Should probably parse all of this
19702    */
19703   vec_validate (config, 6);
19704   config[0].type = VL_API_VLIB_RING;
19705   config[0].size = 256;
19706   config[0].count = 32;
19707
19708   config[1].type = VL_API_VLIB_RING;
19709   config[1].size = 1024;
19710   config[1].count = 16;
19711
19712   config[2].type = VL_API_VLIB_RING;
19713   config[2].size = 4096;
19714   config[2].count = 2;
19715
19716   config[3].type = VL_API_CLIENT_RING;
19717   config[3].size = 256;
19718   config[3].count = 32;
19719
19720   config[4].type = VL_API_CLIENT_RING;
19721   config[4].size = 1024;
19722   config[4].count = 16;
19723
19724   config[5].type = VL_API_CLIENT_RING;
19725   config[5].size = 4096;
19726   config[5].count = 2;
19727
19728   config[6].type = VL_API_QUEUE;
19729   config[6].count = 128;
19730   config[6].size = sizeof (uword);
19731
19732   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19733   if (!rv)
19734     vam->client_index_invalid = 1;
19735   return rv;
19736 #else
19737   return -99;
19738 #endif
19739 }
19740
19741 static void
19742 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19743 {
19744   vat_main_t *vam = &vat_main;
19745   fib_prefix_t lcl, rmt;
19746
19747   ip_prefix_decode (&mp->lcl, &lcl);
19748   ip_prefix_decode (&mp->rmt, &rmt);
19749
19750   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19751     {
19752       print (vam->ofp,
19753              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19754              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19755              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19756              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19757              &rmt.fp_addr.ip4, rmt.fp_len,
19758              clib_net_to_host_u16 (mp->rmt_port),
19759              clib_net_to_host_u32 (mp->action_index), mp->tag);
19760     }
19761   else
19762     {
19763       print (vam->ofp,
19764              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19765              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19766              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19767              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19768              &rmt.fp_addr.ip6, rmt.fp_len,
19769              clib_net_to_host_u16 (mp->rmt_port),
19770              clib_net_to_host_u32 (mp->action_index), mp->tag);
19771     }
19772 }
19773
19774 static void
19775 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19776                                              mp)
19777 {
19778   vat_main_t *vam = &vat_main;
19779   vat_json_node_t *node = NULL;
19780   struct in6_addr ip6;
19781   struct in_addr ip4;
19782
19783   fib_prefix_t lcl, rmt;
19784
19785   ip_prefix_decode (&mp->lcl, &lcl);
19786   ip_prefix_decode (&mp->rmt, &rmt);
19787
19788   if (VAT_JSON_ARRAY != vam->json_tree.type)
19789     {
19790       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19791       vat_json_init_array (&vam->json_tree);
19792     }
19793   node = vat_json_array_add (&vam->json_tree);
19794   vat_json_init_object (node);
19795
19796   vat_json_object_add_uint (node, "appns_index",
19797                             clib_net_to_host_u32 (mp->appns_index));
19798   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19799   vat_json_object_add_uint (node, "scope", mp->scope);
19800   vat_json_object_add_uint (node, "action_index",
19801                             clib_net_to_host_u32 (mp->action_index));
19802   vat_json_object_add_uint (node, "lcl_port",
19803                             clib_net_to_host_u16 (mp->lcl_port));
19804   vat_json_object_add_uint (node, "rmt_port",
19805                             clib_net_to_host_u16 (mp->rmt_port));
19806   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19807   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19808   vat_json_object_add_string_copy (node, "tag", mp->tag);
19809   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19810     {
19811       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19812       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19813       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19814       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19815     }
19816   else
19817     {
19818       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19819       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19820       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19821       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19822     }
19823 }
19824
19825 static int
19826 api_session_rule_add_del (vat_main_t * vam)
19827 {
19828   vl_api_session_rule_add_del_t *mp;
19829   unformat_input_t *i = vam->input;
19830   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19831   u32 appns_index = 0, scope = 0;
19832   ip4_address_t lcl_ip4, rmt_ip4;
19833   ip6_address_t lcl_ip6, rmt_ip6;
19834   u8 is_ip4 = 1, conn_set = 0;
19835   u8 is_add = 1, *tag = 0;
19836   int ret;
19837   fib_prefix_t lcl, rmt;
19838
19839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19840     {
19841       if (unformat (i, "del"))
19842         is_add = 0;
19843       else if (unformat (i, "add"))
19844         ;
19845       else if (unformat (i, "proto tcp"))
19846         proto = 0;
19847       else if (unformat (i, "proto udp"))
19848         proto = 1;
19849       else if (unformat (i, "appns %d", &appns_index))
19850         ;
19851       else if (unformat (i, "scope %d", &scope))
19852         ;
19853       else if (unformat (i, "tag %_%v%_", &tag))
19854         ;
19855       else
19856         if (unformat
19857             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19858              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19859              &rmt_port))
19860         {
19861           is_ip4 = 1;
19862           conn_set = 1;
19863         }
19864       else
19865         if (unformat
19866             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19867              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19868              &rmt_port))
19869         {
19870           is_ip4 = 0;
19871           conn_set = 1;
19872         }
19873       else if (unformat (i, "action %d", &action))
19874         ;
19875       else
19876         break;
19877     }
19878   if (proto == ~0 || !conn_set || action == ~0)
19879     {
19880       errmsg ("transport proto, connection and action must be set");
19881       return -99;
19882     }
19883
19884   if (scope > 3)
19885     {
19886       errmsg ("scope should be 0-3");
19887       return -99;
19888     }
19889
19890   M (SESSION_RULE_ADD_DEL, mp);
19891
19892   clib_memset (&lcl, 0, sizeof (lcl));
19893   clib_memset (&rmt, 0, sizeof (rmt));
19894   if (is_ip4)
19895     {
19896       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19897       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19898       lcl.fp_len = lcl_plen;
19899       rmt.fp_len = rmt_plen;
19900     }
19901   else
19902     {
19903       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19904       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19905       lcl.fp_len = lcl_plen;
19906       rmt.fp_len = rmt_plen;
19907     }
19908
19909
19910   ip_prefix_encode (&lcl, &mp->lcl);
19911   ip_prefix_encode (&rmt, &mp->rmt);
19912   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19913   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19914   mp->transport_proto =
19915     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19916   mp->action_index = clib_host_to_net_u32 (action);
19917   mp->appns_index = clib_host_to_net_u32 (appns_index);
19918   mp->scope = scope;
19919   mp->is_add = is_add;
19920   if (tag)
19921     {
19922       clib_memcpy (mp->tag, tag, vec_len (tag));
19923       vec_free (tag);
19924     }
19925
19926   S (mp);
19927   W (ret);
19928   return ret;
19929 }
19930
19931 static int
19932 api_session_rules_dump (vat_main_t * vam)
19933 {
19934   vl_api_session_rules_dump_t *mp;
19935   vl_api_control_ping_t *mp_ping;
19936   int ret;
19937
19938   if (!vam->json_output)
19939     {
19940       print (vam->ofp, "%=20s", "Session Rules");
19941     }
19942
19943   M (SESSION_RULES_DUMP, mp);
19944   /* send it... */
19945   S (mp);
19946
19947   /* Use a control ping for synchronization */
19948   MPING (CONTROL_PING, mp_ping);
19949   S (mp_ping);
19950
19951   /* Wait for a reply... */
19952   W (ret);
19953   return ret;
19954 }
19955
19956 static int
19957 api_ip_container_proxy_add_del (vat_main_t * vam)
19958 {
19959   vl_api_ip_container_proxy_add_del_t *mp;
19960   unformat_input_t *i = vam->input;
19961   u32 sw_if_index = ~0;
19962   vl_api_prefix_t pfx = { };
19963   u8 is_add = 1;
19964   int ret;
19965
19966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19967     {
19968       if (unformat (i, "del"))
19969         is_add = 0;
19970       else if (unformat (i, "add"))
19971         ;
19972       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19973         ;
19974       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19975         ;
19976       else
19977         break;
19978     }
19979   if (sw_if_index == ~0 || pfx.len == 0)
19980     {
19981       errmsg ("address and sw_if_index must be set");
19982       return -99;
19983     }
19984
19985   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19986
19987   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19988   mp->is_add = is_add;
19989   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19990
19991   S (mp);
19992   W (ret);
19993   return ret;
19994 }
19995
19996 static int
19997 api_qos_record_enable_disable (vat_main_t * vam)
19998 {
19999   unformat_input_t *i = vam->input;
20000   vl_api_qos_record_enable_disable_t *mp;
20001   u32 sw_if_index, qs = 0xff;
20002   u8 sw_if_index_set = 0;
20003   u8 enable = 1;
20004   int ret;
20005
20006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20007     {
20008       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20009         sw_if_index_set = 1;
20010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20011         sw_if_index_set = 1;
20012       else if (unformat (i, "%U", unformat_qos_source, &qs))
20013         ;
20014       else if (unformat (i, "disable"))
20015         enable = 0;
20016       else
20017         {
20018           clib_warning ("parse error '%U'", format_unformat_error, i);
20019           return -99;
20020         }
20021     }
20022
20023   if (sw_if_index_set == 0)
20024     {
20025       errmsg ("missing interface name or sw_if_index");
20026       return -99;
20027     }
20028   if (qs == 0xff)
20029     {
20030       errmsg ("input location must be specified");
20031       return -99;
20032     }
20033
20034   M (QOS_RECORD_ENABLE_DISABLE, mp);
20035
20036   mp->record.sw_if_index = ntohl (sw_if_index);
20037   mp->record.input_source = qs;
20038   mp->enable = enable;
20039
20040   S (mp);
20041   W (ret);
20042   return ret;
20043 }
20044
20045
20046 static int
20047 q_or_quit (vat_main_t * vam)
20048 {
20049 #if VPP_API_TEST_BUILTIN == 0
20050   longjmp (vam->jump_buf, 1);
20051 #endif
20052   return 0;                     /* not so much */
20053 }
20054
20055 static int
20056 q (vat_main_t * vam)
20057 {
20058   return q_or_quit (vam);
20059 }
20060
20061 static int
20062 quit (vat_main_t * vam)
20063 {
20064   return q_or_quit (vam);
20065 }
20066
20067 static int
20068 comment (vat_main_t * vam)
20069 {
20070   return 0;
20071 }
20072
20073 static int
20074 elog_save (vat_main_t * vam)
20075 {
20076 #if VPP_API_TEST_BUILTIN == 0
20077   elog_main_t *em = &vam->elog_main;
20078   unformat_input_t *i = vam->input;
20079   char *file, *chroot_file;
20080   clib_error_t *error;
20081
20082   if (!unformat (i, "%s", &file))
20083     {
20084       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20085       return 0;
20086     }
20087
20088   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20089   if (strstr (file, "..") || index (file, '/'))
20090     {
20091       errmsg ("illegal characters in filename '%s'", file);
20092       return 0;
20093     }
20094
20095   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20096
20097   vec_free (file);
20098
20099   errmsg ("Saving %wd of %wd events to %s",
20100           elog_n_events_in_buffer (em),
20101           elog_buffer_capacity (em), chroot_file);
20102
20103   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20104   vec_free (chroot_file);
20105
20106   if (error)
20107     clib_error_report (error);
20108 #else
20109   errmsg ("Use the vpp event loger...");
20110 #endif
20111
20112   return 0;
20113 }
20114
20115 static int
20116 elog_setup (vat_main_t * vam)
20117 {
20118 #if VPP_API_TEST_BUILTIN == 0
20119   elog_main_t *em = &vam->elog_main;
20120   unformat_input_t *i = vam->input;
20121   u32 nevents = 128 << 10;
20122
20123   (void) unformat (i, "nevents %d", &nevents);
20124
20125   elog_init (em, nevents);
20126   vl_api_set_elog_main (em);
20127   vl_api_set_elog_trace_api_messages (1);
20128   errmsg ("Event logger initialized with %u events", nevents);
20129 #else
20130   errmsg ("Use the vpp event loger...");
20131 #endif
20132   return 0;
20133 }
20134
20135 static int
20136 elog_enable (vat_main_t * vam)
20137 {
20138 #if VPP_API_TEST_BUILTIN == 0
20139   elog_main_t *em = &vam->elog_main;
20140
20141   elog_enable_disable (em, 1 /* enable */ );
20142   vl_api_set_elog_trace_api_messages (1);
20143   errmsg ("Event logger enabled...");
20144 #else
20145   errmsg ("Use the vpp event loger...");
20146 #endif
20147   return 0;
20148 }
20149
20150 static int
20151 elog_disable (vat_main_t * vam)
20152 {
20153 #if VPP_API_TEST_BUILTIN == 0
20154   elog_main_t *em = &vam->elog_main;
20155
20156   elog_enable_disable (em, 0 /* enable */ );
20157   vl_api_set_elog_trace_api_messages (1);
20158   errmsg ("Event logger disabled...");
20159 #else
20160   errmsg ("Use the vpp event loger...");
20161 #endif
20162   return 0;
20163 }
20164
20165 static int
20166 statseg (vat_main_t * vam)
20167 {
20168   ssvm_private_t *ssvmp = &vam->stat_segment;
20169   ssvm_shared_header_t *shared_header = ssvmp->sh;
20170   vlib_counter_t **counters;
20171   u64 thread0_index1_packets;
20172   u64 thread0_index1_bytes;
20173   f64 vector_rate, input_rate;
20174   uword *p;
20175
20176   uword *counter_vector_by_name;
20177   if (vam->stat_segment_lockp == 0)
20178     {
20179       errmsg ("Stat segment not mapped...");
20180       return -99;
20181     }
20182
20183   /* look up "/if/rx for sw_if_index 1 as a test */
20184
20185   clib_spinlock_lock (vam->stat_segment_lockp);
20186
20187   counter_vector_by_name = (uword *) shared_header->opaque[1];
20188
20189   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20190   if (p == 0)
20191     {
20192       clib_spinlock_unlock (vam->stat_segment_lockp);
20193       errmsg ("/if/tx not found?");
20194       return -99;
20195     }
20196
20197   /* Fish per-thread vector of combined counters from shared memory */
20198   counters = (vlib_counter_t **) p[0];
20199
20200   if (vec_len (counters[0]) < 2)
20201     {
20202       clib_spinlock_unlock (vam->stat_segment_lockp);
20203       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20204       return -99;
20205     }
20206
20207   /* Read thread 0 sw_if_index 1 counter */
20208   thread0_index1_packets = counters[0][1].packets;
20209   thread0_index1_bytes = counters[0][1].bytes;
20210
20211   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20212   if (p == 0)
20213     {
20214       clib_spinlock_unlock (vam->stat_segment_lockp);
20215       errmsg ("vector_rate not found?");
20216       return -99;
20217     }
20218
20219   vector_rate = *(f64 *) (p[0]);
20220   p = hash_get_mem (counter_vector_by_name, "input_rate");
20221   if (p == 0)
20222     {
20223       clib_spinlock_unlock (vam->stat_segment_lockp);
20224       errmsg ("input_rate not found?");
20225       return -99;
20226     }
20227   input_rate = *(f64 *) (p[0]);
20228
20229   clib_spinlock_unlock (vam->stat_segment_lockp);
20230
20231   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20232          vector_rate, input_rate);
20233   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20234          thread0_index1_packets, thread0_index1_bytes);
20235
20236   return 0;
20237 }
20238
20239 static int
20240 cmd_cmp (void *a1, void *a2)
20241 {
20242   u8 **c1 = a1;
20243   u8 **c2 = a2;
20244
20245   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20246 }
20247
20248 static int
20249 help (vat_main_t * vam)
20250 {
20251   u8 **cmds = 0;
20252   u8 *name = 0;
20253   hash_pair_t *p;
20254   unformat_input_t *i = vam->input;
20255   int j;
20256
20257   if (unformat (i, "%s", &name))
20258     {
20259       uword *hs;
20260
20261       vec_add1 (name, 0);
20262
20263       hs = hash_get_mem (vam->help_by_name, name);
20264       if (hs)
20265         print (vam->ofp, "usage: %s %s", name, hs[0]);
20266       else
20267         print (vam->ofp, "No such msg / command '%s'", name);
20268       vec_free (name);
20269       return 0;
20270     }
20271
20272   print (vam->ofp, "Help is available for the following:");
20273
20274     /* *INDENT-OFF* */
20275     hash_foreach_pair (p, vam->function_by_name,
20276     ({
20277       vec_add1 (cmds, (u8 *)(p->key));
20278     }));
20279     /* *INDENT-ON* */
20280
20281   vec_sort_with_function (cmds, cmd_cmp);
20282
20283   for (j = 0; j < vec_len (cmds); j++)
20284     print (vam->ofp, "%s", cmds[j]);
20285
20286   vec_free (cmds);
20287   return 0;
20288 }
20289
20290 static int
20291 set (vat_main_t * vam)
20292 {
20293   u8 *name = 0, *value = 0;
20294   unformat_input_t *i = vam->input;
20295
20296   if (unformat (i, "%s", &name))
20297     {
20298       /* The input buffer is a vector, not a string. */
20299       value = vec_dup (i->buffer);
20300       vec_delete (value, i->index, 0);
20301       /* Almost certainly has a trailing newline */
20302       if (value[vec_len (value) - 1] == '\n')
20303         value[vec_len (value) - 1] = 0;
20304       /* Make sure it's a proper string, one way or the other */
20305       vec_add1 (value, 0);
20306       (void) clib_macro_set_value (&vam->macro_main,
20307                                    (char *) name, (char *) value);
20308     }
20309   else
20310     errmsg ("usage: set <name> <value>");
20311
20312   vec_free (name);
20313   vec_free (value);
20314   return 0;
20315 }
20316
20317 static int
20318 unset (vat_main_t * vam)
20319 {
20320   u8 *name = 0;
20321
20322   if (unformat (vam->input, "%s", &name))
20323     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20324       errmsg ("unset: %s wasn't set", name);
20325   vec_free (name);
20326   return 0;
20327 }
20328
20329 typedef struct
20330 {
20331   u8 *name;
20332   u8 *value;
20333 } macro_sort_t;
20334
20335
20336 static int
20337 macro_sort_cmp (void *a1, void *a2)
20338 {
20339   macro_sort_t *s1 = a1;
20340   macro_sort_t *s2 = a2;
20341
20342   return strcmp ((char *) (s1->name), (char *) (s2->name));
20343 }
20344
20345 static int
20346 dump_macro_table (vat_main_t * vam)
20347 {
20348   macro_sort_t *sort_me = 0, *sm;
20349   int i;
20350   hash_pair_t *p;
20351
20352     /* *INDENT-OFF* */
20353     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20354     ({
20355       vec_add2 (sort_me, sm, 1);
20356       sm->name = (u8 *)(p->key);
20357       sm->value = (u8 *) (p->value[0]);
20358     }));
20359     /* *INDENT-ON* */
20360
20361   vec_sort_with_function (sort_me, macro_sort_cmp);
20362
20363   if (vec_len (sort_me))
20364     print (vam->ofp, "%-15s%s", "Name", "Value");
20365   else
20366     print (vam->ofp, "The macro table is empty...");
20367
20368   for (i = 0; i < vec_len (sort_me); i++)
20369     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20370   return 0;
20371 }
20372
20373 static int
20374 dump_node_table (vat_main_t * vam)
20375 {
20376   int i, j;
20377   vlib_node_t *node, *next_node;
20378
20379   if (vec_len (vam->graph_nodes) == 0)
20380     {
20381       print (vam->ofp, "Node table empty, issue get_node_graph...");
20382       return 0;
20383     }
20384
20385   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20386     {
20387       node = vam->graph_nodes[0][i];
20388       print (vam->ofp, "[%d] %s", i, node->name);
20389       for (j = 0; j < vec_len (node->next_nodes); j++)
20390         {
20391           if (node->next_nodes[j] != ~0)
20392             {
20393               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20394               print (vam->ofp, "  [%d] %s", j, next_node->name);
20395             }
20396         }
20397     }
20398   return 0;
20399 }
20400
20401 static int
20402 value_sort_cmp (void *a1, void *a2)
20403 {
20404   name_sort_t *n1 = a1;
20405   name_sort_t *n2 = a2;
20406
20407   if (n1->value < n2->value)
20408     return -1;
20409   if (n1->value > n2->value)
20410     return 1;
20411   return 0;
20412 }
20413
20414
20415 static int
20416 dump_msg_api_table (vat_main_t * vam)
20417 {
20418   api_main_t *am = vlibapi_get_main ();
20419   name_sort_t *nses = 0, *ns;
20420   hash_pair_t *hp;
20421   int i;
20422
20423   /* *INDENT-OFF* */
20424   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20425   ({
20426     vec_add2 (nses, ns, 1);
20427     ns->name = (u8 *)(hp->key);
20428     ns->value = (u32) hp->value[0];
20429   }));
20430   /* *INDENT-ON* */
20431
20432   vec_sort_with_function (nses, value_sort_cmp);
20433
20434   for (i = 0; i < vec_len (nses); i++)
20435     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20436   vec_free (nses);
20437   return 0;
20438 }
20439
20440 static int
20441 get_msg_id (vat_main_t * vam)
20442 {
20443   u8 *name_and_crc;
20444   u32 message_index;
20445
20446   if (unformat (vam->input, "%s", &name_and_crc))
20447     {
20448       message_index = vl_msg_api_get_msg_index (name_and_crc);
20449       if (message_index == ~0)
20450         {
20451           print (vam->ofp, " '%s' not found", name_and_crc);
20452           return 0;
20453         }
20454       print (vam->ofp, " '%s' has message index %d",
20455              name_and_crc, message_index);
20456       return 0;
20457     }
20458   errmsg ("name_and_crc required...");
20459   return 0;
20460 }
20461
20462 static int
20463 search_node_table (vat_main_t * vam)
20464 {
20465   unformat_input_t *line_input = vam->input;
20466   u8 *node_to_find;
20467   int j;
20468   vlib_node_t *node, *next_node;
20469   uword *p;
20470
20471   if (vam->graph_node_index_by_name == 0)
20472     {
20473       print (vam->ofp, "Node table empty, issue get_node_graph...");
20474       return 0;
20475     }
20476
20477   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20478     {
20479       if (unformat (line_input, "%s", &node_to_find))
20480         {
20481           vec_add1 (node_to_find, 0);
20482           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20483           if (p == 0)
20484             {
20485               print (vam->ofp, "%s not found...", node_to_find);
20486               goto out;
20487             }
20488           node = vam->graph_nodes[0][p[0]];
20489           print (vam->ofp, "[%d] %s", p[0], node->name);
20490           for (j = 0; j < vec_len (node->next_nodes); j++)
20491             {
20492               if (node->next_nodes[j] != ~0)
20493                 {
20494                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20495                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20496                 }
20497             }
20498         }
20499
20500       else
20501         {
20502           clib_warning ("parse error '%U'", format_unformat_error,
20503                         line_input);
20504           return -99;
20505         }
20506
20507     out:
20508       vec_free (node_to_find);
20509
20510     }
20511
20512   return 0;
20513 }
20514
20515
20516 static int
20517 script (vat_main_t * vam)
20518 {
20519 #if (VPP_API_TEST_BUILTIN==0)
20520   u8 *s = 0;
20521   char *save_current_file;
20522   unformat_input_t save_input;
20523   jmp_buf save_jump_buf;
20524   u32 save_line_number;
20525
20526   FILE *new_fp, *save_ifp;
20527
20528   if (unformat (vam->input, "%s", &s))
20529     {
20530       new_fp = fopen ((char *) s, "r");
20531       if (new_fp == 0)
20532         {
20533           errmsg ("Couldn't open script file %s", s);
20534           vec_free (s);
20535           return -99;
20536         }
20537     }
20538   else
20539     {
20540       errmsg ("Missing script name");
20541       return -99;
20542     }
20543
20544   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20545   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20546   save_ifp = vam->ifp;
20547   save_line_number = vam->input_line_number;
20548   save_current_file = (char *) vam->current_file;
20549
20550   vam->input_line_number = 0;
20551   vam->ifp = new_fp;
20552   vam->current_file = s;
20553   do_one_file (vam);
20554
20555   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20556   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20557   vam->ifp = save_ifp;
20558   vam->input_line_number = save_line_number;
20559   vam->current_file = (u8 *) save_current_file;
20560   vec_free (s);
20561
20562   return 0;
20563 #else
20564   clib_warning ("use the exec command...");
20565   return -99;
20566 #endif
20567 }
20568
20569 static int
20570 echo (vat_main_t * vam)
20571 {
20572   print (vam->ofp, "%v", vam->input->buffer);
20573   return 0;
20574 }
20575
20576 /* List of API message constructors, CLI names map to api_xxx */
20577 #define foreach_vpe_api_msg                                             \
20578 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20579 _(sw_interface_dump,"")                                                 \
20580 _(sw_interface_set_flags,                                               \
20581   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20582 _(sw_interface_add_del_address,                                         \
20583   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20584 _(sw_interface_set_rx_mode,                                             \
20585   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20586 _(sw_interface_set_rx_placement,                                        \
20587   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20588 _(sw_interface_rx_placement_dump,                                       \
20589   "[<intfc> | sw_if_index <id>]")                                         \
20590 _(sw_interface_set_table,                                               \
20591   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20592 _(sw_interface_set_mpls_enable,                                         \
20593   "<intfc> | sw_if_index [disable | dis]")                              \
20594 _(sw_interface_set_vpath,                                               \
20595   "<intfc> | sw_if_index <id> enable | disable")                        \
20596 _(sw_interface_set_vxlan_bypass,                                        \
20597   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20598 _(sw_interface_set_geneve_bypass,                                       \
20599   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20600 _(sw_interface_set_l2_xconnect,                                         \
20601   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20602   "enable | disable")                                                   \
20603 _(sw_interface_set_l2_bridge,                                           \
20604   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20605   "[shg <split-horizon-group>] [bvi]\n"                                 \
20606   "enable | disable")                                                   \
20607 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20608 _(bridge_domain_add_del,                                                \
20609   "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") \
20610 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20611 _(l2fib_add_del,                                                        \
20612   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20613 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20614 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20615 _(l2_flags,                                                             \
20616   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20617 _(bridge_flags,                                                         \
20618   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20619 _(tap_create_v2,                                                        \
20620   "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]") \
20621 _(tap_delete_v2,                                                        \
20622   "<vpp-if-name> | sw_if_index <id>")                                   \
20623 _(sw_interface_tap_v2_dump, "")                                         \
20624 _(virtio_pci_create,                                                    \
20625   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20626 _(virtio_pci_delete,                                                    \
20627   "<vpp-if-name> | sw_if_index <id>")                                   \
20628 _(sw_interface_virtio_pci_dump, "")                                     \
20629 _(bond_create,                                                          \
20630   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20631   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20632   "[id <if-id>]")                                                       \
20633 _(bond_delete,                                                          \
20634   "<vpp-if-name> | sw_if_index <id>")                                   \
20635 _(bond_add_member,                                                      \
20636   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20637 _(bond_detach_member,                                                   \
20638   "sw_if_index <n>")                                                    \
20639  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20640  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20641  _(sw_member_interface_dump,                                            \
20642   "<vpp-if-name> | sw_if_index <id>")                                   \
20643 _(ip_table_add_del,                                                     \
20644   "table <n> [ipv6] [add | del]\n")                                     \
20645 _(ip_route_add_del,                                                     \
20646   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20647   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20648   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20649   "[multipath] [count <n>] [del]")                                      \
20650 _(ip_mroute_add_del,                                                    \
20651   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20652   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20653 _(mpls_table_add_del,                                                   \
20654   "table <n> [add | del]\n")                                            \
20655 _(mpls_route_add_del,                                                   \
20656   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20657   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20658   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20659   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20660   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20661   "[count <n>] [del]")                                                  \
20662 _(mpls_ip_bind_unbind,                                                  \
20663   "<label> <addr/len>")                                                 \
20664 _(mpls_tunnel_add_del,                                                  \
20665   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20666   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20667   "[l2-only]  [out-label <n>]")                                         \
20668 _(sr_mpls_policy_add,                                                   \
20669   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20670 _(sr_mpls_policy_del,                                                   \
20671   "bsid <id>")                                                          \
20672 _(bier_table_add_del,                                                   \
20673   "<label> <sub-domain> <set> <bsl> [del]")                             \
20674 _(bier_route_add_del,                                                   \
20675   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20676   "[<intfc> | sw_if_index <id>]"                                        \
20677   "[weight <n>] [del] [multipath]")                                     \
20678 _(sw_interface_set_unnumbered,                                          \
20679   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20680 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20681 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20682   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20683   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20684   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20685 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20686 _(ip_table_flush, "table <n> [ipv6]")                                   \
20687 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20688 _(set_ip_flow_hash,                                                     \
20689   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20690 _(sw_interface_ip6_enable_disable,                                      \
20691   "<intfc> | sw_if_index <id> enable | disable")                        \
20692 _(l2_patch_add_del,                                                     \
20693   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20694   "enable | disable")                                                   \
20695 _(sr_localsid_add_del,                                                  \
20696   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20697   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20698 _(classify_add_del_table,                                               \
20699   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20700   " [del] [del-chain] mask <mask-value>\n"                              \
20701   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20702   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20703 _(classify_add_del_session,                                             \
20704   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20705   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20706   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20707   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20708 _(classify_set_interface_ip_table,                                      \
20709   "<intfc> | sw_if_index <nn> table <nn>")                              \
20710 _(classify_set_interface_l2_tables,                                     \
20711   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20712   "  [other-table <nn>]")                                               \
20713 _(get_node_index, "node <node-name")                                    \
20714 _(add_node_next, "node <node-name> next <next-node-name>")              \
20715 _(l2tpv3_create_tunnel,                                                 \
20716   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20717   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20718   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20719 _(l2tpv3_set_tunnel_cookies,                                            \
20720   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20721   "[new_remote_cookie <nn>]\n")                                         \
20722 _(l2tpv3_interface_enable_disable,                                      \
20723   "<intfc> | sw_if_index <nn> enable | disable")                        \
20724 _(l2tpv3_set_lookup_key,                                                \
20725   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20726 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20727 _(vxlan_offload_rx,                                                     \
20728   "hw { <interface name> | hw_if_index <nn>} "                          \
20729   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20730 _(vxlan_add_del_tunnel,                                                 \
20731   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20732   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20733   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20734 _(geneve_add_del_tunnel,                                                \
20735   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20736   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20737   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20738 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20739 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20740 _(gre_tunnel_add_del,                                                   \
20741   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20742   "[teb | erspan <session-id>] [del]")                                  \
20743 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20744 _(l2_fib_clear_table, "")                                               \
20745 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20746 _(l2_interface_vlan_tag_rewrite,                                        \
20747   "<intfc> | sw_if_index <nn> \n"                                       \
20748   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20749   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20750 _(create_vhost_user_if,                                                 \
20751         "socket <filename> [server] [renumber <dev_instance>] "         \
20752         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20753         "[mac <mac_address>] [packed]")                                 \
20754 _(modify_vhost_user_if,                                                 \
20755         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20756         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20757 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20758 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20759 _(show_version, "")                                                     \
20760 _(show_threads, "")                                                     \
20761 _(vxlan_gpe_add_del_tunnel,                                             \
20762   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20763   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20764   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20765   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20766 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20767 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20768 _(interface_name_renumber,                                              \
20769   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20770 _(input_acl_set_interface,                                              \
20771   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20772   "  [l2-table <nn>] [del]")                                            \
20773 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20774 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20775 _(ip_dump, "ipv4 | ipv6")                                               \
20776 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20777 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20778   "  spid_id <n> ")                                                     \
20779 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20780   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20781   "  integ_alg <alg> integ_key <hex>")                                  \
20782 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20783   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20784   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20785   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20786 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20787   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20788   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20789   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20790   "  [instance <n>]")     \
20791 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20792 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20793 _(delete_loopback,"sw_if_index <nn>")                                   \
20794 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20795 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20796 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20797 _(want_interface_events,  "enable|disable")                             \
20798 _(get_first_msg_id, "client <name>")                                    \
20799 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20800 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20801   "fib-id <nn> [ip4][ip6][default]")                                    \
20802 _(get_node_graph, " ")                                                  \
20803 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20804 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20805 _(ioam_disable, "")                                                     \
20806 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20807                             " sw_if_index <sw_if_index> p <priority> "  \
20808                             "w <weight>] [del]")                        \
20809 _(one_add_del_locator, "locator-set <locator_name> "                    \
20810                         "iface <intf> | sw_if_index <sw_if_index> "     \
20811                         "p <priority> w <weight> [del]")                \
20812 _(one_add_del_local_eid,"vni <vni> eid "                                \
20813                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20814                          "locator-set <locator_name> [del]"             \
20815                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20816 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20817 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20818 _(one_enable_disable, "enable|disable")                                 \
20819 _(one_map_register_enable_disable, "enable|disable")                    \
20820 _(one_map_register_fallback_threshold, "<value>")                       \
20821 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20822 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20823                                "[seid <seid>] "                         \
20824                                "rloc <locator> p <prio> "               \
20825                                "w <weight> [rloc <loc> ... ] "          \
20826                                "action <action> [del-all]")             \
20827 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20828                           "<local-eid>")                                \
20829 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20830 _(one_use_petr, "ip-address> | disable")                                \
20831 _(one_map_request_mode, "src-dst|dst-only")                             \
20832 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20833 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20834 _(one_locator_set_dump, "[local | remote]")                             \
20835 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20836 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20837                        "[local] | [remote]")                            \
20838 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20839 _(one_ndp_bd_get, "")                                                   \
20840 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20841 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20842 _(one_l2_arp_bd_get, "")                                                \
20843 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20844 _(one_stats_enable_disable, "enable|disable")                           \
20845 _(show_one_stats_enable_disable, "")                                    \
20846 _(one_eid_table_vni_dump, "")                                           \
20847 _(one_eid_table_map_dump, "l2|l3")                                      \
20848 _(one_map_resolver_dump, "")                                            \
20849 _(one_map_server_dump, "")                                              \
20850 _(one_adjacencies_get, "vni <vni>")                                     \
20851 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20852 _(show_one_rloc_probe_state, "")                                        \
20853 _(show_one_map_register_state, "")                                      \
20854 _(show_one_status, "")                                                  \
20855 _(one_stats_dump, "")                                                   \
20856 _(one_stats_flush, "")                                                  \
20857 _(one_get_map_request_itr_rlocs, "")                                    \
20858 _(one_map_register_set_ttl, "<ttl>")                                    \
20859 _(one_set_transport_protocol, "udp|api")                                \
20860 _(one_get_transport_protocol, "")                                       \
20861 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20862 _(one_show_xtr_mode, "")                                                \
20863 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20864 _(one_show_pitr_mode, "")                                               \
20865 _(one_enable_disable_petr_mode, "enable|disable")                       \
20866 _(one_show_petr_mode, "")                                               \
20867 _(show_one_nsh_mapping, "")                                             \
20868 _(show_one_pitr, "")                                                    \
20869 _(show_one_use_petr, "")                                                \
20870 _(show_one_map_request_mode, "")                                        \
20871 _(show_one_map_register_ttl, "")                                        \
20872 _(show_one_map_register_fallback_threshold, "")                         \
20873 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20874                             " sw_if_index <sw_if_index> p <priority> "  \
20875                             "w <weight>] [del]")                        \
20876 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20877                         "iface <intf> | sw_if_index <sw_if_index> "     \
20878                         "p <priority> w <weight> [del]")                \
20879 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20880                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20881                          "locator-set <locator_name> [del]"             \
20882                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20883 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20884 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20885 _(lisp_enable_disable, "enable|disable")                                \
20886 _(lisp_map_register_enable_disable, "enable|disable")                   \
20887 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20888 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20889                                "[seid <seid>] "                         \
20890                                "rloc <locator> p <prio> "               \
20891                                "w <weight> [rloc <loc> ... ] "          \
20892                                "action <action> [del-all]")             \
20893 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20894                           "<local-eid>")                                \
20895 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20896 _(lisp_use_petr, "<ip-address> | disable")                              \
20897 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20898 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20899 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20900 _(lisp_locator_set_dump, "[local | remote]")                            \
20901 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20902 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20903                        "[local] | [remote]")                            \
20904 _(lisp_eid_table_vni_dump, "")                                          \
20905 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20906 _(lisp_map_resolver_dump, "")                                           \
20907 _(lisp_map_server_dump, "")                                             \
20908 _(lisp_adjacencies_get, "vni <vni>")                                    \
20909 _(gpe_fwd_entry_vnis_get, "")                                           \
20910 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20911 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20912                                 "[table <table-id>]")                   \
20913 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20914 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20915 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20916 _(gpe_get_encap_mode, "")                                               \
20917 _(lisp_gpe_add_del_iface, "up|down")                                    \
20918 _(lisp_gpe_enable_disable, "enable|disable")                            \
20919 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20920   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20921 _(show_lisp_rloc_probe_state, "")                                       \
20922 _(show_lisp_map_register_state, "")                                     \
20923 _(show_lisp_status, "")                                                 \
20924 _(lisp_get_map_request_itr_rlocs, "")                                   \
20925 _(show_lisp_pitr, "")                                                   \
20926 _(show_lisp_use_petr, "")                                               \
20927 _(show_lisp_map_request_mode, "")                                       \
20928 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20929 _(af_packet_delete, "name <host interface name>")                       \
20930 _(af_packet_dump, "")                                                   \
20931 _(policer_add_del, "name <policer name> <params> [del]")                \
20932 _(policer_dump, "[name <policer name>]")                                \
20933 _(policer_classify_set_interface,                                       \
20934   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20935   "  [l2-table <nn>] [del]")                                            \
20936 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20937 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20938 _(mpls_table_dump, "")                                                  \
20939 _(mpls_route_dump, "table-id <ID>")                                     \
20940 _(classify_table_ids, "")                                               \
20941 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20942 _(classify_table_info, "table_id <nn>")                                 \
20943 _(classify_session_dump, "table_id <nn>")                               \
20944 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20945     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20946     "[template_interval <nn>] [udp_checksum]")                          \
20947 _(ipfix_exporter_dump, "")                                              \
20948 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20949 _(ipfix_classify_stream_dump, "")                                       \
20950 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20951 _(ipfix_classify_table_dump, "")                                        \
20952 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20953 _(sw_interface_span_dump, "[l2]")                                           \
20954 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20955 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20956 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20957 _(pg_enable_disable, "[stream <id>] disable")                           \
20958 _(ip_source_and_port_range_check_add_del,                               \
20959   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20960 _(ip_source_and_port_range_check_interface_add_del,                     \
20961   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20962   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20963 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20964 _(l2_interface_pbb_tag_rewrite,                                         \
20965   "<intfc> | sw_if_index <nn> \n"                                       \
20966   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20967   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20968 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20969 _(flow_classify_set_interface,                                          \
20970   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20971 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20972 _(ip_table_dump, "")                                                    \
20973 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20974 _(ip_mtable_dump, "")                                                   \
20975 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20976 _(feature_enable_disable, "arc_name <arc_name> "                        \
20977   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20978 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20979   "[enable | disable] ")                                                \
20980 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20981 "[disable]")                                                            \
20982 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20983   "mac <mac-address> [del]")                                            \
20984 _(l2_xconnect_dump, "")                                                 \
20985 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20986 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20987 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20988 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20989 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20990 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
20991   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
20992 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
20993 _(sock_init_shm, "size <nnn>")                                          \
20994 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
20995 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
20996   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
20997 _(session_rules_dump, "")                                               \
20998 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
20999 _(output_acl_set_interface,                                             \
21000   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21001   "  [l2-table <nn>] [del]")                                            \
21002 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21003
21004 /* List of command functions, CLI names map directly to functions */
21005 #define foreach_cli_function                                    \
21006 _(comment, "usage: comment <ignore-rest-of-line>")              \
21007 _(dump_interface_table, "usage: dump_interface_table")          \
21008 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21009 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21010 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21011 _(dump_macro_table, "usage: dump_macro_table ")                 \
21012 _(dump_node_table, "usage: dump_node_table")                    \
21013 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21014 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21015 _(elog_disable, "usage: elog_disable")                          \
21016 _(elog_enable, "usage: elog_enable")                            \
21017 _(elog_save, "usage: elog_save <filename>")                     \
21018 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21019 _(echo, "usage: echo <message>")                                \
21020 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21021 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21022 _(help, "usage: help")                                          \
21023 _(q, "usage: quit")                                             \
21024 _(quit, "usage: quit")                                          \
21025 _(search_node_table, "usage: search_node_table <name>...")      \
21026 _(set, "usage: set <variable-name> <value>")                    \
21027 _(script, "usage: script <file-name>")                          \
21028 _(statseg, "usage: statseg")                                    \
21029 _(unset, "usage: unset <variable-name>")
21030
21031 #define _(N,n)                                  \
21032     static void vl_api_##n##_t_handler_uni      \
21033     (vl_api_##n##_t * mp)                       \
21034     {                                           \
21035         vat_main_t * vam = &vat_main;           \
21036         if (vam->json_output) {                 \
21037             vl_api_##n##_t_handler_json(mp);    \
21038         } else {                                \
21039             vl_api_##n##_t_handler(mp);         \
21040         }                                       \
21041     }
21042 foreach_vpe_api_reply_msg;
21043 #if VPP_API_TEST_BUILTIN == 0
21044 foreach_standalone_reply_msg;
21045 #endif
21046 #undef _
21047
21048 void
21049 vat_api_hookup (vat_main_t * vam)
21050 {
21051 #define _(N,n)                                                  \
21052     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21053                            vl_api_##n##_t_handler_uni,          \
21054                            vl_noop_handler,                     \
21055                            vl_api_##n##_t_endian,               \
21056                            vl_api_##n##_t_print,                \
21057                            sizeof(vl_api_##n##_t), 1);
21058   foreach_vpe_api_reply_msg;
21059 #if VPP_API_TEST_BUILTIN == 0
21060   foreach_standalone_reply_msg;
21061 #endif
21062 #undef _
21063
21064 #if (VPP_API_TEST_BUILTIN==0)
21065   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21066
21067   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21068
21069   vam->function_by_name = hash_create_string (0, sizeof (uword));
21070
21071   vam->help_by_name = hash_create_string (0, sizeof (uword));
21072 #endif
21073
21074   /* API messages we can send */
21075 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21076   foreach_vpe_api_msg;
21077 #undef _
21078
21079   /* Help strings */
21080 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21081   foreach_vpe_api_msg;
21082 #undef _
21083
21084   /* CLI functions */
21085 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21086   foreach_cli_function;
21087 #undef _
21088
21089   /* Help strings */
21090 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21091   foreach_cli_function;
21092 #undef _
21093 }
21094
21095 #if VPP_API_TEST_BUILTIN
21096 static clib_error_t *
21097 vat_api_hookup_shim (vlib_main_t * vm)
21098 {
21099   vat_api_hookup (&vat_main);
21100   return 0;
21101 }
21102
21103 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21104 #endif
21105
21106 /*
21107  * fd.io coding-style-patch-verification: ON
21108  *
21109  * Local Variables:
21110  * eval: (c-set-style "gnu")
21111  * End:
21112  */