adl: move allow/deny list function to plugin
[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_enslave_reply_t_handler (vl_api_bond_enslave_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_enslave_reply_t_handler_json
1950   (vl_api_bond_enslave_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_slave_reply_t_handler (vl_api_bond_detach_slave_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_slave_reply_t_handler_json
1984   (vl_api_bond_detach_slave_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_interface_bond_details_t_handler
2043   (vl_api_sw_interface_bond_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_slaves), ntohl (mp->slaves));
2052 }
2053
2054 static void vl_api_sw_interface_bond_details_t_handler_json
2055   (vl_api_sw_interface_bond_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_slaves", ntohl (mp->active_slaves));
2074   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2075 }
2076
2077 static int
2078 api_sw_interface_bond_dump (vat_main_t * vam)
2079 {
2080   vl_api_sw_interface_bond_dump_t *mp;
2081   vl_api_control_ping_t *mp_ping;
2082   int ret;
2083
2084   print (vam->ofp,
2085          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2086          "interface name", "sw_if_index", "mode", "load balance",
2087          "active slaves", "slaves");
2088
2089   /* Get list of bond interfaces */
2090   M (SW_INTERFACE_BOND_DUMP, mp);
2091   S (mp);
2092
2093   /* Use a control ping for synchronization */
2094   MPING (CONTROL_PING, mp_ping);
2095   S (mp_ping);
2096
2097   W (ret);
2098   return ret;
2099 }
2100
2101 static void vl_api_sw_interface_slave_details_t_handler
2102   (vl_api_sw_interface_slave_details_t * mp)
2103 {
2104   vat_main_t *vam = &vat_main;
2105
2106   print (vam->ofp,
2107          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2108          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2109          ntohl (mp->weight), mp->is_local_numa);
2110 }
2111
2112 static void vl_api_sw_interface_slave_details_t_handler_json
2113   (vl_api_sw_interface_slave_details_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116   vat_json_node_t *node = NULL;
2117
2118   if (VAT_JSON_ARRAY != vam->json_tree.type)
2119     {
2120       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2121       vat_json_init_array (&vam->json_tree);
2122     }
2123   node = vat_json_array_add (&vam->json_tree);
2124
2125   vat_json_init_object (node);
2126   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2127   vat_json_object_add_string_copy (node, "interface_name",
2128                                    mp->interface_name);
2129   vat_json_object_add_uint (node, "passive", mp->is_passive);
2130   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2131   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2132   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2133 }
2134
2135 static int
2136 api_sw_interface_slave_dump (vat_main_t * vam)
2137 {
2138   unformat_input_t *i = vam->input;
2139   vl_api_sw_interface_slave_dump_t *mp;
2140   vl_api_control_ping_t *mp_ping;
2141   u32 sw_if_index = ~0;
2142   u8 sw_if_index_set = 0;
2143   int ret;
2144
2145   /* Parse args required to build the message */
2146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2147     {
2148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2149         sw_if_index_set = 1;
2150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2151         sw_if_index_set = 1;
2152       else
2153         break;
2154     }
2155
2156   if (sw_if_index_set == 0)
2157     {
2158       errmsg ("missing vpp interface name. ");
2159       return -99;
2160     }
2161
2162   print (vam->ofp,
2163          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2164          "slave interface name", "sw_if_index", "passive", "long_timeout",
2165          "weight", "local numa");
2166
2167   /* Get list of bond interfaces */
2168   M (SW_INTERFACE_SLAVE_DUMP, mp);
2169   mp->sw_if_index = ntohl (sw_if_index);
2170   S (mp);
2171
2172   /* Use a control ping for synchronization */
2173   MPING (CONTROL_PING, mp_ping);
2174   S (mp_ping);
2175
2176   W (ret);
2177   return ret;
2178 }
2179
2180 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2181   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2182 {
2183   vat_main_t *vam = &vat_main;
2184   i32 retval = ntohl (mp->retval);
2185   if (vam->async_mode)
2186     {
2187       vam->async_errors += (retval < 0);
2188     }
2189   else
2190     {
2191       vam->retval = retval;
2192       vam->sw_if_index = ntohl (mp->sw_if_index);
2193       vam->result_ready = 1;
2194     }
2195   vam->regenerate_interface_table = 1;
2196 }
2197
2198 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2199   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vat_json_node_t node;
2203
2204   vat_json_init_object (&node);
2205   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2206   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2207                             ntohl (mp->sw_if_index));
2208
2209   vat_json_print (vam->ofp, &node);
2210   vat_json_free (&node);
2211
2212   vam->retval = ntohl (mp->retval);
2213   vam->result_ready = 1;
2214 }
2215
2216 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2217   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   i32 retval = ntohl (mp->retval);
2221   if (vam->async_mode)
2222     {
2223       vam->async_errors += (retval < 0);
2224     }
2225   else
2226     {
2227       vam->retval = retval;
2228       vam->sw_if_index = ntohl (mp->sw_if_index);
2229       vam->result_ready = 1;
2230     }
2231 }
2232
2233 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2234   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2235 {
2236   vat_main_t *vam = &vat_main;
2237   vat_json_node_t node;
2238
2239   vat_json_init_object (&node);
2240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2241   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2242
2243   vat_json_print (vam->ofp, &node);
2244   vat_json_free (&node);
2245
2246   vam->retval = ntohl (mp->retval);
2247   vam->result_ready = 1;
2248 }
2249
2250 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2251   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2252 {
2253   vat_main_t *vam = &vat_main;
2254   i32 retval = ntohl (mp->retval);
2255   if (vam->async_mode)
2256     {
2257       vam->async_errors += (retval < 0);
2258     }
2259   else
2260     {
2261       vam->retval = retval;
2262       vam->result_ready = 1;
2263     }
2264 }
2265
2266 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2267   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2268 {
2269   vat_main_t *vam = &vat_main;
2270   vat_json_node_t node;
2271
2272   vat_json_init_object (&node);
2273   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2274   vat_json_object_add_uint (&node, "fwd_entry_index",
2275                             clib_net_to_host_u32 (mp->fwd_entry_index));
2276
2277   vat_json_print (vam->ofp, &node);
2278   vat_json_free (&node);
2279
2280   vam->retval = ntohl (mp->retval);
2281   vam->result_ready = 1;
2282 }
2283
2284 u8 *
2285 format_lisp_transport_protocol (u8 * s, va_list * args)
2286 {
2287   u32 proto = va_arg (*args, u32);
2288
2289   switch (proto)
2290     {
2291     case 1:
2292       return format (s, "udp");
2293     case 2:
2294       return format (s, "api");
2295     default:
2296       return 0;
2297     }
2298   return 0;
2299 }
2300
2301 static void vl_api_one_get_transport_protocol_reply_t_handler
2302   (vl_api_one_get_transport_protocol_reply_t * mp)
2303 {
2304   vat_main_t *vam = &vat_main;
2305   i32 retval = ntohl (mp->retval);
2306   if (vam->async_mode)
2307     {
2308       vam->async_errors += (retval < 0);
2309     }
2310   else
2311     {
2312       u32 proto = mp->protocol;
2313       print (vam->ofp, "Transport protocol: %U",
2314              format_lisp_transport_protocol, proto);
2315       vam->retval = retval;
2316       vam->result_ready = 1;
2317     }
2318 }
2319
2320 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2321   (vl_api_one_get_transport_protocol_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   vat_json_node_t node;
2325   u8 *s;
2326
2327   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2328   vec_add1 (s, 0);
2329
2330   vat_json_init_object (&node);
2331   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2332   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2333
2334   vec_free (s);
2335   vat_json_print (vam->ofp, &node);
2336   vat_json_free (&node);
2337
2338   vam->retval = ntohl (mp->retval);
2339   vam->result_ready = 1;
2340 }
2341
2342 static void vl_api_one_add_del_locator_set_reply_t_handler
2343   (vl_api_one_add_del_locator_set_reply_t * mp)
2344 {
2345   vat_main_t *vam = &vat_main;
2346   i32 retval = ntohl (mp->retval);
2347   if (vam->async_mode)
2348     {
2349       vam->async_errors += (retval < 0);
2350     }
2351   else
2352     {
2353       vam->retval = retval;
2354       vam->result_ready = 1;
2355     }
2356 }
2357
2358 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2359   (vl_api_one_add_del_locator_set_reply_t * mp)
2360 {
2361   vat_main_t *vam = &vat_main;
2362   vat_json_node_t node;
2363
2364   vat_json_init_object (&node);
2365   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2366   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2367
2368   vat_json_print (vam->ofp, &node);
2369   vat_json_free (&node);
2370
2371   vam->retval = ntohl (mp->retval);
2372   vam->result_ready = 1;
2373 }
2374
2375 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2376   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2377 {
2378   vat_main_t *vam = &vat_main;
2379   i32 retval = ntohl (mp->retval);
2380   if (vam->async_mode)
2381     {
2382       vam->async_errors += (retval < 0);
2383     }
2384   else
2385     {
2386       vam->retval = retval;
2387       vam->sw_if_index = ntohl (mp->sw_if_index);
2388       vam->result_ready = 1;
2389     }
2390   vam->regenerate_interface_table = 1;
2391 }
2392
2393 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2394   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2395 {
2396   vat_main_t *vam = &vat_main;
2397   vat_json_node_t node;
2398
2399   vat_json_init_object (&node);
2400   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2401   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2402
2403   vat_json_print (vam->ofp, &node);
2404   vat_json_free (&node);
2405
2406   vam->retval = ntohl (mp->retval);
2407   vam->result_ready = 1;
2408 }
2409
2410 static void vl_api_vxlan_offload_rx_reply_t_handler
2411   (vl_api_vxlan_offload_rx_reply_t * mp)
2412 {
2413   vat_main_t *vam = &vat_main;
2414   i32 retval = ntohl (mp->retval);
2415   if (vam->async_mode)
2416     {
2417       vam->async_errors += (retval < 0);
2418     }
2419   else
2420     {
2421       vam->retval = retval;
2422       vam->result_ready = 1;
2423     }
2424 }
2425
2426 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2427   (vl_api_vxlan_offload_rx_reply_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   vat_json_node_t node;
2431
2432   vat_json_init_object (&node);
2433   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2434
2435   vat_json_print (vam->ofp, &node);
2436   vat_json_free (&node);
2437
2438   vam->retval = ntohl (mp->retval);
2439   vam->result_ready = 1;
2440 }
2441
2442 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2443   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2444 {
2445   vat_main_t *vam = &vat_main;
2446   i32 retval = ntohl (mp->retval);
2447   if (vam->async_mode)
2448     {
2449       vam->async_errors += (retval < 0);
2450     }
2451   else
2452     {
2453       vam->retval = retval;
2454       vam->sw_if_index = ntohl (mp->sw_if_index);
2455       vam->result_ready = 1;
2456     }
2457 }
2458
2459 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2460   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   vat_json_node_t node;
2464
2465   vat_json_init_object (&node);
2466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2467   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2468
2469   vat_json_print (vam->ofp, &node);
2470   vat_json_free (&node);
2471
2472   vam->retval = ntohl (mp->retval);
2473   vam->result_ready = 1;
2474 }
2475
2476 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2477   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2478 {
2479   vat_main_t *vam = &vat_main;
2480   i32 retval = ntohl (mp->retval);
2481   if (vam->async_mode)
2482     {
2483       vam->async_errors += (retval < 0);
2484     }
2485   else
2486     {
2487       vam->retval = retval;
2488       vam->sw_if_index = ntohl (mp->sw_if_index);
2489       vam->result_ready = 1;
2490     }
2491   vam->regenerate_interface_table = 1;
2492 }
2493
2494 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2495   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   vat_json_node_t node;
2499
2500   vat_json_init_object (&node);
2501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2503
2504   vat_json_print (vam->ofp, &node);
2505   vat_json_free (&node);
2506
2507   vam->retval = ntohl (mp->retval);
2508   vam->result_ready = 1;
2509 }
2510
2511 static void vl_api_gre_tunnel_add_del_reply_t_handler
2512   (vl_api_gre_tunnel_add_del_reply_t * mp)
2513 {
2514   vat_main_t *vam = &vat_main;
2515   i32 retval = ntohl (mp->retval);
2516   if (vam->async_mode)
2517     {
2518       vam->async_errors += (retval < 0);
2519     }
2520   else
2521     {
2522       vam->retval = retval;
2523       vam->sw_if_index = ntohl (mp->sw_if_index);
2524       vam->result_ready = 1;
2525     }
2526 }
2527
2528 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2529   (vl_api_gre_tunnel_add_del_reply_t * mp)
2530 {
2531   vat_main_t *vam = &vat_main;
2532   vat_json_node_t node;
2533
2534   vat_json_init_object (&node);
2535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2536   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2537
2538   vat_json_print (vam->ofp, &node);
2539   vat_json_free (&node);
2540
2541   vam->retval = ntohl (mp->retval);
2542   vam->result_ready = 1;
2543 }
2544
2545 static void vl_api_create_vhost_user_if_reply_t_handler
2546   (vl_api_create_vhost_user_if_reply_t * mp)
2547 {
2548   vat_main_t *vam = &vat_main;
2549   i32 retval = ntohl (mp->retval);
2550   if (vam->async_mode)
2551     {
2552       vam->async_errors += (retval < 0);
2553     }
2554   else
2555     {
2556       vam->retval = retval;
2557       vam->sw_if_index = ntohl (mp->sw_if_index);
2558       vam->result_ready = 1;
2559     }
2560   vam->regenerate_interface_table = 1;
2561 }
2562
2563 static void vl_api_create_vhost_user_if_reply_t_handler_json
2564   (vl_api_create_vhost_user_if_reply_t * mp)
2565 {
2566   vat_main_t *vam = &vat_main;
2567   vat_json_node_t node;
2568
2569   vat_json_init_object (&node);
2570   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2571   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2572
2573   vat_json_print (vam->ofp, &node);
2574   vat_json_free (&node);
2575
2576   vam->retval = ntohl (mp->retval);
2577   vam->result_ready = 1;
2578 }
2579
2580 static void vl_api_ip_address_details_t_handler
2581   (vl_api_ip_address_details_t * mp)
2582 {
2583   vat_main_t *vam = &vat_main;
2584   static ip_address_details_t empty_ip_address_details = { {0} };
2585   ip_address_details_t *address = NULL;
2586   ip_details_t *current_ip_details = NULL;
2587   ip_details_t *details = NULL;
2588
2589   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2590
2591   if (!details || vam->current_sw_if_index >= vec_len (details)
2592       || !details[vam->current_sw_if_index].present)
2593     {
2594       errmsg ("ip address details arrived but not stored");
2595       errmsg ("ip_dump should be called first");
2596       return;
2597     }
2598
2599   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2600
2601 #define addresses (current_ip_details->addr)
2602
2603   vec_validate_init_empty (addresses, vec_len (addresses),
2604                            empty_ip_address_details);
2605
2606   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2607
2608   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2609   address->prefix_length = mp->prefix.len;
2610 #undef addresses
2611 }
2612
2613 static void vl_api_ip_address_details_t_handler_json
2614   (vl_api_ip_address_details_t * mp)
2615 {
2616   vat_main_t *vam = &vat_main;
2617   vat_json_node_t *node = NULL;
2618
2619   if (VAT_JSON_ARRAY != vam->json_tree.type)
2620     {
2621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2622       vat_json_init_array (&vam->json_tree);
2623     }
2624   node = vat_json_array_add (&vam->json_tree);
2625
2626   vat_json_init_object (node);
2627   vat_json_object_add_prefix (node, &mp->prefix);
2628 }
2629
2630 static void
2631 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2632 {
2633   vat_main_t *vam = &vat_main;
2634   static ip_details_t empty_ip_details = { 0 };
2635   ip_details_t *ip = NULL;
2636   u32 sw_if_index = ~0;
2637
2638   sw_if_index = ntohl (mp->sw_if_index);
2639
2640   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2641                            sw_if_index, empty_ip_details);
2642
2643   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2644                          sw_if_index);
2645
2646   ip->present = 1;
2647 }
2648
2649 static void
2650 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2651 {
2652   vat_main_t *vam = &vat_main;
2653
2654   if (VAT_JSON_ARRAY != vam->json_tree.type)
2655     {
2656       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2657       vat_json_init_array (&vam->json_tree);
2658     }
2659   vat_json_array_add_uint (&vam->json_tree,
2660                            clib_net_to_host_u32 (mp->sw_if_index));
2661 }
2662
2663 static void vl_api_get_first_msg_id_reply_t_handler
2664   (vl_api_get_first_msg_id_reply_t * mp)
2665 {
2666   vat_main_t *vam = &vat_main;
2667   i32 retval = ntohl (mp->retval);
2668
2669   if (vam->async_mode)
2670     {
2671       vam->async_errors += (retval < 0);
2672     }
2673   else
2674     {
2675       vam->retval = retval;
2676       vam->result_ready = 1;
2677     }
2678   if (retval >= 0)
2679     {
2680       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2681     }
2682 }
2683
2684 static void vl_api_get_first_msg_id_reply_t_handler_json
2685   (vl_api_get_first_msg_id_reply_t * mp)
2686 {
2687   vat_main_t *vam = &vat_main;
2688   vat_json_node_t node;
2689
2690   vat_json_init_object (&node);
2691   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2692   vat_json_object_add_uint (&node, "first_msg_id",
2693                             (uint) ntohs (mp->first_msg_id));
2694
2695   vat_json_print (vam->ofp, &node);
2696   vat_json_free (&node);
2697
2698   vam->retval = ntohl (mp->retval);
2699   vam->result_ready = 1;
2700 }
2701
2702 static void vl_api_get_node_graph_reply_t_handler
2703   (vl_api_get_node_graph_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707   u8 *pvt_copy, *reply;
2708   void *oldheap;
2709   vlib_node_t *node;
2710   int i;
2711
2712   if (vam->async_mode)
2713     {
2714       vam->async_errors += (retval < 0);
2715     }
2716   else
2717     {
2718       vam->retval = retval;
2719       vam->result_ready = 1;
2720     }
2721
2722   /* "Should never happen..." */
2723   if (retval != 0)
2724     return;
2725
2726   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2727   pvt_copy = vec_dup (reply);
2728
2729   /* Toss the shared-memory original... */
2730   oldheap = vl_msg_push_heap ();
2731
2732   vec_free (reply);
2733
2734   vl_msg_pop_heap (oldheap);
2735
2736   if (vam->graph_nodes)
2737     {
2738       hash_free (vam->graph_node_index_by_name);
2739
2740       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2741         {
2742           node = vam->graph_nodes[0][i];
2743           vec_free (node->name);
2744           vec_free (node->next_nodes);
2745           vec_free (node);
2746         }
2747       vec_free (vam->graph_nodes[0]);
2748       vec_free (vam->graph_nodes);
2749     }
2750
2751   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2752   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2753   vec_free (pvt_copy);
2754
2755   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2756     {
2757       node = vam->graph_nodes[0][i];
2758       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2759     }
2760 }
2761
2762 static void vl_api_get_node_graph_reply_t_handler_json
2763   (vl_api_get_node_graph_reply_t * mp)
2764 {
2765   vat_main_t *vam = &vat_main;
2766   void *oldheap;
2767   vat_json_node_t node;
2768   u8 *reply;
2769
2770   /* $$$$ make this real? */
2771   vat_json_init_object (&node);
2772   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2773   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2774
2775   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2776
2777   /* Toss the shared-memory original... */
2778   oldheap = vl_msg_push_heap ();
2779
2780   vec_free (reply);
2781
2782   vl_msg_pop_heap (oldheap);
2783
2784   vat_json_print (vam->ofp, &node);
2785   vat_json_free (&node);
2786
2787   vam->retval = ntohl (mp->retval);
2788   vam->result_ready = 1;
2789 }
2790
2791 static void
2792 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2793 {
2794   vat_main_t *vam = &vat_main;
2795   u8 *s = 0;
2796
2797   if (mp->local)
2798     {
2799       s = format (s, "%=16d%=16d%=16d",
2800                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2801     }
2802   else
2803     {
2804       s = format (s, "%=16U%=16d%=16d",
2805                   format_ip46_address,
2806                   mp->ip_address, mp->priority, mp->weight);
2807     }
2808
2809   print (vam->ofp, "%v", s);
2810   vec_free (s);
2811 }
2812
2813 static void
2814 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2815 {
2816   vat_main_t *vam = &vat_main;
2817   vat_json_node_t *node = NULL;
2818   struct in6_addr ip6;
2819   struct in_addr ip4;
2820
2821   if (VAT_JSON_ARRAY != vam->json_tree.type)
2822     {
2823       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2824       vat_json_init_array (&vam->json_tree);
2825     }
2826   node = vat_json_array_add (&vam->json_tree);
2827   vat_json_init_object (node);
2828
2829   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2830   vat_json_object_add_uint (node, "priority", mp->priority);
2831   vat_json_object_add_uint (node, "weight", mp->weight);
2832
2833   if (mp->local)
2834     vat_json_object_add_uint (node, "sw_if_index",
2835                               clib_net_to_host_u32 (mp->sw_if_index));
2836   else
2837     {
2838       if (mp->ip_address.af)
2839         {
2840           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2841           vat_json_object_add_ip6 (node, "address", ip6);
2842         }
2843       else
2844         {
2845           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2846           vat_json_object_add_ip4 (node, "address", ip4);
2847         }
2848     }
2849 }
2850
2851 static void
2852 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2853                                           mp)
2854 {
2855   vat_main_t *vam = &vat_main;
2856   u8 *ls_name = 0;
2857
2858   ls_name = format (0, "%s", mp->ls_name);
2859
2860   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2861          ls_name);
2862   vec_free (ls_name);
2863 }
2864
2865 static void
2866   vl_api_one_locator_set_details_t_handler_json
2867   (vl_api_one_locator_set_details_t * mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   vat_json_node_t *node = 0;
2871   u8 *ls_name = 0;
2872
2873   ls_name = format (0, "%s", mp->ls_name);
2874   vec_add1 (ls_name, 0);
2875
2876   if (VAT_JSON_ARRAY != vam->json_tree.type)
2877     {
2878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2879       vat_json_init_array (&vam->json_tree);
2880     }
2881   node = vat_json_array_add (&vam->json_tree);
2882
2883   vat_json_init_object (node);
2884   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2885   vat_json_object_add_uint (node, "ls_index",
2886                             clib_net_to_host_u32 (mp->ls_index));
2887   vec_free (ls_name);
2888 }
2889
2890 typedef struct
2891 {
2892   u32 spi;
2893   u8 si;
2894 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2895
2896 uword
2897 unformat_nsh_address (unformat_input_t * input, va_list * args)
2898 {
2899   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2900   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2901 }
2902
2903 static u8 *
2904 format_nsh_address_vat (u8 * s, va_list * args)
2905 {
2906   nsh_t *a = va_arg (*args, nsh_t *);
2907   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2908 }
2909
2910 static u8 *
2911 format_lisp_flat_eid (u8 * s, va_list * args)
2912 {
2913   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2914
2915   switch (eid->type)
2916     {
2917     case EID_TYPE_API_PREFIX:
2918       if (eid->address.prefix.address.af)
2919         return format (s, "%U/%d", format_ip6_address,
2920                        eid->address.prefix.address.un.ip6,
2921                        eid->address.prefix.len);
2922       return format (s, "%U/%d", format_ip4_address,
2923                      eid->address.prefix.address.un.ip4,
2924                      eid->address.prefix.len);
2925     case EID_TYPE_API_MAC:
2926       return format (s, "%U", format_ethernet_address, eid->address.mac);
2927     case EID_TYPE_API_NSH:
2928       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2929     }
2930   return 0;
2931 }
2932
2933 static u8 *
2934 format_lisp_eid_vat (u8 * s, va_list * args)
2935 {
2936   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2937   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2938   u8 is_src_dst = (u8) va_arg (*args, int);
2939
2940   if (is_src_dst)
2941     s = format (s, "%U|", format_lisp_flat_eid, seid);
2942
2943   s = format (s, "%U", format_lisp_flat_eid, deid);
2944
2945   return s;
2946 }
2947
2948 static void
2949 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   u8 *s = 0, *eid = 0;
2953
2954   if (~0 == mp->locator_set_index)
2955     s = format (0, "action: %d", mp->action);
2956   else
2957     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2958
2959   eid = format (0, "%U", format_lisp_eid_vat,
2960                 &mp->deid, &mp->seid, mp->is_src_dst);
2961   vec_add1 (eid, 0);
2962
2963   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2964          clib_net_to_host_u32 (mp->vni),
2965          eid,
2966          mp->is_local ? "local" : "remote",
2967          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2968          clib_net_to_host_u16 (mp->key.id), mp->key.key);
2969
2970   vec_free (s);
2971   vec_free (eid);
2972 }
2973
2974 static void
2975 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2976                                              * mp)
2977 {
2978   vat_main_t *vam = &vat_main;
2979   vat_json_node_t *node = 0;
2980   u8 *eid = 0;
2981
2982   if (VAT_JSON_ARRAY != vam->json_tree.type)
2983     {
2984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2985       vat_json_init_array (&vam->json_tree);
2986     }
2987   node = vat_json_array_add (&vam->json_tree);
2988
2989   vat_json_init_object (node);
2990   if (~0 == mp->locator_set_index)
2991     vat_json_object_add_uint (node, "action", mp->action);
2992   else
2993     vat_json_object_add_uint (node, "locator_set_index",
2994                               clib_net_to_host_u32 (mp->locator_set_index));
2995
2996   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2997   if (mp->deid.type == 3)
2998     {
2999       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3000       vat_json_init_object (nsh_json);
3001       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3002       vat_json_object_add_uint (nsh_json, "spi",
3003                                 clib_net_to_host_u32 (nsh->spi));
3004       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3005     }
3006   else
3007     {
3008       eid = format (0, "%U", format_lisp_eid_vat,
3009                     &mp->deid, &mp->seid, mp->is_src_dst);
3010       vec_add1 (eid, 0);
3011       vat_json_object_add_string_copy (node, "eid", eid);
3012       vec_free (eid);
3013     }
3014   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3015   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3016   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3017
3018   if (mp->key.id)
3019     {
3020       vat_json_object_add_uint (node, "key_id",
3021                                 clib_net_to_host_u16 (mp->key.id));
3022       vat_json_object_add_string_copy (node, "key", mp->key.key);
3023     }
3024 }
3025
3026 static void
3027 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3028 {
3029   vat_main_t *vam = &vat_main;
3030   u8 *seid = 0, *deid = 0;
3031   ip46_address_t lloc, rloc;
3032
3033   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3034
3035   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3036
3037   vec_add1 (deid, 0);
3038   vec_add1 (seid, 0);
3039
3040   if (mp->lloc.af)
3041     {
3042       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3043       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3044     }
3045   else
3046     {
3047       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3048       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3049     }
3050
3051
3052   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3053          clib_net_to_host_u32 (mp->vni),
3054          seid, deid,
3055          format_ip46_address, lloc,
3056          format_ip46_address, rloc,
3057          clib_net_to_host_u32 (mp->pkt_count),
3058          clib_net_to_host_u32 (mp->bytes));
3059
3060   vec_free (deid);
3061   vec_free (seid);
3062 }
3063
3064 static void
3065 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3066 {
3067   struct in6_addr ip6;
3068   struct in_addr ip4;
3069   vat_main_t *vam = &vat_main;
3070   vat_json_node_t *node = 0;
3071   u8 *deid = 0, *seid = 0;
3072
3073   if (VAT_JSON_ARRAY != vam->json_tree.type)
3074     {
3075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3076       vat_json_init_array (&vam->json_tree);
3077     }
3078   node = vat_json_array_add (&vam->json_tree);
3079
3080   vat_json_init_object (node);
3081   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3082
3083   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3084
3085   vec_add1 (deid, 0);
3086   vec_add1 (seid, 0);
3087
3088   vat_json_object_add_string_copy (node, "seid", seid);
3089   vat_json_object_add_string_copy (node, "deid", deid);
3090   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3091
3092   if (mp->lloc.af)
3093     {
3094       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3095       vat_json_object_add_ip6 (node, "lloc", ip6);
3096       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3097       vat_json_object_add_ip6 (node, "rloc", ip6);
3098
3099     }
3100   else
3101     {
3102       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3103       vat_json_object_add_ip4 (node, "lloc", ip4);
3104       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3105       vat_json_object_add_ip4 (node, "rloc", ip4);
3106     }
3107   vat_json_object_add_uint (node, "pkt_count",
3108                             clib_net_to_host_u32 (mp->pkt_count));
3109   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3110
3111   vec_free (deid);
3112   vec_free (seid);
3113 }
3114
3115 static void
3116   vl_api_one_eid_table_map_details_t_handler
3117   (vl_api_one_eid_table_map_details_t * mp)
3118 {
3119   vat_main_t *vam = &vat_main;
3120
3121   u8 *line = format (0, "%=10d%=10d",
3122                      clib_net_to_host_u32 (mp->vni),
3123                      clib_net_to_host_u32 (mp->dp_table));
3124   print (vam->ofp, "%v", line);
3125   vec_free (line);
3126 }
3127
3128 static void
3129   vl_api_one_eid_table_map_details_t_handler_json
3130   (vl_api_one_eid_table_map_details_t * mp)
3131 {
3132   vat_main_t *vam = &vat_main;
3133   vat_json_node_t *node = NULL;
3134
3135   if (VAT_JSON_ARRAY != vam->json_tree.type)
3136     {
3137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3138       vat_json_init_array (&vam->json_tree);
3139     }
3140   node = vat_json_array_add (&vam->json_tree);
3141   vat_json_init_object (node);
3142   vat_json_object_add_uint (node, "dp_table",
3143                             clib_net_to_host_u32 (mp->dp_table));
3144   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3145 }
3146
3147 static void
3148   vl_api_one_eid_table_vni_details_t_handler
3149   (vl_api_one_eid_table_vni_details_t * mp)
3150 {
3151   vat_main_t *vam = &vat_main;
3152
3153   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3154   print (vam->ofp, "%v", line);
3155   vec_free (line);
3156 }
3157
3158 static void
3159   vl_api_one_eid_table_vni_details_t_handler_json
3160   (vl_api_one_eid_table_vni_details_t * mp)
3161 {
3162   vat_main_t *vam = &vat_main;
3163   vat_json_node_t *node = NULL;
3164
3165   if (VAT_JSON_ARRAY != vam->json_tree.type)
3166     {
3167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3168       vat_json_init_array (&vam->json_tree);
3169     }
3170   node = vat_json_array_add (&vam->json_tree);
3171   vat_json_init_object (node);
3172   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3173 }
3174
3175 static void
3176   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3177   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3178 {
3179   vat_main_t *vam = &vat_main;
3180   int retval = clib_net_to_host_u32 (mp->retval);
3181
3182   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3183   print (vam->ofp, "fallback threshold value: %d", mp->value);
3184
3185   vam->retval = retval;
3186   vam->result_ready = 1;
3187 }
3188
3189 static void
3190   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3191   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194   vat_json_node_t _node, *node = &_node;
3195   int retval = clib_net_to_host_u32 (mp->retval);
3196
3197   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3198   vat_json_init_object (node);
3199   vat_json_object_add_uint (node, "value", mp->value);
3200
3201   vat_json_print (vam->ofp, node);
3202   vat_json_free (node);
3203
3204   vam->retval = retval;
3205   vam->result_ready = 1;
3206 }
3207
3208 static void
3209   vl_api_show_one_map_register_state_reply_t_handler
3210   (vl_api_show_one_map_register_state_reply_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213   int retval = clib_net_to_host_u32 (mp->retval);
3214
3215   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3216
3217   vam->retval = retval;
3218   vam->result_ready = 1;
3219 }
3220
3221 static void
3222   vl_api_show_one_map_register_state_reply_t_handler_json
3223   (vl_api_show_one_map_register_state_reply_t * mp)
3224 {
3225   vat_main_t *vam = &vat_main;
3226   vat_json_node_t _node, *node = &_node;
3227   int retval = clib_net_to_host_u32 (mp->retval);
3228
3229   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3230
3231   vat_json_init_object (node);
3232   vat_json_object_add_string_copy (node, "state", s);
3233
3234   vat_json_print (vam->ofp, node);
3235   vat_json_free (node);
3236
3237   vam->retval = retval;
3238   vam->result_ready = 1;
3239   vec_free (s);
3240 }
3241
3242 static void
3243   vl_api_show_one_rloc_probe_state_reply_t_handler
3244   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3245 {
3246   vat_main_t *vam = &vat_main;
3247   int retval = clib_net_to_host_u32 (mp->retval);
3248
3249   if (retval)
3250     goto end;
3251
3252   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3253 end:
3254   vam->retval = retval;
3255   vam->result_ready = 1;
3256 }
3257
3258 static void
3259   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3260   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   vat_json_node_t _node, *node = &_node;
3264   int retval = clib_net_to_host_u32 (mp->retval);
3265
3266   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3267   vat_json_init_object (node);
3268   vat_json_object_add_string_copy (node, "state", s);
3269
3270   vat_json_print (vam->ofp, node);
3271   vat_json_free (node);
3272
3273   vam->retval = retval;
3274   vam->result_ready = 1;
3275   vec_free (s);
3276 }
3277
3278 static void
3279   vl_api_show_one_stats_enable_disable_reply_t_handler
3280   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3281 {
3282   vat_main_t *vam = &vat_main;
3283   int retval = clib_net_to_host_u32 (mp->retval);
3284
3285   if (retval)
3286     goto end;
3287
3288   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3289 end:
3290   vam->retval = retval;
3291   vam->result_ready = 1;
3292 }
3293
3294 static void
3295   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3296   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   vat_json_node_t _node, *node = &_node;
3300   int retval = clib_net_to_host_u32 (mp->retval);
3301
3302   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3303   vat_json_init_object (node);
3304   vat_json_object_add_string_copy (node, "state", s);
3305
3306   vat_json_print (vam->ofp, node);
3307   vat_json_free (node);
3308
3309   vam->retval = retval;
3310   vam->result_ready = 1;
3311   vec_free (s);
3312 }
3313
3314 static void
3315 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3316 {
3317   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3318   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3319   e->vni = clib_net_to_host_u32 (e->vni);
3320 }
3321
3322 static void
3323   gpe_fwd_entries_get_reply_t_net_to_host
3324   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3325 {
3326   u32 i;
3327
3328   mp->count = clib_net_to_host_u32 (mp->count);
3329   for (i = 0; i < mp->count; i++)
3330     {
3331       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3332     }
3333 }
3334
3335 static u8 *
3336 format_gpe_encap_mode (u8 * s, va_list * args)
3337 {
3338   u32 mode = va_arg (*args, u32);
3339
3340   switch (mode)
3341     {
3342     case 0:
3343       return format (s, "lisp");
3344     case 1:
3345       return format (s, "vxlan");
3346     }
3347   return 0;
3348 }
3349
3350 static void
3351   vl_api_gpe_get_encap_mode_reply_t_handler
3352   (vl_api_gpe_get_encap_mode_reply_t * mp)
3353 {
3354   vat_main_t *vam = &vat_main;
3355
3356   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3357   vam->retval = ntohl (mp->retval);
3358   vam->result_ready = 1;
3359 }
3360
3361 static void
3362   vl_api_gpe_get_encap_mode_reply_t_handler_json
3363   (vl_api_gpe_get_encap_mode_reply_t * mp)
3364 {
3365   vat_main_t *vam = &vat_main;
3366   vat_json_node_t node;
3367
3368   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3369   vec_add1 (encap_mode, 0);
3370
3371   vat_json_init_object (&node);
3372   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3373
3374   vec_free (encap_mode);
3375   vat_json_print (vam->ofp, &node);
3376   vat_json_free (&node);
3377
3378   vam->retval = ntohl (mp->retval);
3379   vam->result_ready = 1;
3380 }
3381
3382 static void
3383   vl_api_gpe_fwd_entry_path_details_t_handler
3384   (vl_api_gpe_fwd_entry_path_details_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3388
3389   if (mp->lcl_loc.addr.af)
3390     format_ip_address_fcn = format_ip6_address;
3391   else
3392     format_ip_address_fcn = format_ip4_address;
3393
3394   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3395          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3396          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3397 }
3398
3399 static void
3400 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3401 {
3402   struct in6_addr ip6;
3403   struct in_addr ip4;
3404
3405   if (loc->addr.af)
3406     {
3407       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3408       vat_json_object_add_ip6 (n, "address", ip6);
3409     }
3410   else
3411     {
3412       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3413       vat_json_object_add_ip4 (n, "address", ip4);
3414     }
3415   vat_json_object_add_uint (n, "weight", loc->weight);
3416 }
3417
3418 static void
3419   vl_api_gpe_fwd_entry_path_details_t_handler_json
3420   (vl_api_gpe_fwd_entry_path_details_t * mp)
3421 {
3422   vat_main_t *vam = &vat_main;
3423   vat_json_node_t *node = NULL;
3424   vat_json_node_t *loc_node;
3425
3426   if (VAT_JSON_ARRAY != vam->json_tree.type)
3427     {
3428       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3429       vat_json_init_array (&vam->json_tree);
3430     }
3431   node = vat_json_array_add (&vam->json_tree);
3432   vat_json_init_object (node);
3433
3434   loc_node = vat_json_object_add (node, "local_locator");
3435   vat_json_init_object (loc_node);
3436   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3437
3438   loc_node = vat_json_object_add (node, "remote_locator");
3439   vat_json_init_object (loc_node);
3440   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3441 }
3442
3443 static void
3444   vl_api_gpe_fwd_entries_get_reply_t_handler
3445   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3446 {
3447   vat_main_t *vam = &vat_main;
3448   u32 i;
3449   int retval = clib_net_to_host_u32 (mp->retval);
3450   vl_api_gpe_fwd_entry_t *e;
3451
3452   if (retval)
3453     goto end;
3454
3455   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3456
3457   for (i = 0; i < mp->count; i++)
3458     {
3459       e = &mp->entries[i];
3460       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3461              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3462     }
3463
3464 end:
3465   vam->retval = retval;
3466   vam->result_ready = 1;
3467 }
3468
3469 static void
3470   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3471   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3472 {
3473   u8 *s = 0;
3474   vat_main_t *vam = &vat_main;
3475   vat_json_node_t *e = 0, root;
3476   u32 i;
3477   int retval = clib_net_to_host_u32 (mp->retval);
3478   vl_api_gpe_fwd_entry_t *fwd;
3479
3480   if (retval)
3481     goto end;
3482
3483   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3484   vat_json_init_array (&root);
3485
3486   for (i = 0; i < mp->count; i++)
3487     {
3488       e = vat_json_array_add (&root);
3489       fwd = &mp->entries[i];
3490
3491       vat_json_init_object (e);
3492       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3493       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3494       vat_json_object_add_int (e, "vni", fwd->vni);
3495       vat_json_object_add_int (e, "action", fwd->action);
3496
3497       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3498       vec_add1 (s, 0);
3499       vat_json_object_add_string_copy (e, "leid", s);
3500       vec_free (s);
3501
3502       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3503       vec_add1 (s, 0);
3504       vat_json_object_add_string_copy (e, "reid", s);
3505       vec_free (s);
3506     }
3507
3508   vat_json_print (vam->ofp, &root);
3509   vat_json_free (&root);
3510
3511 end:
3512   vam->retval = retval;
3513   vam->result_ready = 1;
3514 }
3515
3516 static void
3517   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3518   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521   u32 i, n;
3522   int retval = clib_net_to_host_u32 (mp->retval);
3523   vl_api_gpe_native_fwd_rpath_t *r;
3524
3525   if (retval)
3526     goto end;
3527
3528   n = clib_net_to_host_u32 (mp->count);
3529
3530   for (i = 0; i < n; i++)
3531     {
3532       r = &mp->entries[i];
3533       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3534              clib_net_to_host_u32 (r->fib_index),
3535              clib_net_to_host_u32 (r->nh_sw_if_index),
3536              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3537              r->nh_addr.un);
3538     }
3539
3540 end:
3541   vam->retval = retval;
3542   vam->result_ready = 1;
3543 }
3544
3545 static void
3546   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3547   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   vat_json_node_t root, *e;
3551   u32 i, n;
3552   int retval = clib_net_to_host_u32 (mp->retval);
3553   vl_api_gpe_native_fwd_rpath_t *r;
3554   u8 *s;
3555
3556   if (retval)
3557     goto end;
3558
3559   n = clib_net_to_host_u32 (mp->count);
3560   vat_json_init_array (&root);
3561
3562   for (i = 0; i < n; i++)
3563     {
3564       e = vat_json_array_add (&root);
3565       vat_json_init_object (e);
3566       r = &mp->entries[i];
3567       s =
3568         format (0, "%U",
3569                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3570                 r->nh_addr.un);
3571       vec_add1 (s, 0);
3572       vat_json_object_add_string_copy (e, "ip4", s);
3573       vec_free (s);
3574
3575       vat_json_object_add_uint (e, "fib_index",
3576                                 clib_net_to_host_u32 (r->fib_index));
3577       vat_json_object_add_uint (e, "nh_sw_if_index",
3578                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3579     }
3580
3581   vat_json_print (vam->ofp, &root);
3582   vat_json_free (&root);
3583
3584 end:
3585   vam->retval = retval;
3586   vam->result_ready = 1;
3587 }
3588
3589 static void
3590   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3591   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3592 {
3593   vat_main_t *vam = &vat_main;
3594   u32 i, n;
3595   int retval = clib_net_to_host_u32 (mp->retval);
3596
3597   if (retval)
3598     goto end;
3599
3600   n = clib_net_to_host_u32 (mp->count);
3601
3602   for (i = 0; i < n; i++)
3603     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3604
3605 end:
3606   vam->retval = retval;
3607   vam->result_ready = 1;
3608 }
3609
3610 static void
3611   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3612   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3613 {
3614   vat_main_t *vam = &vat_main;
3615   vat_json_node_t root;
3616   u32 i, n;
3617   int retval = clib_net_to_host_u32 (mp->retval);
3618
3619   if (retval)
3620     goto end;
3621
3622   n = clib_net_to_host_u32 (mp->count);
3623   vat_json_init_array (&root);
3624
3625   for (i = 0; i < n; i++)
3626     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3627
3628   vat_json_print (vam->ofp, &root);
3629   vat_json_free (&root);
3630
3631 end:
3632   vam->retval = retval;
3633   vam->result_ready = 1;
3634 }
3635
3636 static void
3637   vl_api_one_ndp_entries_get_reply_t_handler
3638   (vl_api_one_ndp_entries_get_reply_t * mp)
3639 {
3640   vat_main_t *vam = &vat_main;
3641   u32 i, n;
3642   int retval = clib_net_to_host_u32 (mp->retval);
3643
3644   if (retval)
3645     goto end;
3646
3647   n = clib_net_to_host_u32 (mp->count);
3648
3649   for (i = 0; i < n; i++)
3650     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3651            format_ethernet_address, mp->entries[i].mac);
3652
3653 end:
3654   vam->retval = retval;
3655   vam->result_ready = 1;
3656 }
3657
3658 static void
3659   vl_api_one_ndp_entries_get_reply_t_handler_json
3660   (vl_api_one_ndp_entries_get_reply_t * mp)
3661 {
3662   u8 *s = 0;
3663   vat_main_t *vam = &vat_main;
3664   vat_json_node_t *e = 0, root;
3665   u32 i, n;
3666   int retval = clib_net_to_host_u32 (mp->retval);
3667   vl_api_one_ndp_entry_t *arp_entry;
3668
3669   if (retval)
3670     goto end;
3671
3672   n = clib_net_to_host_u32 (mp->count);
3673   vat_json_init_array (&root);
3674
3675   for (i = 0; i < n; i++)
3676     {
3677       e = vat_json_array_add (&root);
3678       arp_entry = &mp->entries[i];
3679
3680       vat_json_init_object (e);
3681       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3682       vec_add1 (s, 0);
3683
3684       vat_json_object_add_string_copy (e, "mac", s);
3685       vec_free (s);
3686
3687       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3688       vec_add1 (s, 0);
3689       vat_json_object_add_string_copy (e, "ip6", s);
3690       vec_free (s);
3691     }
3692
3693   vat_json_print (vam->ofp, &root);
3694   vat_json_free (&root);
3695
3696 end:
3697   vam->retval = retval;
3698   vam->result_ready = 1;
3699 }
3700
3701 static void
3702   vl_api_one_l2_arp_entries_get_reply_t_handler
3703   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3704 {
3705   vat_main_t *vam = &vat_main;
3706   u32 i, n;
3707   int retval = clib_net_to_host_u32 (mp->retval);
3708
3709   if (retval)
3710     goto end;
3711
3712   n = clib_net_to_host_u32 (mp->count);
3713
3714   for (i = 0; i < n; i++)
3715     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3716            format_ethernet_address, mp->entries[i].mac);
3717
3718 end:
3719   vam->retval = retval;
3720   vam->result_ready = 1;
3721 }
3722
3723 static void
3724   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3725   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3726 {
3727   u8 *s = 0;
3728   vat_main_t *vam = &vat_main;
3729   vat_json_node_t *e = 0, root;
3730   u32 i, n;
3731   int retval = clib_net_to_host_u32 (mp->retval);
3732   vl_api_one_l2_arp_entry_t *arp_entry;
3733
3734   if (retval)
3735     goto end;
3736
3737   n = clib_net_to_host_u32 (mp->count);
3738   vat_json_init_array (&root);
3739
3740   for (i = 0; i < n; i++)
3741     {
3742       e = vat_json_array_add (&root);
3743       arp_entry = &mp->entries[i];
3744
3745       vat_json_init_object (e);
3746       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3747       vec_add1 (s, 0);
3748
3749       vat_json_object_add_string_copy (e, "mac", s);
3750       vec_free (s);
3751
3752       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3753       vec_add1 (s, 0);
3754       vat_json_object_add_string_copy (e, "ip4", s);
3755       vec_free (s);
3756     }
3757
3758   vat_json_print (vam->ofp, &root);
3759   vat_json_free (&root);
3760
3761 end:
3762   vam->retval = retval;
3763   vam->result_ready = 1;
3764 }
3765
3766 static void
3767 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3768 {
3769   vat_main_t *vam = &vat_main;
3770   u32 i, n;
3771   int retval = clib_net_to_host_u32 (mp->retval);
3772
3773   if (retval)
3774     goto end;
3775
3776   n = clib_net_to_host_u32 (mp->count);
3777
3778   for (i = 0; i < n; i++)
3779     {
3780       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3781     }
3782
3783 end:
3784   vam->retval = retval;
3785   vam->result_ready = 1;
3786 }
3787
3788 static void
3789   vl_api_one_ndp_bd_get_reply_t_handler_json
3790   (vl_api_one_ndp_bd_get_reply_t * mp)
3791 {
3792   vat_main_t *vam = &vat_main;
3793   vat_json_node_t root;
3794   u32 i, n;
3795   int retval = clib_net_to_host_u32 (mp->retval);
3796
3797   if (retval)
3798     goto end;
3799
3800   n = clib_net_to_host_u32 (mp->count);
3801   vat_json_init_array (&root);
3802
3803   for (i = 0; i < n; i++)
3804     {
3805       vat_json_array_add_uint (&root,
3806                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3807     }
3808
3809   vat_json_print (vam->ofp, &root);
3810   vat_json_free (&root);
3811
3812 end:
3813   vam->retval = retval;
3814   vam->result_ready = 1;
3815 }
3816
3817 static void
3818   vl_api_one_l2_arp_bd_get_reply_t_handler
3819   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3820 {
3821   vat_main_t *vam = &vat_main;
3822   u32 i, n;
3823   int retval = clib_net_to_host_u32 (mp->retval);
3824
3825   if (retval)
3826     goto end;
3827
3828   n = clib_net_to_host_u32 (mp->count);
3829
3830   for (i = 0; i < n; i++)
3831     {
3832       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3833     }
3834
3835 end:
3836   vam->retval = retval;
3837   vam->result_ready = 1;
3838 }
3839
3840 static void
3841   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3842   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3843 {
3844   vat_main_t *vam = &vat_main;
3845   vat_json_node_t root;
3846   u32 i, n;
3847   int retval = clib_net_to_host_u32 (mp->retval);
3848
3849   if (retval)
3850     goto end;
3851
3852   n = clib_net_to_host_u32 (mp->count);
3853   vat_json_init_array (&root);
3854
3855   for (i = 0; i < n; i++)
3856     {
3857       vat_json_array_add_uint (&root,
3858                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3859     }
3860
3861   vat_json_print (vam->ofp, &root);
3862   vat_json_free (&root);
3863
3864 end:
3865   vam->retval = retval;
3866   vam->result_ready = 1;
3867 }
3868
3869 static void
3870   vl_api_one_adjacencies_get_reply_t_handler
3871   (vl_api_one_adjacencies_get_reply_t * mp)
3872 {
3873   vat_main_t *vam = &vat_main;
3874   u32 i, n;
3875   int retval = clib_net_to_host_u32 (mp->retval);
3876   vl_api_one_adjacency_t *a;
3877
3878   if (retval)
3879     goto end;
3880
3881   n = clib_net_to_host_u32 (mp->count);
3882
3883   for (i = 0; i < n; i++)
3884     {
3885       a = &mp->adjacencies[i];
3886       print (vam->ofp, "%U %40U",
3887              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3888     }
3889
3890 end:
3891   vam->retval = retval;
3892   vam->result_ready = 1;
3893 }
3894
3895 static void
3896   vl_api_one_adjacencies_get_reply_t_handler_json
3897   (vl_api_one_adjacencies_get_reply_t * mp)
3898 {
3899   u8 *s = 0;
3900   vat_main_t *vam = &vat_main;
3901   vat_json_node_t *e = 0, root;
3902   u32 i, n;
3903   int retval = clib_net_to_host_u32 (mp->retval);
3904   vl_api_one_adjacency_t *a;
3905
3906   if (retval)
3907     goto end;
3908
3909   n = clib_net_to_host_u32 (mp->count);
3910   vat_json_init_array (&root);
3911
3912   for (i = 0; i < n; i++)
3913     {
3914       e = vat_json_array_add (&root);
3915       a = &mp->adjacencies[i];
3916
3917       vat_json_init_object (e);
3918       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3919       vec_add1 (s, 0);
3920       vat_json_object_add_string_copy (e, "leid", s);
3921       vec_free (s);
3922
3923       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3924       vec_add1 (s, 0);
3925       vat_json_object_add_string_copy (e, "reid", s);
3926       vec_free (s);
3927     }
3928
3929   vat_json_print (vam->ofp, &root);
3930   vat_json_free (&root);
3931
3932 end:
3933   vam->retval = retval;
3934   vam->result_ready = 1;
3935 }
3936
3937 static void
3938 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3939 {
3940   vat_main_t *vam = &vat_main;
3941
3942   print (vam->ofp, "%=20U",
3943          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3944          mp->ip_address.un);
3945 }
3946
3947 static void
3948   vl_api_one_map_server_details_t_handler_json
3949   (vl_api_one_map_server_details_t * mp)
3950 {
3951   vat_main_t *vam = &vat_main;
3952   vat_json_node_t *node = NULL;
3953   struct in6_addr ip6;
3954   struct in_addr ip4;
3955
3956   if (VAT_JSON_ARRAY != vam->json_tree.type)
3957     {
3958       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3959       vat_json_init_array (&vam->json_tree);
3960     }
3961   node = vat_json_array_add (&vam->json_tree);
3962
3963   vat_json_init_object (node);
3964   if (mp->ip_address.af)
3965     {
3966       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3967       vat_json_object_add_ip6 (node, "map-server", ip6);
3968     }
3969   else
3970     {
3971       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3972       vat_json_object_add_ip4 (node, "map-server", ip4);
3973     }
3974 }
3975
3976 static void
3977 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3978                                            * mp)
3979 {
3980   vat_main_t *vam = &vat_main;
3981
3982   print (vam->ofp, "%=20U",
3983          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3984          mp->ip_address.un);
3985 }
3986
3987 static void
3988   vl_api_one_map_resolver_details_t_handler_json
3989   (vl_api_one_map_resolver_details_t * mp)
3990 {
3991   vat_main_t *vam = &vat_main;
3992   vat_json_node_t *node = NULL;
3993   struct in6_addr ip6;
3994   struct in_addr ip4;
3995
3996   if (VAT_JSON_ARRAY != vam->json_tree.type)
3997     {
3998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3999       vat_json_init_array (&vam->json_tree);
4000     }
4001   node = vat_json_array_add (&vam->json_tree);
4002
4003   vat_json_init_object (node);
4004   if (mp->ip_address.af)
4005     {
4006       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4007       vat_json_object_add_ip6 (node, "map resolver", ip6);
4008     }
4009   else
4010     {
4011       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4012       vat_json_object_add_ip4 (node, "map resolver", ip4);
4013     }
4014 }
4015
4016 static void
4017 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4018 {
4019   vat_main_t *vam = &vat_main;
4020   i32 retval = ntohl (mp->retval);
4021
4022   if (0 <= retval)
4023     {
4024       print (vam->ofp, "feature: %s\ngpe: %s",
4025              mp->feature_status ? "enabled" : "disabled",
4026              mp->gpe_status ? "enabled" : "disabled");
4027     }
4028
4029   vam->retval = retval;
4030   vam->result_ready = 1;
4031 }
4032
4033 static void
4034   vl_api_show_one_status_reply_t_handler_json
4035   (vl_api_show_one_status_reply_t * mp)
4036 {
4037   vat_main_t *vam = &vat_main;
4038   vat_json_node_t node;
4039   u8 *gpe_status = NULL;
4040   u8 *feature_status = NULL;
4041
4042   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4043   feature_status = format (0, "%s",
4044                            mp->feature_status ? "enabled" : "disabled");
4045   vec_add1 (gpe_status, 0);
4046   vec_add1 (feature_status, 0);
4047
4048   vat_json_init_object (&node);
4049   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4050   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4051
4052   vec_free (gpe_status);
4053   vec_free (feature_status);
4054
4055   vat_json_print (vam->ofp, &node);
4056   vat_json_free (&node);
4057
4058   vam->retval = ntohl (mp->retval);
4059   vam->result_ready = 1;
4060 }
4061
4062 static void
4063   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4064   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4065 {
4066   vat_main_t *vam = &vat_main;
4067   i32 retval = ntohl (mp->retval);
4068
4069   if (retval >= 0)
4070     {
4071       print (vam->ofp, "%=20s", mp->locator_set_name);
4072     }
4073
4074   vam->retval = retval;
4075   vam->result_ready = 1;
4076 }
4077
4078 static void
4079   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4080   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4081 {
4082   vat_main_t *vam = &vat_main;
4083   vat_json_node_t *node = NULL;
4084
4085   if (VAT_JSON_ARRAY != vam->json_tree.type)
4086     {
4087       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4088       vat_json_init_array (&vam->json_tree);
4089     }
4090   node = vat_json_array_add (&vam->json_tree);
4091
4092   vat_json_init_object (node);
4093   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4094
4095   vat_json_print (vam->ofp, node);
4096   vat_json_free (node);
4097
4098   vam->retval = ntohl (mp->retval);
4099   vam->result_ready = 1;
4100 }
4101
4102 static u8 *
4103 format_lisp_map_request_mode (u8 * s, va_list * args)
4104 {
4105   u32 mode = va_arg (*args, u32);
4106
4107   switch (mode)
4108     {
4109     case 0:
4110       return format (0, "dst-only");
4111     case 1:
4112       return format (0, "src-dst");
4113     }
4114   return 0;
4115 }
4116
4117 static void
4118   vl_api_show_one_map_request_mode_reply_t_handler
4119   (vl_api_show_one_map_request_mode_reply_t * mp)
4120 {
4121   vat_main_t *vam = &vat_main;
4122   i32 retval = ntohl (mp->retval);
4123
4124   if (0 <= retval)
4125     {
4126       u32 mode = mp->mode;
4127       print (vam->ofp, "map_request_mode: %U",
4128              format_lisp_map_request_mode, mode);
4129     }
4130
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_show_one_map_request_mode_reply_t_handler_json
4137   (vl_api_show_one_map_request_mode_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   vat_json_node_t node;
4141   u8 *s = 0;
4142   u32 mode;
4143
4144   mode = mp->mode;
4145   s = format (0, "%U", format_lisp_map_request_mode, mode);
4146   vec_add1 (s, 0);
4147
4148   vat_json_init_object (&node);
4149   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4150   vat_json_print (vam->ofp, &node);
4151   vat_json_free (&node);
4152
4153   vec_free (s);
4154   vam->retval = ntohl (mp->retval);
4155   vam->result_ready = 1;
4156 }
4157
4158 static void
4159   vl_api_one_show_xtr_mode_reply_t_handler
4160   (vl_api_one_show_xtr_mode_reply_t * mp)
4161 {
4162   vat_main_t *vam = &vat_main;
4163   i32 retval = ntohl (mp->retval);
4164
4165   if (0 <= retval)
4166     {
4167       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4168     }
4169
4170   vam->retval = retval;
4171   vam->result_ready = 1;
4172 }
4173
4174 static void
4175   vl_api_one_show_xtr_mode_reply_t_handler_json
4176   (vl_api_one_show_xtr_mode_reply_t * mp)
4177 {
4178   vat_main_t *vam = &vat_main;
4179   vat_json_node_t node;
4180   u8 *status = 0;
4181
4182   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4183   vec_add1 (status, 0);
4184
4185   vat_json_init_object (&node);
4186   vat_json_object_add_string_copy (&node, "status", status);
4187
4188   vec_free (status);
4189
4190   vat_json_print (vam->ofp, &node);
4191   vat_json_free (&node);
4192
4193   vam->retval = ntohl (mp->retval);
4194   vam->result_ready = 1;
4195 }
4196
4197 static void
4198   vl_api_one_show_pitr_mode_reply_t_handler
4199   (vl_api_one_show_pitr_mode_reply_t * mp)
4200 {
4201   vat_main_t *vam = &vat_main;
4202   i32 retval = ntohl (mp->retval);
4203
4204   if (0 <= retval)
4205     {
4206       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4207     }
4208
4209   vam->retval = retval;
4210   vam->result_ready = 1;
4211 }
4212
4213 static void
4214   vl_api_one_show_pitr_mode_reply_t_handler_json
4215   (vl_api_one_show_pitr_mode_reply_t * mp)
4216 {
4217   vat_main_t *vam = &vat_main;
4218   vat_json_node_t node;
4219   u8 *status = 0;
4220
4221   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4222   vec_add1 (status, 0);
4223
4224   vat_json_init_object (&node);
4225   vat_json_object_add_string_copy (&node, "status", status);
4226
4227   vec_free (status);
4228
4229   vat_json_print (vam->ofp, &node);
4230   vat_json_free (&node);
4231
4232   vam->retval = ntohl (mp->retval);
4233   vam->result_ready = 1;
4234 }
4235
4236 static void
4237   vl_api_one_show_petr_mode_reply_t_handler
4238   (vl_api_one_show_petr_mode_reply_t * mp)
4239 {
4240   vat_main_t *vam = &vat_main;
4241   i32 retval = ntohl (mp->retval);
4242
4243   if (0 <= retval)
4244     {
4245       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4246     }
4247
4248   vam->retval = retval;
4249   vam->result_ready = 1;
4250 }
4251
4252 static void
4253   vl_api_one_show_petr_mode_reply_t_handler_json
4254   (vl_api_one_show_petr_mode_reply_t * mp)
4255 {
4256   vat_main_t *vam = &vat_main;
4257   vat_json_node_t node;
4258   u8 *status = 0;
4259
4260   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4261   vec_add1 (status, 0);
4262
4263   vat_json_init_object (&node);
4264   vat_json_object_add_string_copy (&node, "status", status);
4265
4266   vec_free (status);
4267
4268   vat_json_print (vam->ofp, &node);
4269   vat_json_free (&node);
4270
4271   vam->retval = ntohl (mp->retval);
4272   vam->result_ready = 1;
4273 }
4274
4275 static void
4276   vl_api_show_one_use_petr_reply_t_handler
4277   (vl_api_show_one_use_petr_reply_t * mp)
4278 {
4279   vat_main_t *vam = &vat_main;
4280   i32 retval = ntohl (mp->retval);
4281
4282   if (0 <= retval)
4283     {
4284       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4285       if (mp->status)
4286         {
4287           print (vam->ofp, "Proxy-ETR address; %U",
4288                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4289                  mp->ip_address.un);
4290         }
4291     }
4292
4293   vam->retval = retval;
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_show_one_use_petr_reply_t_handler_json
4299   (vl_api_show_one_use_petr_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   vat_json_node_t node;
4303   u8 *status = 0;
4304   struct in_addr ip4;
4305   struct in6_addr ip6;
4306
4307   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4308   vec_add1 (status, 0);
4309
4310   vat_json_init_object (&node);
4311   vat_json_object_add_string_copy (&node, "status", status);
4312   if (mp->status)
4313     {
4314       if (mp->ip_address.af)
4315         {
4316           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4317           vat_json_object_add_ip6 (&node, "address", ip6);
4318         }
4319       else
4320         {
4321           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4322           vat_json_object_add_ip4 (&node, "address", ip4);
4323         }
4324     }
4325
4326   vec_free (status);
4327
4328   vat_json_print (vam->ofp, &node);
4329   vat_json_free (&node);
4330
4331   vam->retval = ntohl (mp->retval);
4332   vam->result_ready = 1;
4333 }
4334
4335 static void
4336   vl_api_show_one_nsh_mapping_reply_t_handler
4337   (vl_api_show_one_nsh_mapping_reply_t * mp)
4338 {
4339   vat_main_t *vam = &vat_main;
4340   i32 retval = ntohl (mp->retval);
4341
4342   if (0 <= retval)
4343     {
4344       print (vam->ofp, "%-20s%-16s",
4345              mp->is_set ? "set" : "not-set",
4346              mp->is_set ? (char *) mp->locator_set_name : "");
4347     }
4348
4349   vam->retval = retval;
4350   vam->result_ready = 1;
4351 }
4352
4353 static void
4354   vl_api_show_one_nsh_mapping_reply_t_handler_json
4355   (vl_api_show_one_nsh_mapping_reply_t * mp)
4356 {
4357   vat_main_t *vam = &vat_main;
4358   vat_json_node_t node;
4359   u8 *status = 0;
4360
4361   status = format (0, "%s", mp->is_set ? "yes" : "no");
4362   vec_add1 (status, 0);
4363
4364   vat_json_init_object (&node);
4365   vat_json_object_add_string_copy (&node, "is_set", status);
4366   if (mp->is_set)
4367     {
4368       vat_json_object_add_string_copy (&node, "locator_set",
4369                                        mp->locator_set_name);
4370     }
4371
4372   vec_free (status);
4373
4374   vat_json_print (vam->ofp, &node);
4375   vat_json_free (&node);
4376
4377   vam->retval = ntohl (mp->retval);
4378   vam->result_ready = 1;
4379 }
4380
4381 static void
4382   vl_api_show_one_map_register_ttl_reply_t_handler
4383   (vl_api_show_one_map_register_ttl_reply_t * mp)
4384 {
4385   vat_main_t *vam = &vat_main;
4386   i32 retval = ntohl (mp->retval);
4387
4388   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4389
4390   if (0 <= retval)
4391     {
4392       print (vam->ofp, "ttl: %u", mp->ttl);
4393     }
4394
4395   vam->retval = retval;
4396   vam->result_ready = 1;
4397 }
4398
4399 static void
4400   vl_api_show_one_map_register_ttl_reply_t_handler_json
4401   (vl_api_show_one_map_register_ttl_reply_t * mp)
4402 {
4403   vat_main_t *vam = &vat_main;
4404   vat_json_node_t node;
4405
4406   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4407   vat_json_init_object (&node);
4408   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4409
4410   vat_json_print (vam->ofp, &node);
4411   vat_json_free (&node);
4412
4413   vam->retval = ntohl (mp->retval);
4414   vam->result_ready = 1;
4415 }
4416
4417 static void
4418 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4419 {
4420   vat_main_t *vam = &vat_main;
4421   i32 retval = ntohl (mp->retval);
4422
4423   if (0 <= retval)
4424     {
4425       print (vam->ofp, "%-20s%-16s",
4426              mp->status ? "enabled" : "disabled",
4427              mp->status ? (char *) mp->locator_set_name : "");
4428     }
4429
4430   vam->retval = retval;
4431   vam->result_ready = 1;
4432 }
4433
4434 static void
4435 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4436 {
4437   vat_main_t *vam = &vat_main;
4438   vat_json_node_t node;
4439   u8 *status = 0;
4440
4441   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4442   vec_add1 (status, 0);
4443
4444   vat_json_init_object (&node);
4445   vat_json_object_add_string_copy (&node, "status", status);
4446   if (mp->status)
4447     {
4448       vat_json_object_add_string_copy (&node, "locator_set",
4449                                        mp->locator_set_name);
4450     }
4451
4452   vec_free (status);
4453
4454   vat_json_print (vam->ofp, &node);
4455   vat_json_free (&node);
4456
4457   vam->retval = ntohl (mp->retval);
4458   vam->result_ready = 1;
4459 }
4460
4461 static u8 *
4462 format_policer_type (u8 * s, va_list * va)
4463 {
4464   u32 i = va_arg (*va, u32);
4465
4466   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4467     s = format (s, "1r2c");
4468   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4469     s = format (s, "1r3c");
4470   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4471     s = format (s, "2r3c-2698");
4472   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4473     s = format (s, "2r3c-4115");
4474   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4475     s = format (s, "2r3c-mef5cf1");
4476   else
4477     s = format (s, "ILLEGAL");
4478   return s;
4479 }
4480
4481 static u8 *
4482 format_policer_rate_type (u8 * s, va_list * va)
4483 {
4484   u32 i = va_arg (*va, u32);
4485
4486   if (i == SSE2_QOS_RATE_KBPS)
4487     s = format (s, "kbps");
4488   else if (i == SSE2_QOS_RATE_PPS)
4489     s = format (s, "pps");
4490   else
4491     s = format (s, "ILLEGAL");
4492   return s;
4493 }
4494
4495 static u8 *
4496 format_policer_round_type (u8 * s, va_list * va)
4497 {
4498   u32 i = va_arg (*va, u32);
4499
4500   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4501     s = format (s, "closest");
4502   else if (i == SSE2_QOS_ROUND_TO_UP)
4503     s = format (s, "up");
4504   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4505     s = format (s, "down");
4506   else
4507     s = format (s, "ILLEGAL");
4508   return s;
4509 }
4510
4511 static u8 *
4512 format_policer_action_type (u8 * s, va_list * va)
4513 {
4514   u32 i = va_arg (*va, u32);
4515
4516   if (i == SSE2_QOS_ACTION_DROP)
4517     s = format (s, "drop");
4518   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4519     s = format (s, "transmit");
4520   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4521     s = format (s, "mark-and-transmit");
4522   else
4523     s = format (s, "ILLEGAL");
4524   return s;
4525 }
4526
4527 static u8 *
4528 format_dscp (u8 * s, va_list * va)
4529 {
4530   u32 i = va_arg (*va, u32);
4531   char *t = 0;
4532
4533   switch (i)
4534     {
4535 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4536       foreach_vnet_dscp
4537 #undef _
4538     default:
4539       return format (s, "ILLEGAL");
4540     }
4541   s = format (s, "%s", t);
4542   return s;
4543 }
4544
4545 static void
4546 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4547 {
4548   vat_main_t *vam = &vat_main;
4549   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4550
4551   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4552     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4553   else
4554     conform_dscp_str = format (0, "");
4555
4556   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4557     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4558   else
4559     exceed_dscp_str = format (0, "");
4560
4561   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4562     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4563   else
4564     violate_dscp_str = format (0, "");
4565
4566   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4567          "rate type %U, round type %U, %s rate, %s color-aware, "
4568          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4569          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4570          "conform action %U%s, exceed action %U%s, violate action %U%s",
4571          mp->name,
4572          format_policer_type, mp->type,
4573          ntohl (mp->cir),
4574          ntohl (mp->eir),
4575          clib_net_to_host_u64 (mp->cb),
4576          clib_net_to_host_u64 (mp->eb),
4577          format_policer_rate_type, mp->rate_type,
4578          format_policer_round_type, mp->round_type,
4579          mp->single_rate ? "single" : "dual",
4580          mp->color_aware ? "is" : "not",
4581          ntohl (mp->cir_tokens_per_period),
4582          ntohl (mp->pir_tokens_per_period),
4583          ntohl (mp->scale),
4584          ntohl (mp->current_limit),
4585          ntohl (mp->current_bucket),
4586          ntohl (mp->extended_limit),
4587          ntohl (mp->extended_bucket),
4588          clib_net_to_host_u64 (mp->last_update_time),
4589          format_policer_action_type, mp->conform_action.type,
4590          conform_dscp_str,
4591          format_policer_action_type, mp->exceed_action.type,
4592          exceed_dscp_str,
4593          format_policer_action_type, mp->violate_action.type,
4594          violate_dscp_str);
4595
4596   vec_free (conform_dscp_str);
4597   vec_free (exceed_dscp_str);
4598   vec_free (violate_dscp_str);
4599 }
4600
4601 static void vl_api_policer_details_t_handler_json
4602   (vl_api_policer_details_t * mp)
4603 {
4604   vat_main_t *vam = &vat_main;
4605   vat_json_node_t *node;
4606   u8 *rate_type_str, *round_type_str, *type_str;
4607   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4608
4609   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4610   round_type_str =
4611     format (0, "%U", format_policer_round_type, mp->round_type);
4612   type_str = format (0, "%U", format_policer_type, mp->type);
4613   conform_action_str = format (0, "%U", format_policer_action_type,
4614                                mp->conform_action.type);
4615   exceed_action_str = format (0, "%U", format_policer_action_type,
4616                               mp->exceed_action.type);
4617   violate_action_str = format (0, "%U", format_policer_action_type,
4618                                mp->violate_action.type);
4619
4620   if (VAT_JSON_ARRAY != vam->json_tree.type)
4621     {
4622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4623       vat_json_init_array (&vam->json_tree);
4624     }
4625   node = vat_json_array_add (&vam->json_tree);
4626
4627   vat_json_init_object (node);
4628   vat_json_object_add_string_copy (node, "name", mp->name);
4629   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4630   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4631   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4632   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4633   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4634   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4635   vat_json_object_add_string_copy (node, "type", type_str);
4636   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4637   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4638   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4639   vat_json_object_add_uint (node, "cir_tokens_per_period",
4640                             ntohl (mp->cir_tokens_per_period));
4641   vat_json_object_add_uint (node, "eir_tokens_per_period",
4642                             ntohl (mp->pir_tokens_per_period));
4643   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4644   vat_json_object_add_uint (node, "current_bucket",
4645                             ntohl (mp->current_bucket));
4646   vat_json_object_add_uint (node, "extended_limit",
4647                             ntohl (mp->extended_limit));
4648   vat_json_object_add_uint (node, "extended_bucket",
4649                             ntohl (mp->extended_bucket));
4650   vat_json_object_add_uint (node, "last_update_time",
4651                             ntohl (mp->last_update_time));
4652   vat_json_object_add_string_copy (node, "conform_action",
4653                                    conform_action_str);
4654   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4655     {
4656       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4657       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4658       vec_free (dscp_str);
4659     }
4660   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4661   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4662     {
4663       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4664       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4665       vec_free (dscp_str);
4666     }
4667   vat_json_object_add_string_copy (node, "violate_action",
4668                                    violate_action_str);
4669   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4670     {
4671       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4672       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4673       vec_free (dscp_str);
4674     }
4675
4676   vec_free (rate_type_str);
4677   vec_free (round_type_str);
4678   vec_free (type_str);
4679   vec_free (conform_action_str);
4680   vec_free (exceed_action_str);
4681   vec_free (violate_action_str);
4682 }
4683
4684 static void
4685 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4686                                            mp)
4687 {
4688   vat_main_t *vam = &vat_main;
4689   int i, count = ntohl (mp->count);
4690
4691   if (count > 0)
4692     print (vam->ofp, "classify table ids (%d) : ", count);
4693   for (i = 0; i < count; i++)
4694     {
4695       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4696       print (vam->ofp, (i < count - 1) ? "," : "");
4697     }
4698   vam->retval = ntohl (mp->retval);
4699   vam->result_ready = 1;
4700 }
4701
4702 static void
4703   vl_api_classify_table_ids_reply_t_handler_json
4704   (vl_api_classify_table_ids_reply_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   int i, count = ntohl (mp->count);
4708
4709   if (count > 0)
4710     {
4711       vat_json_node_t node;
4712
4713       vat_json_init_object (&node);
4714       for (i = 0; i < count; i++)
4715         {
4716           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4717         }
4718       vat_json_print (vam->ofp, &node);
4719       vat_json_free (&node);
4720     }
4721   vam->retval = ntohl (mp->retval);
4722   vam->result_ready = 1;
4723 }
4724
4725 static void
4726   vl_api_classify_table_by_interface_reply_t_handler
4727   (vl_api_classify_table_by_interface_reply_t * mp)
4728 {
4729   vat_main_t *vam = &vat_main;
4730   u32 table_id;
4731
4732   table_id = ntohl (mp->l2_table_id);
4733   if (table_id != ~0)
4734     print (vam->ofp, "l2 table id : %d", table_id);
4735   else
4736     print (vam->ofp, "l2 table id : No input ACL tables configured");
4737   table_id = ntohl (mp->ip4_table_id);
4738   if (table_id != ~0)
4739     print (vam->ofp, "ip4 table id : %d", table_id);
4740   else
4741     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4742   table_id = ntohl (mp->ip6_table_id);
4743   if (table_id != ~0)
4744     print (vam->ofp, "ip6 table id : %d", table_id);
4745   else
4746     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4747   vam->retval = ntohl (mp->retval);
4748   vam->result_ready = 1;
4749 }
4750
4751 static void
4752   vl_api_classify_table_by_interface_reply_t_handler_json
4753   (vl_api_classify_table_by_interface_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   vat_json_node_t node;
4757
4758   vat_json_init_object (&node);
4759
4760   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4761   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4762   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4763
4764   vat_json_print (vam->ofp, &node);
4765   vat_json_free (&node);
4766
4767   vam->retval = ntohl (mp->retval);
4768   vam->result_ready = 1;
4769 }
4770
4771 static void vl_api_policer_add_del_reply_t_handler
4772   (vl_api_policer_add_del_reply_t * mp)
4773 {
4774   vat_main_t *vam = &vat_main;
4775   i32 retval = ntohl (mp->retval);
4776   if (vam->async_mode)
4777     {
4778       vam->async_errors += (retval < 0);
4779     }
4780   else
4781     {
4782       vam->retval = retval;
4783       vam->result_ready = 1;
4784       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4785         /*
4786          * Note: this is just barely thread-safe, depends on
4787          * the main thread spinning waiting for an answer...
4788          */
4789         errmsg ("policer index %d", ntohl (mp->policer_index));
4790     }
4791 }
4792
4793 static void vl_api_policer_add_del_reply_t_handler_json
4794   (vl_api_policer_add_del_reply_t * mp)
4795 {
4796   vat_main_t *vam = &vat_main;
4797   vat_json_node_t node;
4798
4799   vat_json_init_object (&node);
4800   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4801   vat_json_object_add_uint (&node, "policer_index",
4802                             ntohl (mp->policer_index));
4803
4804   vat_json_print (vam->ofp, &node);
4805   vat_json_free (&node);
4806
4807   vam->retval = ntohl (mp->retval);
4808   vam->result_ready = 1;
4809 }
4810
4811 /* Format hex dump. */
4812 u8 *
4813 format_hex_bytes (u8 * s, va_list * va)
4814 {
4815   u8 *bytes = va_arg (*va, u8 *);
4816   int n_bytes = va_arg (*va, int);
4817   uword i;
4818
4819   /* Print short or long form depending on byte count. */
4820   uword short_form = n_bytes <= 32;
4821   u32 indent = format_get_indent (s);
4822
4823   if (n_bytes == 0)
4824     return s;
4825
4826   for (i = 0; i < n_bytes; i++)
4827     {
4828       if (!short_form && (i % 32) == 0)
4829         s = format (s, "%08x: ", i);
4830       s = format (s, "%02x", bytes[i]);
4831       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4832         s = format (s, "\n%U", format_white_space, indent);
4833     }
4834
4835   return s;
4836 }
4837
4838 static void
4839 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4840                                             * mp)
4841 {
4842   vat_main_t *vam = &vat_main;
4843   i32 retval = ntohl (mp->retval);
4844   if (retval == 0)
4845     {
4846       print (vam->ofp, "classify table info :");
4847       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4848              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4849              ntohl (mp->miss_next_index));
4850       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4851              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4852              ntohl (mp->match_n_vectors));
4853       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4854              ntohl (mp->mask_length));
4855     }
4856   vam->retval = retval;
4857   vam->result_ready = 1;
4858 }
4859
4860 static void
4861   vl_api_classify_table_info_reply_t_handler_json
4862   (vl_api_classify_table_info_reply_t * mp)
4863 {
4864   vat_main_t *vam = &vat_main;
4865   vat_json_node_t node;
4866
4867   i32 retval = ntohl (mp->retval);
4868   if (retval == 0)
4869     {
4870       vat_json_init_object (&node);
4871
4872       vat_json_object_add_int (&node, "sessions",
4873                                ntohl (mp->active_sessions));
4874       vat_json_object_add_int (&node, "nexttbl",
4875                                ntohl (mp->next_table_index));
4876       vat_json_object_add_int (&node, "nextnode",
4877                                ntohl (mp->miss_next_index));
4878       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4879       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4880       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4881       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4882                       ntohl (mp->mask_length), 0);
4883       vat_json_object_add_string_copy (&node, "mask", s);
4884
4885       vat_json_print (vam->ofp, &node);
4886       vat_json_free (&node);
4887     }
4888   vam->retval = ntohl (mp->retval);
4889   vam->result_ready = 1;
4890 }
4891
4892 static void
4893 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4894                                            mp)
4895 {
4896   vat_main_t *vam = &vat_main;
4897
4898   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4899          ntohl (mp->hit_next_index), ntohl (mp->advance),
4900          ntohl (mp->opaque_index));
4901   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4902          ntohl (mp->match_length));
4903 }
4904
4905 static void
4906   vl_api_classify_session_details_t_handler_json
4907   (vl_api_classify_session_details_t * mp)
4908 {
4909   vat_main_t *vam = &vat_main;
4910   vat_json_node_t *node = NULL;
4911
4912   if (VAT_JSON_ARRAY != vam->json_tree.type)
4913     {
4914       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4915       vat_json_init_array (&vam->json_tree);
4916     }
4917   node = vat_json_array_add (&vam->json_tree);
4918
4919   vat_json_init_object (node);
4920   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4921   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4922   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4923   u8 *s =
4924     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4925             0);
4926   vat_json_object_add_string_copy (node, "match", s);
4927 }
4928
4929 static void vl_api_pg_create_interface_reply_t_handler
4930   (vl_api_pg_create_interface_reply_t * mp)
4931 {
4932   vat_main_t *vam = &vat_main;
4933
4934   vam->retval = ntohl (mp->retval);
4935   vam->result_ready = 1;
4936 }
4937
4938 static void vl_api_pg_create_interface_reply_t_handler_json
4939   (vl_api_pg_create_interface_reply_t * mp)
4940 {
4941   vat_main_t *vam = &vat_main;
4942   vat_json_node_t node;
4943
4944   i32 retval = ntohl (mp->retval);
4945   if (retval == 0)
4946     {
4947       vat_json_init_object (&node);
4948
4949       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4950
4951       vat_json_print (vam->ofp, &node);
4952       vat_json_free (&node);
4953     }
4954   vam->retval = ntohl (mp->retval);
4955   vam->result_ready = 1;
4956 }
4957
4958 static void vl_api_policer_classify_details_t_handler
4959   (vl_api_policer_classify_details_t * mp)
4960 {
4961   vat_main_t *vam = &vat_main;
4962
4963   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4964          ntohl (mp->table_index));
4965 }
4966
4967 static void vl_api_policer_classify_details_t_handler_json
4968   (vl_api_policer_classify_details_t * mp)
4969 {
4970   vat_main_t *vam = &vat_main;
4971   vat_json_node_t *node;
4972
4973   if (VAT_JSON_ARRAY != vam->json_tree.type)
4974     {
4975       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4976       vat_json_init_array (&vam->json_tree);
4977     }
4978   node = vat_json_array_add (&vam->json_tree);
4979
4980   vat_json_init_object (node);
4981   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4982   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4983 }
4984
4985 static void vl_api_flow_classify_details_t_handler
4986   (vl_api_flow_classify_details_t * mp)
4987 {
4988   vat_main_t *vam = &vat_main;
4989
4990   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4991          ntohl (mp->table_index));
4992 }
4993
4994 static void vl_api_flow_classify_details_t_handler_json
4995   (vl_api_flow_classify_details_t * mp)
4996 {
4997   vat_main_t *vam = &vat_main;
4998   vat_json_node_t *node;
4999
5000   if (VAT_JSON_ARRAY != vam->json_tree.type)
5001     {
5002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5003       vat_json_init_array (&vam->json_tree);
5004     }
5005   node = vat_json_array_add (&vam->json_tree);
5006
5007   vat_json_init_object (node);
5008   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5009   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5010 }
5011
5012 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5013 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5014 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5015 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5016 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5017 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5018 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5019 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5020 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5021 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5022
5023 /*
5024  * Generate boilerplate reply handlers, which
5025  * dig the return value out of the xxx_reply_t API message,
5026  * stick it into vam->retval, and set vam->result_ready
5027  *
5028  * Could also do this by pointing N message decode slots at
5029  * a single function, but that could break in subtle ways.
5030  */
5031
5032 #define foreach_standard_reply_retval_handler           \
5033 _(sw_interface_set_flags_reply)                         \
5034 _(sw_interface_add_del_address_reply)                   \
5035 _(sw_interface_set_rx_mode_reply)                       \
5036 _(sw_interface_set_rx_placement_reply)                  \
5037 _(sw_interface_set_table_reply)                         \
5038 _(sw_interface_set_mpls_enable_reply)                   \
5039 _(sw_interface_set_vpath_reply)                         \
5040 _(sw_interface_set_vxlan_bypass_reply)                  \
5041 _(sw_interface_set_geneve_bypass_reply)                 \
5042 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5043 _(sw_interface_set_l2_bridge_reply)                     \
5044 _(sw_interface_set_bond_weight_reply)                   \
5045 _(bridge_domain_add_del_reply)                          \
5046 _(sw_interface_set_l2_xconnect_reply)                   \
5047 _(l2fib_add_del_reply)                                  \
5048 _(l2fib_flush_int_reply)                                \
5049 _(l2fib_flush_bd_reply)                                 \
5050 _(ip_route_add_del_reply)                               \
5051 _(ip_table_add_del_reply)                               \
5052 _(ip_table_replace_begin_reply)                         \
5053 _(ip_table_flush_reply)                                 \
5054 _(ip_table_replace_end_reply)                           \
5055 _(ip_mroute_add_del_reply)                              \
5056 _(mpls_route_add_del_reply)                             \
5057 _(mpls_table_add_del_reply)                             \
5058 _(mpls_ip_bind_unbind_reply)                            \
5059 _(bier_route_add_del_reply)                             \
5060 _(bier_table_add_del_reply)                             \
5061 _(sw_interface_set_unnumbered_reply)                    \
5062 _(set_ip_flow_hash_reply)                               \
5063 _(sw_interface_ip6_enable_disable_reply)                \
5064 _(l2_patch_add_del_reply)                               \
5065 _(sr_mpls_policy_add_reply)                             \
5066 _(sr_mpls_policy_mod_reply)                             \
5067 _(sr_mpls_policy_del_reply)                             \
5068 _(sr_policy_add_reply)                                  \
5069 _(sr_policy_mod_reply)                                  \
5070 _(sr_policy_del_reply)                                  \
5071 _(sr_localsid_add_del_reply)                            \
5072 _(sr_steering_add_del_reply)                            \
5073 _(classify_add_del_session_reply)                       \
5074 _(classify_set_interface_ip_table_reply)                \
5075 _(classify_set_interface_l2_tables_reply)               \
5076 _(l2tpv3_set_tunnel_cookies_reply)                      \
5077 _(l2tpv3_interface_enable_disable_reply)                \
5078 _(l2tpv3_set_lookup_key_reply)                          \
5079 _(l2_fib_clear_table_reply)                             \
5080 _(l2_interface_efp_filter_reply)                        \
5081 _(l2_interface_vlan_tag_rewrite_reply)                  \
5082 _(modify_vhost_user_if_reply)                           \
5083 _(delete_vhost_user_if_reply)                           \
5084 _(want_l2_macs_events_reply)                            \
5085 _(input_acl_set_interface_reply)                        \
5086 _(ipsec_spd_add_del_reply)                              \
5087 _(ipsec_interface_add_del_spd_reply)                    \
5088 _(ipsec_spd_entry_add_del_reply)                        \
5089 _(ipsec_sad_entry_add_del_reply)                        \
5090 _(ipsec_tunnel_if_add_del_reply)                        \
5091 _(ipsec_tunnel_if_set_sa_reply)                         \
5092 _(delete_loopback_reply)                                \
5093 _(bd_ip_mac_add_del_reply)                              \
5094 _(bd_ip_mac_flush_reply)                                \
5095 _(want_interface_events_reply)                          \
5096 _(cop_interface_enable_disable_reply)                   \
5097 _(cop_whitelist_enable_disable_reply)                   \
5098 _(sw_interface_clear_stats_reply)                       \
5099 _(ioam_enable_reply)                                    \
5100 _(ioam_disable_reply)                                   \
5101 _(one_add_del_locator_reply)                            \
5102 _(one_add_del_local_eid_reply)                          \
5103 _(one_add_del_remote_mapping_reply)                     \
5104 _(one_add_del_adjacency_reply)                          \
5105 _(one_add_del_map_resolver_reply)                       \
5106 _(one_add_del_map_server_reply)                         \
5107 _(one_enable_disable_reply)                             \
5108 _(one_rloc_probe_enable_disable_reply)                  \
5109 _(one_map_register_enable_disable_reply)                \
5110 _(one_map_register_set_ttl_reply)                       \
5111 _(one_set_transport_protocol_reply)                     \
5112 _(one_map_register_fallback_threshold_reply)            \
5113 _(one_pitr_set_locator_set_reply)                       \
5114 _(one_map_request_mode_reply)                           \
5115 _(one_add_del_map_request_itr_rlocs_reply)              \
5116 _(one_eid_table_add_del_map_reply)                      \
5117 _(one_use_petr_reply)                                   \
5118 _(one_stats_enable_disable_reply)                       \
5119 _(one_add_del_l2_arp_entry_reply)                       \
5120 _(one_add_del_ndp_entry_reply)                          \
5121 _(one_stats_flush_reply)                                \
5122 _(one_enable_disable_xtr_mode_reply)                    \
5123 _(one_enable_disable_pitr_mode_reply)                   \
5124 _(one_enable_disable_petr_mode_reply)                   \
5125 _(gpe_enable_disable_reply)                             \
5126 _(gpe_set_encap_mode_reply)                             \
5127 _(gpe_add_del_iface_reply)                              \
5128 _(gpe_add_del_native_fwd_rpath_reply)                   \
5129 _(af_packet_delete_reply)                               \
5130 _(policer_classify_set_interface_reply)                 \
5131 _(set_ipfix_exporter_reply)                             \
5132 _(set_ipfix_classify_stream_reply)                      \
5133 _(ipfix_classify_table_add_del_reply)                   \
5134 _(flow_classify_set_interface_reply)                    \
5135 _(sw_interface_span_enable_disable_reply)               \
5136 _(pg_capture_reply)                                     \
5137 _(pg_enable_disable_reply)                              \
5138 _(ip_source_and_port_range_check_add_del_reply)         \
5139 _(ip_source_and_port_range_check_interface_add_del_reply)\
5140 _(delete_subif_reply)                                   \
5141 _(l2_interface_pbb_tag_rewrite_reply)                   \
5142 _(set_punt_reply)                                       \
5143 _(feature_enable_disable_reply)                         \
5144 _(feature_gso_enable_disable_reply)                     \
5145 _(sw_interface_tag_add_del_reply)                       \
5146 _(sw_interface_add_del_mac_address_reply)               \
5147 _(hw_interface_set_mtu_reply)                           \
5148 _(p2p_ethernet_add_reply)                               \
5149 _(p2p_ethernet_del_reply)                               \
5150 _(lldp_config_reply)                                    \
5151 _(sw_interface_set_lldp_reply)                          \
5152 _(tcp_configure_src_addresses_reply)                    \
5153 _(session_rule_add_del_reply)                           \
5154 _(ip_container_proxy_add_del_reply)                     \
5155 _(output_acl_set_interface_reply)                       \
5156 _(qos_record_enable_disable_reply)
5157
5158 #define _(n)                                    \
5159     static void vl_api_##n##_t_handler          \
5160     (vl_api_##n##_t * mp)                       \
5161     {                                           \
5162         vat_main_t * vam = &vat_main;           \
5163         i32 retval = ntohl(mp->retval);         \
5164         if (vam->async_mode) {                  \
5165             vam->async_errors += (retval < 0);  \
5166         } else {                                \
5167             vam->retval = retval;               \
5168             vam->result_ready = 1;              \
5169         }                                       \
5170     }
5171 foreach_standard_reply_retval_handler;
5172 #undef _
5173
5174 #define _(n)                                    \
5175     static void vl_api_##n##_t_handler_json     \
5176     (vl_api_##n##_t * mp)                       \
5177     {                                           \
5178         vat_main_t * vam = &vat_main;           \
5179         vat_json_node_t node;                   \
5180         vat_json_init_object(&node);            \
5181         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5182         vat_json_print(vam->ofp, &node);        \
5183         vam->retval = ntohl(mp->retval);        \
5184         vam->result_ready = 1;                  \
5185     }
5186 foreach_standard_reply_retval_handler;
5187 #undef _
5188
5189 /*
5190  * Table of message reply handlers, must include boilerplate handlers
5191  * we just generated
5192  */
5193
5194 #define foreach_vpe_api_reply_msg                                       \
5195 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5196 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5197 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5198 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5199 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5200 _(CLI_REPLY, cli_reply)                                                 \
5201 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5202 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5203   sw_interface_add_del_address_reply)                                   \
5204 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5205 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5206 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5207 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5208 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5209 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5210 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5211 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5212 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5213 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5214   sw_interface_set_l2_xconnect_reply)                                   \
5215 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5216   sw_interface_set_l2_bridge_reply)                                     \
5217 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5218 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5219 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5220 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5221 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5222 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5223 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5224 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5225 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5226 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5227 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5228 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5229 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5230 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5231 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5232 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5233 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5234 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5235 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5236 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5237 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5238 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5239 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5240 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5241 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5242 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5243 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5244 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5245 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5246 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5247 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5248 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5249 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5250 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5251   sw_interface_set_unnumbered_reply)                                    \
5252 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5253 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5254 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5255 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5256   sw_interface_ip6_enable_disable_reply)                                \
5257 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5258 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5259 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5260 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5261 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5262 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5263 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5264 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5265 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5266 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5267 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5268 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5269 classify_set_interface_ip_table_reply)                                  \
5270 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5271   classify_set_interface_l2_tables_reply)                               \
5272 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5273 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5274 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5275 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5276 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5277   l2tpv3_interface_enable_disable_reply)                                \
5278 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5279 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5280 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5281 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5282 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5283 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5284 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5285 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5286 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5287 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5288 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5289 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5290 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5291 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5292 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5293 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5294 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5295 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5296 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5297 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5298 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5299 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5300 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5301 _(L2_MACS_EVENT, l2_macs_event)                                         \
5302 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5303 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5304 _(IP_DETAILS, ip_details)                                               \
5305 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5306 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5307 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5308 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5309 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5310 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5311 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5312 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5313 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5314 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5315 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5316 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5317 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5318 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5319 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5320 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5321 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5322 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5323 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5324 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5325 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5326 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5327 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5328 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5329 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5330 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5331 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5332 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5333   one_map_register_enable_disable_reply)                                \
5334 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5335 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5336 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5337 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5338   one_map_register_fallback_threshold_reply)                            \
5339 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5340   one_rloc_probe_enable_disable_reply)                                  \
5341 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5342 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5343 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5344 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5345 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5346 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5347 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5348 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5349 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5350 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5351 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5352 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5353 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5354 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5355 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5356 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5357   show_one_stats_enable_disable_reply)                                  \
5358 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5359 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5360 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5361 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5362 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5363 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5364 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5365 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5366   one_enable_disable_pitr_mode_reply)                                   \
5367 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5368   one_enable_disable_petr_mode_reply)                                   \
5369 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5370 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5371 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5372 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5373 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5374 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5375 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5376 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5377 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5378 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5379 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5380 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5381   gpe_add_del_native_fwd_rpath_reply)                                   \
5382 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5383   gpe_fwd_entry_path_details)                                           \
5384 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5385 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5386   one_add_del_map_request_itr_rlocs_reply)                              \
5387 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5388   one_get_map_request_itr_rlocs_reply)                                  \
5389 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5390 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5391 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5392 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5393 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5394 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5395   show_one_map_register_state_reply)                                    \
5396 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5397 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5398   show_one_map_register_fallback_threshold_reply)                       \
5399 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5400 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5401 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5402 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5403 _(POLICER_DETAILS, policer_details)                                     \
5404 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5405 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5406 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5407 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5408 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5409 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5410 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5411 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5412 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5413 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5414 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5415 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5416 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5417 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5418 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5419 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5420 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5421 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5422 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5423 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5424 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5425 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5426 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5427 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5428  ip_source_and_port_range_check_add_del_reply)                          \
5429 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5430  ip_source_and_port_range_check_interface_add_del_reply)                \
5431 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5432 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5433 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5434 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5435 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5436 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5437 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5438 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5439 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5440 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5441 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5442 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5443 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5444 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5445 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5446 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5447 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5448 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5449 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5450 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5451 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5452 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5453 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5454
5455 #define foreach_standalone_reply_msg                                    \
5456 _(SW_INTERFACE_EVENT, sw_interface_event)
5457
5458 typedef struct
5459 {
5460   u8 *name;
5461   u32 value;
5462 } name_sort_t;
5463
5464 #define STR_VTR_OP_CASE(op)     \
5465     case L2_VTR_ ## op:         \
5466         return "" # op;
5467
5468 static const char *
5469 str_vtr_op (u32 vtr_op)
5470 {
5471   switch (vtr_op)
5472     {
5473       STR_VTR_OP_CASE (DISABLED);
5474       STR_VTR_OP_CASE (PUSH_1);
5475       STR_VTR_OP_CASE (PUSH_2);
5476       STR_VTR_OP_CASE (POP_1);
5477       STR_VTR_OP_CASE (POP_2);
5478       STR_VTR_OP_CASE (TRANSLATE_1_1);
5479       STR_VTR_OP_CASE (TRANSLATE_1_2);
5480       STR_VTR_OP_CASE (TRANSLATE_2_1);
5481       STR_VTR_OP_CASE (TRANSLATE_2_2);
5482     }
5483
5484   return "UNKNOWN";
5485 }
5486
5487 static int
5488 dump_sub_interface_table (vat_main_t * vam)
5489 {
5490   const sw_interface_subif_t *sub = NULL;
5491
5492   if (vam->json_output)
5493     {
5494       clib_warning
5495         ("JSON output supported only for VPE API calls and dump_stats_table");
5496       return -99;
5497     }
5498
5499   print (vam->ofp,
5500          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5501          "Interface", "sw_if_index",
5502          "sub id", "dot1ad", "tags", "outer id",
5503          "inner id", "exact", "default", "outer any", "inner any");
5504
5505   vec_foreach (sub, vam->sw_if_subif_table)
5506   {
5507     print (vam->ofp,
5508            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5509            sub->interface_name,
5510            sub->sw_if_index,
5511            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5512            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5513            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5514            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5515     if (sub->vtr_op != L2_VTR_DISABLED)
5516       {
5517         print (vam->ofp,
5518                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5519                "tag1: %d tag2: %d ]",
5520                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5521                sub->vtr_tag1, sub->vtr_tag2);
5522       }
5523   }
5524
5525   return 0;
5526 }
5527
5528 static int
5529 name_sort_cmp (void *a1, void *a2)
5530 {
5531   name_sort_t *n1 = a1;
5532   name_sort_t *n2 = a2;
5533
5534   return strcmp ((char *) n1->name, (char *) n2->name);
5535 }
5536
5537 static int
5538 dump_interface_table (vat_main_t * vam)
5539 {
5540   hash_pair_t *p;
5541   name_sort_t *nses = 0, *ns;
5542
5543   if (vam->json_output)
5544     {
5545       clib_warning
5546         ("JSON output supported only for VPE API calls and dump_stats_table");
5547       return -99;
5548     }
5549
5550   /* *INDENT-OFF* */
5551   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5552   ({
5553     vec_add2 (nses, ns, 1);
5554     ns->name = (u8 *)(p->key);
5555     ns->value = (u32) p->value[0];
5556   }));
5557   /* *INDENT-ON* */
5558
5559   vec_sort_with_function (nses, name_sort_cmp);
5560
5561   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5562   vec_foreach (ns, nses)
5563   {
5564     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5565   }
5566   vec_free (nses);
5567   return 0;
5568 }
5569
5570 static int
5571 dump_ip_table (vat_main_t * vam, int is_ipv6)
5572 {
5573   const ip_details_t *det = NULL;
5574   const ip_address_details_t *address = NULL;
5575   u32 i = ~0;
5576
5577   print (vam->ofp, "%-12s", "sw_if_index");
5578
5579   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5580   {
5581     i++;
5582     if (!det->present)
5583       {
5584         continue;
5585       }
5586     print (vam->ofp, "%-12d", i);
5587     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5588     if (!det->addr)
5589       {
5590         continue;
5591       }
5592     vec_foreach (address, det->addr)
5593     {
5594       print (vam->ofp,
5595              "            %-30U%-13d",
5596              is_ipv6 ? format_ip6_address : format_ip4_address,
5597              address->ip, address->prefix_length);
5598     }
5599   }
5600
5601   return 0;
5602 }
5603
5604 static int
5605 dump_ipv4_table (vat_main_t * vam)
5606 {
5607   if (vam->json_output)
5608     {
5609       clib_warning
5610         ("JSON output supported only for VPE API calls and dump_stats_table");
5611       return -99;
5612     }
5613
5614   return dump_ip_table (vam, 0);
5615 }
5616
5617 static int
5618 dump_ipv6_table (vat_main_t * vam)
5619 {
5620   if (vam->json_output)
5621     {
5622       clib_warning
5623         ("JSON output supported only for VPE API calls and dump_stats_table");
5624       return -99;
5625     }
5626
5627   return dump_ip_table (vam, 1);
5628 }
5629
5630 /*
5631  * Pass CLI buffers directly in the CLI_INBAND API message,
5632  * instead of an additional shared memory area.
5633  */
5634 static int
5635 exec_inband (vat_main_t * vam)
5636 {
5637   vl_api_cli_inband_t *mp;
5638   unformat_input_t *i = vam->input;
5639   int ret;
5640
5641   if (vec_len (i->buffer) == 0)
5642     return -1;
5643
5644   if (vam->exec_mode == 0 && unformat (i, "mode"))
5645     {
5646       vam->exec_mode = 1;
5647       return 0;
5648     }
5649   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5650     {
5651       vam->exec_mode = 0;
5652       return 0;
5653     }
5654
5655   /*
5656    * In order for the CLI command to work, it
5657    * must be a vector ending in \n, not a C-string ending
5658    * in \n\0.
5659    */
5660   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5661   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5662
5663   S (mp);
5664   W (ret);
5665   /* json responses may or may not include a useful reply... */
5666   if (vec_len (vam->cmd_reply))
5667     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5668   return ret;
5669 }
5670
5671 int
5672 exec (vat_main_t * vam)
5673 {
5674   return exec_inband (vam);
5675 }
5676
5677 static int
5678 api_create_loopback (vat_main_t * vam)
5679 {
5680   unformat_input_t *i = vam->input;
5681   vl_api_create_loopback_t *mp;
5682   vl_api_create_loopback_instance_t *mp_lbi;
5683   u8 mac_address[6];
5684   u8 mac_set = 0;
5685   u8 is_specified = 0;
5686   u32 user_instance = 0;
5687   int ret;
5688
5689   clib_memset (mac_address, 0, sizeof (mac_address));
5690
5691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5692     {
5693       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5694         mac_set = 1;
5695       if (unformat (i, "instance %d", &user_instance))
5696         is_specified = 1;
5697       else
5698         break;
5699     }
5700
5701   if (is_specified)
5702     {
5703       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5704       mp_lbi->is_specified = is_specified;
5705       if (is_specified)
5706         mp_lbi->user_instance = htonl (user_instance);
5707       if (mac_set)
5708         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5709       S (mp_lbi);
5710     }
5711   else
5712     {
5713       /* Construct the API message */
5714       M (CREATE_LOOPBACK, mp);
5715       if (mac_set)
5716         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5717       S (mp);
5718     }
5719
5720   W (ret);
5721   return ret;
5722 }
5723
5724 static int
5725 api_delete_loopback (vat_main_t * vam)
5726 {
5727   unformat_input_t *i = vam->input;
5728   vl_api_delete_loopback_t *mp;
5729   u32 sw_if_index = ~0;
5730   int ret;
5731
5732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5733     {
5734       if (unformat (i, "sw_if_index %d", &sw_if_index))
5735         ;
5736       else
5737         break;
5738     }
5739
5740   if (sw_if_index == ~0)
5741     {
5742       errmsg ("missing sw_if_index");
5743       return -99;
5744     }
5745
5746   /* Construct the API message */
5747   M (DELETE_LOOPBACK, mp);
5748   mp->sw_if_index = ntohl (sw_if_index);
5749
5750   S (mp);
5751   W (ret);
5752   return ret;
5753 }
5754
5755 static int
5756 api_want_interface_events (vat_main_t * vam)
5757 {
5758   unformat_input_t *i = vam->input;
5759   vl_api_want_interface_events_t *mp;
5760   int enable = -1;
5761   int ret;
5762
5763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5764     {
5765       if (unformat (i, "enable"))
5766         enable = 1;
5767       else if (unformat (i, "disable"))
5768         enable = 0;
5769       else
5770         break;
5771     }
5772
5773   if (enable == -1)
5774     {
5775       errmsg ("missing enable|disable");
5776       return -99;
5777     }
5778
5779   M (WANT_INTERFACE_EVENTS, mp);
5780   mp->enable_disable = enable;
5781
5782   vam->interface_event_display = enable;
5783
5784   S (mp);
5785   W (ret);
5786   return ret;
5787 }
5788
5789
5790 /* Note: non-static, called once to set up the initial intfc table */
5791 int
5792 api_sw_interface_dump (vat_main_t * vam)
5793 {
5794   vl_api_sw_interface_dump_t *mp;
5795   vl_api_control_ping_t *mp_ping;
5796   hash_pair_t *p;
5797   name_sort_t *nses = 0, *ns;
5798   sw_interface_subif_t *sub = NULL;
5799   int ret;
5800
5801   /* Toss the old name table */
5802   /* *INDENT-OFF* */
5803   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5804   ({
5805     vec_add2 (nses, ns, 1);
5806     ns->name = (u8 *)(p->key);
5807     ns->value = (u32) p->value[0];
5808   }));
5809   /* *INDENT-ON* */
5810
5811   hash_free (vam->sw_if_index_by_interface_name);
5812
5813   vec_foreach (ns, nses) vec_free (ns->name);
5814
5815   vec_free (nses);
5816
5817   vec_foreach (sub, vam->sw_if_subif_table)
5818   {
5819     vec_free (sub->interface_name);
5820   }
5821   vec_free (vam->sw_if_subif_table);
5822
5823   /* recreate the interface name hash table */
5824   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5825
5826   /*
5827    * Ask for all interface names. Otherwise, the epic catalog of
5828    * name filters becomes ridiculously long, and vat ends up needing
5829    * to be taught about new interface types.
5830    */
5831   M (SW_INTERFACE_DUMP, mp);
5832   S (mp);
5833
5834   /* Use a control ping for synchronization */
5835   MPING (CONTROL_PING, mp_ping);
5836   S (mp_ping);
5837
5838   W (ret);
5839   return ret;
5840 }
5841
5842 static int
5843 api_sw_interface_set_flags (vat_main_t * vam)
5844 {
5845   unformat_input_t *i = vam->input;
5846   vl_api_sw_interface_set_flags_t *mp;
5847   u32 sw_if_index;
5848   u8 sw_if_index_set = 0;
5849   u8 admin_up = 0;
5850   int ret;
5851
5852   /* Parse args required to build the message */
5853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5854     {
5855       if (unformat (i, "admin-up"))
5856         admin_up = 1;
5857       else if (unformat (i, "admin-down"))
5858         admin_up = 0;
5859       else
5860         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5861         sw_if_index_set = 1;
5862       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5863         sw_if_index_set = 1;
5864       else
5865         break;
5866     }
5867
5868   if (sw_if_index_set == 0)
5869     {
5870       errmsg ("missing interface name or sw_if_index");
5871       return -99;
5872     }
5873
5874   /* Construct the API message */
5875   M (SW_INTERFACE_SET_FLAGS, mp);
5876   mp->sw_if_index = ntohl (sw_if_index);
5877   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5878
5879   /* send it... */
5880   S (mp);
5881
5882   /* Wait for a reply, return the good/bad news... */
5883   W (ret);
5884   return ret;
5885 }
5886
5887 static int
5888 api_sw_interface_set_rx_mode (vat_main_t * vam)
5889 {
5890   unformat_input_t *i = vam->input;
5891   vl_api_sw_interface_set_rx_mode_t *mp;
5892   u32 sw_if_index;
5893   u8 sw_if_index_set = 0;
5894   int ret;
5895   u8 queue_id_valid = 0;
5896   u32 queue_id;
5897   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5898
5899   /* Parse args required to build the message */
5900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5901     {
5902       if (unformat (i, "queue %d", &queue_id))
5903         queue_id_valid = 1;
5904       else if (unformat (i, "polling"))
5905         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5906       else if (unformat (i, "interrupt"))
5907         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5908       else if (unformat (i, "adaptive"))
5909         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5910       else
5911         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5912         sw_if_index_set = 1;
5913       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5914         sw_if_index_set = 1;
5915       else
5916         break;
5917     }
5918
5919   if (sw_if_index_set == 0)
5920     {
5921       errmsg ("missing interface name or sw_if_index");
5922       return -99;
5923     }
5924   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5925     {
5926       errmsg ("missing rx-mode");
5927       return -99;
5928     }
5929
5930   /* Construct the API message */
5931   M (SW_INTERFACE_SET_RX_MODE, mp);
5932   mp->sw_if_index = ntohl (sw_if_index);
5933   mp->mode = (vl_api_rx_mode_t) mode;
5934   mp->queue_id_valid = queue_id_valid;
5935   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5936
5937   /* send it... */
5938   S (mp);
5939
5940   /* Wait for a reply, return the good/bad news... */
5941   W (ret);
5942   return ret;
5943 }
5944
5945 static int
5946 api_sw_interface_set_rx_placement (vat_main_t * vam)
5947 {
5948   unformat_input_t *i = vam->input;
5949   vl_api_sw_interface_set_rx_placement_t *mp;
5950   u32 sw_if_index;
5951   u8 sw_if_index_set = 0;
5952   int ret;
5953   u8 is_main = 0;
5954   u32 queue_id, thread_index;
5955
5956   /* Parse args required to build the message */
5957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5958     {
5959       if (unformat (i, "queue %d", &queue_id))
5960         ;
5961       else if (unformat (i, "main"))
5962         is_main = 1;
5963       else if (unformat (i, "worker %d", &thread_index))
5964         ;
5965       else
5966         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5967         sw_if_index_set = 1;
5968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5969         sw_if_index_set = 1;
5970       else
5971         break;
5972     }
5973
5974   if (sw_if_index_set == 0)
5975     {
5976       errmsg ("missing interface name or sw_if_index");
5977       return -99;
5978     }
5979
5980   if (is_main)
5981     thread_index = 0;
5982   /* Construct the API message */
5983   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5984   mp->sw_if_index = ntohl (sw_if_index);
5985   mp->worker_id = ntohl (thread_index);
5986   mp->queue_id = ntohl (queue_id);
5987   mp->is_main = is_main;
5988
5989   /* send it... */
5990   S (mp);
5991   /* Wait for a reply, return the good/bad news... */
5992   W (ret);
5993   return ret;
5994 }
5995
5996 static void vl_api_sw_interface_rx_placement_details_t_handler
5997   (vl_api_sw_interface_rx_placement_details_t * mp)
5998 {
5999   vat_main_t *vam = &vat_main;
6000   u32 worker_id = ntohl (mp->worker_id);
6001
6002   print (vam->ofp,
6003          "\n%-11d %-11s %-6d %-5d %-9s",
6004          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6005          worker_id, ntohl (mp->queue_id),
6006          (mp->mode ==
6007           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6008 }
6009
6010 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6011   (vl_api_sw_interface_rx_placement_details_t * mp)
6012 {
6013   vat_main_t *vam = &vat_main;
6014   vat_json_node_t *node = NULL;
6015
6016   if (VAT_JSON_ARRAY != vam->json_tree.type)
6017     {
6018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6019       vat_json_init_array (&vam->json_tree);
6020     }
6021   node = vat_json_array_add (&vam->json_tree);
6022
6023   vat_json_init_object (node);
6024   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6025   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6026   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6027   vat_json_object_add_uint (node, "mode", mp->mode);
6028 }
6029
6030 static int
6031 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6032 {
6033   unformat_input_t *i = vam->input;
6034   vl_api_sw_interface_rx_placement_dump_t *mp;
6035   vl_api_control_ping_t *mp_ping;
6036   int ret;
6037   u32 sw_if_index;
6038   u8 sw_if_index_set = 0;
6039
6040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6041     {
6042       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6043         sw_if_index_set++;
6044       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6045         sw_if_index_set++;
6046       else
6047         break;
6048     }
6049
6050   print (vam->ofp,
6051          "\n%-11s %-11s %-6s %-5s %-4s",
6052          "sw_if_index", "main/worker", "thread", "queue", "mode");
6053
6054   /* Dump Interface rx placement */
6055   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6056
6057   if (sw_if_index_set)
6058     mp->sw_if_index = htonl (sw_if_index);
6059   else
6060     mp->sw_if_index = ~0;
6061
6062   S (mp);
6063
6064   /* Use a control ping for synchronization */
6065   MPING (CONTROL_PING, mp_ping);
6066   S (mp_ping);
6067
6068   W (ret);
6069   return ret;
6070 }
6071
6072 static int
6073 api_sw_interface_clear_stats (vat_main_t * vam)
6074 {
6075   unformat_input_t *i = vam->input;
6076   vl_api_sw_interface_clear_stats_t *mp;
6077   u32 sw_if_index;
6078   u8 sw_if_index_set = 0;
6079   int ret;
6080
6081   /* Parse args required to build the message */
6082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6083     {
6084       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6085         sw_if_index_set = 1;
6086       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6087         sw_if_index_set = 1;
6088       else
6089         break;
6090     }
6091
6092   /* Construct the API message */
6093   M (SW_INTERFACE_CLEAR_STATS, mp);
6094
6095   if (sw_if_index_set == 1)
6096     mp->sw_if_index = ntohl (sw_if_index);
6097   else
6098     mp->sw_if_index = ~0;
6099
6100   /* send it... */
6101   S (mp);
6102
6103   /* Wait for a reply, return the good/bad news... */
6104   W (ret);
6105   return ret;
6106 }
6107
6108 static int
6109 api_sw_interface_add_del_address (vat_main_t * vam)
6110 {
6111   unformat_input_t *i = vam->input;
6112   vl_api_sw_interface_add_del_address_t *mp;
6113   u32 sw_if_index;
6114   u8 sw_if_index_set = 0;
6115   u8 is_add = 1, del_all = 0;
6116   u32 address_length = 0;
6117   u8 v4_address_set = 0;
6118   u8 v6_address_set = 0;
6119   ip4_address_t v4address;
6120   ip6_address_t v6address;
6121   int ret;
6122
6123   /* Parse args required to build the message */
6124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6125     {
6126       if (unformat (i, "del-all"))
6127         del_all = 1;
6128       else if (unformat (i, "del"))
6129         is_add = 0;
6130       else
6131         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6132         sw_if_index_set = 1;
6133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6134         sw_if_index_set = 1;
6135       else if (unformat (i, "%U/%d",
6136                          unformat_ip4_address, &v4address, &address_length))
6137         v4_address_set = 1;
6138       else if (unformat (i, "%U/%d",
6139                          unformat_ip6_address, &v6address, &address_length))
6140         v6_address_set = 1;
6141       else
6142         break;
6143     }
6144
6145   if (sw_if_index_set == 0)
6146     {
6147       errmsg ("missing interface name or sw_if_index");
6148       return -99;
6149     }
6150   if (v4_address_set && v6_address_set)
6151     {
6152       errmsg ("both v4 and v6 addresses set");
6153       return -99;
6154     }
6155   if (!v4_address_set && !v6_address_set && !del_all)
6156     {
6157       errmsg ("no addresses set");
6158       return -99;
6159     }
6160
6161   /* Construct the API message */
6162   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6163
6164   mp->sw_if_index = ntohl (sw_if_index);
6165   mp->is_add = is_add;
6166   mp->del_all = del_all;
6167   if (v6_address_set)
6168     {
6169       mp->prefix.address.af = ADDRESS_IP6;
6170       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6171     }
6172   else
6173     {
6174       mp->prefix.address.af = ADDRESS_IP4;
6175       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6176     }
6177   mp->prefix.len = address_length;
6178
6179   /* send it... */
6180   S (mp);
6181
6182   /* Wait for a reply, return good/bad news  */
6183   W (ret);
6184   return ret;
6185 }
6186
6187 static int
6188 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6189 {
6190   unformat_input_t *i = vam->input;
6191   vl_api_sw_interface_set_mpls_enable_t *mp;
6192   u32 sw_if_index;
6193   u8 sw_if_index_set = 0;
6194   u8 enable = 1;
6195   int ret;
6196
6197   /* Parse args required to build the message */
6198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6199     {
6200       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6201         sw_if_index_set = 1;
6202       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6203         sw_if_index_set = 1;
6204       else if (unformat (i, "disable"))
6205         enable = 0;
6206       else if (unformat (i, "dis"))
6207         enable = 0;
6208       else
6209         break;
6210     }
6211
6212   if (sw_if_index_set == 0)
6213     {
6214       errmsg ("missing interface name or sw_if_index");
6215       return -99;
6216     }
6217
6218   /* Construct the API message */
6219   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6220
6221   mp->sw_if_index = ntohl (sw_if_index);
6222   mp->enable = enable;
6223
6224   /* send it... */
6225   S (mp);
6226
6227   /* Wait for a reply... */
6228   W (ret);
6229   return ret;
6230 }
6231
6232 static int
6233 api_sw_interface_set_table (vat_main_t * vam)
6234 {
6235   unformat_input_t *i = vam->input;
6236   vl_api_sw_interface_set_table_t *mp;
6237   u32 sw_if_index, vrf_id = 0;
6238   u8 sw_if_index_set = 0;
6239   u8 is_ipv6 = 0;
6240   int ret;
6241
6242   /* Parse args required to build the message */
6243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6244     {
6245       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6246         sw_if_index_set = 1;
6247       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6248         sw_if_index_set = 1;
6249       else if (unformat (i, "vrf %d", &vrf_id))
6250         ;
6251       else if (unformat (i, "ipv6"))
6252         is_ipv6 = 1;
6253       else
6254         break;
6255     }
6256
6257   if (sw_if_index_set == 0)
6258     {
6259       errmsg ("missing interface name or sw_if_index");
6260       return -99;
6261     }
6262
6263   /* Construct the API message */
6264   M (SW_INTERFACE_SET_TABLE, mp);
6265
6266   mp->sw_if_index = ntohl (sw_if_index);
6267   mp->is_ipv6 = is_ipv6;
6268   mp->vrf_id = ntohl (vrf_id);
6269
6270   /* send it... */
6271   S (mp);
6272
6273   /* Wait for a reply... */
6274   W (ret);
6275   return ret;
6276 }
6277
6278 static void vl_api_sw_interface_get_table_reply_t_handler
6279   (vl_api_sw_interface_get_table_reply_t * mp)
6280 {
6281   vat_main_t *vam = &vat_main;
6282
6283   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6284
6285   vam->retval = ntohl (mp->retval);
6286   vam->result_ready = 1;
6287
6288 }
6289
6290 static void vl_api_sw_interface_get_table_reply_t_handler_json
6291   (vl_api_sw_interface_get_table_reply_t * mp)
6292 {
6293   vat_main_t *vam = &vat_main;
6294   vat_json_node_t node;
6295
6296   vat_json_init_object (&node);
6297   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6298   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6299
6300   vat_json_print (vam->ofp, &node);
6301   vat_json_free (&node);
6302
6303   vam->retval = ntohl (mp->retval);
6304   vam->result_ready = 1;
6305 }
6306
6307 static int
6308 api_sw_interface_get_table (vat_main_t * vam)
6309 {
6310   unformat_input_t *i = vam->input;
6311   vl_api_sw_interface_get_table_t *mp;
6312   u32 sw_if_index;
6313   u8 sw_if_index_set = 0;
6314   u8 is_ipv6 = 0;
6315   int ret;
6316
6317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6318     {
6319       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6320         sw_if_index_set = 1;
6321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6322         sw_if_index_set = 1;
6323       else if (unformat (i, "ipv6"))
6324         is_ipv6 = 1;
6325       else
6326         break;
6327     }
6328
6329   if (sw_if_index_set == 0)
6330     {
6331       errmsg ("missing interface name or sw_if_index");
6332       return -99;
6333     }
6334
6335   M (SW_INTERFACE_GET_TABLE, mp);
6336   mp->sw_if_index = htonl (sw_if_index);
6337   mp->is_ipv6 = is_ipv6;
6338
6339   S (mp);
6340   W (ret);
6341   return ret;
6342 }
6343
6344 static int
6345 api_sw_interface_set_vpath (vat_main_t * vam)
6346 {
6347   unformat_input_t *i = vam->input;
6348   vl_api_sw_interface_set_vpath_t *mp;
6349   u32 sw_if_index = 0;
6350   u8 sw_if_index_set = 0;
6351   u8 is_enable = 0;
6352   int ret;
6353
6354   /* Parse args required to build the message */
6355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6356     {
6357       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6358         sw_if_index_set = 1;
6359       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6360         sw_if_index_set = 1;
6361       else if (unformat (i, "enable"))
6362         is_enable = 1;
6363       else if (unformat (i, "disable"))
6364         is_enable = 0;
6365       else
6366         break;
6367     }
6368
6369   if (sw_if_index_set == 0)
6370     {
6371       errmsg ("missing interface name or sw_if_index");
6372       return -99;
6373     }
6374
6375   /* Construct the API message */
6376   M (SW_INTERFACE_SET_VPATH, mp);
6377
6378   mp->sw_if_index = ntohl (sw_if_index);
6379   mp->enable = is_enable;
6380
6381   /* send it... */
6382   S (mp);
6383
6384   /* Wait for a reply... */
6385   W (ret);
6386   return ret;
6387 }
6388
6389 static int
6390 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6391 {
6392   unformat_input_t *i = vam->input;
6393   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6394   u32 sw_if_index = 0;
6395   u8 sw_if_index_set = 0;
6396   u8 is_enable = 1;
6397   u8 is_ipv6 = 0;
6398   int ret;
6399
6400   /* Parse args required to build the message */
6401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6402     {
6403       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6404         sw_if_index_set = 1;
6405       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6406         sw_if_index_set = 1;
6407       else if (unformat (i, "enable"))
6408         is_enable = 1;
6409       else if (unformat (i, "disable"))
6410         is_enable = 0;
6411       else if (unformat (i, "ip4"))
6412         is_ipv6 = 0;
6413       else if (unformat (i, "ip6"))
6414         is_ipv6 = 1;
6415       else
6416         break;
6417     }
6418
6419   if (sw_if_index_set == 0)
6420     {
6421       errmsg ("missing interface name or sw_if_index");
6422       return -99;
6423     }
6424
6425   /* Construct the API message */
6426   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6427
6428   mp->sw_if_index = ntohl (sw_if_index);
6429   mp->enable = is_enable;
6430   mp->is_ipv6 = is_ipv6;
6431
6432   /* send it... */
6433   S (mp);
6434
6435   /* Wait for a reply... */
6436   W (ret);
6437   return ret;
6438 }
6439
6440 static int
6441 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6442 {
6443   unformat_input_t *i = vam->input;
6444   vl_api_sw_interface_set_geneve_bypass_t *mp;
6445   u32 sw_if_index = 0;
6446   u8 sw_if_index_set = 0;
6447   u8 is_enable = 1;
6448   u8 is_ipv6 = 0;
6449   int ret;
6450
6451   /* Parse args required to build the message */
6452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6453     {
6454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6455         sw_if_index_set = 1;
6456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6457         sw_if_index_set = 1;
6458       else if (unformat (i, "enable"))
6459         is_enable = 1;
6460       else if (unformat (i, "disable"))
6461         is_enable = 0;
6462       else if (unformat (i, "ip4"))
6463         is_ipv6 = 0;
6464       else if (unformat (i, "ip6"))
6465         is_ipv6 = 1;
6466       else
6467         break;
6468     }
6469
6470   if (sw_if_index_set == 0)
6471     {
6472       errmsg ("missing interface name or sw_if_index");
6473       return -99;
6474     }
6475
6476   /* Construct the API message */
6477   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6478
6479   mp->sw_if_index = ntohl (sw_if_index);
6480   mp->enable = is_enable;
6481   mp->is_ipv6 = is_ipv6;
6482
6483   /* send it... */
6484   S (mp);
6485
6486   /* Wait for a reply... */
6487   W (ret);
6488   return ret;
6489 }
6490
6491 static int
6492 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6493 {
6494   unformat_input_t *i = vam->input;
6495   vl_api_sw_interface_set_l2_xconnect_t *mp;
6496   u32 rx_sw_if_index;
6497   u8 rx_sw_if_index_set = 0;
6498   u32 tx_sw_if_index;
6499   u8 tx_sw_if_index_set = 0;
6500   u8 enable = 1;
6501   int ret;
6502
6503   /* Parse args required to build the message */
6504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6505     {
6506       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6507         rx_sw_if_index_set = 1;
6508       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6509         tx_sw_if_index_set = 1;
6510       else if (unformat (i, "rx"))
6511         {
6512           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6513             {
6514               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6515                             &rx_sw_if_index))
6516                 rx_sw_if_index_set = 1;
6517             }
6518           else
6519             break;
6520         }
6521       else if (unformat (i, "tx"))
6522         {
6523           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6524             {
6525               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6526                             &tx_sw_if_index))
6527                 tx_sw_if_index_set = 1;
6528             }
6529           else
6530             break;
6531         }
6532       else if (unformat (i, "enable"))
6533         enable = 1;
6534       else if (unformat (i, "disable"))
6535         enable = 0;
6536       else
6537         break;
6538     }
6539
6540   if (rx_sw_if_index_set == 0)
6541     {
6542       errmsg ("missing rx interface name or rx_sw_if_index");
6543       return -99;
6544     }
6545
6546   if (enable && (tx_sw_if_index_set == 0))
6547     {
6548       errmsg ("missing tx interface name or tx_sw_if_index");
6549       return -99;
6550     }
6551
6552   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6553
6554   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6555   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6556   mp->enable = enable;
6557
6558   S (mp);
6559   W (ret);
6560   return ret;
6561 }
6562
6563 static int
6564 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6565 {
6566   unformat_input_t *i = vam->input;
6567   vl_api_sw_interface_set_l2_bridge_t *mp;
6568   vl_api_l2_port_type_t port_type;
6569   u32 rx_sw_if_index;
6570   u8 rx_sw_if_index_set = 0;
6571   u32 bd_id;
6572   u8 bd_id_set = 0;
6573   u32 shg = 0;
6574   u8 enable = 1;
6575   int ret;
6576
6577   port_type = L2_API_PORT_TYPE_NORMAL;
6578
6579   /* Parse args required to build the message */
6580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6581     {
6582       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6583         rx_sw_if_index_set = 1;
6584       else if (unformat (i, "bd_id %d", &bd_id))
6585         bd_id_set = 1;
6586       else
6587         if (unformat
6588             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6589         rx_sw_if_index_set = 1;
6590       else if (unformat (i, "shg %d", &shg))
6591         ;
6592       else if (unformat (i, "bvi"))
6593         port_type = L2_API_PORT_TYPE_BVI;
6594       else if (unformat (i, "uu-fwd"))
6595         port_type = L2_API_PORT_TYPE_UU_FWD;
6596       else if (unformat (i, "enable"))
6597         enable = 1;
6598       else if (unformat (i, "disable"))
6599         enable = 0;
6600       else
6601         break;
6602     }
6603
6604   if (rx_sw_if_index_set == 0)
6605     {
6606       errmsg ("missing rx interface name or sw_if_index");
6607       return -99;
6608     }
6609
6610   if (enable && (bd_id_set == 0))
6611     {
6612       errmsg ("missing bridge domain");
6613       return -99;
6614     }
6615
6616   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6617
6618   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6619   mp->bd_id = ntohl (bd_id);
6620   mp->shg = (u8) shg;
6621   mp->port_type = ntohl (port_type);
6622   mp->enable = enable;
6623
6624   S (mp);
6625   W (ret);
6626   return ret;
6627 }
6628
6629 static int
6630 api_bridge_domain_dump (vat_main_t * vam)
6631 {
6632   unformat_input_t *i = vam->input;
6633   vl_api_bridge_domain_dump_t *mp;
6634   vl_api_control_ping_t *mp_ping;
6635   u32 bd_id = ~0;
6636   int ret;
6637
6638   /* Parse args required to build the message */
6639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6640     {
6641       if (unformat (i, "bd_id %d", &bd_id))
6642         ;
6643       else
6644         break;
6645     }
6646
6647   M (BRIDGE_DOMAIN_DUMP, mp);
6648   mp->bd_id = ntohl (bd_id);
6649   S (mp);
6650
6651   /* Use a control ping for synchronization */
6652   MPING (CONTROL_PING, mp_ping);
6653   S (mp_ping);
6654
6655   W (ret);
6656   return ret;
6657 }
6658
6659 static int
6660 api_bridge_domain_add_del (vat_main_t * vam)
6661 {
6662   unformat_input_t *i = vam->input;
6663   vl_api_bridge_domain_add_del_t *mp;
6664   u32 bd_id = ~0;
6665   u8 is_add = 1;
6666   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6667   u8 *bd_tag = NULL;
6668   u32 mac_age = 0;
6669   int ret;
6670
6671   /* Parse args required to build the message */
6672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6673     {
6674       if (unformat (i, "bd_id %d", &bd_id))
6675         ;
6676       else if (unformat (i, "flood %d", &flood))
6677         ;
6678       else if (unformat (i, "uu-flood %d", &uu_flood))
6679         ;
6680       else if (unformat (i, "forward %d", &forward))
6681         ;
6682       else if (unformat (i, "learn %d", &learn))
6683         ;
6684       else if (unformat (i, "arp-term %d", &arp_term))
6685         ;
6686       else if (unformat (i, "mac-age %d", &mac_age))
6687         ;
6688       else if (unformat (i, "bd-tag %s", &bd_tag))
6689         ;
6690       else if (unformat (i, "del"))
6691         {
6692           is_add = 0;
6693           flood = uu_flood = forward = learn = 0;
6694         }
6695       else
6696         break;
6697     }
6698
6699   if (bd_id == ~0)
6700     {
6701       errmsg ("missing bridge domain");
6702       ret = -99;
6703       goto done;
6704     }
6705
6706   if (mac_age > 255)
6707     {
6708       errmsg ("mac age must be less than 256 ");
6709       ret = -99;
6710       goto done;
6711     }
6712
6713   if ((bd_tag) && (vec_len (bd_tag) > 63))
6714     {
6715       errmsg ("bd-tag cannot be longer than 63");
6716       ret = -99;
6717       goto done;
6718     }
6719
6720   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6721
6722   mp->bd_id = ntohl (bd_id);
6723   mp->flood = flood;
6724   mp->uu_flood = uu_flood;
6725   mp->forward = forward;
6726   mp->learn = learn;
6727   mp->arp_term = arp_term;
6728   mp->is_add = is_add;
6729   mp->mac_age = (u8) mac_age;
6730   if (bd_tag)
6731     {
6732       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6733       mp->bd_tag[vec_len (bd_tag)] = 0;
6734     }
6735   S (mp);
6736   W (ret);
6737
6738 done:
6739   vec_free (bd_tag);
6740   return ret;
6741 }
6742
6743 static int
6744 api_l2fib_flush_bd (vat_main_t * vam)
6745 {
6746   unformat_input_t *i = vam->input;
6747   vl_api_l2fib_flush_bd_t *mp;
6748   u32 bd_id = ~0;
6749   int ret;
6750
6751   /* Parse args required to build the message */
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "bd_id %d", &bd_id));
6755       else
6756         break;
6757     }
6758
6759   if (bd_id == ~0)
6760     {
6761       errmsg ("missing bridge domain");
6762       return -99;
6763     }
6764
6765   M (L2FIB_FLUSH_BD, mp);
6766
6767   mp->bd_id = htonl (bd_id);
6768
6769   S (mp);
6770   W (ret);
6771   return ret;
6772 }
6773
6774 static int
6775 api_l2fib_flush_int (vat_main_t * vam)
6776 {
6777   unformat_input_t *i = vam->input;
6778   vl_api_l2fib_flush_int_t *mp;
6779   u32 sw_if_index = ~0;
6780   int ret;
6781
6782   /* Parse args required to build the message */
6783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6784     {
6785       if (unformat (i, "sw_if_index %d", &sw_if_index));
6786       else
6787         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6788       else
6789         break;
6790     }
6791
6792   if (sw_if_index == ~0)
6793     {
6794       errmsg ("missing interface name or sw_if_index");
6795       return -99;
6796     }
6797
6798   M (L2FIB_FLUSH_INT, mp);
6799
6800   mp->sw_if_index = ntohl (sw_if_index);
6801
6802   S (mp);
6803   W (ret);
6804   return ret;
6805 }
6806
6807 static int
6808 api_l2fib_add_del (vat_main_t * vam)
6809 {
6810   unformat_input_t *i = vam->input;
6811   vl_api_l2fib_add_del_t *mp;
6812   f64 timeout;
6813   u8 mac[6] = { 0 };
6814   u8 mac_set = 0;
6815   u32 bd_id;
6816   u8 bd_id_set = 0;
6817   u32 sw_if_index = 0;
6818   u8 sw_if_index_set = 0;
6819   u8 is_add = 1;
6820   u8 static_mac = 0;
6821   u8 filter_mac = 0;
6822   u8 bvi_mac = 0;
6823   int count = 1;
6824   f64 before = 0;
6825   int j;
6826
6827   /* Parse args required to build the message */
6828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6829     {
6830       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6831         mac_set = 1;
6832       else if (unformat (i, "bd_id %d", &bd_id))
6833         bd_id_set = 1;
6834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6835         sw_if_index_set = 1;
6836       else if (unformat (i, "sw_if"))
6837         {
6838           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6839             {
6840               if (unformat
6841                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6842                 sw_if_index_set = 1;
6843             }
6844           else
6845             break;
6846         }
6847       else if (unformat (i, "static"))
6848         static_mac = 1;
6849       else if (unformat (i, "filter"))
6850         {
6851           filter_mac = 1;
6852           static_mac = 1;
6853         }
6854       else if (unformat (i, "bvi"))
6855         {
6856           bvi_mac = 1;
6857           static_mac = 1;
6858         }
6859       else if (unformat (i, "del"))
6860         is_add = 0;
6861       else if (unformat (i, "count %d", &count))
6862         ;
6863       else
6864         break;
6865     }
6866
6867   if (mac_set == 0)
6868     {
6869       errmsg ("missing mac address");
6870       return -99;
6871     }
6872
6873   if (bd_id_set == 0)
6874     {
6875       errmsg ("missing bridge domain");
6876       return -99;
6877     }
6878
6879   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6880     {
6881       errmsg ("missing interface name or sw_if_index");
6882       return -99;
6883     }
6884
6885   if (count > 1)
6886     {
6887       /* Turn on async mode */
6888       vam->async_mode = 1;
6889       vam->async_errors = 0;
6890       before = vat_time_now (vam);
6891     }
6892
6893   for (j = 0; j < count; j++)
6894     {
6895       M (L2FIB_ADD_DEL, mp);
6896
6897       clib_memcpy (mp->mac, mac, 6);
6898       mp->bd_id = ntohl (bd_id);
6899       mp->is_add = is_add;
6900       mp->sw_if_index = ntohl (sw_if_index);
6901
6902       if (is_add)
6903         {
6904           mp->static_mac = static_mac;
6905           mp->filter_mac = filter_mac;
6906           mp->bvi_mac = bvi_mac;
6907         }
6908       increment_mac_address (mac);
6909       /* send it... */
6910       S (mp);
6911     }
6912
6913   if (count > 1)
6914     {
6915       vl_api_control_ping_t *mp_ping;
6916       f64 after;
6917
6918       /* Shut off async mode */
6919       vam->async_mode = 0;
6920
6921       MPING (CONTROL_PING, mp_ping);
6922       S (mp_ping);
6923
6924       timeout = vat_time_now (vam) + 1.0;
6925       while (vat_time_now (vam) < timeout)
6926         if (vam->result_ready == 1)
6927           goto out;
6928       vam->retval = -99;
6929
6930     out:
6931       if (vam->retval == -99)
6932         errmsg ("timeout");
6933
6934       if (vam->async_errors > 0)
6935         {
6936           errmsg ("%d asynchronous errors", vam->async_errors);
6937           vam->retval = -98;
6938         }
6939       vam->async_errors = 0;
6940       after = vat_time_now (vam);
6941
6942       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6943              count, after - before, count / (after - before));
6944     }
6945   else
6946     {
6947       int ret;
6948
6949       /* Wait for a reply... */
6950       W (ret);
6951       return ret;
6952     }
6953   /* Return the good/bad news */
6954   return (vam->retval);
6955 }
6956
6957 static int
6958 api_bridge_domain_set_mac_age (vat_main_t * vam)
6959 {
6960   unformat_input_t *i = vam->input;
6961   vl_api_bridge_domain_set_mac_age_t *mp;
6962   u32 bd_id = ~0;
6963   u32 mac_age = 0;
6964   int ret;
6965
6966   /* Parse args required to build the message */
6967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6968     {
6969       if (unformat (i, "bd_id %d", &bd_id));
6970       else if (unformat (i, "mac-age %d", &mac_age));
6971       else
6972         break;
6973     }
6974
6975   if (bd_id == ~0)
6976     {
6977       errmsg ("missing bridge domain");
6978       return -99;
6979     }
6980
6981   if (mac_age > 255)
6982     {
6983       errmsg ("mac age must be less than 256 ");
6984       return -99;
6985     }
6986
6987   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6988
6989   mp->bd_id = htonl (bd_id);
6990   mp->mac_age = (u8) mac_age;
6991
6992   S (mp);
6993   W (ret);
6994   return ret;
6995 }
6996
6997 static int
6998 api_l2_flags (vat_main_t * vam)
6999 {
7000   unformat_input_t *i = vam->input;
7001   vl_api_l2_flags_t *mp;
7002   u32 sw_if_index;
7003   u32 flags = 0;
7004   u8 sw_if_index_set = 0;
7005   u8 is_set = 0;
7006   int ret;
7007
7008   /* Parse args required to build the message */
7009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7010     {
7011       if (unformat (i, "sw_if_index %d", &sw_if_index))
7012         sw_if_index_set = 1;
7013       else if (unformat (i, "sw_if"))
7014         {
7015           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7016             {
7017               if (unformat
7018                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7019                 sw_if_index_set = 1;
7020             }
7021           else
7022             break;
7023         }
7024       else if (unformat (i, "learn"))
7025         flags |= L2_LEARN;
7026       else if (unformat (i, "forward"))
7027         flags |= L2_FWD;
7028       else if (unformat (i, "flood"))
7029         flags |= L2_FLOOD;
7030       else if (unformat (i, "uu-flood"))
7031         flags |= L2_UU_FLOOD;
7032       else if (unformat (i, "arp-term"))
7033         flags |= L2_ARP_TERM;
7034       else if (unformat (i, "off"))
7035         is_set = 0;
7036       else if (unformat (i, "disable"))
7037         is_set = 0;
7038       else
7039         break;
7040     }
7041
7042   if (sw_if_index_set == 0)
7043     {
7044       errmsg ("missing interface name or sw_if_index");
7045       return -99;
7046     }
7047
7048   M (L2_FLAGS, mp);
7049
7050   mp->sw_if_index = ntohl (sw_if_index);
7051   mp->feature_bitmap = ntohl (flags);
7052   mp->is_set = is_set;
7053
7054   S (mp);
7055   W (ret);
7056   return ret;
7057 }
7058
7059 static int
7060 api_bridge_flags (vat_main_t * vam)
7061 {
7062   unformat_input_t *i = vam->input;
7063   vl_api_bridge_flags_t *mp;
7064   u32 bd_id;
7065   u8 bd_id_set = 0;
7066   u8 is_set = 1;
7067   bd_flags_t flags = 0;
7068   int ret;
7069
7070   /* Parse args required to build the message */
7071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072     {
7073       if (unformat (i, "bd_id %d", &bd_id))
7074         bd_id_set = 1;
7075       else if (unformat (i, "learn"))
7076         flags |= BRIDGE_API_FLAG_LEARN;
7077       else if (unformat (i, "forward"))
7078         flags |= BRIDGE_API_FLAG_FWD;
7079       else if (unformat (i, "flood"))
7080         flags |= BRIDGE_API_FLAG_FLOOD;
7081       else if (unformat (i, "uu-flood"))
7082         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7083       else if (unformat (i, "arp-term"))
7084         flags |= BRIDGE_API_FLAG_ARP_TERM;
7085       else if (unformat (i, "off"))
7086         is_set = 0;
7087       else if (unformat (i, "disable"))
7088         is_set = 0;
7089       else
7090         break;
7091     }
7092
7093   if (bd_id_set == 0)
7094     {
7095       errmsg ("missing bridge domain");
7096       return -99;
7097     }
7098
7099   M (BRIDGE_FLAGS, mp);
7100
7101   mp->bd_id = ntohl (bd_id);
7102   mp->flags = ntohl (flags);
7103   mp->is_set = is_set;
7104
7105   S (mp);
7106   W (ret);
7107   return ret;
7108 }
7109
7110 static int
7111 api_bd_ip_mac_add_del (vat_main_t * vam)
7112 {
7113   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7114   vl_api_mac_address_t mac = { 0 };
7115   unformat_input_t *i = vam->input;
7116   vl_api_bd_ip_mac_add_del_t *mp;
7117   u32 bd_id;
7118   u8 is_add = 1;
7119   u8 bd_id_set = 0;
7120   u8 ip_set = 0;
7121   u8 mac_set = 0;
7122   int ret;
7123
7124
7125   /* Parse args required to build the message */
7126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7127     {
7128       if (unformat (i, "bd_id %d", &bd_id))
7129         {
7130           bd_id_set++;
7131         }
7132       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7133         {
7134           ip_set++;
7135         }
7136       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7137         {
7138           mac_set++;
7139         }
7140       else if (unformat (i, "del"))
7141         is_add = 0;
7142       else
7143         break;
7144     }
7145
7146   if (bd_id_set == 0)
7147     {
7148       errmsg ("missing bridge domain");
7149       return -99;
7150     }
7151   else if (ip_set == 0)
7152     {
7153       errmsg ("missing IP address");
7154       return -99;
7155     }
7156   else if (mac_set == 0)
7157     {
7158       errmsg ("missing MAC address");
7159       return -99;
7160     }
7161
7162   M (BD_IP_MAC_ADD_DEL, mp);
7163
7164   mp->entry.bd_id = ntohl (bd_id);
7165   mp->is_add = is_add;
7166
7167   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7168   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7169
7170   S (mp);
7171   W (ret);
7172   return ret;
7173 }
7174
7175 static int
7176 api_bd_ip_mac_flush (vat_main_t * vam)
7177 {
7178   unformat_input_t *i = vam->input;
7179   vl_api_bd_ip_mac_flush_t *mp;
7180   u32 bd_id;
7181   u8 bd_id_set = 0;
7182   int ret;
7183
7184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7185     {
7186       if (unformat (i, "bd_id %d", &bd_id))
7187         {
7188           bd_id_set++;
7189         }
7190       else
7191         break;
7192     }
7193
7194   if (bd_id_set == 0)
7195     {
7196       errmsg ("missing bridge domain");
7197       return -99;
7198     }
7199
7200   M (BD_IP_MAC_FLUSH, mp);
7201
7202   mp->bd_id = ntohl (bd_id);
7203
7204   S (mp);
7205   W (ret);
7206   return ret;
7207 }
7208
7209 static void vl_api_bd_ip_mac_details_t_handler
7210   (vl_api_bd_ip_mac_details_t * mp)
7211 {
7212   vat_main_t *vam = &vat_main;
7213
7214   print (vam->ofp,
7215          "\n%-5d %U %U",
7216          ntohl (mp->entry.bd_id),
7217          format_vl_api_mac_address, mp->entry.mac,
7218          format_vl_api_address, &mp->entry.ip);
7219 }
7220
7221 static void vl_api_bd_ip_mac_details_t_handler_json
7222   (vl_api_bd_ip_mac_details_t * mp)
7223 {
7224   vat_main_t *vam = &vat_main;
7225   vat_json_node_t *node = NULL;
7226
7227   if (VAT_JSON_ARRAY != vam->json_tree.type)
7228     {
7229       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7230       vat_json_init_array (&vam->json_tree);
7231     }
7232   node = vat_json_array_add (&vam->json_tree);
7233
7234   vat_json_init_object (node);
7235   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7236   vat_json_object_add_string_copy (node, "mac_address",
7237                                    format (0, "%U", format_vl_api_mac_address,
7238                                            &mp->entry.mac));
7239   u8 *ip = 0;
7240
7241   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7242   vat_json_object_add_string_copy (node, "ip_address", ip);
7243   vec_free (ip);
7244 }
7245
7246 static int
7247 api_bd_ip_mac_dump (vat_main_t * vam)
7248 {
7249   unformat_input_t *i = vam->input;
7250   vl_api_bd_ip_mac_dump_t *mp;
7251   vl_api_control_ping_t *mp_ping;
7252   int ret;
7253   u32 bd_id;
7254   u8 bd_id_set = 0;
7255
7256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7257     {
7258       if (unformat (i, "bd_id %d", &bd_id))
7259         {
7260           bd_id_set++;
7261         }
7262       else
7263         break;
7264     }
7265
7266   print (vam->ofp,
7267          "\n%-5s %-7s %-20s %-30s",
7268          "bd_id", "is_ipv6", "mac_address", "ip_address");
7269
7270   /* Dump Bridge Domain Ip to Mac entries */
7271   M (BD_IP_MAC_DUMP, mp);
7272
7273   if (bd_id_set)
7274     mp->bd_id = htonl (bd_id);
7275   else
7276     mp->bd_id = ~0;
7277
7278   S (mp);
7279
7280   /* Use a control ping for synchronization */
7281   MPING (CONTROL_PING, mp_ping);
7282   S (mp_ping);
7283
7284   W (ret);
7285   return ret;
7286 }
7287
7288 static int
7289 api_tap_create_v2 (vat_main_t * vam)
7290 {
7291   unformat_input_t *i = vam->input;
7292   vl_api_tap_create_v2_t *mp;
7293   u8 mac_address[6];
7294   u8 random_mac = 1;
7295   u32 id = ~0;
7296   u32 num_rx_queues = 0;
7297   u8 *host_if_name = 0;
7298   u8 host_if_name_set = 0;
7299   u8 *host_ns = 0;
7300   u8 host_ns_set = 0;
7301   u8 host_mac_addr[6];
7302   u8 host_mac_addr_set = 0;
7303   u8 *host_bridge = 0;
7304   u8 host_bridge_set = 0;
7305   u8 host_ip4_prefix_set = 0;
7306   u8 host_ip6_prefix_set = 0;
7307   ip4_address_t host_ip4_addr;
7308   ip4_address_t host_ip4_gw;
7309   u8 host_ip4_gw_set = 0;
7310   u32 host_ip4_prefix_len = 0;
7311   ip6_address_t host_ip6_addr;
7312   ip6_address_t host_ip6_gw;
7313   u8 host_ip6_gw_set = 0;
7314   u32 host_ip6_prefix_len = 0;
7315   u32 host_mtu_size = 0;
7316   u8 host_mtu_set = 0;
7317   u32 tap_flags = 0;
7318   int ret;
7319   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7320
7321   clib_memset (mac_address, 0, sizeof (mac_address));
7322
7323   /* Parse args required to build the message */
7324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7325     {
7326       if (unformat (i, "id %u", &id))
7327         ;
7328       else
7329         if (unformat
7330             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7331         random_mac = 0;
7332       else if (unformat (i, "host-if-name %s", &host_if_name))
7333         host_if_name_set = 1;
7334       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7335         ;
7336       else if (unformat (i, "host-ns %s", &host_ns))
7337         host_ns_set = 1;
7338       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7339                          host_mac_addr))
7340         host_mac_addr_set = 1;
7341       else if (unformat (i, "host-bridge %s", &host_bridge))
7342         host_bridge_set = 1;
7343       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7344                          &host_ip4_addr, &host_ip4_prefix_len))
7345         host_ip4_prefix_set = 1;
7346       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7347                          &host_ip6_addr, &host_ip6_prefix_len))
7348         host_ip6_prefix_set = 1;
7349       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7350                          &host_ip4_gw))
7351         host_ip4_gw_set = 1;
7352       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7353                          &host_ip6_gw))
7354         host_ip6_gw_set = 1;
7355       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7356         ;
7357       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7358         ;
7359       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7360         host_mtu_set = 1;
7361       else if (unformat (i, "no-gso"))
7362         tap_flags &= ~TAP_API_FLAG_GSO;
7363       else if (unformat (i, "gso"))
7364         tap_flags |= TAP_API_FLAG_GSO;
7365       else if (unformat (i, "csum-offload"))
7366         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7367       else if (unformat (i, "persist"))
7368         tap_flags |= TAP_API_FLAG_PERSIST;
7369       else if (unformat (i, "attach"))
7370         tap_flags |= TAP_API_FLAG_ATTACH;
7371       else if (unformat (i, "tun"))
7372         tap_flags |= TAP_API_FLAG_TUN;
7373       else if (unformat (i, "gro-coalesce"))
7374         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7375       else
7376         break;
7377     }
7378
7379   if (vec_len (host_if_name) > 63)
7380     {
7381       errmsg ("tap name too long. ");
7382       return -99;
7383     }
7384   if (vec_len (host_ns) > 63)
7385     {
7386       errmsg ("host name space too long. ");
7387       return -99;
7388     }
7389   if (vec_len (host_bridge) > 63)
7390     {
7391       errmsg ("host bridge name too long. ");
7392       return -99;
7393     }
7394   if (host_ip4_prefix_len > 32)
7395     {
7396       errmsg ("host ip4 prefix length not valid. ");
7397       return -99;
7398     }
7399   if (host_ip6_prefix_len > 128)
7400     {
7401       errmsg ("host ip6 prefix length not valid. ");
7402       return -99;
7403     }
7404   if (!is_pow2 (rx_ring_sz))
7405     {
7406       errmsg ("rx ring size must be power of 2. ");
7407       return -99;
7408     }
7409   if (rx_ring_sz > 32768)
7410     {
7411       errmsg ("rx ring size must be 32768 or lower. ");
7412       return -99;
7413     }
7414   if (!is_pow2 (tx_ring_sz))
7415     {
7416       errmsg ("tx ring size must be power of 2. ");
7417       return -99;
7418     }
7419   if (tx_ring_sz > 32768)
7420     {
7421       errmsg ("tx ring size must be 32768 or lower. ");
7422       return -99;
7423     }
7424   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7425     {
7426       errmsg ("host MTU size must be in between 64 and 65355. ");
7427       return -99;
7428     }
7429
7430   /* Construct the API message */
7431   M (TAP_CREATE_V2, mp);
7432
7433   mp->id = ntohl (id);
7434   mp->use_random_mac = random_mac;
7435   mp->num_rx_queues = (u8) num_rx_queues;
7436   mp->tx_ring_sz = ntohs (tx_ring_sz);
7437   mp->rx_ring_sz = ntohs (rx_ring_sz);
7438   mp->host_mtu_set = host_mtu_set;
7439   mp->host_mtu_size = ntohl (host_mtu_size);
7440   mp->host_mac_addr_set = host_mac_addr_set;
7441   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7442   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7443   mp->host_ip4_gw_set = host_ip4_gw_set;
7444   mp->host_ip6_gw_set = host_ip6_gw_set;
7445   mp->tap_flags = ntohl (tap_flags);
7446   mp->host_namespace_set = host_ns_set;
7447   mp->host_if_name_set = host_if_name_set;
7448   mp->host_bridge_set = host_bridge_set;
7449
7450   if (random_mac == 0)
7451     clib_memcpy (mp->mac_address, mac_address, 6);
7452   if (host_mac_addr_set)
7453     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7454   if (host_if_name_set)
7455     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7456   if (host_ns_set)
7457     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7458   if (host_bridge_set)
7459     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7460   if (host_ip4_prefix_set)
7461     {
7462       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7463       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7464     }
7465   if (host_ip6_prefix_set)
7466     {
7467       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7468       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7469     }
7470   if (host_ip4_gw_set)
7471     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7472   if (host_ip6_gw_set)
7473     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7474
7475   vec_free (host_ns);
7476   vec_free (host_if_name);
7477   vec_free (host_bridge);
7478
7479   /* send it... */
7480   S (mp);
7481
7482   /* Wait for a reply... */
7483   W (ret);
7484   return ret;
7485 }
7486
7487 static int
7488 api_tap_delete_v2 (vat_main_t * vam)
7489 {
7490   unformat_input_t *i = vam->input;
7491   vl_api_tap_delete_v2_t *mp;
7492   u32 sw_if_index = ~0;
7493   u8 sw_if_index_set = 0;
7494   int ret;
7495
7496   /* Parse args required to build the message */
7497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7498     {
7499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7500         sw_if_index_set = 1;
7501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7502         sw_if_index_set = 1;
7503       else
7504         break;
7505     }
7506
7507   if (sw_if_index_set == 0)
7508     {
7509       errmsg ("missing vpp interface name. ");
7510       return -99;
7511     }
7512
7513   /* Construct the API message */
7514   M (TAP_DELETE_V2, mp);
7515
7516   mp->sw_if_index = ntohl (sw_if_index);
7517
7518   /* send it... */
7519   S (mp);
7520
7521   /* Wait for a reply... */
7522   W (ret);
7523   return ret;
7524 }
7525
7526 uword
7527 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7528 {
7529   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7530   u32 x[4];
7531
7532   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7533     return 0;
7534
7535   addr->domain = x[0];
7536   addr->bus = x[1];
7537   addr->slot = x[2];
7538   addr->function = x[3];
7539
7540   return 1;
7541 }
7542
7543 static int
7544 api_virtio_pci_create (vat_main_t * vam)
7545 {
7546   unformat_input_t *i = vam->input;
7547   vl_api_virtio_pci_create_t *mp;
7548   u8 mac_address[6];
7549   u8 random_mac = 1;
7550   u8 gso_enabled = 0;
7551   u8 checksum_offload_enabled = 0;
7552   u32 pci_addr = 0;
7553   u64 features = (u64) ~ (0ULL);
7554   int ret;
7555
7556   clib_memset (mac_address, 0, sizeof (mac_address));
7557
7558   /* Parse args required to build the message */
7559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7560     {
7561       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7562         {
7563           random_mac = 0;
7564         }
7565       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7566         ;
7567       else if (unformat (i, "features 0x%llx", &features))
7568         ;
7569       else if (unformat (i, "gso-enabled"))
7570         gso_enabled = 1;
7571       else if (unformat (i, "csum-offload-enabled"))
7572         checksum_offload_enabled = 1;
7573       else
7574         break;
7575     }
7576
7577   if (pci_addr == 0)
7578     {
7579       errmsg ("pci address must be non zero. ");
7580       return -99;
7581     }
7582
7583   /* Construct the API message */
7584   M (VIRTIO_PCI_CREATE, mp);
7585
7586   mp->use_random_mac = random_mac;
7587
7588   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7589   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7590   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7591   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7592
7593   mp->features = clib_host_to_net_u64 (features);
7594   mp->gso_enabled = gso_enabled;
7595   mp->checksum_offload_enabled = checksum_offload_enabled;
7596
7597   if (random_mac == 0)
7598     clib_memcpy (mp->mac_address, mac_address, 6);
7599
7600   /* send it... */
7601   S (mp);
7602
7603   /* Wait for a reply... */
7604   W (ret);
7605   return ret;
7606 }
7607
7608 static int
7609 api_virtio_pci_delete (vat_main_t * vam)
7610 {
7611   unformat_input_t *i = vam->input;
7612   vl_api_virtio_pci_delete_t *mp;
7613   u32 sw_if_index = ~0;
7614   u8 sw_if_index_set = 0;
7615   int ret;
7616
7617   /* Parse args required to build the message */
7618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7619     {
7620       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7621         sw_if_index_set = 1;
7622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7623         sw_if_index_set = 1;
7624       else
7625         break;
7626     }
7627
7628   if (sw_if_index_set == 0)
7629     {
7630       errmsg ("missing vpp interface name. ");
7631       return -99;
7632     }
7633
7634   /* Construct the API message */
7635   M (VIRTIO_PCI_DELETE, mp);
7636
7637   mp->sw_if_index = htonl (sw_if_index);
7638
7639   /* send it... */
7640   S (mp);
7641
7642   /* Wait for a reply... */
7643   W (ret);
7644   return ret;
7645 }
7646
7647 static int
7648 api_bond_create (vat_main_t * vam)
7649 {
7650   unformat_input_t *i = vam->input;
7651   vl_api_bond_create_t *mp;
7652   u8 mac_address[6];
7653   u8 custom_mac = 0;
7654   int ret;
7655   u8 mode;
7656   u8 lb;
7657   u8 mode_is_set = 0;
7658   u32 id = ~0;
7659   u8 numa_only = 0;
7660
7661   clib_memset (mac_address, 0, sizeof (mac_address));
7662   lb = BOND_LB_L2;
7663
7664   /* Parse args required to build the message */
7665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7666     {
7667       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7668         mode_is_set = 1;
7669       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7670                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7671         ;
7672       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7673                          mac_address))
7674         custom_mac = 1;
7675       else if (unformat (i, "numa-only"))
7676         numa_only = 1;
7677       else if (unformat (i, "id %u", &id))
7678         ;
7679       else
7680         break;
7681     }
7682
7683   if (mode_is_set == 0)
7684     {
7685       errmsg ("Missing bond mode. ");
7686       return -99;
7687     }
7688
7689   /* Construct the API message */
7690   M (BOND_CREATE, mp);
7691
7692   mp->use_custom_mac = custom_mac;
7693
7694   mp->mode = htonl (mode);
7695   mp->lb = htonl (lb);
7696   mp->id = htonl (id);
7697   mp->numa_only = numa_only;
7698
7699   if (custom_mac)
7700     clib_memcpy (mp->mac_address, mac_address, 6);
7701
7702   /* send it... */
7703   S (mp);
7704
7705   /* Wait for a reply... */
7706   W (ret);
7707   return ret;
7708 }
7709
7710 static int
7711 api_bond_delete (vat_main_t * vam)
7712 {
7713   unformat_input_t *i = vam->input;
7714   vl_api_bond_delete_t *mp;
7715   u32 sw_if_index = ~0;
7716   u8 sw_if_index_set = 0;
7717   int ret;
7718
7719   /* Parse args required to build the message */
7720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7721     {
7722       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7723         sw_if_index_set = 1;
7724       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7725         sw_if_index_set = 1;
7726       else
7727         break;
7728     }
7729
7730   if (sw_if_index_set == 0)
7731     {
7732       errmsg ("missing vpp interface name. ");
7733       return -99;
7734     }
7735
7736   /* Construct the API message */
7737   M (BOND_DELETE, mp);
7738
7739   mp->sw_if_index = ntohl (sw_if_index);
7740
7741   /* send it... */
7742   S (mp);
7743
7744   /* Wait for a reply... */
7745   W (ret);
7746   return ret;
7747 }
7748
7749 static int
7750 api_bond_enslave (vat_main_t * vam)
7751 {
7752   unformat_input_t *i = vam->input;
7753   vl_api_bond_enslave_t *mp;
7754   u32 bond_sw_if_index;
7755   int ret;
7756   u8 is_passive;
7757   u8 is_long_timeout;
7758   u32 bond_sw_if_index_is_set = 0;
7759   u32 sw_if_index;
7760   u8 sw_if_index_is_set = 0;
7761
7762   /* Parse args required to build the message */
7763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7764     {
7765       if (unformat (i, "sw_if_index %d", &sw_if_index))
7766         sw_if_index_is_set = 1;
7767       else if (unformat (i, "bond %u", &bond_sw_if_index))
7768         bond_sw_if_index_is_set = 1;
7769       else if (unformat (i, "passive %d", &is_passive))
7770         ;
7771       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7772         ;
7773       else
7774         break;
7775     }
7776
7777   if (bond_sw_if_index_is_set == 0)
7778     {
7779       errmsg ("Missing bond sw_if_index. ");
7780       return -99;
7781     }
7782   if (sw_if_index_is_set == 0)
7783     {
7784       errmsg ("Missing slave sw_if_index. ");
7785       return -99;
7786     }
7787
7788   /* Construct the API message */
7789   M (BOND_ENSLAVE, mp);
7790
7791   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7792   mp->sw_if_index = ntohl (sw_if_index);
7793   mp->is_long_timeout = is_long_timeout;
7794   mp->is_passive = is_passive;
7795
7796   /* send it... */
7797   S (mp);
7798
7799   /* Wait for a reply... */
7800   W (ret);
7801   return ret;
7802 }
7803
7804 static int
7805 api_bond_detach_slave (vat_main_t * vam)
7806 {
7807   unformat_input_t *i = vam->input;
7808   vl_api_bond_detach_slave_t *mp;
7809   u32 sw_if_index = ~0;
7810   u8 sw_if_index_set = 0;
7811   int ret;
7812
7813   /* Parse args required to build the message */
7814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7815     {
7816       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7817         sw_if_index_set = 1;
7818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7819         sw_if_index_set = 1;
7820       else
7821         break;
7822     }
7823
7824   if (sw_if_index_set == 0)
7825     {
7826       errmsg ("missing vpp interface name. ");
7827       return -99;
7828     }
7829
7830   /* Construct the API message */
7831   M (BOND_DETACH_SLAVE, mp);
7832
7833   mp->sw_if_index = ntohl (sw_if_index);
7834
7835   /* send it... */
7836   S (mp);
7837
7838   /* Wait for a reply... */
7839   W (ret);
7840   return ret;
7841 }
7842
7843 static int
7844 api_ip_table_add_del (vat_main_t * vam)
7845 {
7846   unformat_input_t *i = vam->input;
7847   vl_api_ip_table_add_del_t *mp;
7848   u32 table_id = ~0;
7849   u8 is_ipv6 = 0;
7850   u8 is_add = 1;
7851   int ret = 0;
7852
7853   /* Parse args required to build the message */
7854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7855     {
7856       if (unformat (i, "ipv6"))
7857         is_ipv6 = 1;
7858       else if (unformat (i, "del"))
7859         is_add = 0;
7860       else if (unformat (i, "add"))
7861         is_add = 1;
7862       else if (unformat (i, "table %d", &table_id))
7863         ;
7864       else
7865         {
7866           clib_warning ("parse error '%U'", format_unformat_error, i);
7867           return -99;
7868         }
7869     }
7870
7871   if (~0 == table_id)
7872     {
7873       errmsg ("missing table-ID");
7874       return -99;
7875     }
7876
7877   /* Construct the API message */
7878   M (IP_TABLE_ADD_DEL, mp);
7879
7880   mp->table.table_id = ntohl (table_id);
7881   mp->table.is_ip6 = is_ipv6;
7882   mp->is_add = is_add;
7883
7884   /* send it... */
7885   S (mp);
7886
7887   /* Wait for a reply... */
7888   W (ret);
7889
7890   return ret;
7891 }
7892
7893 uword
7894 unformat_fib_path (unformat_input_t * input, va_list * args)
7895 {
7896   vat_main_t *vam = va_arg (*args, vat_main_t *);
7897   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7898   u32 weight, preference;
7899   mpls_label_t out_label;
7900
7901   clib_memset (path, 0, sizeof (*path));
7902   path->weight = 1;
7903   path->sw_if_index = ~0;
7904   path->rpf_id = ~0;
7905   path->n_labels = 0;
7906
7907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7908     {
7909       if (unformat (input, "%U %U",
7910                     unformat_vl_api_ip4_address,
7911                     &path->nh.address.ip4,
7912                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7913         {
7914           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7915         }
7916       else if (unformat (input, "%U %U",
7917                          unformat_vl_api_ip6_address,
7918                          &path->nh.address.ip6,
7919                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7920         {
7921           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7922         }
7923       else if (unformat (input, "weight %u", &weight))
7924         {
7925           path->weight = weight;
7926         }
7927       else if (unformat (input, "preference %u", &preference))
7928         {
7929           path->preference = preference;
7930         }
7931       else if (unformat (input, "%U next-hop-table %d",
7932                          unformat_vl_api_ip4_address,
7933                          &path->nh.address.ip4, &path->table_id))
7934         {
7935           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7936         }
7937       else if (unformat (input, "%U next-hop-table %d",
7938                          unformat_vl_api_ip6_address,
7939                          &path->nh.address.ip6, &path->table_id))
7940         {
7941           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7942         }
7943       else if (unformat (input, "%U",
7944                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7945         {
7946           /*
7947            * the recursive next-hops are by default in the default table
7948            */
7949           path->table_id = 0;
7950           path->sw_if_index = ~0;
7951           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7952         }
7953       else if (unformat (input, "%U",
7954                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7955         {
7956           /*
7957            * the recursive next-hops are by default in the default table
7958            */
7959           path->table_id = 0;
7960           path->sw_if_index = ~0;
7961           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7962         }
7963       else if (unformat (input, "resolve-via-host"))
7964         {
7965           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7966         }
7967       else if (unformat (input, "resolve-via-attached"))
7968         {
7969           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7970         }
7971       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7972         {
7973           path->type = FIB_API_PATH_TYPE_LOCAL;
7974           path->sw_if_index = ~0;
7975           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7976         }
7977       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7978         {
7979           path->type = FIB_API_PATH_TYPE_LOCAL;
7980           path->sw_if_index = ~0;
7981           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7982         }
7983       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7984         ;
7985       else if (unformat (input, "via-label %d", &path->nh.via_label))
7986         {
7987           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7988           path->sw_if_index = ~0;
7989         }
7990       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7991         {
7992           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7993           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7994         }
7995       else if (unformat (input, "local"))
7996         {
7997           path->type = FIB_API_PATH_TYPE_LOCAL;
7998         }
7999       else if (unformat (input, "out-labels"))
8000         {
8001           while (unformat (input, "%d", &out_label))
8002             {
8003               path->label_stack[path->n_labels].label = out_label;
8004               path->label_stack[path->n_labels].is_uniform = 0;
8005               path->label_stack[path->n_labels].ttl = 64;
8006               path->n_labels++;
8007             }
8008         }
8009       else if (unformat (input, "via"))
8010         {
8011           /* new path, back up and return */
8012           unformat_put_input (input);
8013           unformat_put_input (input);
8014           unformat_put_input (input);
8015           unformat_put_input (input);
8016           break;
8017         }
8018       else
8019         {
8020           return (0);
8021         }
8022     }
8023
8024   path->proto = ntohl (path->proto);
8025   path->type = ntohl (path->type);
8026   path->flags = ntohl (path->flags);
8027   path->table_id = ntohl (path->table_id);
8028   path->sw_if_index = ntohl (path->sw_if_index);
8029
8030   return (1);
8031 }
8032
8033 static int
8034 api_ip_route_add_del (vat_main_t * vam)
8035 {
8036   unformat_input_t *i = vam->input;
8037   vl_api_ip_route_add_del_t *mp;
8038   u32 vrf_id = 0;
8039   u8 is_add = 1;
8040   u8 is_multipath = 0;
8041   u8 prefix_set = 0;
8042   u8 path_count = 0;
8043   vl_api_prefix_t pfx = { };
8044   vl_api_fib_path_t paths[8];
8045   int count = 1;
8046   int j;
8047   f64 before = 0;
8048   u32 random_add_del = 0;
8049   u32 *random_vector = 0;
8050   u32 random_seed = 0xdeaddabe;
8051
8052   /* Parse args required to build the message */
8053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8054     {
8055       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8056         prefix_set = 1;
8057       else if (unformat (i, "del"))
8058         is_add = 0;
8059       else if (unformat (i, "add"))
8060         is_add = 1;
8061       else if (unformat (i, "vrf %d", &vrf_id))
8062         ;
8063       else if (unformat (i, "count %d", &count))
8064         ;
8065       else if (unformat (i, "random"))
8066         random_add_del = 1;
8067       else if (unformat (i, "multipath"))
8068         is_multipath = 1;
8069       else if (unformat (i, "seed %d", &random_seed))
8070         ;
8071       else
8072         if (unformat
8073             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8074         {
8075           path_count++;
8076           if (8 == path_count)
8077             {
8078               errmsg ("max 8 paths");
8079               return -99;
8080             }
8081         }
8082       else
8083         {
8084           clib_warning ("parse error '%U'", format_unformat_error, i);
8085           return -99;
8086         }
8087     }
8088
8089   if (!path_count)
8090     {
8091       errmsg ("specify a path; via ...");
8092       return -99;
8093     }
8094   if (prefix_set == 0)
8095     {
8096       errmsg ("missing prefix");
8097       return -99;
8098     }
8099
8100   /* Generate a pile of unique, random routes */
8101   if (random_add_del)
8102     {
8103       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8104       u32 this_random_address;
8105       uword *random_hash;
8106
8107       random_hash = hash_create (count, sizeof (uword));
8108
8109       hash_set (random_hash, i->as_u32, 1);
8110       for (j = 0; j <= count; j++)
8111         {
8112           do
8113             {
8114               this_random_address = random_u32 (&random_seed);
8115               this_random_address =
8116                 clib_host_to_net_u32 (this_random_address);
8117             }
8118           while (hash_get (random_hash, this_random_address));
8119           vec_add1 (random_vector, this_random_address);
8120           hash_set (random_hash, this_random_address, 1);
8121         }
8122       hash_free (random_hash);
8123       set_ip4_address (&pfx.address, random_vector[0]);
8124     }
8125
8126   if (count > 1)
8127     {
8128       /* Turn on async mode */
8129       vam->async_mode = 1;
8130       vam->async_errors = 0;
8131       before = vat_time_now (vam);
8132     }
8133
8134   for (j = 0; j < count; j++)
8135     {
8136       /* Construct the API message */
8137       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8138
8139       mp->is_add = is_add;
8140       mp->is_multipath = is_multipath;
8141
8142       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8143       mp->route.table_id = ntohl (vrf_id);
8144       mp->route.n_paths = path_count;
8145
8146       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8147
8148       if (random_add_del)
8149         set_ip4_address (&pfx.address, random_vector[j + 1]);
8150       else
8151         increment_address (&pfx.address);
8152       /* send it... */
8153       S (mp);
8154       /* If we receive SIGTERM, stop now... */
8155       if (vam->do_exit)
8156         break;
8157     }
8158
8159   /* When testing multiple add/del ops, use a control-ping to sync */
8160   if (count > 1)
8161     {
8162       vl_api_control_ping_t *mp_ping;
8163       f64 after;
8164       f64 timeout;
8165
8166       /* Shut off async mode */
8167       vam->async_mode = 0;
8168
8169       MPING (CONTROL_PING, mp_ping);
8170       S (mp_ping);
8171
8172       timeout = vat_time_now (vam) + 1.0;
8173       while (vat_time_now (vam) < timeout)
8174         if (vam->result_ready == 1)
8175           goto out;
8176       vam->retval = -99;
8177
8178     out:
8179       if (vam->retval == -99)
8180         errmsg ("timeout");
8181
8182       if (vam->async_errors > 0)
8183         {
8184           errmsg ("%d asynchronous errors", vam->async_errors);
8185           vam->retval = -98;
8186         }
8187       vam->async_errors = 0;
8188       after = vat_time_now (vam);
8189
8190       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8191       if (j > 0)
8192         count = j;
8193
8194       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8195              count, after - before, count / (after - before));
8196     }
8197   else
8198     {
8199       int ret;
8200
8201       /* Wait for a reply... */
8202       W (ret);
8203       return ret;
8204     }
8205
8206   /* Return the good/bad news */
8207   return (vam->retval);
8208 }
8209
8210 static int
8211 api_ip_mroute_add_del (vat_main_t * vam)
8212 {
8213   unformat_input_t *i = vam->input;
8214   u8 path_set = 0, prefix_set = 0, is_add = 1;
8215   vl_api_ip_mroute_add_del_t *mp;
8216   mfib_entry_flags_t eflags = 0;
8217   vl_api_mfib_path_t path;
8218   vl_api_mprefix_t pfx = { };
8219   u32 vrf_id = 0;
8220   int ret;
8221
8222   /* Parse args required to build the message */
8223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8224     {
8225       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8226         {
8227           prefix_set = 1;
8228           pfx.grp_address_length = htons (pfx.grp_address_length);
8229         }
8230       else if (unformat (i, "del"))
8231         is_add = 0;
8232       else if (unformat (i, "add"))
8233         is_add = 1;
8234       else if (unformat (i, "vrf %d", &vrf_id))
8235         ;
8236       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8237         path.itf_flags = htonl (path.itf_flags);
8238       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8239         ;
8240       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8241         path_set = 1;
8242       else
8243         {
8244           clib_warning ("parse error '%U'", format_unformat_error, i);
8245           return -99;
8246         }
8247     }
8248
8249   if (prefix_set == 0)
8250     {
8251       errmsg ("missing addresses\n");
8252       return -99;
8253     }
8254   if (path_set == 0)
8255     {
8256       errmsg ("missing path\n");
8257       return -99;
8258     }
8259
8260   /* Construct the API message */
8261   M (IP_MROUTE_ADD_DEL, mp);
8262
8263   mp->is_add = is_add;
8264   mp->is_multipath = 1;
8265
8266   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8267   mp->route.table_id = htonl (vrf_id);
8268   mp->route.n_paths = 1;
8269   mp->route.entry_flags = htonl (eflags);
8270
8271   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8272
8273   /* send it... */
8274   S (mp);
8275   /* Wait for a reply... */
8276   W (ret);
8277   return ret;
8278 }
8279
8280 static int
8281 api_mpls_table_add_del (vat_main_t * vam)
8282 {
8283   unformat_input_t *i = vam->input;
8284   vl_api_mpls_table_add_del_t *mp;
8285   u32 table_id = ~0;
8286   u8 is_add = 1;
8287   int ret = 0;
8288
8289   /* Parse args required to build the message */
8290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8291     {
8292       if (unformat (i, "table %d", &table_id))
8293         ;
8294       else if (unformat (i, "del"))
8295         is_add = 0;
8296       else if (unformat (i, "add"))
8297         is_add = 1;
8298       else
8299         {
8300           clib_warning ("parse error '%U'", format_unformat_error, i);
8301           return -99;
8302         }
8303     }
8304
8305   if (~0 == table_id)
8306     {
8307       errmsg ("missing table-ID");
8308       return -99;
8309     }
8310
8311   /* Construct the API message */
8312   M (MPLS_TABLE_ADD_DEL, mp);
8313
8314   mp->mt_table.mt_table_id = ntohl (table_id);
8315   mp->mt_is_add = is_add;
8316
8317   /* send it... */
8318   S (mp);
8319
8320   /* Wait for a reply... */
8321   W (ret);
8322
8323   return ret;
8324 }
8325
8326 static int
8327 api_mpls_route_add_del (vat_main_t * vam)
8328 {
8329   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8330   mpls_label_t local_label = MPLS_LABEL_INVALID;
8331   unformat_input_t *i = vam->input;
8332   vl_api_mpls_route_add_del_t *mp;
8333   vl_api_fib_path_t paths[8];
8334   int count = 1, j;
8335   f64 before = 0;
8336
8337   /* Parse args required to build the message */
8338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8339     {
8340       if (unformat (i, "%d", &local_label))
8341         ;
8342       else if (unformat (i, "eos"))
8343         is_eos = 1;
8344       else if (unformat (i, "non-eos"))
8345         is_eos = 0;
8346       else if (unformat (i, "del"))
8347         is_add = 0;
8348       else if (unformat (i, "add"))
8349         is_add = 1;
8350       else if (unformat (i, "multipath"))
8351         is_multipath = 1;
8352       else if (unformat (i, "count %d", &count))
8353         ;
8354       else
8355         if (unformat
8356             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8357         {
8358           path_count++;
8359           if (8 == path_count)
8360             {
8361               errmsg ("max 8 paths");
8362               return -99;
8363             }
8364         }
8365       else
8366         {
8367           clib_warning ("parse error '%U'", format_unformat_error, i);
8368           return -99;
8369         }
8370     }
8371
8372   if (!path_count)
8373     {
8374       errmsg ("specify a path; via ...");
8375       return -99;
8376     }
8377
8378   if (MPLS_LABEL_INVALID == local_label)
8379     {
8380       errmsg ("missing label");
8381       return -99;
8382     }
8383
8384   if (count > 1)
8385     {
8386       /* Turn on async mode */
8387       vam->async_mode = 1;
8388       vam->async_errors = 0;
8389       before = vat_time_now (vam);
8390     }
8391
8392   for (j = 0; j < count; j++)
8393     {
8394       /* Construct the API message */
8395       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8396
8397       mp->mr_is_add = is_add;
8398       mp->mr_is_multipath = is_multipath;
8399
8400       mp->mr_route.mr_label = local_label;
8401       mp->mr_route.mr_eos = is_eos;
8402       mp->mr_route.mr_table_id = 0;
8403       mp->mr_route.mr_n_paths = path_count;
8404
8405       clib_memcpy (&mp->mr_route.mr_paths, paths,
8406                    sizeof (paths[0]) * path_count);
8407
8408       local_label++;
8409
8410       /* send it... */
8411       S (mp);
8412       /* If we receive SIGTERM, stop now... */
8413       if (vam->do_exit)
8414         break;
8415     }
8416
8417   /* When testing multiple add/del ops, use a control-ping to sync */
8418   if (count > 1)
8419     {
8420       vl_api_control_ping_t *mp_ping;
8421       f64 after;
8422       f64 timeout;
8423
8424       /* Shut off async mode */
8425       vam->async_mode = 0;
8426
8427       MPING (CONTROL_PING, mp_ping);
8428       S (mp_ping);
8429
8430       timeout = vat_time_now (vam) + 1.0;
8431       while (vat_time_now (vam) < timeout)
8432         if (vam->result_ready == 1)
8433           goto out;
8434       vam->retval = -99;
8435
8436     out:
8437       if (vam->retval == -99)
8438         errmsg ("timeout");
8439
8440       if (vam->async_errors > 0)
8441         {
8442           errmsg ("%d asynchronous errors", vam->async_errors);
8443           vam->retval = -98;
8444         }
8445       vam->async_errors = 0;
8446       after = vat_time_now (vam);
8447
8448       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8449       if (j > 0)
8450         count = j;
8451
8452       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8453              count, after - before, count / (after - before));
8454     }
8455   else
8456     {
8457       int ret;
8458
8459       /* Wait for a reply... */
8460       W (ret);
8461       return ret;
8462     }
8463
8464   /* Return the good/bad news */
8465   return (vam->retval);
8466   return (0);
8467 }
8468
8469 static int
8470 api_mpls_ip_bind_unbind (vat_main_t * vam)
8471 {
8472   unformat_input_t *i = vam->input;
8473   vl_api_mpls_ip_bind_unbind_t *mp;
8474   u32 ip_table_id = 0;
8475   u8 is_bind = 1;
8476   vl_api_prefix_t pfx;
8477   u8 prefix_set = 0;
8478   mpls_label_t local_label = MPLS_LABEL_INVALID;
8479   int ret;
8480
8481   /* Parse args required to build the message */
8482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8483     {
8484       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8485         prefix_set = 1;
8486       else if (unformat (i, "%d", &local_label))
8487         ;
8488       else if (unformat (i, "table-id %d", &ip_table_id))
8489         ;
8490       else if (unformat (i, "unbind"))
8491         is_bind = 0;
8492       else if (unformat (i, "bind"))
8493         is_bind = 1;
8494       else
8495         {
8496           clib_warning ("parse error '%U'", format_unformat_error, i);
8497           return -99;
8498         }
8499     }
8500
8501   if (!prefix_set)
8502     {
8503       errmsg ("IP prefix not set");
8504       return -99;
8505     }
8506
8507   if (MPLS_LABEL_INVALID == local_label)
8508     {
8509       errmsg ("missing label");
8510       return -99;
8511     }
8512
8513   /* Construct the API message */
8514   M (MPLS_IP_BIND_UNBIND, mp);
8515
8516   mp->mb_is_bind = is_bind;
8517   mp->mb_ip_table_id = ntohl (ip_table_id);
8518   mp->mb_mpls_table_id = 0;
8519   mp->mb_label = ntohl (local_label);
8520   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8521
8522   /* send it... */
8523   S (mp);
8524
8525   /* Wait for a reply... */
8526   W (ret);
8527   return ret;
8528   return (0);
8529 }
8530
8531 static int
8532 api_sr_mpls_policy_add (vat_main_t * vam)
8533 {
8534   unformat_input_t *i = vam->input;
8535   vl_api_sr_mpls_policy_add_t *mp;
8536   u32 bsid = 0;
8537   u32 weight = 1;
8538   u8 type = 0;
8539   u8 n_segments = 0;
8540   u32 sid;
8541   u32 *segments = NULL;
8542   int ret;
8543
8544   /* Parse args required to build the message */
8545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8546     {
8547       if (unformat (i, "bsid %d", &bsid))
8548         ;
8549       else if (unformat (i, "weight %d", &weight))
8550         ;
8551       else if (unformat (i, "spray"))
8552         type = 1;
8553       else if (unformat (i, "next %d", &sid))
8554         {
8555           n_segments += 1;
8556           vec_add1 (segments, htonl (sid));
8557         }
8558       else
8559         {
8560           clib_warning ("parse error '%U'", format_unformat_error, i);
8561           return -99;
8562         }
8563     }
8564
8565   if (bsid == 0)
8566     {
8567       errmsg ("bsid not set");
8568       return -99;
8569     }
8570
8571   if (n_segments == 0)
8572     {
8573       errmsg ("no sid in segment stack");
8574       return -99;
8575     }
8576
8577   /* Construct the API message */
8578   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8579
8580   mp->bsid = htonl (bsid);
8581   mp->weight = htonl (weight);
8582   mp->is_spray = type;
8583   mp->n_segments = n_segments;
8584   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8585   vec_free (segments);
8586
8587   /* send it... */
8588   S (mp);
8589
8590   /* Wait for a reply... */
8591   W (ret);
8592   return ret;
8593 }
8594
8595 static int
8596 api_sr_mpls_policy_del (vat_main_t * vam)
8597 {
8598   unformat_input_t *i = vam->input;
8599   vl_api_sr_mpls_policy_del_t *mp;
8600   u32 bsid = 0;
8601   int ret;
8602
8603   /* Parse args required to build the message */
8604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8605     {
8606       if (unformat (i, "bsid %d", &bsid))
8607         ;
8608       else
8609         {
8610           clib_warning ("parse error '%U'", format_unformat_error, i);
8611           return -99;
8612         }
8613     }
8614
8615   if (bsid == 0)
8616     {
8617       errmsg ("bsid not set");
8618       return -99;
8619     }
8620
8621   /* Construct the API message */
8622   M (SR_MPLS_POLICY_DEL, mp);
8623
8624   mp->bsid = htonl (bsid);
8625
8626   /* send it... */
8627   S (mp);
8628
8629   /* Wait for a reply... */
8630   W (ret);
8631   return ret;
8632 }
8633
8634 static int
8635 api_bier_table_add_del (vat_main_t * vam)
8636 {
8637   unformat_input_t *i = vam->input;
8638   vl_api_bier_table_add_del_t *mp;
8639   u8 is_add = 1;
8640   u32 set = 0, sub_domain = 0, hdr_len = 3;
8641   mpls_label_t local_label = MPLS_LABEL_INVALID;
8642   int ret;
8643
8644   /* Parse args required to build the message */
8645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8646     {
8647       if (unformat (i, "sub-domain %d", &sub_domain))
8648         ;
8649       else if (unformat (i, "set %d", &set))
8650         ;
8651       else if (unformat (i, "label %d", &local_label))
8652         ;
8653       else if (unformat (i, "hdr-len %d", &hdr_len))
8654         ;
8655       else if (unformat (i, "add"))
8656         is_add = 1;
8657       else if (unformat (i, "del"))
8658         is_add = 0;
8659       else
8660         {
8661           clib_warning ("parse error '%U'", format_unformat_error, i);
8662           return -99;
8663         }
8664     }
8665
8666   if (MPLS_LABEL_INVALID == local_label)
8667     {
8668       errmsg ("missing label\n");
8669       return -99;
8670     }
8671
8672   /* Construct the API message */
8673   M (BIER_TABLE_ADD_DEL, mp);
8674
8675   mp->bt_is_add = is_add;
8676   mp->bt_label = ntohl (local_label);
8677   mp->bt_tbl_id.bt_set = set;
8678   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8679   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8680
8681   /* send it... */
8682   S (mp);
8683
8684   /* Wait for a reply... */
8685   W (ret);
8686
8687   return (ret);
8688 }
8689
8690 static int
8691 api_bier_route_add_del (vat_main_t * vam)
8692 {
8693   unformat_input_t *i = vam->input;
8694   vl_api_bier_route_add_del_t *mp;
8695   u8 is_add = 1;
8696   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8697   ip4_address_t v4_next_hop_address;
8698   ip6_address_t v6_next_hop_address;
8699   u8 next_hop_set = 0;
8700   u8 next_hop_proto_is_ip4 = 1;
8701   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8702   int ret;
8703
8704   /* Parse args required to build the message */
8705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8706     {
8707       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8708         {
8709           next_hop_proto_is_ip4 = 1;
8710           next_hop_set = 1;
8711         }
8712       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8713         {
8714           next_hop_proto_is_ip4 = 0;
8715           next_hop_set = 1;
8716         }
8717       if (unformat (i, "sub-domain %d", &sub_domain))
8718         ;
8719       else if (unformat (i, "set %d", &set))
8720         ;
8721       else if (unformat (i, "hdr-len %d", &hdr_len))
8722         ;
8723       else if (unformat (i, "bp %d", &bp))
8724         ;
8725       else if (unformat (i, "add"))
8726         is_add = 1;
8727       else if (unformat (i, "del"))
8728         is_add = 0;
8729       else if (unformat (i, "out-label %d", &next_hop_out_label))
8730         ;
8731       else
8732         {
8733           clib_warning ("parse error '%U'", format_unformat_error, i);
8734           return -99;
8735         }
8736     }
8737
8738   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8739     {
8740       errmsg ("next hop / label set\n");
8741       return -99;
8742     }
8743   if (0 == bp)
8744     {
8745       errmsg ("bit=position not set\n");
8746       return -99;
8747     }
8748
8749   /* Construct the API message */
8750   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8751
8752   mp->br_is_add = is_add;
8753   mp->br_route.br_tbl_id.bt_set = set;
8754   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8755   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8756   mp->br_route.br_bp = ntohs (bp);
8757   mp->br_route.br_n_paths = 1;
8758   mp->br_route.br_paths[0].n_labels = 1;
8759   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8760   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8761                                     FIB_API_PATH_NH_PROTO_IP4 :
8762                                     FIB_API_PATH_NH_PROTO_IP6);
8763
8764   if (next_hop_proto_is_ip4)
8765     {
8766       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8767                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8768     }
8769   else
8770     {
8771       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8772                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8773     }
8774
8775   /* send it... */
8776   S (mp);
8777
8778   /* Wait for a reply... */
8779   W (ret);
8780
8781   return (ret);
8782 }
8783
8784 static int
8785 api_mpls_tunnel_add_del (vat_main_t * vam)
8786 {
8787   unformat_input_t *i = vam->input;
8788   vl_api_mpls_tunnel_add_del_t *mp;
8789
8790   vl_api_fib_path_t paths[8];
8791   u32 sw_if_index = ~0;
8792   u8 path_count = 0;
8793   u8 l2_only = 0;
8794   u8 is_add = 1;
8795   int ret;
8796
8797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8798     {
8799       if (unformat (i, "add"))
8800         is_add = 1;
8801       else
8802         if (unformat
8803             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8804         is_add = 0;
8805       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8806         is_add = 0;
8807       else if (unformat (i, "l2-only"))
8808         l2_only = 1;
8809       else
8810         if (unformat
8811             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8812         {
8813           path_count++;
8814           if (8 == path_count)
8815             {
8816               errmsg ("max 8 paths");
8817               return -99;
8818             }
8819         }
8820       else
8821         {
8822           clib_warning ("parse error '%U'", format_unformat_error, i);
8823           return -99;
8824         }
8825     }
8826
8827   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8828
8829   mp->mt_is_add = is_add;
8830   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8831   mp->mt_tunnel.mt_l2_only = l2_only;
8832   mp->mt_tunnel.mt_is_multicast = 0;
8833   mp->mt_tunnel.mt_n_paths = path_count;
8834
8835   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8836                sizeof (paths[0]) * path_count);
8837
8838   S (mp);
8839   W (ret);
8840   return ret;
8841 }
8842
8843 static int
8844 api_sw_interface_set_unnumbered (vat_main_t * vam)
8845 {
8846   unformat_input_t *i = vam->input;
8847   vl_api_sw_interface_set_unnumbered_t *mp;
8848   u32 sw_if_index;
8849   u32 unnum_sw_index = ~0;
8850   u8 is_add = 1;
8851   u8 sw_if_index_set = 0;
8852   int ret;
8853
8854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8855     {
8856       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8857         sw_if_index_set = 1;
8858       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8859         sw_if_index_set = 1;
8860       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8861         ;
8862       else if (unformat (i, "del"))
8863         is_add = 0;
8864       else
8865         {
8866           clib_warning ("parse error '%U'", format_unformat_error, i);
8867           return -99;
8868         }
8869     }
8870
8871   if (sw_if_index_set == 0)
8872     {
8873       errmsg ("missing interface name or sw_if_index");
8874       return -99;
8875     }
8876
8877   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8878
8879   mp->sw_if_index = ntohl (sw_if_index);
8880   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8881   mp->is_add = is_add;
8882
8883   S (mp);
8884   W (ret);
8885   return ret;
8886 }
8887
8888
8889 static int
8890 api_create_vlan_subif (vat_main_t * vam)
8891 {
8892   unformat_input_t *i = vam->input;
8893   vl_api_create_vlan_subif_t *mp;
8894   u32 sw_if_index;
8895   u8 sw_if_index_set = 0;
8896   u32 vlan_id;
8897   u8 vlan_id_set = 0;
8898   int ret;
8899
8900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8901     {
8902       if (unformat (i, "sw_if_index %d", &sw_if_index))
8903         sw_if_index_set = 1;
8904       else
8905         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8906         sw_if_index_set = 1;
8907       else if (unformat (i, "vlan %d", &vlan_id))
8908         vlan_id_set = 1;
8909       else
8910         {
8911           clib_warning ("parse error '%U'", format_unformat_error, i);
8912           return -99;
8913         }
8914     }
8915
8916   if (sw_if_index_set == 0)
8917     {
8918       errmsg ("missing interface name or sw_if_index");
8919       return -99;
8920     }
8921
8922   if (vlan_id_set == 0)
8923     {
8924       errmsg ("missing vlan_id");
8925       return -99;
8926     }
8927   M (CREATE_VLAN_SUBIF, mp);
8928
8929   mp->sw_if_index = ntohl (sw_if_index);
8930   mp->vlan_id = ntohl (vlan_id);
8931
8932   S (mp);
8933   W (ret);
8934   return ret;
8935 }
8936
8937 #define foreach_create_subif_bit                \
8938 _(no_tags)                                      \
8939 _(one_tag)                                      \
8940 _(two_tags)                                     \
8941 _(dot1ad)                                       \
8942 _(exact_match)                                  \
8943 _(default_sub)                                  \
8944 _(outer_vlan_id_any)                            \
8945 _(inner_vlan_id_any)
8946
8947 #define foreach_create_subif_flag               \
8948 _(0, "no_tags")                                 \
8949 _(1, "one_tag")                                 \
8950 _(2, "two_tags")                                \
8951 _(3, "dot1ad")                                  \
8952 _(4, "exact_match")                             \
8953 _(5, "default_sub")                             \
8954 _(6, "outer_vlan_id_any")                       \
8955 _(7, "inner_vlan_id_any")
8956
8957 static int
8958 api_create_subif (vat_main_t * vam)
8959 {
8960   unformat_input_t *i = vam->input;
8961   vl_api_create_subif_t *mp;
8962   u32 sw_if_index;
8963   u8 sw_if_index_set = 0;
8964   u32 sub_id;
8965   u8 sub_id_set = 0;
8966   u32 __attribute__ ((unused)) no_tags = 0;
8967   u32 __attribute__ ((unused)) one_tag = 0;
8968   u32 __attribute__ ((unused)) two_tags = 0;
8969   u32 __attribute__ ((unused)) dot1ad = 0;
8970   u32 __attribute__ ((unused)) exact_match = 0;
8971   u32 __attribute__ ((unused)) default_sub = 0;
8972   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8973   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8974   u32 tmp;
8975   u16 outer_vlan_id = 0;
8976   u16 inner_vlan_id = 0;
8977   int ret;
8978
8979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8980     {
8981       if (unformat (i, "sw_if_index %d", &sw_if_index))
8982         sw_if_index_set = 1;
8983       else
8984         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8985         sw_if_index_set = 1;
8986       else if (unformat (i, "sub_id %d", &sub_id))
8987         sub_id_set = 1;
8988       else if (unformat (i, "outer_vlan_id %d", &tmp))
8989         outer_vlan_id = tmp;
8990       else if (unformat (i, "inner_vlan_id %d", &tmp))
8991         inner_vlan_id = tmp;
8992
8993 #define _(a) else if (unformat (i, #a)) a = 1 ;
8994       foreach_create_subif_bit
8995 #undef _
8996         else
8997         {
8998           clib_warning ("parse error '%U'", format_unformat_error, i);
8999           return -99;
9000         }
9001     }
9002
9003   if (sw_if_index_set == 0)
9004     {
9005       errmsg ("missing interface name or sw_if_index");
9006       return -99;
9007     }
9008
9009   if (sub_id_set == 0)
9010     {
9011       errmsg ("missing sub_id");
9012       return -99;
9013     }
9014   M (CREATE_SUBIF, mp);
9015
9016   mp->sw_if_index = ntohl (sw_if_index);
9017   mp->sub_id = ntohl (sub_id);
9018
9019 #define _(a,b) mp->sub_if_flags |= (1 << a);
9020   foreach_create_subif_flag;
9021 #undef _
9022
9023   mp->outer_vlan_id = ntohs (outer_vlan_id);
9024   mp->inner_vlan_id = ntohs (inner_vlan_id);
9025
9026   S (mp);
9027   W (ret);
9028   return ret;
9029 }
9030
9031 static int
9032 api_ip_table_replace_begin (vat_main_t * vam)
9033 {
9034   unformat_input_t *i = vam->input;
9035   vl_api_ip_table_replace_begin_t *mp;
9036   u32 table_id = 0;
9037   u8 is_ipv6 = 0;
9038
9039   int ret;
9040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9041     {
9042       if (unformat (i, "table %d", &table_id))
9043         ;
9044       else if (unformat (i, "ipv6"))
9045         is_ipv6 = 1;
9046       else
9047         {
9048           clib_warning ("parse error '%U'", format_unformat_error, i);
9049           return -99;
9050         }
9051     }
9052
9053   M (IP_TABLE_REPLACE_BEGIN, mp);
9054
9055   mp->table.table_id = ntohl (table_id);
9056   mp->table.is_ip6 = is_ipv6;
9057
9058   S (mp);
9059   W (ret);
9060   return ret;
9061 }
9062
9063 static int
9064 api_ip_table_flush (vat_main_t * vam)
9065 {
9066   unformat_input_t *i = vam->input;
9067   vl_api_ip_table_flush_t *mp;
9068   u32 table_id = 0;
9069   u8 is_ipv6 = 0;
9070
9071   int ret;
9072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9073     {
9074       if (unformat (i, "table %d", &table_id))
9075         ;
9076       else if (unformat (i, "ipv6"))
9077         is_ipv6 = 1;
9078       else
9079         {
9080           clib_warning ("parse error '%U'", format_unformat_error, i);
9081           return -99;
9082         }
9083     }
9084
9085   M (IP_TABLE_FLUSH, mp);
9086
9087   mp->table.table_id = ntohl (table_id);
9088   mp->table.is_ip6 = is_ipv6;
9089
9090   S (mp);
9091   W (ret);
9092   return ret;
9093 }
9094
9095 static int
9096 api_ip_table_replace_end (vat_main_t * vam)
9097 {
9098   unformat_input_t *i = vam->input;
9099   vl_api_ip_table_replace_end_t *mp;
9100   u32 table_id = 0;
9101   u8 is_ipv6 = 0;
9102
9103   int ret;
9104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9105     {
9106       if (unformat (i, "table %d", &table_id))
9107         ;
9108       else if (unformat (i, "ipv6"))
9109         is_ipv6 = 1;
9110       else
9111         {
9112           clib_warning ("parse error '%U'", format_unformat_error, i);
9113           return -99;
9114         }
9115     }
9116
9117   M (IP_TABLE_REPLACE_END, mp);
9118
9119   mp->table.table_id = ntohl (table_id);
9120   mp->table.is_ip6 = is_ipv6;
9121
9122   S (mp);
9123   W (ret);
9124   return ret;
9125 }
9126
9127 static int
9128 api_set_ip_flow_hash (vat_main_t * vam)
9129 {
9130   unformat_input_t *i = vam->input;
9131   vl_api_set_ip_flow_hash_t *mp;
9132   u32 vrf_id = 0;
9133   u8 is_ipv6 = 0;
9134   u8 vrf_id_set = 0;
9135   u8 src = 0;
9136   u8 dst = 0;
9137   u8 sport = 0;
9138   u8 dport = 0;
9139   u8 proto = 0;
9140   u8 reverse = 0;
9141   int ret;
9142
9143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9144     {
9145       if (unformat (i, "vrf %d", &vrf_id))
9146         vrf_id_set = 1;
9147       else if (unformat (i, "ipv6"))
9148         is_ipv6 = 1;
9149       else if (unformat (i, "src"))
9150         src = 1;
9151       else if (unformat (i, "dst"))
9152         dst = 1;
9153       else if (unformat (i, "sport"))
9154         sport = 1;
9155       else if (unformat (i, "dport"))
9156         dport = 1;
9157       else if (unformat (i, "proto"))
9158         proto = 1;
9159       else if (unformat (i, "reverse"))
9160         reverse = 1;
9161
9162       else
9163         {
9164           clib_warning ("parse error '%U'", format_unformat_error, i);
9165           return -99;
9166         }
9167     }
9168
9169   if (vrf_id_set == 0)
9170     {
9171       errmsg ("missing vrf id");
9172       return -99;
9173     }
9174
9175   M (SET_IP_FLOW_HASH, mp);
9176   mp->src = src;
9177   mp->dst = dst;
9178   mp->sport = sport;
9179   mp->dport = dport;
9180   mp->proto = proto;
9181   mp->reverse = reverse;
9182   mp->vrf_id = ntohl (vrf_id);
9183   mp->is_ipv6 = is_ipv6;
9184
9185   S (mp);
9186   W (ret);
9187   return ret;
9188 }
9189
9190 static int
9191 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9192 {
9193   unformat_input_t *i = vam->input;
9194   vl_api_sw_interface_ip6_enable_disable_t *mp;
9195   u32 sw_if_index;
9196   u8 sw_if_index_set = 0;
9197   u8 enable = 0;
9198   int ret;
9199
9200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9201     {
9202       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9203         sw_if_index_set = 1;
9204       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9205         sw_if_index_set = 1;
9206       else if (unformat (i, "enable"))
9207         enable = 1;
9208       else if (unformat (i, "disable"))
9209         enable = 0;
9210       else
9211         {
9212           clib_warning ("parse error '%U'", format_unformat_error, i);
9213           return -99;
9214         }
9215     }
9216
9217   if (sw_if_index_set == 0)
9218     {
9219       errmsg ("missing interface name or sw_if_index");
9220       return -99;
9221     }
9222
9223   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9224
9225   mp->sw_if_index = ntohl (sw_if_index);
9226   mp->enable = enable;
9227
9228   S (mp);
9229   W (ret);
9230   return ret;
9231 }
9232
9233
9234 static int
9235 api_l2_patch_add_del (vat_main_t * vam)
9236 {
9237   unformat_input_t *i = vam->input;
9238   vl_api_l2_patch_add_del_t *mp;
9239   u32 rx_sw_if_index;
9240   u8 rx_sw_if_index_set = 0;
9241   u32 tx_sw_if_index;
9242   u8 tx_sw_if_index_set = 0;
9243   u8 is_add = 1;
9244   int ret;
9245
9246   /* Parse args required to build the message */
9247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9248     {
9249       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9250         rx_sw_if_index_set = 1;
9251       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9252         tx_sw_if_index_set = 1;
9253       else if (unformat (i, "rx"))
9254         {
9255           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9256             {
9257               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9258                             &rx_sw_if_index))
9259                 rx_sw_if_index_set = 1;
9260             }
9261           else
9262             break;
9263         }
9264       else if (unformat (i, "tx"))
9265         {
9266           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9267             {
9268               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9269                             &tx_sw_if_index))
9270                 tx_sw_if_index_set = 1;
9271             }
9272           else
9273             break;
9274         }
9275       else if (unformat (i, "del"))
9276         is_add = 0;
9277       else
9278         break;
9279     }
9280
9281   if (rx_sw_if_index_set == 0)
9282     {
9283       errmsg ("missing rx interface name or rx_sw_if_index");
9284       return -99;
9285     }
9286
9287   if (tx_sw_if_index_set == 0)
9288     {
9289       errmsg ("missing tx interface name or tx_sw_if_index");
9290       return -99;
9291     }
9292
9293   M (L2_PATCH_ADD_DEL, mp);
9294
9295   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9296   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9297   mp->is_add = is_add;
9298
9299   S (mp);
9300   W (ret);
9301   return ret;
9302 }
9303
9304 u8 is_del;
9305 u8 localsid_addr[16];
9306 u8 end_psp;
9307 u8 behavior;
9308 u32 sw_if_index;
9309 u32 vlan_index;
9310 u32 fib_table;
9311 u8 nh_addr[16];
9312
9313 static int
9314 api_sr_localsid_add_del (vat_main_t * vam)
9315 {
9316   unformat_input_t *i = vam->input;
9317   vl_api_sr_localsid_add_del_t *mp;
9318
9319   u8 is_del;
9320   ip6_address_t localsid;
9321   u8 end_psp = 0;
9322   u8 behavior = ~0;
9323   u32 sw_if_index;
9324   u32 fib_table = ~(u32) 0;
9325   ip46_address_t nh_addr;
9326   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9327
9328   bool nexthop_set = 0;
9329
9330   int ret;
9331
9332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9333     {
9334       if (unformat (i, "del"))
9335         is_del = 1;
9336       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9337       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9338         nexthop_set = 1;
9339       else if (unformat (i, "behavior %u", &behavior));
9340       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9341       else if (unformat (i, "fib-table %u", &fib_table));
9342       else if (unformat (i, "end.psp %u", &behavior));
9343       else
9344         break;
9345     }
9346
9347   M (SR_LOCALSID_ADD_DEL, mp);
9348
9349   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9350
9351   if (nexthop_set)
9352     {
9353       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9354     }
9355   mp->behavior = behavior;
9356   mp->sw_if_index = ntohl (sw_if_index);
9357   mp->fib_table = ntohl (fib_table);
9358   mp->end_psp = end_psp;
9359   mp->is_del = is_del;
9360
9361   S (mp);
9362   W (ret);
9363   return ret;
9364 }
9365
9366 static int
9367 api_ioam_enable (vat_main_t * vam)
9368 {
9369   unformat_input_t *input = vam->input;
9370   vl_api_ioam_enable_t *mp;
9371   u32 id = 0;
9372   int has_trace_option = 0;
9373   int has_pot_option = 0;
9374   int has_seqno_option = 0;
9375   int has_analyse_option = 0;
9376   int ret;
9377
9378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9379     {
9380       if (unformat (input, "trace"))
9381         has_trace_option = 1;
9382       else if (unformat (input, "pot"))
9383         has_pot_option = 1;
9384       else if (unformat (input, "seqno"))
9385         has_seqno_option = 1;
9386       else if (unformat (input, "analyse"))
9387         has_analyse_option = 1;
9388       else
9389         break;
9390     }
9391   M (IOAM_ENABLE, mp);
9392   mp->id = htons (id);
9393   mp->seqno = has_seqno_option;
9394   mp->analyse = has_analyse_option;
9395   mp->pot_enable = has_pot_option;
9396   mp->trace_enable = has_trace_option;
9397
9398   S (mp);
9399   W (ret);
9400   return ret;
9401 }
9402
9403
9404 static int
9405 api_ioam_disable (vat_main_t * vam)
9406 {
9407   vl_api_ioam_disable_t *mp;
9408   int ret;
9409
9410   M (IOAM_DISABLE, mp);
9411   S (mp);
9412   W (ret);
9413   return ret;
9414 }
9415
9416 #define foreach_tcp_proto_field                 \
9417 _(src_port)                                     \
9418 _(dst_port)
9419
9420 #define foreach_udp_proto_field                 \
9421 _(src_port)                                     \
9422 _(dst_port)
9423
9424 #define foreach_ip4_proto_field                 \
9425 _(src_address)                                  \
9426 _(dst_address)                                  \
9427 _(tos)                                          \
9428 _(length)                                       \
9429 _(fragment_id)                                  \
9430 _(ttl)                                          \
9431 _(protocol)                                     \
9432 _(checksum)
9433
9434 typedef struct
9435 {
9436   u16 src_port, dst_port;
9437 } tcpudp_header_t;
9438
9439 #if VPP_API_TEST_BUILTIN == 0
9440 uword
9441 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9442 {
9443   u8 **maskp = va_arg (*args, u8 **);
9444   u8 *mask = 0;
9445   u8 found_something = 0;
9446   tcp_header_t *tcp;
9447
9448 #define _(a) u8 a=0;
9449   foreach_tcp_proto_field;
9450 #undef _
9451
9452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9453     {
9454       if (0);
9455 #define _(a) else if (unformat (input, #a)) a=1;
9456       foreach_tcp_proto_field
9457 #undef _
9458         else
9459         break;
9460     }
9461
9462 #define _(a) found_something += a;
9463   foreach_tcp_proto_field;
9464 #undef _
9465
9466   if (found_something == 0)
9467     return 0;
9468
9469   vec_validate (mask, sizeof (*tcp) - 1);
9470
9471   tcp = (tcp_header_t *) mask;
9472
9473 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9474   foreach_tcp_proto_field;
9475 #undef _
9476
9477   *maskp = mask;
9478   return 1;
9479 }
9480
9481 uword
9482 unformat_udp_mask (unformat_input_t * input, va_list * args)
9483 {
9484   u8 **maskp = va_arg (*args, u8 **);
9485   u8 *mask = 0;
9486   u8 found_something = 0;
9487   udp_header_t *udp;
9488
9489 #define _(a) u8 a=0;
9490   foreach_udp_proto_field;
9491 #undef _
9492
9493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9494     {
9495       if (0);
9496 #define _(a) else if (unformat (input, #a)) a=1;
9497       foreach_udp_proto_field
9498 #undef _
9499         else
9500         break;
9501     }
9502
9503 #define _(a) found_something += a;
9504   foreach_udp_proto_field;
9505 #undef _
9506
9507   if (found_something == 0)
9508     return 0;
9509
9510   vec_validate (mask, sizeof (*udp) - 1);
9511
9512   udp = (udp_header_t *) mask;
9513
9514 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9515   foreach_udp_proto_field;
9516 #undef _
9517
9518   *maskp = mask;
9519   return 1;
9520 }
9521
9522 uword
9523 unformat_l4_mask (unformat_input_t * input, va_list * args)
9524 {
9525   u8 **maskp = va_arg (*args, u8 **);
9526   u16 src_port = 0, dst_port = 0;
9527   tcpudp_header_t *tcpudp;
9528
9529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9530     {
9531       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9532         return 1;
9533       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9534         return 1;
9535       else if (unformat (input, "src_port"))
9536         src_port = 0xFFFF;
9537       else if (unformat (input, "dst_port"))
9538         dst_port = 0xFFFF;
9539       else
9540         return 0;
9541     }
9542
9543   if (!src_port && !dst_port)
9544     return 0;
9545
9546   u8 *mask = 0;
9547   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9548
9549   tcpudp = (tcpudp_header_t *) mask;
9550   tcpudp->src_port = src_port;
9551   tcpudp->dst_port = dst_port;
9552
9553   *maskp = mask;
9554
9555   return 1;
9556 }
9557
9558 uword
9559 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9560 {
9561   u8 **maskp = va_arg (*args, u8 **);
9562   u8 *mask = 0;
9563   u8 found_something = 0;
9564   ip4_header_t *ip;
9565
9566 #define _(a) u8 a=0;
9567   foreach_ip4_proto_field;
9568 #undef _
9569   u8 version = 0;
9570   u8 hdr_length = 0;
9571
9572
9573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9574     {
9575       if (unformat (input, "version"))
9576         version = 1;
9577       else if (unformat (input, "hdr_length"))
9578         hdr_length = 1;
9579       else if (unformat (input, "src"))
9580         src_address = 1;
9581       else if (unformat (input, "dst"))
9582         dst_address = 1;
9583       else if (unformat (input, "proto"))
9584         protocol = 1;
9585
9586 #define _(a) else if (unformat (input, #a)) a=1;
9587       foreach_ip4_proto_field
9588 #undef _
9589         else
9590         break;
9591     }
9592
9593 #define _(a) found_something += a;
9594   foreach_ip4_proto_field;
9595 #undef _
9596
9597   if (found_something == 0)
9598     return 0;
9599
9600   vec_validate (mask, sizeof (*ip) - 1);
9601
9602   ip = (ip4_header_t *) mask;
9603
9604 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9605   foreach_ip4_proto_field;
9606 #undef _
9607
9608   ip->ip_version_and_header_length = 0;
9609
9610   if (version)
9611     ip->ip_version_and_header_length |= 0xF0;
9612
9613   if (hdr_length)
9614     ip->ip_version_and_header_length |= 0x0F;
9615
9616   *maskp = mask;
9617   return 1;
9618 }
9619
9620 #define foreach_ip6_proto_field                 \
9621 _(src_address)                                  \
9622 _(dst_address)                                  \
9623 _(payload_length)                               \
9624 _(hop_limit)                                    \
9625 _(protocol)
9626
9627 uword
9628 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9629 {
9630   u8 **maskp = va_arg (*args, u8 **);
9631   u8 *mask = 0;
9632   u8 found_something = 0;
9633   ip6_header_t *ip;
9634   u32 ip_version_traffic_class_and_flow_label;
9635
9636 #define _(a) u8 a=0;
9637   foreach_ip6_proto_field;
9638 #undef _
9639   u8 version = 0;
9640   u8 traffic_class = 0;
9641   u8 flow_label = 0;
9642
9643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9644     {
9645       if (unformat (input, "version"))
9646         version = 1;
9647       else if (unformat (input, "traffic-class"))
9648         traffic_class = 1;
9649       else if (unformat (input, "flow-label"))
9650         flow_label = 1;
9651       else if (unformat (input, "src"))
9652         src_address = 1;
9653       else if (unformat (input, "dst"))
9654         dst_address = 1;
9655       else if (unformat (input, "proto"))
9656         protocol = 1;
9657
9658 #define _(a) else if (unformat (input, #a)) a=1;
9659       foreach_ip6_proto_field
9660 #undef _
9661         else
9662         break;
9663     }
9664
9665 #define _(a) found_something += a;
9666   foreach_ip6_proto_field;
9667 #undef _
9668
9669   if (found_something == 0)
9670     return 0;
9671
9672   vec_validate (mask, sizeof (*ip) - 1);
9673
9674   ip = (ip6_header_t *) mask;
9675
9676 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9677   foreach_ip6_proto_field;
9678 #undef _
9679
9680   ip_version_traffic_class_and_flow_label = 0;
9681
9682   if (version)
9683     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9684
9685   if (traffic_class)
9686     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9687
9688   if (flow_label)
9689     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9690
9691   ip->ip_version_traffic_class_and_flow_label =
9692     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9693
9694   *maskp = mask;
9695   return 1;
9696 }
9697
9698 uword
9699 unformat_l3_mask (unformat_input_t * input, va_list * args)
9700 {
9701   u8 **maskp = va_arg (*args, u8 **);
9702
9703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9704     {
9705       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9706         return 1;
9707       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9708         return 1;
9709       else
9710         break;
9711     }
9712   return 0;
9713 }
9714
9715 uword
9716 unformat_l2_mask (unformat_input_t * input, va_list * args)
9717 {
9718   u8 **maskp = va_arg (*args, u8 **);
9719   u8 *mask = 0;
9720   u8 src = 0;
9721   u8 dst = 0;
9722   u8 proto = 0;
9723   u8 tag1 = 0;
9724   u8 tag2 = 0;
9725   u8 ignore_tag1 = 0;
9726   u8 ignore_tag2 = 0;
9727   u8 cos1 = 0;
9728   u8 cos2 = 0;
9729   u8 dot1q = 0;
9730   u8 dot1ad = 0;
9731   int len = 14;
9732
9733   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9734     {
9735       if (unformat (input, "src"))
9736         src = 1;
9737       else if (unformat (input, "dst"))
9738         dst = 1;
9739       else if (unformat (input, "proto"))
9740         proto = 1;
9741       else if (unformat (input, "tag1"))
9742         tag1 = 1;
9743       else if (unformat (input, "tag2"))
9744         tag2 = 1;
9745       else if (unformat (input, "ignore-tag1"))
9746         ignore_tag1 = 1;
9747       else if (unformat (input, "ignore-tag2"))
9748         ignore_tag2 = 1;
9749       else if (unformat (input, "cos1"))
9750         cos1 = 1;
9751       else if (unformat (input, "cos2"))
9752         cos2 = 1;
9753       else if (unformat (input, "dot1q"))
9754         dot1q = 1;
9755       else if (unformat (input, "dot1ad"))
9756         dot1ad = 1;
9757       else
9758         break;
9759     }
9760   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9761        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9762     return 0;
9763
9764   if (tag1 || ignore_tag1 || cos1 || dot1q)
9765     len = 18;
9766   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9767     len = 22;
9768
9769   vec_validate (mask, len - 1);
9770
9771   if (dst)
9772     clib_memset (mask, 0xff, 6);
9773
9774   if (src)
9775     clib_memset (mask + 6, 0xff, 6);
9776
9777   if (tag2 || dot1ad)
9778     {
9779       /* inner vlan tag */
9780       if (tag2)
9781         {
9782           mask[19] = 0xff;
9783           mask[18] = 0x0f;
9784         }
9785       if (cos2)
9786         mask[18] |= 0xe0;
9787       if (proto)
9788         mask[21] = mask[20] = 0xff;
9789       if (tag1)
9790         {
9791           mask[15] = 0xff;
9792           mask[14] = 0x0f;
9793         }
9794       if (cos1)
9795         mask[14] |= 0xe0;
9796       *maskp = mask;
9797       return 1;
9798     }
9799   if (tag1 | dot1q)
9800     {
9801       if (tag1)
9802         {
9803           mask[15] = 0xff;
9804           mask[14] = 0x0f;
9805         }
9806       if (cos1)
9807         mask[14] |= 0xe0;
9808       if (proto)
9809         mask[16] = mask[17] = 0xff;
9810
9811       *maskp = mask;
9812       return 1;
9813     }
9814   if (cos2)
9815     mask[18] |= 0xe0;
9816   if (cos1)
9817     mask[14] |= 0xe0;
9818   if (proto)
9819     mask[12] = mask[13] = 0xff;
9820
9821   *maskp = mask;
9822   return 1;
9823 }
9824
9825 uword
9826 unformat_classify_mask (unformat_input_t * input, va_list * args)
9827 {
9828   u8 **maskp = va_arg (*args, u8 **);
9829   u32 *skipp = va_arg (*args, u32 *);
9830   u32 *matchp = va_arg (*args, u32 *);
9831   u32 match;
9832   u8 *mask = 0;
9833   u8 *l2 = 0;
9834   u8 *l3 = 0;
9835   u8 *l4 = 0;
9836   int i;
9837
9838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9839     {
9840       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9841         ;
9842       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9843         ;
9844       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9845         ;
9846       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9847         ;
9848       else
9849         break;
9850     }
9851
9852   if (l4 && !l3)
9853     {
9854       vec_free (mask);
9855       vec_free (l2);
9856       vec_free (l4);
9857       return 0;
9858     }
9859
9860   if (mask || l2 || l3 || l4)
9861     {
9862       if (l2 || l3 || l4)
9863         {
9864           /* "With a free Ethernet header in every package" */
9865           if (l2 == 0)
9866             vec_validate (l2, 13);
9867           mask = l2;
9868           if (vec_len (l3))
9869             {
9870               vec_append (mask, l3);
9871               vec_free (l3);
9872             }
9873           if (vec_len (l4))
9874             {
9875               vec_append (mask, l4);
9876               vec_free (l4);
9877             }
9878         }
9879
9880       /* Scan forward looking for the first significant mask octet */
9881       for (i = 0; i < vec_len (mask); i++)
9882         if (mask[i])
9883           break;
9884
9885       /* compute (skip, match) params */
9886       *skipp = i / sizeof (u32x4);
9887       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9888
9889       /* Pad mask to an even multiple of the vector size */
9890       while (vec_len (mask) % sizeof (u32x4))
9891         vec_add1 (mask, 0);
9892
9893       match = vec_len (mask) / sizeof (u32x4);
9894
9895       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9896         {
9897           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9898           if (*tmp || *(tmp + 1))
9899             break;
9900           match--;
9901         }
9902       if (match == 0)
9903         clib_warning ("BUG: match 0");
9904
9905       _vec_len (mask) = match * sizeof (u32x4);
9906
9907       *matchp = match;
9908       *maskp = mask;
9909
9910       return 1;
9911     }
9912
9913   return 0;
9914 }
9915 #endif /* VPP_API_TEST_BUILTIN */
9916
9917 #define foreach_l2_next                         \
9918 _(drop, DROP)                                   \
9919 _(ethernet, ETHERNET_INPUT)                     \
9920 _(ip4, IP4_INPUT)                               \
9921 _(ip6, IP6_INPUT)
9922
9923 uword
9924 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9925 {
9926   u32 *miss_next_indexp = va_arg (*args, u32 *);
9927   u32 next_index = 0;
9928   u32 tmp;
9929
9930 #define _(n,N) \
9931   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9932   foreach_l2_next;
9933 #undef _
9934
9935   if (unformat (input, "%d", &tmp))
9936     {
9937       next_index = tmp;
9938       goto out;
9939     }
9940
9941   return 0;
9942
9943 out:
9944   *miss_next_indexp = next_index;
9945   return 1;
9946 }
9947
9948 #define foreach_ip_next                         \
9949 _(drop, DROP)                                   \
9950 _(local, LOCAL)                                 \
9951 _(rewrite, REWRITE)
9952
9953 uword
9954 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9955 {
9956   u32 *miss_next_indexp = va_arg (*args, u32 *);
9957   u32 next_index = 0;
9958   u32 tmp;
9959
9960 #define _(n,N) \
9961   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9962   foreach_ip_next;
9963 #undef _
9964
9965   if (unformat (input, "%d", &tmp))
9966     {
9967       next_index = tmp;
9968       goto out;
9969     }
9970
9971   return 0;
9972
9973 out:
9974   *miss_next_indexp = next_index;
9975   return 1;
9976 }
9977
9978 #define foreach_acl_next                        \
9979 _(deny, DENY)
9980
9981 uword
9982 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9983 {
9984   u32 *miss_next_indexp = va_arg (*args, u32 *);
9985   u32 next_index = 0;
9986   u32 tmp;
9987
9988 #define _(n,N) \
9989   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9990   foreach_acl_next;
9991 #undef _
9992
9993   if (unformat (input, "permit"))
9994     {
9995       next_index = ~0;
9996       goto out;
9997     }
9998   else if (unformat (input, "%d", &tmp))
9999     {
10000       next_index = tmp;
10001       goto out;
10002     }
10003
10004   return 0;
10005
10006 out:
10007   *miss_next_indexp = next_index;
10008   return 1;
10009 }
10010
10011 uword
10012 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10013 {
10014   u32 *r = va_arg (*args, u32 *);
10015
10016   if (unformat (input, "conform-color"))
10017     *r = POLICE_CONFORM;
10018   else if (unformat (input, "exceed-color"))
10019     *r = POLICE_EXCEED;
10020   else
10021     return 0;
10022
10023   return 1;
10024 }
10025
10026 static int
10027 api_classify_add_del_table (vat_main_t * vam)
10028 {
10029   unformat_input_t *i = vam->input;
10030   vl_api_classify_add_del_table_t *mp;
10031
10032   u32 nbuckets = 2;
10033   u32 skip = ~0;
10034   u32 match = ~0;
10035   int is_add = 1;
10036   int del_chain = 0;
10037   u32 table_index = ~0;
10038   u32 next_table_index = ~0;
10039   u32 miss_next_index = ~0;
10040   u32 memory_size = 32 << 20;
10041   u8 *mask = 0;
10042   u32 current_data_flag = 0;
10043   int current_data_offset = 0;
10044   int ret;
10045
10046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10047     {
10048       if (unformat (i, "del"))
10049         is_add = 0;
10050       else if (unformat (i, "del-chain"))
10051         {
10052           is_add = 0;
10053           del_chain = 1;
10054         }
10055       else if (unformat (i, "buckets %d", &nbuckets))
10056         ;
10057       else if (unformat (i, "memory_size %d", &memory_size))
10058         ;
10059       else if (unformat (i, "skip %d", &skip))
10060         ;
10061       else if (unformat (i, "match %d", &match))
10062         ;
10063       else if (unformat (i, "table %d", &table_index))
10064         ;
10065       else if (unformat (i, "mask %U", unformat_classify_mask,
10066                          &mask, &skip, &match))
10067         ;
10068       else if (unformat (i, "next-table %d", &next_table_index))
10069         ;
10070       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10071                          &miss_next_index))
10072         ;
10073       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10074                          &miss_next_index))
10075         ;
10076       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10077                          &miss_next_index))
10078         ;
10079       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10080         ;
10081       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10082         ;
10083       else
10084         break;
10085     }
10086
10087   if (is_add && mask == 0)
10088     {
10089       errmsg ("Mask required");
10090       return -99;
10091     }
10092
10093   if (is_add && skip == ~0)
10094     {
10095       errmsg ("skip count required");
10096       return -99;
10097     }
10098
10099   if (is_add && match == ~0)
10100     {
10101       errmsg ("match count required");
10102       return -99;
10103     }
10104
10105   if (!is_add && table_index == ~0)
10106     {
10107       errmsg ("table index required for delete");
10108       return -99;
10109     }
10110
10111   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10112
10113   mp->is_add = is_add;
10114   mp->del_chain = del_chain;
10115   mp->table_index = ntohl (table_index);
10116   mp->nbuckets = ntohl (nbuckets);
10117   mp->memory_size = ntohl (memory_size);
10118   mp->skip_n_vectors = ntohl (skip);
10119   mp->match_n_vectors = ntohl (match);
10120   mp->next_table_index = ntohl (next_table_index);
10121   mp->miss_next_index = ntohl (miss_next_index);
10122   mp->current_data_flag = ntohl (current_data_flag);
10123   mp->current_data_offset = ntohl (current_data_offset);
10124   mp->mask_len = ntohl (vec_len (mask));
10125   clib_memcpy (mp->mask, mask, vec_len (mask));
10126
10127   vec_free (mask);
10128
10129   S (mp);
10130   W (ret);
10131   return ret;
10132 }
10133
10134 #if VPP_API_TEST_BUILTIN == 0
10135 uword
10136 unformat_l4_match (unformat_input_t * input, va_list * args)
10137 {
10138   u8 **matchp = va_arg (*args, u8 **);
10139
10140   u8 *proto_header = 0;
10141   int src_port = 0;
10142   int dst_port = 0;
10143
10144   tcpudp_header_t h;
10145
10146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10147     {
10148       if (unformat (input, "src_port %d", &src_port))
10149         ;
10150       else if (unformat (input, "dst_port %d", &dst_port))
10151         ;
10152       else
10153         return 0;
10154     }
10155
10156   h.src_port = clib_host_to_net_u16 (src_port);
10157   h.dst_port = clib_host_to_net_u16 (dst_port);
10158   vec_validate (proto_header, sizeof (h) - 1);
10159   memcpy (proto_header, &h, sizeof (h));
10160
10161   *matchp = proto_header;
10162
10163   return 1;
10164 }
10165
10166 uword
10167 unformat_ip4_match (unformat_input_t * input, va_list * args)
10168 {
10169   u8 **matchp = va_arg (*args, u8 **);
10170   u8 *match = 0;
10171   ip4_header_t *ip;
10172   int version = 0;
10173   u32 version_val;
10174   int hdr_length = 0;
10175   u32 hdr_length_val;
10176   int src = 0, dst = 0;
10177   ip4_address_t src_val, dst_val;
10178   int proto = 0;
10179   u32 proto_val;
10180   int tos = 0;
10181   u32 tos_val;
10182   int length = 0;
10183   u32 length_val;
10184   int fragment_id = 0;
10185   u32 fragment_id_val;
10186   int ttl = 0;
10187   int ttl_val;
10188   int checksum = 0;
10189   u32 checksum_val;
10190
10191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10192     {
10193       if (unformat (input, "version %d", &version_val))
10194         version = 1;
10195       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10196         hdr_length = 1;
10197       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10198         src = 1;
10199       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10200         dst = 1;
10201       else if (unformat (input, "proto %d", &proto_val))
10202         proto = 1;
10203       else if (unformat (input, "tos %d", &tos_val))
10204         tos = 1;
10205       else if (unformat (input, "length %d", &length_val))
10206         length = 1;
10207       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10208         fragment_id = 1;
10209       else if (unformat (input, "ttl %d", &ttl_val))
10210         ttl = 1;
10211       else if (unformat (input, "checksum %d", &checksum_val))
10212         checksum = 1;
10213       else
10214         break;
10215     }
10216
10217   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10218       + ttl + checksum == 0)
10219     return 0;
10220
10221   /*
10222    * Aligned because we use the real comparison functions
10223    */
10224   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10225
10226   ip = (ip4_header_t *) match;
10227
10228   /* These are realistically matched in practice */
10229   if (src)
10230     ip->src_address.as_u32 = src_val.as_u32;
10231
10232   if (dst)
10233     ip->dst_address.as_u32 = dst_val.as_u32;
10234
10235   if (proto)
10236     ip->protocol = proto_val;
10237
10238
10239   /* These are not, but they're included for completeness */
10240   if (version)
10241     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10242
10243   if (hdr_length)
10244     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10245
10246   if (tos)
10247     ip->tos = tos_val;
10248
10249   if (length)
10250     ip->length = clib_host_to_net_u16 (length_val);
10251
10252   if (ttl)
10253     ip->ttl = ttl_val;
10254
10255   if (checksum)
10256     ip->checksum = clib_host_to_net_u16 (checksum_val);
10257
10258   *matchp = match;
10259   return 1;
10260 }
10261
10262 uword
10263 unformat_ip6_match (unformat_input_t * input, va_list * args)
10264 {
10265   u8 **matchp = va_arg (*args, u8 **);
10266   u8 *match = 0;
10267   ip6_header_t *ip;
10268   int version = 0;
10269   u32 version_val;
10270   u8 traffic_class = 0;
10271   u32 traffic_class_val = 0;
10272   u8 flow_label = 0;
10273   u8 flow_label_val;
10274   int src = 0, dst = 0;
10275   ip6_address_t src_val, dst_val;
10276   int proto = 0;
10277   u32 proto_val;
10278   int payload_length = 0;
10279   u32 payload_length_val;
10280   int hop_limit = 0;
10281   int hop_limit_val;
10282   u32 ip_version_traffic_class_and_flow_label;
10283
10284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10285     {
10286       if (unformat (input, "version %d", &version_val))
10287         version = 1;
10288       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10289         traffic_class = 1;
10290       else if (unformat (input, "flow_label %d", &flow_label_val))
10291         flow_label = 1;
10292       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10293         src = 1;
10294       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10295         dst = 1;
10296       else if (unformat (input, "proto %d", &proto_val))
10297         proto = 1;
10298       else if (unformat (input, "payload_length %d", &payload_length_val))
10299         payload_length = 1;
10300       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10301         hop_limit = 1;
10302       else
10303         break;
10304     }
10305
10306   if (version + traffic_class + flow_label + src + dst + proto +
10307       payload_length + hop_limit == 0)
10308     return 0;
10309
10310   /*
10311    * Aligned because we use the real comparison functions
10312    */
10313   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10314
10315   ip = (ip6_header_t *) match;
10316
10317   if (src)
10318     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10319
10320   if (dst)
10321     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10322
10323   if (proto)
10324     ip->protocol = proto_val;
10325
10326   ip_version_traffic_class_and_flow_label = 0;
10327
10328   if (version)
10329     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10330
10331   if (traffic_class)
10332     ip_version_traffic_class_and_flow_label |=
10333       (traffic_class_val & 0xFF) << 20;
10334
10335   if (flow_label)
10336     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10337
10338   ip->ip_version_traffic_class_and_flow_label =
10339     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10340
10341   if (payload_length)
10342     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10343
10344   if (hop_limit)
10345     ip->hop_limit = hop_limit_val;
10346
10347   *matchp = match;
10348   return 1;
10349 }
10350
10351 uword
10352 unformat_l3_match (unformat_input_t * input, va_list * args)
10353 {
10354   u8 **matchp = va_arg (*args, u8 **);
10355
10356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10357     {
10358       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10359         return 1;
10360       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10361         return 1;
10362       else
10363         break;
10364     }
10365   return 0;
10366 }
10367
10368 uword
10369 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10370 {
10371   u8 *tagp = va_arg (*args, u8 *);
10372   u32 tag;
10373
10374   if (unformat (input, "%d", &tag))
10375     {
10376       tagp[0] = (tag >> 8) & 0x0F;
10377       tagp[1] = tag & 0xFF;
10378       return 1;
10379     }
10380
10381   return 0;
10382 }
10383
10384 uword
10385 unformat_l2_match (unformat_input_t * input, va_list * args)
10386 {
10387   u8 **matchp = va_arg (*args, u8 **);
10388   u8 *match = 0;
10389   u8 src = 0;
10390   u8 src_val[6];
10391   u8 dst = 0;
10392   u8 dst_val[6];
10393   u8 proto = 0;
10394   u16 proto_val;
10395   u8 tag1 = 0;
10396   u8 tag1_val[2];
10397   u8 tag2 = 0;
10398   u8 tag2_val[2];
10399   int len = 14;
10400   u8 ignore_tag1 = 0;
10401   u8 ignore_tag2 = 0;
10402   u8 cos1 = 0;
10403   u8 cos2 = 0;
10404   u32 cos1_val = 0;
10405   u32 cos2_val = 0;
10406
10407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10408     {
10409       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10410         src = 1;
10411       else
10412         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10413         dst = 1;
10414       else if (unformat (input, "proto %U",
10415                          unformat_ethernet_type_host_byte_order, &proto_val))
10416         proto = 1;
10417       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10418         tag1 = 1;
10419       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10420         tag2 = 1;
10421       else if (unformat (input, "ignore-tag1"))
10422         ignore_tag1 = 1;
10423       else if (unformat (input, "ignore-tag2"))
10424         ignore_tag2 = 1;
10425       else if (unformat (input, "cos1 %d", &cos1_val))
10426         cos1 = 1;
10427       else if (unformat (input, "cos2 %d", &cos2_val))
10428         cos2 = 1;
10429       else
10430         break;
10431     }
10432   if ((src + dst + proto + tag1 + tag2 +
10433        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10434     return 0;
10435
10436   if (tag1 || ignore_tag1 || cos1)
10437     len = 18;
10438   if (tag2 || ignore_tag2 || cos2)
10439     len = 22;
10440
10441   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10442
10443   if (dst)
10444     clib_memcpy (match, dst_val, 6);
10445
10446   if (src)
10447     clib_memcpy (match + 6, src_val, 6);
10448
10449   if (tag2)
10450     {
10451       /* inner vlan tag */
10452       match[19] = tag2_val[1];
10453       match[18] = tag2_val[0];
10454       if (cos2)
10455         match[18] |= (cos2_val & 0x7) << 5;
10456       if (proto)
10457         {
10458           match[21] = proto_val & 0xff;
10459           match[20] = proto_val >> 8;
10460         }
10461       if (tag1)
10462         {
10463           match[15] = tag1_val[1];
10464           match[14] = tag1_val[0];
10465         }
10466       if (cos1)
10467         match[14] |= (cos1_val & 0x7) << 5;
10468       *matchp = match;
10469       return 1;
10470     }
10471   if (tag1)
10472     {
10473       match[15] = tag1_val[1];
10474       match[14] = tag1_val[0];
10475       if (proto)
10476         {
10477           match[17] = proto_val & 0xff;
10478           match[16] = proto_val >> 8;
10479         }
10480       if (cos1)
10481         match[14] |= (cos1_val & 0x7) << 5;
10482
10483       *matchp = match;
10484       return 1;
10485     }
10486   if (cos2)
10487     match[18] |= (cos2_val & 0x7) << 5;
10488   if (cos1)
10489     match[14] |= (cos1_val & 0x7) << 5;
10490   if (proto)
10491     {
10492       match[13] = proto_val & 0xff;
10493       match[12] = proto_val >> 8;
10494     }
10495
10496   *matchp = match;
10497   return 1;
10498 }
10499
10500 uword
10501 unformat_qos_source (unformat_input_t * input, va_list * args)
10502 {
10503   int *qs = va_arg (*args, int *);
10504
10505   if (unformat (input, "ip"))
10506     *qs = QOS_SOURCE_IP;
10507   else if (unformat (input, "mpls"))
10508     *qs = QOS_SOURCE_MPLS;
10509   else if (unformat (input, "ext"))
10510     *qs = QOS_SOURCE_EXT;
10511   else if (unformat (input, "vlan"))
10512     *qs = QOS_SOURCE_VLAN;
10513   else
10514     return 0;
10515
10516   return 1;
10517 }
10518 #endif
10519
10520 uword
10521 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10522 {
10523   u8 **matchp = va_arg (*args, u8 **);
10524   u32 skip_n_vectors = va_arg (*args, u32);
10525   u32 match_n_vectors = va_arg (*args, u32);
10526
10527   u8 *match = 0;
10528   u8 *l2 = 0;
10529   u8 *l3 = 0;
10530   u8 *l4 = 0;
10531
10532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10533     {
10534       if (unformat (input, "hex %U", unformat_hex_string, &match))
10535         ;
10536       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10537         ;
10538       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10539         ;
10540       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10541         ;
10542       else
10543         break;
10544     }
10545
10546   if (l4 && !l3)
10547     {
10548       vec_free (match);
10549       vec_free (l2);
10550       vec_free (l4);
10551       return 0;
10552     }
10553
10554   if (match || l2 || l3 || l4)
10555     {
10556       if (l2 || l3 || l4)
10557         {
10558           /* "Win a free Ethernet header in every packet" */
10559           if (l2 == 0)
10560             vec_validate_aligned (l2, 13, sizeof (u32x4));
10561           match = l2;
10562           if (vec_len (l3))
10563             {
10564               vec_append_aligned (match, l3, sizeof (u32x4));
10565               vec_free (l3);
10566             }
10567           if (vec_len (l4))
10568             {
10569               vec_append_aligned (match, l4, sizeof (u32x4));
10570               vec_free (l4);
10571             }
10572         }
10573
10574       /* Make sure the vector is big enough even if key is all 0's */
10575       vec_validate_aligned
10576         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10577          sizeof (u32x4));
10578
10579       /* Set size, include skipped vectors */
10580       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10581
10582       *matchp = match;
10583
10584       return 1;
10585     }
10586
10587   return 0;
10588 }
10589
10590 static int
10591 api_classify_add_del_session (vat_main_t * vam)
10592 {
10593   unformat_input_t *i = vam->input;
10594   vl_api_classify_add_del_session_t *mp;
10595   int is_add = 1;
10596   u32 table_index = ~0;
10597   u32 hit_next_index = ~0;
10598   u32 opaque_index = ~0;
10599   u8 *match = 0;
10600   i32 advance = 0;
10601   u32 skip_n_vectors = 0;
10602   u32 match_n_vectors = 0;
10603   u32 action = 0;
10604   u32 metadata = 0;
10605   int ret;
10606
10607   /*
10608    * Warning: you have to supply skip_n and match_n
10609    * because the API client cant simply look at the classify
10610    * table object.
10611    */
10612
10613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10614     {
10615       if (unformat (i, "del"))
10616         is_add = 0;
10617       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10618                          &hit_next_index))
10619         ;
10620       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10621                          &hit_next_index))
10622         ;
10623       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10624                          &hit_next_index))
10625         ;
10626       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10627         ;
10628       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10629         ;
10630       else if (unformat (i, "opaque-index %d", &opaque_index))
10631         ;
10632       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10633         ;
10634       else if (unformat (i, "match_n %d", &match_n_vectors))
10635         ;
10636       else if (unformat (i, "match %U", api_unformat_classify_match,
10637                          &match, skip_n_vectors, match_n_vectors))
10638         ;
10639       else if (unformat (i, "advance %d", &advance))
10640         ;
10641       else if (unformat (i, "table-index %d", &table_index))
10642         ;
10643       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10644         action = 1;
10645       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10646         action = 2;
10647       else if (unformat (i, "action %d", &action))
10648         ;
10649       else if (unformat (i, "metadata %d", &metadata))
10650         ;
10651       else
10652         break;
10653     }
10654
10655   if (table_index == ~0)
10656     {
10657       errmsg ("Table index required");
10658       return -99;
10659     }
10660
10661   if (is_add && match == 0)
10662     {
10663       errmsg ("Match value required");
10664       return -99;
10665     }
10666
10667   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10668
10669   mp->is_add = is_add;
10670   mp->table_index = ntohl (table_index);
10671   mp->hit_next_index = ntohl (hit_next_index);
10672   mp->opaque_index = ntohl (opaque_index);
10673   mp->advance = ntohl (advance);
10674   mp->action = action;
10675   mp->metadata = ntohl (metadata);
10676   mp->match_len = ntohl (vec_len (match));
10677   clib_memcpy (mp->match, match, vec_len (match));
10678   vec_free (match);
10679
10680   S (mp);
10681   W (ret);
10682   return ret;
10683 }
10684
10685 static int
10686 api_classify_set_interface_ip_table (vat_main_t * vam)
10687 {
10688   unformat_input_t *i = vam->input;
10689   vl_api_classify_set_interface_ip_table_t *mp;
10690   u32 sw_if_index;
10691   int sw_if_index_set;
10692   u32 table_index = ~0;
10693   u8 is_ipv6 = 0;
10694   int ret;
10695
10696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10697     {
10698       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10699         sw_if_index_set = 1;
10700       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10701         sw_if_index_set = 1;
10702       else if (unformat (i, "table %d", &table_index))
10703         ;
10704       else
10705         {
10706           clib_warning ("parse error '%U'", format_unformat_error, i);
10707           return -99;
10708         }
10709     }
10710
10711   if (sw_if_index_set == 0)
10712     {
10713       errmsg ("missing interface name or sw_if_index");
10714       return -99;
10715     }
10716
10717
10718   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10719
10720   mp->sw_if_index = ntohl (sw_if_index);
10721   mp->table_index = ntohl (table_index);
10722   mp->is_ipv6 = is_ipv6;
10723
10724   S (mp);
10725   W (ret);
10726   return ret;
10727 }
10728
10729 static int
10730 api_classify_set_interface_l2_tables (vat_main_t * vam)
10731 {
10732   unformat_input_t *i = vam->input;
10733   vl_api_classify_set_interface_l2_tables_t *mp;
10734   u32 sw_if_index;
10735   int sw_if_index_set;
10736   u32 ip4_table_index = ~0;
10737   u32 ip6_table_index = ~0;
10738   u32 other_table_index = ~0;
10739   u32 is_input = 1;
10740   int ret;
10741
10742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10743     {
10744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10745         sw_if_index_set = 1;
10746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10747         sw_if_index_set = 1;
10748       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10749         ;
10750       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10751         ;
10752       else if (unformat (i, "other-table %d", &other_table_index))
10753         ;
10754       else if (unformat (i, "is-input %d", &is_input))
10755         ;
10756       else
10757         {
10758           clib_warning ("parse error '%U'", format_unformat_error, i);
10759           return -99;
10760         }
10761     }
10762
10763   if (sw_if_index_set == 0)
10764     {
10765       errmsg ("missing interface name or sw_if_index");
10766       return -99;
10767     }
10768
10769
10770   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10771
10772   mp->sw_if_index = ntohl (sw_if_index);
10773   mp->ip4_table_index = ntohl (ip4_table_index);
10774   mp->ip6_table_index = ntohl (ip6_table_index);
10775   mp->other_table_index = ntohl (other_table_index);
10776   mp->is_input = (u8) is_input;
10777
10778   S (mp);
10779   W (ret);
10780   return ret;
10781 }
10782
10783 static int
10784 api_set_ipfix_exporter (vat_main_t * vam)
10785 {
10786   unformat_input_t *i = vam->input;
10787   vl_api_set_ipfix_exporter_t *mp;
10788   ip4_address_t collector_address;
10789   u8 collector_address_set = 0;
10790   u32 collector_port = ~0;
10791   ip4_address_t src_address;
10792   u8 src_address_set = 0;
10793   u32 vrf_id = ~0;
10794   u32 path_mtu = ~0;
10795   u32 template_interval = ~0;
10796   u8 udp_checksum = 0;
10797   int ret;
10798
10799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10800     {
10801       if (unformat (i, "collector_address %U", unformat_ip4_address,
10802                     &collector_address))
10803         collector_address_set = 1;
10804       else if (unformat (i, "collector_port %d", &collector_port))
10805         ;
10806       else if (unformat (i, "src_address %U", unformat_ip4_address,
10807                          &src_address))
10808         src_address_set = 1;
10809       else if (unformat (i, "vrf_id %d", &vrf_id))
10810         ;
10811       else if (unformat (i, "path_mtu %d", &path_mtu))
10812         ;
10813       else if (unformat (i, "template_interval %d", &template_interval))
10814         ;
10815       else if (unformat (i, "udp_checksum"))
10816         udp_checksum = 1;
10817       else
10818         break;
10819     }
10820
10821   if (collector_address_set == 0)
10822     {
10823       errmsg ("collector_address required");
10824       return -99;
10825     }
10826
10827   if (src_address_set == 0)
10828     {
10829       errmsg ("src_address required");
10830       return -99;
10831     }
10832
10833   M (SET_IPFIX_EXPORTER, mp);
10834
10835   memcpy (mp->collector_address.un.ip4, collector_address.data,
10836           sizeof (collector_address.data));
10837   mp->collector_port = htons ((u16) collector_port);
10838   memcpy (mp->src_address.un.ip4, src_address.data,
10839           sizeof (src_address.data));
10840   mp->vrf_id = htonl (vrf_id);
10841   mp->path_mtu = htonl (path_mtu);
10842   mp->template_interval = htonl (template_interval);
10843   mp->udp_checksum = udp_checksum;
10844
10845   S (mp);
10846   W (ret);
10847   return ret;
10848 }
10849
10850 static int
10851 api_set_ipfix_classify_stream (vat_main_t * vam)
10852 {
10853   unformat_input_t *i = vam->input;
10854   vl_api_set_ipfix_classify_stream_t *mp;
10855   u32 domain_id = 0;
10856   u32 src_port = UDP_DST_PORT_ipfix;
10857   int ret;
10858
10859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10860     {
10861       if (unformat (i, "domain %d", &domain_id))
10862         ;
10863       else if (unformat (i, "src_port %d", &src_port))
10864         ;
10865       else
10866         {
10867           errmsg ("unknown input `%U'", format_unformat_error, i);
10868           return -99;
10869         }
10870     }
10871
10872   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10873
10874   mp->domain_id = htonl (domain_id);
10875   mp->src_port = htons ((u16) src_port);
10876
10877   S (mp);
10878   W (ret);
10879   return ret;
10880 }
10881
10882 static int
10883 api_ipfix_classify_table_add_del (vat_main_t * vam)
10884 {
10885   unformat_input_t *i = vam->input;
10886   vl_api_ipfix_classify_table_add_del_t *mp;
10887   int is_add = -1;
10888   u32 classify_table_index = ~0;
10889   u8 ip_version = 0;
10890   u8 transport_protocol = 255;
10891   int ret;
10892
10893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10894     {
10895       if (unformat (i, "add"))
10896         is_add = 1;
10897       else if (unformat (i, "del"))
10898         is_add = 0;
10899       else if (unformat (i, "table %d", &classify_table_index))
10900         ;
10901       else if (unformat (i, "ip4"))
10902         ip_version = 4;
10903       else if (unformat (i, "ip6"))
10904         ip_version = 6;
10905       else if (unformat (i, "tcp"))
10906         transport_protocol = 6;
10907       else if (unformat (i, "udp"))
10908         transport_protocol = 17;
10909       else
10910         {
10911           errmsg ("unknown input `%U'", format_unformat_error, i);
10912           return -99;
10913         }
10914     }
10915
10916   if (is_add == -1)
10917     {
10918       errmsg ("expecting: add|del");
10919       return -99;
10920     }
10921   if (classify_table_index == ~0)
10922     {
10923       errmsg ("classifier table not specified");
10924       return -99;
10925     }
10926   if (ip_version == 0)
10927     {
10928       errmsg ("IP version not specified");
10929       return -99;
10930     }
10931
10932   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10933
10934   mp->is_add = is_add;
10935   mp->table_id = htonl (classify_table_index);
10936   mp->ip_version = ip_version;
10937   mp->transport_protocol = transport_protocol;
10938
10939   S (mp);
10940   W (ret);
10941   return ret;
10942 }
10943
10944 static int
10945 api_get_node_index (vat_main_t * vam)
10946 {
10947   unformat_input_t *i = vam->input;
10948   vl_api_get_node_index_t *mp;
10949   u8 *name = 0;
10950   int ret;
10951
10952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10953     {
10954       if (unformat (i, "node %s", &name))
10955         ;
10956       else
10957         break;
10958     }
10959   if (name == 0)
10960     {
10961       errmsg ("node name required");
10962       return -99;
10963     }
10964   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10965     {
10966       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10967       return -99;
10968     }
10969
10970   M (GET_NODE_INDEX, mp);
10971   clib_memcpy (mp->node_name, name, vec_len (name));
10972   vec_free (name);
10973
10974   S (mp);
10975   W (ret);
10976   return ret;
10977 }
10978
10979 static int
10980 api_get_next_index (vat_main_t * vam)
10981 {
10982   unformat_input_t *i = vam->input;
10983   vl_api_get_next_index_t *mp;
10984   u8 *node_name = 0, *next_node_name = 0;
10985   int ret;
10986
10987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10988     {
10989       if (unformat (i, "node-name %s", &node_name))
10990         ;
10991       else if (unformat (i, "next-node-name %s", &next_node_name))
10992         break;
10993     }
10994
10995   if (node_name == 0)
10996     {
10997       errmsg ("node name required");
10998       return -99;
10999     }
11000   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11001     {
11002       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11003       return -99;
11004     }
11005
11006   if (next_node_name == 0)
11007     {
11008       errmsg ("next node name required");
11009       return -99;
11010     }
11011   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11012     {
11013       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11014       return -99;
11015     }
11016
11017   M (GET_NEXT_INDEX, mp);
11018   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11019   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11020   vec_free (node_name);
11021   vec_free (next_node_name);
11022
11023   S (mp);
11024   W (ret);
11025   return ret;
11026 }
11027
11028 static int
11029 api_add_node_next (vat_main_t * vam)
11030 {
11031   unformat_input_t *i = vam->input;
11032   vl_api_add_node_next_t *mp;
11033   u8 *name = 0;
11034   u8 *next = 0;
11035   int ret;
11036
11037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11038     {
11039       if (unformat (i, "node %s", &name))
11040         ;
11041       else if (unformat (i, "next %s", &next))
11042         ;
11043       else
11044         break;
11045     }
11046   if (name == 0)
11047     {
11048       errmsg ("node name required");
11049       return -99;
11050     }
11051   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11052     {
11053       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11054       return -99;
11055     }
11056   if (next == 0)
11057     {
11058       errmsg ("next node required");
11059       return -99;
11060     }
11061   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11062     {
11063       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11064       return -99;
11065     }
11066
11067   M (ADD_NODE_NEXT, mp);
11068   clib_memcpy (mp->node_name, name, vec_len (name));
11069   clib_memcpy (mp->next_name, next, vec_len (next));
11070   vec_free (name);
11071   vec_free (next);
11072
11073   S (mp);
11074   W (ret);
11075   return ret;
11076 }
11077
11078 static int
11079 api_l2tpv3_create_tunnel (vat_main_t * vam)
11080 {
11081   unformat_input_t *i = vam->input;
11082   ip6_address_t client_address, our_address;
11083   int client_address_set = 0;
11084   int our_address_set = 0;
11085   u32 local_session_id = 0;
11086   u32 remote_session_id = 0;
11087   u64 local_cookie = 0;
11088   u64 remote_cookie = 0;
11089   u8 l2_sublayer_present = 0;
11090   vl_api_l2tpv3_create_tunnel_t *mp;
11091   int ret;
11092
11093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11094     {
11095       if (unformat (i, "client_address %U", unformat_ip6_address,
11096                     &client_address))
11097         client_address_set = 1;
11098       else if (unformat (i, "our_address %U", unformat_ip6_address,
11099                          &our_address))
11100         our_address_set = 1;
11101       else if (unformat (i, "local_session_id %d", &local_session_id))
11102         ;
11103       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11104         ;
11105       else if (unformat (i, "local_cookie %lld", &local_cookie))
11106         ;
11107       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11108         ;
11109       else if (unformat (i, "l2-sublayer-present"))
11110         l2_sublayer_present = 1;
11111       else
11112         break;
11113     }
11114
11115   if (client_address_set == 0)
11116     {
11117       errmsg ("client_address required");
11118       return -99;
11119     }
11120
11121   if (our_address_set == 0)
11122     {
11123       errmsg ("our_address required");
11124       return -99;
11125     }
11126
11127   M (L2TPV3_CREATE_TUNNEL, mp);
11128
11129   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11130                sizeof (ip6_address_t));
11131
11132   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11133                sizeof (ip6_address_t));
11134
11135   mp->local_session_id = ntohl (local_session_id);
11136   mp->remote_session_id = ntohl (remote_session_id);
11137   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11138   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11139   mp->l2_sublayer_present = l2_sublayer_present;
11140
11141   S (mp);
11142   W (ret);
11143   return ret;
11144 }
11145
11146 static int
11147 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11148 {
11149   unformat_input_t *i = vam->input;
11150   u32 sw_if_index;
11151   u8 sw_if_index_set = 0;
11152   u64 new_local_cookie = 0;
11153   u64 new_remote_cookie = 0;
11154   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11155   int ret;
11156
11157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11158     {
11159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11160         sw_if_index_set = 1;
11161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11162         sw_if_index_set = 1;
11163       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11164         ;
11165       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11166         ;
11167       else
11168         break;
11169     }
11170
11171   if (sw_if_index_set == 0)
11172     {
11173       errmsg ("missing interface name or sw_if_index");
11174       return -99;
11175     }
11176
11177   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11178
11179   mp->sw_if_index = ntohl (sw_if_index);
11180   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11181   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11182
11183   S (mp);
11184   W (ret);
11185   return ret;
11186 }
11187
11188 static int
11189 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11190 {
11191   unformat_input_t *i = vam->input;
11192   vl_api_l2tpv3_interface_enable_disable_t *mp;
11193   u32 sw_if_index;
11194   u8 sw_if_index_set = 0;
11195   u8 enable_disable = 1;
11196   int ret;
11197
11198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11199     {
11200       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11201         sw_if_index_set = 1;
11202       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11203         sw_if_index_set = 1;
11204       else if (unformat (i, "enable"))
11205         enable_disable = 1;
11206       else if (unformat (i, "disable"))
11207         enable_disable = 0;
11208       else
11209         break;
11210     }
11211
11212   if (sw_if_index_set == 0)
11213     {
11214       errmsg ("missing interface name or sw_if_index");
11215       return -99;
11216     }
11217
11218   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11219
11220   mp->sw_if_index = ntohl (sw_if_index);
11221   mp->enable_disable = enable_disable;
11222
11223   S (mp);
11224   W (ret);
11225   return ret;
11226 }
11227
11228 static int
11229 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11230 {
11231   unformat_input_t *i = vam->input;
11232   vl_api_l2tpv3_set_lookup_key_t *mp;
11233   u8 key = ~0;
11234   int ret;
11235
11236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11237     {
11238       if (unformat (i, "lookup_v6_src"))
11239         key = L2T_LOOKUP_SRC_ADDRESS;
11240       else if (unformat (i, "lookup_v6_dst"))
11241         key = L2T_LOOKUP_DST_ADDRESS;
11242       else if (unformat (i, "lookup_session_id"))
11243         key = L2T_LOOKUP_SESSION_ID;
11244       else
11245         break;
11246     }
11247
11248   if (key == (u8) ~ 0)
11249     {
11250       errmsg ("l2tp session lookup key unset");
11251       return -99;
11252     }
11253
11254   M (L2TPV3_SET_LOOKUP_KEY, mp);
11255
11256   mp->key = key;
11257
11258   S (mp);
11259   W (ret);
11260   return ret;
11261 }
11262
11263 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11264   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11265 {
11266   vat_main_t *vam = &vat_main;
11267
11268   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11269          format_ip6_address, mp->our_address,
11270          format_ip6_address, mp->client_address,
11271          clib_net_to_host_u32 (mp->sw_if_index));
11272
11273   print (vam->ofp,
11274          "   local cookies %016llx %016llx remote cookie %016llx",
11275          clib_net_to_host_u64 (mp->local_cookie[0]),
11276          clib_net_to_host_u64 (mp->local_cookie[1]),
11277          clib_net_to_host_u64 (mp->remote_cookie));
11278
11279   print (vam->ofp, "   local session-id %d remote session-id %d",
11280          clib_net_to_host_u32 (mp->local_session_id),
11281          clib_net_to_host_u32 (mp->remote_session_id));
11282
11283   print (vam->ofp, "   l2 specific sublayer %s\n",
11284          mp->l2_sublayer_present ? "preset" : "absent");
11285
11286 }
11287
11288 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11289   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11290 {
11291   vat_main_t *vam = &vat_main;
11292   vat_json_node_t *node = NULL;
11293   struct in6_addr addr;
11294
11295   if (VAT_JSON_ARRAY != vam->json_tree.type)
11296     {
11297       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11298       vat_json_init_array (&vam->json_tree);
11299     }
11300   node = vat_json_array_add (&vam->json_tree);
11301
11302   vat_json_init_object (node);
11303
11304   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11305   vat_json_object_add_ip6 (node, "our_address", addr);
11306   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11307   vat_json_object_add_ip6 (node, "client_address", addr);
11308
11309   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11310   vat_json_init_array (lc);
11311   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11312   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11313   vat_json_object_add_uint (node, "remote_cookie",
11314                             clib_net_to_host_u64 (mp->remote_cookie));
11315
11316   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11317   vat_json_object_add_uint (node, "local_session_id",
11318                             clib_net_to_host_u32 (mp->local_session_id));
11319   vat_json_object_add_uint (node, "remote_session_id",
11320                             clib_net_to_host_u32 (mp->remote_session_id));
11321   vat_json_object_add_string_copy (node, "l2_sublayer",
11322                                    mp->l2_sublayer_present ? (u8 *) "present"
11323                                    : (u8 *) "absent");
11324 }
11325
11326 static int
11327 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11328 {
11329   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11330   vl_api_control_ping_t *mp_ping;
11331   int ret;
11332
11333   /* Get list of l2tpv3-tunnel interfaces */
11334   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11335   S (mp);
11336
11337   /* Use a control ping for synchronization */
11338   MPING (CONTROL_PING, mp_ping);
11339   S (mp_ping);
11340
11341   W (ret);
11342   return ret;
11343 }
11344
11345
11346 static void vl_api_sw_interface_tap_v2_details_t_handler
11347   (vl_api_sw_interface_tap_v2_details_t * mp)
11348 {
11349   vat_main_t *vam = &vat_main;
11350
11351   u8 *ip4 =
11352     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11353             mp->host_ip4_prefix.len);
11354   u8 *ip6 =
11355     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11356             mp->host_ip6_prefix.len);
11357
11358   print (vam->ofp,
11359          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11360          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11361          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11362          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11363          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11364
11365   vec_free (ip4);
11366   vec_free (ip6);
11367 }
11368
11369 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11370   (vl_api_sw_interface_tap_v2_details_t * mp)
11371 {
11372   vat_main_t *vam = &vat_main;
11373   vat_json_node_t *node = NULL;
11374
11375   if (VAT_JSON_ARRAY != vam->json_tree.type)
11376     {
11377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11378       vat_json_init_array (&vam->json_tree);
11379     }
11380   node = vat_json_array_add (&vam->json_tree);
11381
11382   vat_json_init_object (node);
11383   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11384   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11385   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11386   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11387   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11388   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11389   vat_json_object_add_string_copy (node, "host_mac_addr",
11390                                    format (0, "%U", format_ethernet_address,
11391                                            &mp->host_mac_addr));
11392   vat_json_object_add_string_copy (node, "host_namespace",
11393                                    mp->host_namespace);
11394   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11395   vat_json_object_add_string_copy (node, "host_ip4_addr",
11396                                    format (0, "%U/%d", format_ip4_address,
11397                                            mp->host_ip4_prefix.address,
11398                                            mp->host_ip4_prefix.len));
11399   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11400                                    format (0, "%U/%d", format_ip6_address,
11401                                            mp->host_ip6_prefix.address,
11402                                            mp->host_ip6_prefix.len));
11403
11404 }
11405
11406 static int
11407 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11408 {
11409   vl_api_sw_interface_tap_v2_dump_t *mp;
11410   vl_api_control_ping_t *mp_ping;
11411   int ret;
11412
11413   print (vam->ofp,
11414          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11415          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11416          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11417          "host_ip6_addr");
11418
11419   /* Get list of tap interfaces */
11420   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11421   S (mp);
11422
11423   /* Use a control ping for synchronization */
11424   MPING (CONTROL_PING, mp_ping);
11425   S (mp_ping);
11426
11427   W (ret);
11428   return ret;
11429 }
11430
11431 static void vl_api_sw_interface_virtio_pci_details_t_handler
11432   (vl_api_sw_interface_virtio_pci_details_t * mp)
11433 {
11434   vat_main_t *vam = &vat_main;
11435
11436   typedef union
11437   {
11438     struct
11439     {
11440       u16 domain;
11441       u8 bus;
11442       u8 slot:5;
11443       u8 function:3;
11444     };
11445     u32 as_u32;
11446   } pci_addr_t;
11447   pci_addr_t addr;
11448
11449   addr.domain = ntohs (mp->pci_addr.domain);
11450   addr.bus = mp->pci_addr.bus;
11451   addr.slot = mp->pci_addr.slot;
11452   addr.function = mp->pci_addr.function;
11453
11454   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11455                          addr.slot, addr.function);
11456
11457   print (vam->ofp,
11458          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11459          pci_addr, ntohl (mp->sw_if_index),
11460          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11461          format_ethernet_address, mp->mac_addr,
11462          clib_net_to_host_u64 (mp->features));
11463   vec_free (pci_addr);
11464 }
11465
11466 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11467   (vl_api_sw_interface_virtio_pci_details_t * mp)
11468 {
11469   vat_main_t *vam = &vat_main;
11470   vat_json_node_t *node = NULL;
11471   vlib_pci_addr_t pci_addr;
11472
11473   if (VAT_JSON_ARRAY != vam->json_tree.type)
11474     {
11475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11476       vat_json_init_array (&vam->json_tree);
11477     }
11478   node = vat_json_array_add (&vam->json_tree);
11479
11480   pci_addr.domain = ntohs (mp->pci_addr.domain);
11481   pci_addr.bus = mp->pci_addr.bus;
11482   pci_addr.slot = mp->pci_addr.slot;
11483   pci_addr.function = mp->pci_addr.function;
11484
11485   vat_json_init_object (node);
11486   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11487   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11488   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11489   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11490   vat_json_object_add_uint (node, "features",
11491                             clib_net_to_host_u64 (mp->features));
11492   vat_json_object_add_string_copy (node, "mac_addr",
11493                                    format (0, "%U", format_ethernet_address,
11494                                            &mp->mac_addr));
11495 }
11496
11497 static int
11498 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11499 {
11500   vl_api_sw_interface_virtio_pci_dump_t *mp;
11501   vl_api_control_ping_t *mp_ping;
11502   int ret;
11503
11504   print (vam->ofp,
11505          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11506          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11507          "mac_addr", "features");
11508
11509   /* Get list of tap interfaces */
11510   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11511   S (mp);
11512
11513   /* Use a control ping for synchronization */
11514   MPING (CONTROL_PING, mp_ping);
11515   S (mp_ping);
11516
11517   W (ret);
11518   return ret;
11519 }
11520
11521 static int
11522 api_vxlan_offload_rx (vat_main_t * vam)
11523 {
11524   unformat_input_t *line_input = vam->input;
11525   vl_api_vxlan_offload_rx_t *mp;
11526   u32 hw_if_index = ~0, rx_if_index = ~0;
11527   u8 is_add = 1;
11528   int ret;
11529
11530   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11531     {
11532       if (unformat (line_input, "del"))
11533         is_add = 0;
11534       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11535                          &hw_if_index))
11536         ;
11537       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11538         ;
11539       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11540                          &rx_if_index))
11541         ;
11542       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11543         ;
11544       else
11545         {
11546           errmsg ("parse error '%U'", format_unformat_error, line_input);
11547           return -99;
11548         }
11549     }
11550
11551   if (hw_if_index == ~0)
11552     {
11553       errmsg ("no hw interface");
11554       return -99;
11555     }
11556
11557   if (rx_if_index == ~0)
11558     {
11559       errmsg ("no rx tunnel");
11560       return -99;
11561     }
11562
11563   M (VXLAN_OFFLOAD_RX, mp);
11564
11565   mp->hw_if_index = ntohl (hw_if_index);
11566   mp->sw_if_index = ntohl (rx_if_index);
11567   mp->enable = is_add;
11568
11569   S (mp);
11570   W (ret);
11571   return ret;
11572 }
11573
11574 static uword unformat_vxlan_decap_next
11575   (unformat_input_t * input, va_list * args)
11576 {
11577   u32 *result = va_arg (*args, u32 *);
11578   u32 tmp;
11579
11580   if (unformat (input, "l2"))
11581     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11582   else if (unformat (input, "%d", &tmp))
11583     *result = tmp;
11584   else
11585     return 0;
11586   return 1;
11587 }
11588
11589 static int
11590 api_vxlan_add_del_tunnel (vat_main_t * vam)
11591 {
11592   unformat_input_t *line_input = vam->input;
11593   vl_api_vxlan_add_del_tunnel_t *mp;
11594   ip46_address_t src, dst;
11595   u8 is_add = 1;
11596   u8 ipv4_set = 0, ipv6_set = 0;
11597   u8 src_set = 0;
11598   u8 dst_set = 0;
11599   u8 grp_set = 0;
11600   u32 instance = ~0;
11601   u32 mcast_sw_if_index = ~0;
11602   u32 encap_vrf_id = 0;
11603   u32 decap_next_index = ~0;
11604   u32 vni = 0;
11605   int ret;
11606
11607   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11608   clib_memset (&src, 0, sizeof src);
11609   clib_memset (&dst, 0, sizeof dst);
11610
11611   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11612     {
11613       if (unformat (line_input, "del"))
11614         is_add = 0;
11615       else if (unformat (line_input, "instance %d", &instance))
11616         ;
11617       else
11618         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11619         {
11620           ipv4_set = 1;
11621           src_set = 1;
11622         }
11623       else
11624         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11625         {
11626           ipv4_set = 1;
11627           dst_set = 1;
11628         }
11629       else
11630         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11631         {
11632           ipv6_set = 1;
11633           src_set = 1;
11634         }
11635       else
11636         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11637         {
11638           ipv6_set = 1;
11639           dst_set = 1;
11640         }
11641       else if (unformat (line_input, "group %U %U",
11642                          unformat_ip4_address, &dst.ip4,
11643                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11644         {
11645           grp_set = dst_set = 1;
11646           ipv4_set = 1;
11647         }
11648       else if (unformat (line_input, "group %U",
11649                          unformat_ip4_address, &dst.ip4))
11650         {
11651           grp_set = dst_set = 1;
11652           ipv4_set = 1;
11653         }
11654       else if (unformat (line_input, "group %U %U",
11655                          unformat_ip6_address, &dst.ip6,
11656                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11657         {
11658           grp_set = dst_set = 1;
11659           ipv6_set = 1;
11660         }
11661       else if (unformat (line_input, "group %U",
11662                          unformat_ip6_address, &dst.ip6))
11663         {
11664           grp_set = dst_set = 1;
11665           ipv6_set = 1;
11666         }
11667       else
11668         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11669         ;
11670       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11671         ;
11672       else if (unformat (line_input, "decap-next %U",
11673                          unformat_vxlan_decap_next, &decap_next_index))
11674         ;
11675       else if (unformat (line_input, "vni %d", &vni))
11676         ;
11677       else
11678         {
11679           errmsg ("parse error '%U'", format_unformat_error, line_input);
11680           return -99;
11681         }
11682     }
11683
11684   if (src_set == 0)
11685     {
11686       errmsg ("tunnel src address not specified");
11687       return -99;
11688     }
11689   if (dst_set == 0)
11690     {
11691       errmsg ("tunnel dst address not specified");
11692       return -99;
11693     }
11694
11695   if (grp_set && !ip46_address_is_multicast (&dst))
11696     {
11697       errmsg ("tunnel group address not multicast");
11698       return -99;
11699     }
11700   if (grp_set && mcast_sw_if_index == ~0)
11701     {
11702       errmsg ("tunnel nonexistent multicast device");
11703       return -99;
11704     }
11705   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11706     {
11707       errmsg ("tunnel dst address must be unicast");
11708       return -99;
11709     }
11710
11711
11712   if (ipv4_set && ipv6_set)
11713     {
11714       errmsg ("both IPv4 and IPv6 addresses specified");
11715       return -99;
11716     }
11717
11718   if ((vni == 0) || (vni >> 24))
11719     {
11720       errmsg ("vni not specified or out of range");
11721       return -99;
11722     }
11723
11724   M (VXLAN_ADD_DEL_TUNNEL, mp);
11725
11726   if (ipv6_set)
11727     {
11728       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11729       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11730     }
11731   else
11732     {
11733       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11734       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11735     }
11736   mp->src_address.af = ipv6_set;
11737   mp->dst_address.af = ipv6_set;
11738
11739   mp->instance = htonl (instance);
11740   mp->encap_vrf_id = ntohl (encap_vrf_id);
11741   mp->decap_next_index = ntohl (decap_next_index);
11742   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11743   mp->vni = ntohl (vni);
11744   mp->is_add = is_add;
11745
11746   S (mp);
11747   W (ret);
11748   return ret;
11749 }
11750
11751 static void vl_api_vxlan_tunnel_details_t_handler
11752   (vl_api_vxlan_tunnel_details_t * mp)
11753 {
11754   vat_main_t *vam = &vat_main;
11755   ip46_address_t src =
11756     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11757   ip46_address_t dst =
11758     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11759
11760   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11761          ntohl (mp->sw_if_index),
11762          ntohl (mp->instance),
11763          format_ip46_address, &src, IP46_TYPE_ANY,
11764          format_ip46_address, &dst, IP46_TYPE_ANY,
11765          ntohl (mp->encap_vrf_id),
11766          ntohl (mp->decap_next_index), ntohl (mp->vni),
11767          ntohl (mp->mcast_sw_if_index));
11768 }
11769
11770 static void vl_api_vxlan_tunnel_details_t_handler_json
11771   (vl_api_vxlan_tunnel_details_t * mp)
11772 {
11773   vat_main_t *vam = &vat_main;
11774   vat_json_node_t *node = NULL;
11775
11776   if (VAT_JSON_ARRAY != vam->json_tree.type)
11777     {
11778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11779       vat_json_init_array (&vam->json_tree);
11780     }
11781   node = vat_json_array_add (&vam->json_tree);
11782
11783   vat_json_init_object (node);
11784   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11785
11786   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11787
11788   if (mp->src_address.af)
11789     {
11790       struct in6_addr ip6;
11791
11792       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11793       vat_json_object_add_ip6 (node, "src_address", ip6);
11794       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11795       vat_json_object_add_ip6 (node, "dst_address", ip6);
11796     }
11797   else
11798     {
11799       struct in_addr ip4;
11800
11801       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11802       vat_json_object_add_ip4 (node, "src_address", ip4);
11803       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11804       vat_json_object_add_ip4 (node, "dst_address", ip4);
11805     }
11806   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11807   vat_json_object_add_uint (node, "decap_next_index",
11808                             ntohl (mp->decap_next_index));
11809   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11810   vat_json_object_add_uint (node, "mcast_sw_if_index",
11811                             ntohl (mp->mcast_sw_if_index));
11812 }
11813
11814 static int
11815 api_vxlan_tunnel_dump (vat_main_t * vam)
11816 {
11817   unformat_input_t *i = vam->input;
11818   vl_api_vxlan_tunnel_dump_t *mp;
11819   vl_api_control_ping_t *mp_ping;
11820   u32 sw_if_index;
11821   u8 sw_if_index_set = 0;
11822   int ret;
11823
11824   /* Parse args required to build the message */
11825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11826     {
11827       if (unformat (i, "sw_if_index %d", &sw_if_index))
11828         sw_if_index_set = 1;
11829       else
11830         break;
11831     }
11832
11833   if (sw_if_index_set == 0)
11834     {
11835       sw_if_index = ~0;
11836     }
11837
11838   if (!vam->json_output)
11839     {
11840       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11841              "sw_if_index", "instance", "src_address", "dst_address",
11842              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11843     }
11844
11845   /* Get list of vxlan-tunnel interfaces */
11846   M (VXLAN_TUNNEL_DUMP, mp);
11847
11848   mp->sw_if_index = htonl (sw_if_index);
11849
11850   S (mp);
11851
11852   /* Use a control ping for synchronization */
11853   MPING (CONTROL_PING, mp_ping);
11854   S (mp_ping);
11855
11856   W (ret);
11857   return ret;
11858 }
11859
11860 static uword unformat_geneve_decap_next
11861   (unformat_input_t * input, va_list * args)
11862 {
11863   u32 *result = va_arg (*args, u32 *);
11864   u32 tmp;
11865
11866   if (unformat (input, "l2"))
11867     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11868   else if (unformat (input, "%d", &tmp))
11869     *result = tmp;
11870   else
11871     return 0;
11872   return 1;
11873 }
11874
11875 static int
11876 api_geneve_add_del_tunnel (vat_main_t * vam)
11877 {
11878   unformat_input_t *line_input = vam->input;
11879   vl_api_geneve_add_del_tunnel_t *mp;
11880   ip46_address_t src, dst;
11881   u8 is_add = 1;
11882   u8 ipv4_set = 0, ipv6_set = 0;
11883   u8 src_set = 0;
11884   u8 dst_set = 0;
11885   u8 grp_set = 0;
11886   u32 mcast_sw_if_index = ~0;
11887   u32 encap_vrf_id = 0;
11888   u32 decap_next_index = ~0;
11889   u32 vni = 0;
11890   int ret;
11891
11892   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11893   clib_memset (&src, 0, sizeof src);
11894   clib_memset (&dst, 0, sizeof dst);
11895
11896   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11897     {
11898       if (unformat (line_input, "del"))
11899         is_add = 0;
11900       else
11901         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11902         {
11903           ipv4_set = 1;
11904           src_set = 1;
11905         }
11906       else
11907         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11908         {
11909           ipv4_set = 1;
11910           dst_set = 1;
11911         }
11912       else
11913         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11914         {
11915           ipv6_set = 1;
11916           src_set = 1;
11917         }
11918       else
11919         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11920         {
11921           ipv6_set = 1;
11922           dst_set = 1;
11923         }
11924       else if (unformat (line_input, "group %U %U",
11925                          unformat_ip4_address, &dst.ip4,
11926                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11927         {
11928           grp_set = dst_set = 1;
11929           ipv4_set = 1;
11930         }
11931       else if (unformat (line_input, "group %U",
11932                          unformat_ip4_address, &dst.ip4))
11933         {
11934           grp_set = dst_set = 1;
11935           ipv4_set = 1;
11936         }
11937       else if (unformat (line_input, "group %U %U",
11938                          unformat_ip6_address, &dst.ip6,
11939                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11940         {
11941           grp_set = dst_set = 1;
11942           ipv6_set = 1;
11943         }
11944       else if (unformat (line_input, "group %U",
11945                          unformat_ip6_address, &dst.ip6))
11946         {
11947           grp_set = dst_set = 1;
11948           ipv6_set = 1;
11949         }
11950       else
11951         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11952         ;
11953       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11954         ;
11955       else if (unformat (line_input, "decap-next %U",
11956                          unformat_geneve_decap_next, &decap_next_index))
11957         ;
11958       else if (unformat (line_input, "vni %d", &vni))
11959         ;
11960       else
11961         {
11962           errmsg ("parse error '%U'", format_unformat_error, line_input);
11963           return -99;
11964         }
11965     }
11966
11967   if (src_set == 0)
11968     {
11969       errmsg ("tunnel src address not specified");
11970       return -99;
11971     }
11972   if (dst_set == 0)
11973     {
11974       errmsg ("tunnel dst address not specified");
11975       return -99;
11976     }
11977
11978   if (grp_set && !ip46_address_is_multicast (&dst))
11979     {
11980       errmsg ("tunnel group address not multicast");
11981       return -99;
11982     }
11983   if (grp_set && mcast_sw_if_index == ~0)
11984     {
11985       errmsg ("tunnel nonexistent multicast device");
11986       return -99;
11987     }
11988   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11989     {
11990       errmsg ("tunnel dst address must be unicast");
11991       return -99;
11992     }
11993
11994
11995   if (ipv4_set && ipv6_set)
11996     {
11997       errmsg ("both IPv4 and IPv6 addresses specified");
11998       return -99;
11999     }
12000
12001   if ((vni == 0) || (vni >> 24))
12002     {
12003       errmsg ("vni not specified or out of range");
12004       return -99;
12005     }
12006
12007   M (GENEVE_ADD_DEL_TUNNEL, mp);
12008
12009   if (ipv6_set)
12010     {
12011       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12012       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12013     }
12014   else
12015     {
12016       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12017       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12018     }
12019   mp->encap_vrf_id = ntohl (encap_vrf_id);
12020   mp->decap_next_index = ntohl (decap_next_index);
12021   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12022   mp->vni = ntohl (vni);
12023   mp->is_add = is_add;
12024
12025   S (mp);
12026   W (ret);
12027   return ret;
12028 }
12029
12030 static void vl_api_geneve_tunnel_details_t_handler
12031   (vl_api_geneve_tunnel_details_t * mp)
12032 {
12033   vat_main_t *vam = &vat_main;
12034   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12035   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12036
12037   if (mp->src_address.af == ADDRESS_IP6)
12038     {
12039       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12040       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12041     }
12042   else
12043     {
12044       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12045       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12046     }
12047
12048   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12049          ntohl (mp->sw_if_index),
12050          format_ip46_address, &src, IP46_TYPE_ANY,
12051          format_ip46_address, &dst, IP46_TYPE_ANY,
12052          ntohl (mp->encap_vrf_id),
12053          ntohl (mp->decap_next_index), ntohl (mp->vni),
12054          ntohl (mp->mcast_sw_if_index));
12055 }
12056
12057 static void vl_api_geneve_tunnel_details_t_handler_json
12058   (vl_api_geneve_tunnel_details_t * mp)
12059 {
12060   vat_main_t *vam = &vat_main;
12061   vat_json_node_t *node = NULL;
12062   bool is_ipv6;
12063
12064   if (VAT_JSON_ARRAY != vam->json_tree.type)
12065     {
12066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12067       vat_json_init_array (&vam->json_tree);
12068     }
12069   node = vat_json_array_add (&vam->json_tree);
12070
12071   vat_json_init_object (node);
12072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12073   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12074   if (is_ipv6)
12075     {
12076       struct in6_addr ip6;
12077
12078       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12079       vat_json_object_add_ip6 (node, "src_address", ip6);
12080       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12081       vat_json_object_add_ip6 (node, "dst_address", ip6);
12082     }
12083   else
12084     {
12085       struct in_addr ip4;
12086
12087       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12088       vat_json_object_add_ip4 (node, "src_address", ip4);
12089       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12090       vat_json_object_add_ip4 (node, "dst_address", ip4);
12091     }
12092   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12093   vat_json_object_add_uint (node, "decap_next_index",
12094                             ntohl (mp->decap_next_index));
12095   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12096   vat_json_object_add_uint (node, "mcast_sw_if_index",
12097                             ntohl (mp->mcast_sw_if_index));
12098 }
12099
12100 static int
12101 api_geneve_tunnel_dump (vat_main_t * vam)
12102 {
12103   unformat_input_t *i = vam->input;
12104   vl_api_geneve_tunnel_dump_t *mp;
12105   vl_api_control_ping_t *mp_ping;
12106   u32 sw_if_index;
12107   u8 sw_if_index_set = 0;
12108   int ret;
12109
12110   /* Parse args required to build the message */
12111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12112     {
12113       if (unformat (i, "sw_if_index %d", &sw_if_index))
12114         sw_if_index_set = 1;
12115       else
12116         break;
12117     }
12118
12119   if (sw_if_index_set == 0)
12120     {
12121       sw_if_index = ~0;
12122     }
12123
12124   if (!vam->json_output)
12125     {
12126       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12127              "sw_if_index", "local_address", "remote_address",
12128              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12129     }
12130
12131   /* Get list of geneve-tunnel interfaces */
12132   M (GENEVE_TUNNEL_DUMP, mp);
12133
12134   mp->sw_if_index = htonl (sw_if_index);
12135
12136   S (mp);
12137
12138   /* Use a control ping for synchronization */
12139   M (CONTROL_PING, mp_ping);
12140   S (mp_ping);
12141
12142   W (ret);
12143   return ret;
12144 }
12145
12146 static int
12147 api_gre_tunnel_add_del (vat_main_t * vam)
12148 {
12149   unformat_input_t *line_input = vam->input;
12150   vl_api_address_t src = { }, dst =
12151   {
12152   };
12153   vl_api_gre_tunnel_add_del_t *mp;
12154   vl_api_gre_tunnel_type_t t_type;
12155   u8 is_add = 1;
12156   u8 src_set = 0;
12157   u8 dst_set = 0;
12158   u32 outer_table_id = 0;
12159   u32 session_id = 0;
12160   u32 instance = ~0;
12161   int ret;
12162
12163   t_type = GRE_API_TUNNEL_TYPE_L3;
12164
12165   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12166     {
12167       if (unformat (line_input, "del"))
12168         is_add = 0;
12169       else if (unformat (line_input, "instance %d", &instance))
12170         ;
12171       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12172         {
12173           src_set = 1;
12174         }
12175       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12176         {
12177           dst_set = 1;
12178         }
12179       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12180         ;
12181       else if (unformat (line_input, "teb"))
12182         t_type = GRE_API_TUNNEL_TYPE_TEB;
12183       else if (unformat (line_input, "erspan %d", &session_id))
12184         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12185       else
12186         {
12187           errmsg ("parse error '%U'", format_unformat_error, line_input);
12188           return -99;
12189         }
12190     }
12191
12192   if (src_set == 0)
12193     {
12194       errmsg ("tunnel src address not specified");
12195       return -99;
12196     }
12197   if (dst_set == 0)
12198     {
12199       errmsg ("tunnel dst address not specified");
12200       return -99;
12201     }
12202
12203   M (GRE_TUNNEL_ADD_DEL, mp);
12204
12205   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12206   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12207
12208   mp->tunnel.instance = htonl (instance);
12209   mp->tunnel.outer_table_id = htonl (outer_table_id);
12210   mp->is_add = is_add;
12211   mp->tunnel.session_id = htons ((u16) session_id);
12212   mp->tunnel.type = htonl (t_type);
12213
12214   S (mp);
12215   W (ret);
12216   return ret;
12217 }
12218
12219 static void vl_api_gre_tunnel_details_t_handler
12220   (vl_api_gre_tunnel_details_t * mp)
12221 {
12222   vat_main_t *vam = &vat_main;
12223
12224   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12225          ntohl (mp->tunnel.sw_if_index),
12226          ntohl (mp->tunnel.instance),
12227          format_vl_api_address, &mp->tunnel.src,
12228          format_vl_api_address, &mp->tunnel.dst,
12229          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12230          ntohl (mp->tunnel.session_id));
12231 }
12232
12233 static void vl_api_gre_tunnel_details_t_handler_json
12234   (vl_api_gre_tunnel_details_t * mp)
12235 {
12236   vat_main_t *vam = &vat_main;
12237   vat_json_node_t *node = NULL;
12238
12239   if (VAT_JSON_ARRAY != vam->json_tree.type)
12240     {
12241       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12242       vat_json_init_array (&vam->json_tree);
12243     }
12244   node = vat_json_array_add (&vam->json_tree);
12245
12246   vat_json_init_object (node);
12247   vat_json_object_add_uint (node, "sw_if_index",
12248                             ntohl (mp->tunnel.sw_if_index));
12249   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12250
12251   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12252   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12253   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12254   vat_json_object_add_uint (node, "outer_table_id",
12255                             ntohl (mp->tunnel.outer_table_id));
12256   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12257 }
12258
12259 static int
12260 api_gre_tunnel_dump (vat_main_t * vam)
12261 {
12262   unformat_input_t *i = vam->input;
12263   vl_api_gre_tunnel_dump_t *mp;
12264   vl_api_control_ping_t *mp_ping;
12265   u32 sw_if_index;
12266   u8 sw_if_index_set = 0;
12267   int ret;
12268
12269   /* Parse args required to build the message */
12270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12271     {
12272       if (unformat (i, "sw_if_index %d", &sw_if_index))
12273         sw_if_index_set = 1;
12274       else
12275         break;
12276     }
12277
12278   if (sw_if_index_set == 0)
12279     {
12280       sw_if_index = ~0;
12281     }
12282
12283   if (!vam->json_output)
12284     {
12285       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12286              "sw_if_index", "instance", "src_address", "dst_address",
12287              "tunnel_type", "outer_fib_id", "session_id");
12288     }
12289
12290   /* Get list of gre-tunnel interfaces */
12291   M (GRE_TUNNEL_DUMP, mp);
12292
12293   mp->sw_if_index = htonl (sw_if_index);
12294
12295   S (mp);
12296
12297   /* Use a control ping for synchronization */
12298   MPING (CONTROL_PING, mp_ping);
12299   S (mp_ping);
12300
12301   W (ret);
12302   return ret;
12303 }
12304
12305 static int
12306 api_l2_fib_clear_table (vat_main_t * vam)
12307 {
12308 //  unformat_input_t * i = vam->input;
12309   vl_api_l2_fib_clear_table_t *mp;
12310   int ret;
12311
12312   M (L2_FIB_CLEAR_TABLE, mp);
12313
12314   S (mp);
12315   W (ret);
12316   return ret;
12317 }
12318
12319 static int
12320 api_l2_interface_efp_filter (vat_main_t * vam)
12321 {
12322   unformat_input_t *i = vam->input;
12323   vl_api_l2_interface_efp_filter_t *mp;
12324   u32 sw_if_index;
12325   u8 enable = 1;
12326   u8 sw_if_index_set = 0;
12327   int ret;
12328
12329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12330     {
12331       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12332         sw_if_index_set = 1;
12333       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12334         sw_if_index_set = 1;
12335       else if (unformat (i, "enable"))
12336         enable = 1;
12337       else if (unformat (i, "disable"))
12338         enable = 0;
12339       else
12340         {
12341           clib_warning ("parse error '%U'", format_unformat_error, i);
12342           return -99;
12343         }
12344     }
12345
12346   if (sw_if_index_set == 0)
12347     {
12348       errmsg ("missing sw_if_index");
12349       return -99;
12350     }
12351
12352   M (L2_INTERFACE_EFP_FILTER, mp);
12353
12354   mp->sw_if_index = ntohl (sw_if_index);
12355   mp->enable_disable = enable;
12356
12357   S (mp);
12358   W (ret);
12359   return ret;
12360 }
12361
12362 #define foreach_vtr_op                          \
12363 _("disable",  L2_VTR_DISABLED)                  \
12364 _("push-1",  L2_VTR_PUSH_1)                     \
12365 _("push-2",  L2_VTR_PUSH_2)                     \
12366 _("pop-1",  L2_VTR_POP_1)                       \
12367 _("pop-2",  L2_VTR_POP_2)                       \
12368 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12369 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12370 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12371 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12372
12373 static int
12374 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12375 {
12376   unformat_input_t *i = vam->input;
12377   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12378   u32 sw_if_index;
12379   u8 sw_if_index_set = 0;
12380   u8 vtr_op_set = 0;
12381   u32 vtr_op = 0;
12382   u32 push_dot1q = 1;
12383   u32 tag1 = ~0;
12384   u32 tag2 = ~0;
12385   int ret;
12386
12387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12388     {
12389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12390         sw_if_index_set = 1;
12391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12392         sw_if_index_set = 1;
12393       else if (unformat (i, "vtr_op %d", &vtr_op))
12394         vtr_op_set = 1;
12395 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12396       foreach_vtr_op
12397 #undef _
12398         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12399         ;
12400       else if (unformat (i, "tag1 %d", &tag1))
12401         ;
12402       else if (unformat (i, "tag2 %d", &tag2))
12403         ;
12404       else
12405         {
12406           clib_warning ("parse error '%U'", format_unformat_error, i);
12407           return -99;
12408         }
12409     }
12410
12411   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12412     {
12413       errmsg ("missing vtr operation or sw_if_index");
12414       return -99;
12415     }
12416
12417   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12418   mp->sw_if_index = ntohl (sw_if_index);
12419   mp->vtr_op = ntohl (vtr_op);
12420   mp->push_dot1q = ntohl (push_dot1q);
12421   mp->tag1 = ntohl (tag1);
12422   mp->tag2 = ntohl (tag2);
12423
12424   S (mp);
12425   W (ret);
12426   return ret;
12427 }
12428
12429 static int
12430 api_create_vhost_user_if (vat_main_t * vam)
12431 {
12432   unformat_input_t *i = vam->input;
12433   vl_api_create_vhost_user_if_t *mp;
12434   u8 *file_name;
12435   u8 is_server = 0;
12436   u8 file_name_set = 0;
12437   u32 custom_dev_instance = ~0;
12438   u8 hwaddr[6];
12439   u8 use_custom_mac = 0;
12440   u8 disable_mrg_rxbuf = 0;
12441   u8 disable_indirect_desc = 0;
12442   u8 *tag = 0;
12443   u8 enable_gso = 0;
12444   u8 enable_packed = 0;
12445   int ret;
12446
12447   /* Shut up coverity */
12448   clib_memset (hwaddr, 0, sizeof (hwaddr));
12449
12450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12451     {
12452       if (unformat (i, "socket %s", &file_name))
12453         {
12454           file_name_set = 1;
12455         }
12456       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12457         ;
12458       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12459         use_custom_mac = 1;
12460       else if (unformat (i, "server"))
12461         is_server = 1;
12462       else if (unformat (i, "disable_mrg_rxbuf"))
12463         disable_mrg_rxbuf = 1;
12464       else if (unformat (i, "disable_indirect_desc"))
12465         disable_indirect_desc = 1;
12466       else if (unformat (i, "gso"))
12467         enable_gso = 1;
12468       else if (unformat (i, "packed"))
12469         enable_packed = 1;
12470       else if (unformat (i, "tag %s", &tag))
12471         ;
12472       else
12473         break;
12474     }
12475
12476   if (file_name_set == 0)
12477     {
12478       errmsg ("missing socket file name");
12479       return -99;
12480     }
12481
12482   if (vec_len (file_name) > 255)
12483     {
12484       errmsg ("socket file name too long");
12485       return -99;
12486     }
12487   vec_add1 (file_name, 0);
12488
12489   M (CREATE_VHOST_USER_IF, mp);
12490
12491   mp->is_server = is_server;
12492   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12493   mp->disable_indirect_desc = disable_indirect_desc;
12494   mp->enable_gso = enable_gso;
12495   mp->enable_packed = enable_packed;
12496   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12497   vec_free (file_name);
12498   if (custom_dev_instance != ~0)
12499     {
12500       mp->renumber = 1;
12501       mp->custom_dev_instance = ntohl (custom_dev_instance);
12502     }
12503
12504   mp->use_custom_mac = use_custom_mac;
12505   clib_memcpy (mp->mac_address, hwaddr, 6);
12506   if (tag)
12507     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12508   vec_free (tag);
12509
12510   S (mp);
12511   W (ret);
12512   return ret;
12513 }
12514
12515 static int
12516 api_modify_vhost_user_if (vat_main_t * vam)
12517 {
12518   unformat_input_t *i = vam->input;
12519   vl_api_modify_vhost_user_if_t *mp;
12520   u8 *file_name;
12521   u8 is_server = 0;
12522   u8 file_name_set = 0;
12523   u32 custom_dev_instance = ~0;
12524   u8 sw_if_index_set = 0;
12525   u32 sw_if_index = (u32) ~ 0;
12526   u8 enable_gso = 0;
12527   u8 enable_packed = 0;
12528   int ret;
12529
12530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12531     {
12532       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12533         sw_if_index_set = 1;
12534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12535         sw_if_index_set = 1;
12536       else if (unformat (i, "socket %s", &file_name))
12537         {
12538           file_name_set = 1;
12539         }
12540       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12541         ;
12542       else if (unformat (i, "server"))
12543         is_server = 1;
12544       else if (unformat (i, "gso"))
12545         enable_gso = 1;
12546       else if (unformat (i, "packed"))
12547         enable_packed = 1;
12548       else
12549         break;
12550     }
12551
12552   if (sw_if_index_set == 0)
12553     {
12554       errmsg ("missing sw_if_index or interface name");
12555       return -99;
12556     }
12557
12558   if (file_name_set == 0)
12559     {
12560       errmsg ("missing socket file name");
12561       return -99;
12562     }
12563
12564   if (vec_len (file_name) > 255)
12565     {
12566       errmsg ("socket file name too long");
12567       return -99;
12568     }
12569   vec_add1 (file_name, 0);
12570
12571   M (MODIFY_VHOST_USER_IF, mp);
12572
12573   mp->sw_if_index = ntohl (sw_if_index);
12574   mp->is_server = is_server;
12575   mp->enable_gso = enable_gso;
12576   mp->enable_packed = enable_packed;
12577   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12578   vec_free (file_name);
12579   if (custom_dev_instance != ~0)
12580     {
12581       mp->renumber = 1;
12582       mp->custom_dev_instance = ntohl (custom_dev_instance);
12583     }
12584
12585   S (mp);
12586   W (ret);
12587   return ret;
12588 }
12589
12590 static int
12591 api_delete_vhost_user_if (vat_main_t * vam)
12592 {
12593   unformat_input_t *i = vam->input;
12594   vl_api_delete_vhost_user_if_t *mp;
12595   u32 sw_if_index = ~0;
12596   u8 sw_if_index_set = 0;
12597   int ret;
12598
12599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12600     {
12601       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12602         sw_if_index_set = 1;
12603       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12604         sw_if_index_set = 1;
12605       else
12606         break;
12607     }
12608
12609   if (sw_if_index_set == 0)
12610     {
12611       errmsg ("missing sw_if_index or interface name");
12612       return -99;
12613     }
12614
12615
12616   M (DELETE_VHOST_USER_IF, mp);
12617
12618   mp->sw_if_index = ntohl (sw_if_index);
12619
12620   S (mp);
12621   W (ret);
12622   return ret;
12623 }
12624
12625 static void vl_api_sw_interface_vhost_user_details_t_handler
12626   (vl_api_sw_interface_vhost_user_details_t * mp)
12627 {
12628   vat_main_t *vam = &vat_main;
12629   u64 features;
12630
12631   features =
12632     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12633                                                     clib_net_to_host_u32
12634                                                     (mp->features_last_32) <<
12635                                                     32);
12636
12637   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12638          (char *) mp->interface_name,
12639          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12640          features, mp->is_server,
12641          ntohl (mp->num_regions), (char *) mp->sock_filename);
12642   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12643 }
12644
12645 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12646   (vl_api_sw_interface_vhost_user_details_t * mp)
12647 {
12648   vat_main_t *vam = &vat_main;
12649   vat_json_node_t *node = NULL;
12650
12651   if (VAT_JSON_ARRAY != vam->json_tree.type)
12652     {
12653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12654       vat_json_init_array (&vam->json_tree);
12655     }
12656   node = vat_json_array_add (&vam->json_tree);
12657
12658   vat_json_init_object (node);
12659   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12660   vat_json_object_add_string_copy (node, "interface_name",
12661                                    mp->interface_name);
12662   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12663                             ntohl (mp->virtio_net_hdr_sz));
12664   vat_json_object_add_uint (node, "features_first_32",
12665                             clib_net_to_host_u32 (mp->features_first_32));
12666   vat_json_object_add_uint (node, "features_last_32",
12667                             clib_net_to_host_u32 (mp->features_last_32));
12668   vat_json_object_add_uint (node, "is_server", mp->is_server);
12669   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12670   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12671   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12672 }
12673
12674 static int
12675 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12676 {
12677   unformat_input_t *i = vam->input;
12678   vl_api_sw_interface_vhost_user_dump_t *mp;
12679   vl_api_control_ping_t *mp_ping;
12680   int ret;
12681   u32 sw_if_index = ~0;
12682
12683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12684     {
12685       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12686         ;
12687       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12688         ;
12689       else
12690         break;
12691     }
12692
12693   print (vam->ofp,
12694          "Interface name            idx hdr_sz features server regions filename");
12695
12696   /* Get list of vhost-user interfaces */
12697   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12698   mp->sw_if_index = ntohl (sw_if_index);
12699   S (mp);
12700
12701   /* Use a control ping for synchronization */
12702   MPING (CONTROL_PING, mp_ping);
12703   S (mp_ping);
12704
12705   W (ret);
12706   return ret;
12707 }
12708
12709 static int
12710 api_show_version (vat_main_t * vam)
12711 {
12712   vl_api_show_version_t *mp;
12713   int ret;
12714
12715   M (SHOW_VERSION, mp);
12716
12717   S (mp);
12718   W (ret);
12719   return ret;
12720 }
12721
12722
12723 static int
12724 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12725 {
12726   unformat_input_t *line_input = vam->input;
12727   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12728   ip46_address_t local, remote;
12729   u8 is_add = 1;
12730   u8 local_set = 0;
12731   u8 remote_set = 0;
12732   u8 grp_set = 0;
12733   u32 mcast_sw_if_index = ~0;
12734   u32 encap_vrf_id = 0;
12735   u32 decap_vrf_id = 0;
12736   u8 protocol = ~0;
12737   u32 vni;
12738   u8 vni_set = 0;
12739   int ret;
12740
12741   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12742     {
12743       if (unformat (line_input, "del"))
12744         is_add = 0;
12745       else if (unformat (line_input, "local %U",
12746                          unformat_ip46_address, &local))
12747         {
12748           local_set = 1;
12749         }
12750       else if (unformat (line_input, "remote %U",
12751                          unformat_ip46_address, &remote))
12752         {
12753           remote_set = 1;
12754         }
12755       else if (unformat (line_input, "group %U %U",
12756                          unformat_ip46_address, &remote,
12757                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12758         {
12759           grp_set = remote_set = 1;
12760         }
12761       else if (unformat (line_input, "group %U",
12762                          unformat_ip46_address, &remote))
12763         {
12764           grp_set = remote_set = 1;
12765         }
12766       else
12767         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12768         ;
12769       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12770         ;
12771       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12772         ;
12773       else if (unformat (line_input, "vni %d", &vni))
12774         vni_set = 1;
12775       else if (unformat (line_input, "next-ip4"))
12776         protocol = 1;
12777       else if (unformat (line_input, "next-ip6"))
12778         protocol = 2;
12779       else if (unformat (line_input, "next-ethernet"))
12780         protocol = 3;
12781       else if (unformat (line_input, "next-nsh"))
12782         protocol = 4;
12783       else
12784         {
12785           errmsg ("parse error '%U'", format_unformat_error, line_input);
12786           return -99;
12787         }
12788     }
12789
12790   if (local_set == 0)
12791     {
12792       errmsg ("tunnel local address not specified");
12793       return -99;
12794     }
12795   if (remote_set == 0)
12796     {
12797       errmsg ("tunnel remote address not specified");
12798       return -99;
12799     }
12800   if (grp_set && mcast_sw_if_index == ~0)
12801     {
12802       errmsg ("tunnel nonexistent multicast device");
12803       return -99;
12804     }
12805   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12806     {
12807       errmsg ("both IPv4 and IPv6 addresses specified");
12808       return -99;
12809     }
12810
12811   if (vni_set == 0)
12812     {
12813       errmsg ("vni not specified");
12814       return -99;
12815     }
12816
12817   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12818
12819   ip_address_encode (&local,
12820                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12821                      IP46_TYPE_IP6, &mp->local);
12822   ip_address_encode (&remote,
12823                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12824                      IP46_TYPE_IP6, &mp->remote);
12825
12826   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12827   mp->encap_vrf_id = ntohl (encap_vrf_id);
12828   mp->decap_vrf_id = ntohl (decap_vrf_id);
12829   mp->protocol = protocol;
12830   mp->vni = ntohl (vni);
12831   mp->is_add = is_add;
12832
12833   S (mp);
12834   W (ret);
12835   return ret;
12836 }
12837
12838 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12839   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12840 {
12841   vat_main_t *vam = &vat_main;
12842   ip46_address_t local, remote;
12843
12844   ip_address_decode (&mp->local, &local);
12845   ip_address_decode (&mp->remote, &remote);
12846
12847   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12848          ntohl (mp->sw_if_index),
12849          format_ip46_address, &local, IP46_TYPE_ANY,
12850          format_ip46_address, &remote, IP46_TYPE_ANY,
12851          ntohl (mp->vni), mp->protocol,
12852          ntohl (mp->mcast_sw_if_index),
12853          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12854 }
12855
12856
12857 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12858   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12859 {
12860   vat_main_t *vam = &vat_main;
12861   vat_json_node_t *node = NULL;
12862   struct in_addr ip4;
12863   struct in6_addr ip6;
12864   ip46_address_t local, remote;
12865
12866   ip_address_decode (&mp->local, &local);
12867   ip_address_decode (&mp->remote, &remote);
12868
12869   if (VAT_JSON_ARRAY != vam->json_tree.type)
12870     {
12871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12872       vat_json_init_array (&vam->json_tree);
12873     }
12874   node = vat_json_array_add (&vam->json_tree);
12875
12876   vat_json_init_object (node);
12877   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12878   if (ip46_address_is_ip4 (&local))
12879     {
12880       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12881       vat_json_object_add_ip4 (node, "local", ip4);
12882       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12883       vat_json_object_add_ip4 (node, "remote", ip4);
12884     }
12885   else
12886     {
12887       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12888       vat_json_object_add_ip6 (node, "local", ip6);
12889       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12890       vat_json_object_add_ip6 (node, "remote", ip6);
12891     }
12892   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12893   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12894   vat_json_object_add_uint (node, "mcast_sw_if_index",
12895                             ntohl (mp->mcast_sw_if_index));
12896   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12897   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12898   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12899 }
12900
12901 static int
12902 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12903 {
12904   unformat_input_t *i = vam->input;
12905   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12906   vl_api_control_ping_t *mp_ping;
12907   u32 sw_if_index;
12908   u8 sw_if_index_set = 0;
12909   int ret;
12910
12911   /* Parse args required to build the message */
12912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12913     {
12914       if (unformat (i, "sw_if_index %d", &sw_if_index))
12915         sw_if_index_set = 1;
12916       else
12917         break;
12918     }
12919
12920   if (sw_if_index_set == 0)
12921     {
12922       sw_if_index = ~0;
12923     }
12924
12925   if (!vam->json_output)
12926     {
12927       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12928              "sw_if_index", "local", "remote", "vni",
12929              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12930     }
12931
12932   /* Get list of vxlan-tunnel interfaces */
12933   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12934
12935   mp->sw_if_index = htonl (sw_if_index);
12936
12937   S (mp);
12938
12939   /* Use a control ping for synchronization */
12940   MPING (CONTROL_PING, mp_ping);
12941   S (mp_ping);
12942
12943   W (ret);
12944   return ret;
12945 }
12946
12947 static void vl_api_l2_fib_table_details_t_handler
12948   (vl_api_l2_fib_table_details_t * mp)
12949 {
12950   vat_main_t *vam = &vat_main;
12951
12952   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12953          "       %d       %d     %d",
12954          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12955          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12956          mp->bvi_mac);
12957 }
12958
12959 static void vl_api_l2_fib_table_details_t_handler_json
12960   (vl_api_l2_fib_table_details_t * mp)
12961 {
12962   vat_main_t *vam = &vat_main;
12963   vat_json_node_t *node = NULL;
12964
12965   if (VAT_JSON_ARRAY != vam->json_tree.type)
12966     {
12967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12968       vat_json_init_array (&vam->json_tree);
12969     }
12970   node = vat_json_array_add (&vam->json_tree);
12971
12972   vat_json_init_object (node);
12973   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12974   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12975   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12976   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12977   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12978   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12979 }
12980
12981 static int
12982 api_l2_fib_table_dump (vat_main_t * vam)
12983 {
12984   unformat_input_t *i = vam->input;
12985   vl_api_l2_fib_table_dump_t *mp;
12986   vl_api_control_ping_t *mp_ping;
12987   u32 bd_id;
12988   u8 bd_id_set = 0;
12989   int ret;
12990
12991   /* Parse args required to build the message */
12992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12993     {
12994       if (unformat (i, "bd_id %d", &bd_id))
12995         bd_id_set = 1;
12996       else
12997         break;
12998     }
12999
13000   if (bd_id_set == 0)
13001     {
13002       errmsg ("missing bridge domain");
13003       return -99;
13004     }
13005
13006   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13007
13008   /* Get list of l2 fib entries */
13009   M (L2_FIB_TABLE_DUMP, mp);
13010
13011   mp->bd_id = ntohl (bd_id);
13012   S (mp);
13013
13014   /* Use a control ping for synchronization */
13015   MPING (CONTROL_PING, mp_ping);
13016   S (mp_ping);
13017
13018   W (ret);
13019   return ret;
13020 }
13021
13022
13023 static int
13024 api_interface_name_renumber (vat_main_t * vam)
13025 {
13026   unformat_input_t *line_input = vam->input;
13027   vl_api_interface_name_renumber_t *mp;
13028   u32 sw_if_index = ~0;
13029   u32 new_show_dev_instance = ~0;
13030   int ret;
13031
13032   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13033     {
13034       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13035                     &sw_if_index))
13036         ;
13037       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13038         ;
13039       else if (unformat (line_input, "new_show_dev_instance %d",
13040                          &new_show_dev_instance))
13041         ;
13042       else
13043         break;
13044     }
13045
13046   if (sw_if_index == ~0)
13047     {
13048       errmsg ("missing interface name or sw_if_index");
13049       return -99;
13050     }
13051
13052   if (new_show_dev_instance == ~0)
13053     {
13054       errmsg ("missing new_show_dev_instance");
13055       return -99;
13056     }
13057
13058   M (INTERFACE_NAME_RENUMBER, mp);
13059
13060   mp->sw_if_index = ntohl (sw_if_index);
13061   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13062
13063   S (mp);
13064   W (ret);
13065   return ret;
13066 }
13067
13068 static int
13069 api_want_l2_macs_events (vat_main_t * vam)
13070 {
13071   unformat_input_t *line_input = vam->input;
13072   vl_api_want_l2_macs_events_t *mp;
13073   u8 enable_disable = 1;
13074   u32 scan_delay = 0;
13075   u32 max_macs_in_event = 0;
13076   u32 learn_limit = 0;
13077   int ret;
13078
13079   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13080     {
13081       if (unformat (line_input, "learn-limit %d", &learn_limit))
13082         ;
13083       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13084         ;
13085       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13086         ;
13087       else if (unformat (line_input, "disable"))
13088         enable_disable = 0;
13089       else
13090         break;
13091     }
13092
13093   M (WANT_L2_MACS_EVENTS, mp);
13094   mp->enable_disable = enable_disable;
13095   mp->pid = htonl (getpid ());
13096   mp->learn_limit = htonl (learn_limit);
13097   mp->scan_delay = (u8) scan_delay;
13098   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13099   S (mp);
13100   W (ret);
13101   return ret;
13102 }
13103
13104 static int
13105 api_input_acl_set_interface (vat_main_t * vam)
13106 {
13107   unformat_input_t *i = vam->input;
13108   vl_api_input_acl_set_interface_t *mp;
13109   u32 sw_if_index;
13110   int sw_if_index_set;
13111   u32 ip4_table_index = ~0;
13112   u32 ip6_table_index = ~0;
13113   u32 l2_table_index = ~0;
13114   u8 is_add = 1;
13115   int ret;
13116
13117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13118     {
13119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13120         sw_if_index_set = 1;
13121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13122         sw_if_index_set = 1;
13123       else if (unformat (i, "del"))
13124         is_add = 0;
13125       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13126         ;
13127       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13128         ;
13129       else if (unformat (i, "l2-table %d", &l2_table_index))
13130         ;
13131       else
13132         {
13133           clib_warning ("parse error '%U'", format_unformat_error, i);
13134           return -99;
13135         }
13136     }
13137
13138   if (sw_if_index_set == 0)
13139     {
13140       errmsg ("missing interface name or sw_if_index");
13141       return -99;
13142     }
13143
13144   M (INPUT_ACL_SET_INTERFACE, mp);
13145
13146   mp->sw_if_index = ntohl (sw_if_index);
13147   mp->ip4_table_index = ntohl (ip4_table_index);
13148   mp->ip6_table_index = ntohl (ip6_table_index);
13149   mp->l2_table_index = ntohl (l2_table_index);
13150   mp->is_add = is_add;
13151
13152   S (mp);
13153   W (ret);
13154   return ret;
13155 }
13156
13157 static int
13158 api_output_acl_set_interface (vat_main_t * vam)
13159 {
13160   unformat_input_t *i = vam->input;
13161   vl_api_output_acl_set_interface_t *mp;
13162   u32 sw_if_index;
13163   int sw_if_index_set;
13164   u32 ip4_table_index = ~0;
13165   u32 ip6_table_index = ~0;
13166   u32 l2_table_index = ~0;
13167   u8 is_add = 1;
13168   int ret;
13169
13170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13171     {
13172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13173         sw_if_index_set = 1;
13174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13175         sw_if_index_set = 1;
13176       else if (unformat (i, "del"))
13177         is_add = 0;
13178       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13179         ;
13180       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13181         ;
13182       else if (unformat (i, "l2-table %d", &l2_table_index))
13183         ;
13184       else
13185         {
13186           clib_warning ("parse error '%U'", format_unformat_error, i);
13187           return -99;
13188         }
13189     }
13190
13191   if (sw_if_index_set == 0)
13192     {
13193       errmsg ("missing interface name or sw_if_index");
13194       return -99;
13195     }
13196
13197   M (OUTPUT_ACL_SET_INTERFACE, mp);
13198
13199   mp->sw_if_index = ntohl (sw_if_index);
13200   mp->ip4_table_index = ntohl (ip4_table_index);
13201   mp->ip6_table_index = ntohl (ip6_table_index);
13202   mp->l2_table_index = ntohl (l2_table_index);
13203   mp->is_add = is_add;
13204
13205   S (mp);
13206   W (ret);
13207   return ret;
13208 }
13209
13210 static int
13211 api_ip_address_dump (vat_main_t * vam)
13212 {
13213   unformat_input_t *i = vam->input;
13214   vl_api_ip_address_dump_t *mp;
13215   vl_api_control_ping_t *mp_ping;
13216   u32 sw_if_index = ~0;
13217   u8 sw_if_index_set = 0;
13218   u8 ipv4_set = 0;
13219   u8 ipv6_set = 0;
13220   int ret;
13221
13222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13223     {
13224       if (unformat (i, "sw_if_index %d", &sw_if_index))
13225         sw_if_index_set = 1;
13226       else
13227         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13228         sw_if_index_set = 1;
13229       else if (unformat (i, "ipv4"))
13230         ipv4_set = 1;
13231       else if (unformat (i, "ipv6"))
13232         ipv6_set = 1;
13233       else
13234         break;
13235     }
13236
13237   if (ipv4_set && ipv6_set)
13238     {
13239       errmsg ("ipv4 and ipv6 flags cannot be both set");
13240       return -99;
13241     }
13242
13243   if ((!ipv4_set) && (!ipv6_set))
13244     {
13245       errmsg ("no ipv4 nor ipv6 flag set");
13246       return -99;
13247     }
13248
13249   if (sw_if_index_set == 0)
13250     {
13251       errmsg ("missing interface name or sw_if_index");
13252       return -99;
13253     }
13254
13255   vam->current_sw_if_index = sw_if_index;
13256   vam->is_ipv6 = ipv6_set;
13257
13258   M (IP_ADDRESS_DUMP, mp);
13259   mp->sw_if_index = ntohl (sw_if_index);
13260   mp->is_ipv6 = ipv6_set;
13261   S (mp);
13262
13263   /* Use a control ping for synchronization */
13264   MPING (CONTROL_PING, mp_ping);
13265   S (mp_ping);
13266
13267   W (ret);
13268   return ret;
13269 }
13270
13271 static int
13272 api_ip_dump (vat_main_t * vam)
13273 {
13274   vl_api_ip_dump_t *mp;
13275   vl_api_control_ping_t *mp_ping;
13276   unformat_input_t *in = vam->input;
13277   int ipv4_set = 0;
13278   int ipv6_set = 0;
13279   int is_ipv6;
13280   int i;
13281   int ret;
13282
13283   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13284     {
13285       if (unformat (in, "ipv4"))
13286         ipv4_set = 1;
13287       else if (unformat (in, "ipv6"))
13288         ipv6_set = 1;
13289       else
13290         break;
13291     }
13292
13293   if (ipv4_set && ipv6_set)
13294     {
13295       errmsg ("ipv4 and ipv6 flags cannot be both set");
13296       return -99;
13297     }
13298
13299   if ((!ipv4_set) && (!ipv6_set))
13300     {
13301       errmsg ("no ipv4 nor ipv6 flag set");
13302       return -99;
13303     }
13304
13305   is_ipv6 = ipv6_set;
13306   vam->is_ipv6 = is_ipv6;
13307
13308   /* free old data */
13309   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13310     {
13311       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13312     }
13313   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13314
13315   M (IP_DUMP, mp);
13316   mp->is_ipv6 = ipv6_set;
13317   S (mp);
13318
13319   /* Use a control ping for synchronization */
13320   MPING (CONTROL_PING, mp_ping);
13321   S (mp_ping);
13322
13323   W (ret);
13324   return ret;
13325 }
13326
13327 static int
13328 api_ipsec_spd_add_del (vat_main_t * vam)
13329 {
13330   unformat_input_t *i = vam->input;
13331   vl_api_ipsec_spd_add_del_t *mp;
13332   u32 spd_id = ~0;
13333   u8 is_add = 1;
13334   int ret;
13335
13336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13337     {
13338       if (unformat (i, "spd_id %d", &spd_id))
13339         ;
13340       else if (unformat (i, "del"))
13341         is_add = 0;
13342       else
13343         {
13344           clib_warning ("parse error '%U'", format_unformat_error, i);
13345           return -99;
13346         }
13347     }
13348   if (spd_id == ~0)
13349     {
13350       errmsg ("spd_id must be set");
13351       return -99;
13352     }
13353
13354   M (IPSEC_SPD_ADD_DEL, mp);
13355
13356   mp->spd_id = ntohl (spd_id);
13357   mp->is_add = is_add;
13358
13359   S (mp);
13360   W (ret);
13361   return ret;
13362 }
13363
13364 static int
13365 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13366 {
13367   unformat_input_t *i = vam->input;
13368   vl_api_ipsec_interface_add_del_spd_t *mp;
13369   u32 sw_if_index;
13370   u8 sw_if_index_set = 0;
13371   u32 spd_id = (u32) ~ 0;
13372   u8 is_add = 1;
13373   int ret;
13374
13375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13376     {
13377       if (unformat (i, "del"))
13378         is_add = 0;
13379       else if (unformat (i, "spd_id %d", &spd_id))
13380         ;
13381       else
13382         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13383         sw_if_index_set = 1;
13384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13385         sw_if_index_set = 1;
13386       else
13387         {
13388           clib_warning ("parse error '%U'", format_unformat_error, i);
13389           return -99;
13390         }
13391
13392     }
13393
13394   if (spd_id == (u32) ~ 0)
13395     {
13396       errmsg ("spd_id must be set");
13397       return -99;
13398     }
13399
13400   if (sw_if_index_set == 0)
13401     {
13402       errmsg ("missing interface name or sw_if_index");
13403       return -99;
13404     }
13405
13406   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13407
13408   mp->spd_id = ntohl (spd_id);
13409   mp->sw_if_index = ntohl (sw_if_index);
13410   mp->is_add = is_add;
13411
13412   S (mp);
13413   W (ret);
13414   return ret;
13415 }
13416
13417 static int
13418 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13419 {
13420   unformat_input_t *i = vam->input;
13421   vl_api_ipsec_spd_entry_add_del_t *mp;
13422   u8 is_add = 1, is_outbound = 0;
13423   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13424   i32 priority = 0;
13425   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13426   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13427   vl_api_address_t laddr_start = { }, laddr_stop =
13428   {
13429   }, raddr_start =
13430   {
13431   }, raddr_stop =
13432   {
13433   };
13434   int ret;
13435
13436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13437     {
13438       if (unformat (i, "del"))
13439         is_add = 0;
13440       if (unformat (i, "outbound"))
13441         is_outbound = 1;
13442       if (unformat (i, "inbound"))
13443         is_outbound = 0;
13444       else if (unformat (i, "spd_id %d", &spd_id))
13445         ;
13446       else if (unformat (i, "sa_id %d", &sa_id))
13447         ;
13448       else if (unformat (i, "priority %d", &priority))
13449         ;
13450       else if (unformat (i, "protocol %d", &protocol))
13451         ;
13452       else if (unformat (i, "lport_start %d", &lport_start))
13453         ;
13454       else if (unformat (i, "lport_stop %d", &lport_stop))
13455         ;
13456       else if (unformat (i, "rport_start %d", &rport_start))
13457         ;
13458       else if (unformat (i, "rport_stop %d", &rport_stop))
13459         ;
13460       else if (unformat (i, "laddr_start %U",
13461                          unformat_vl_api_address, &laddr_start))
13462         ;
13463       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13464                          &laddr_stop))
13465         ;
13466       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13467                          &raddr_start))
13468         ;
13469       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13470                          &raddr_stop))
13471         ;
13472       else
13473         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13474         {
13475           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13476             {
13477               clib_warning ("unsupported action: 'resolve'");
13478               return -99;
13479             }
13480         }
13481       else
13482         {
13483           clib_warning ("parse error '%U'", format_unformat_error, i);
13484           return -99;
13485         }
13486
13487     }
13488
13489   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13490
13491   mp->is_add = is_add;
13492
13493   mp->entry.spd_id = ntohl (spd_id);
13494   mp->entry.priority = ntohl (priority);
13495   mp->entry.is_outbound = is_outbound;
13496
13497   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13498                sizeof (vl_api_address_t));
13499   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13500                sizeof (vl_api_address_t));
13501   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13502                sizeof (vl_api_address_t));
13503   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13504                sizeof (vl_api_address_t));
13505
13506   mp->entry.protocol = (u8) protocol;
13507   mp->entry.local_port_start = ntohs ((u16) lport_start);
13508   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13509   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13510   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13511   mp->entry.policy = (u8) policy;
13512   mp->entry.sa_id = ntohl (sa_id);
13513
13514   S (mp);
13515   W (ret);
13516   return ret;
13517 }
13518
13519 static int
13520 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13521 {
13522   unformat_input_t *i = vam->input;
13523   vl_api_ipsec_sad_entry_add_del_t *mp;
13524   u32 sad_id = 0, spi = 0;
13525   u8 *ck = 0, *ik = 0;
13526   u8 is_add = 1;
13527
13528   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13529   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13530   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13531   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13532   vl_api_address_t tun_src, tun_dst;
13533   int ret;
13534
13535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13536     {
13537       if (unformat (i, "del"))
13538         is_add = 0;
13539       else if (unformat (i, "sad_id %d", &sad_id))
13540         ;
13541       else if (unformat (i, "spi %d", &spi))
13542         ;
13543       else if (unformat (i, "esp"))
13544         protocol = IPSEC_API_PROTO_ESP;
13545       else
13546         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13547         {
13548           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13549           if (ADDRESS_IP6 == tun_src.af)
13550             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13551         }
13552       else
13553         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13554         {
13555           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13556           if (ADDRESS_IP6 == tun_src.af)
13557             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13558         }
13559       else
13560         if (unformat (i, "crypto_alg %U",
13561                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13562         ;
13563       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13564         ;
13565       else if (unformat (i, "integ_alg %U",
13566                          unformat_ipsec_api_integ_alg, &integ_alg))
13567         ;
13568       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13569         ;
13570       else
13571         {
13572           clib_warning ("parse error '%U'", format_unformat_error, i);
13573           return -99;
13574         }
13575
13576     }
13577
13578   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13579
13580   mp->is_add = is_add;
13581   mp->entry.sad_id = ntohl (sad_id);
13582   mp->entry.protocol = protocol;
13583   mp->entry.spi = ntohl (spi);
13584   mp->entry.flags = flags;
13585
13586   mp->entry.crypto_algorithm = crypto_alg;
13587   mp->entry.integrity_algorithm = integ_alg;
13588   mp->entry.crypto_key.length = vec_len (ck);
13589   mp->entry.integrity_key.length = vec_len (ik);
13590
13591   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13592     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13593
13594   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13595     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13596
13597   if (ck)
13598     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13599   if (ik)
13600     clib_memcpy (mp->entry.integrity_key.data, ik,
13601                  mp->entry.integrity_key.length);
13602
13603   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13604     {
13605       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13606                    sizeof (mp->entry.tunnel_src));
13607       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13608                    sizeof (mp->entry.tunnel_dst));
13609     }
13610
13611   S (mp);
13612   W (ret);
13613   return ret;
13614 }
13615
13616 static int
13617 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13618 {
13619   unformat_input_t *i = vam->input;
13620   vl_api_ipsec_tunnel_if_add_del_t *mp;
13621   u32 local_spi = 0, remote_spi = 0;
13622   u32 crypto_alg = 0, integ_alg = 0;
13623   u8 *lck = NULL, *rck = NULL;
13624   u8 *lik = NULL, *rik = NULL;
13625   vl_api_address_t local_ip = { 0 };
13626   vl_api_address_t remote_ip = { 0 };
13627   f64 before = 0;
13628   u8 is_add = 1;
13629   u8 esn = 0;
13630   u8 anti_replay = 0;
13631   u8 renumber = 0;
13632   u32 instance = ~0;
13633   u32 count = 1, jj;
13634   int ret = -1;
13635
13636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13637     {
13638       if (unformat (i, "del"))
13639         is_add = 0;
13640       else if (unformat (i, "esn"))
13641         esn = 1;
13642       else if (unformat (i, "anti-replay"))
13643         anti_replay = 1;
13644       else if (unformat (i, "count %d", &count))
13645         ;
13646       else if (unformat (i, "local_spi %d", &local_spi))
13647         ;
13648       else if (unformat (i, "remote_spi %d", &remote_spi))
13649         ;
13650       else
13651         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13652         ;
13653       else
13654         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13655         ;
13656       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13657         ;
13658       else
13659         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13660         ;
13661       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13662         ;
13663       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13664         ;
13665       else
13666         if (unformat
13667             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13668         {
13669           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13670             {
13671               errmsg ("unsupported crypto-alg: '%U'\n",
13672                       format_ipsec_crypto_alg, crypto_alg);
13673               return -99;
13674             }
13675         }
13676       else
13677         if (unformat
13678             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13679         {
13680           if (integ_alg >= IPSEC_INTEG_N_ALG)
13681             {
13682               errmsg ("unsupported integ-alg: '%U'\n",
13683                       format_ipsec_integ_alg, integ_alg);
13684               return -99;
13685             }
13686         }
13687       else if (unformat (i, "instance %u", &instance))
13688         renumber = 1;
13689       else
13690         {
13691           errmsg ("parse error '%U'\n", format_unformat_error, i);
13692           return -99;
13693         }
13694     }
13695
13696   if (count > 1)
13697     {
13698       /* Turn on async mode */
13699       vam->async_mode = 1;
13700       vam->async_errors = 0;
13701       before = vat_time_now (vam);
13702     }
13703
13704   for (jj = 0; jj < count; jj++)
13705     {
13706       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13707
13708       mp->is_add = is_add;
13709       mp->esn = esn;
13710       mp->anti_replay = anti_replay;
13711
13712       if (jj > 0)
13713         increment_address (&remote_ip);
13714
13715       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13716       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13717
13718       mp->local_spi = htonl (local_spi + jj);
13719       mp->remote_spi = htonl (remote_spi + jj);
13720       mp->crypto_alg = (u8) crypto_alg;
13721
13722       mp->local_crypto_key_len = 0;
13723       if (lck)
13724         {
13725           mp->local_crypto_key_len = vec_len (lck);
13726           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13727             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13728           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13729         }
13730
13731       mp->remote_crypto_key_len = 0;
13732       if (rck)
13733         {
13734           mp->remote_crypto_key_len = vec_len (rck);
13735           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13736             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13737           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13738         }
13739
13740       mp->integ_alg = (u8) integ_alg;
13741
13742       mp->local_integ_key_len = 0;
13743       if (lik)
13744         {
13745           mp->local_integ_key_len = vec_len (lik);
13746           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13747             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13748           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13749         }
13750
13751       mp->remote_integ_key_len = 0;
13752       if (rik)
13753         {
13754           mp->remote_integ_key_len = vec_len (rik);
13755           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13756             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13757           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13758         }
13759
13760       if (renumber)
13761         {
13762           mp->renumber = renumber;
13763           mp->show_instance = ntohl (instance);
13764         }
13765       S (mp);
13766     }
13767
13768   /* When testing multiple add/del ops, use a control-ping to sync */
13769   if (count > 1)
13770     {
13771       vl_api_control_ping_t *mp_ping;
13772       f64 after;
13773       f64 timeout;
13774
13775       /* Shut off async mode */
13776       vam->async_mode = 0;
13777
13778       MPING (CONTROL_PING, mp_ping);
13779       S (mp_ping);
13780
13781       timeout = vat_time_now (vam) + 1.0;
13782       while (vat_time_now (vam) < timeout)
13783         if (vam->result_ready == 1)
13784           goto out;
13785       vam->retval = -99;
13786
13787     out:
13788       if (vam->retval == -99)
13789         errmsg ("timeout");
13790
13791       if (vam->async_errors > 0)
13792         {
13793           errmsg ("%d asynchronous errors", vam->async_errors);
13794           vam->retval = -98;
13795         }
13796       vam->async_errors = 0;
13797       after = vat_time_now (vam);
13798
13799       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13800       if (jj > 0)
13801         count = jj;
13802
13803       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13804              count, after - before, count / (after - before));
13805     }
13806   else
13807     {
13808       /* Wait for a reply... */
13809       W (ret);
13810       return ret;
13811     }
13812
13813   return ret;
13814 }
13815
13816 static void
13817 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13818 {
13819   vat_main_t *vam = &vat_main;
13820
13821   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13822          "crypto_key %U integ_alg %u integ_key %U flags %x "
13823          "tunnel_src_addr %U tunnel_dst_addr %U "
13824          "salt %u seq_outbound %lu last_seq_inbound %lu "
13825          "replay_window %lu stat_index %u\n",
13826          ntohl (mp->entry.sad_id),
13827          ntohl (mp->sw_if_index),
13828          ntohl (mp->entry.spi),
13829          ntohl (mp->entry.protocol),
13830          ntohl (mp->entry.crypto_algorithm),
13831          format_hex_bytes, mp->entry.crypto_key.data,
13832          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13833          format_hex_bytes, mp->entry.integrity_key.data,
13834          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13835          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13836          &mp->entry.tunnel_dst, ntohl (mp->salt),
13837          clib_net_to_host_u64 (mp->seq_outbound),
13838          clib_net_to_host_u64 (mp->last_seq_inbound),
13839          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13840 }
13841
13842 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13843 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13844
13845 static void vl_api_ipsec_sa_details_t_handler_json
13846   (vl_api_ipsec_sa_details_t * mp)
13847 {
13848   vat_main_t *vam = &vat_main;
13849   vat_json_node_t *node = NULL;
13850   vl_api_ipsec_sad_flags_t flags;
13851
13852   if (VAT_JSON_ARRAY != vam->json_tree.type)
13853     {
13854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13855       vat_json_init_array (&vam->json_tree);
13856     }
13857   node = vat_json_array_add (&vam->json_tree);
13858
13859   vat_json_init_object (node);
13860   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13862   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13863   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13864   vat_json_object_add_uint (node, "crypto_alg",
13865                             ntohl (mp->entry.crypto_algorithm));
13866   vat_json_object_add_uint (node, "integ_alg",
13867                             ntohl (mp->entry.integrity_algorithm));
13868   flags = ntohl (mp->entry.flags);
13869   vat_json_object_add_uint (node, "use_esn",
13870                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13871   vat_json_object_add_uint (node, "use_anti_replay",
13872                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13873   vat_json_object_add_uint (node, "is_tunnel",
13874                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13875   vat_json_object_add_uint (node, "is_tunnel_ip6",
13876                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13877   vat_json_object_add_uint (node, "udp_encap",
13878                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13879   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13880                              mp->entry.crypto_key.length);
13881   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13882                              mp->entry.integrity_key.length);
13883   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13884   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13885   vat_json_object_add_uint (node, "replay_window",
13886                             clib_net_to_host_u64 (mp->replay_window));
13887   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13888 }
13889
13890 static int
13891 api_ipsec_sa_dump (vat_main_t * vam)
13892 {
13893   unformat_input_t *i = vam->input;
13894   vl_api_ipsec_sa_dump_t *mp;
13895   vl_api_control_ping_t *mp_ping;
13896   u32 sa_id = ~0;
13897   int ret;
13898
13899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13900     {
13901       if (unformat (i, "sa_id %d", &sa_id))
13902         ;
13903       else
13904         {
13905           clib_warning ("parse error '%U'", format_unformat_error, i);
13906           return -99;
13907         }
13908     }
13909
13910   M (IPSEC_SA_DUMP, mp);
13911
13912   mp->sa_id = ntohl (sa_id);
13913
13914   S (mp);
13915
13916   /* Use a control ping for synchronization */
13917   M (CONTROL_PING, mp_ping);
13918   S (mp_ping);
13919
13920   W (ret);
13921   return ret;
13922 }
13923
13924 static int
13925 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13926 {
13927   unformat_input_t *i = vam->input;
13928   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13929   u32 sw_if_index = ~0;
13930   u32 sa_id = ~0;
13931   u8 is_outbound = (u8) ~ 0;
13932   int ret;
13933
13934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13935     {
13936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13937         ;
13938       else if (unformat (i, "sa_id %d", &sa_id))
13939         ;
13940       else if (unformat (i, "outbound"))
13941         is_outbound = 1;
13942       else if (unformat (i, "inbound"))
13943         is_outbound = 0;
13944       else
13945         {
13946           clib_warning ("parse error '%U'", format_unformat_error, i);
13947           return -99;
13948         }
13949     }
13950
13951   if (sw_if_index == ~0)
13952     {
13953       errmsg ("interface must be specified");
13954       return -99;
13955     }
13956
13957   if (sa_id == ~0)
13958     {
13959       errmsg ("SA ID must be specified");
13960       return -99;
13961     }
13962
13963   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13964
13965   mp->sw_if_index = htonl (sw_if_index);
13966   mp->sa_id = htonl (sa_id);
13967   mp->is_outbound = is_outbound;
13968
13969   S (mp);
13970   W (ret);
13971
13972   return ret;
13973 }
13974
13975 static int
13976 api_get_first_msg_id (vat_main_t * vam)
13977 {
13978   vl_api_get_first_msg_id_t *mp;
13979   unformat_input_t *i = vam->input;
13980   u8 *name;
13981   u8 name_set = 0;
13982   int ret;
13983
13984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13985     {
13986       if (unformat (i, "client %s", &name))
13987         name_set = 1;
13988       else
13989         break;
13990     }
13991
13992   if (name_set == 0)
13993     {
13994       errmsg ("missing client name");
13995       return -99;
13996     }
13997   vec_add1 (name, 0);
13998
13999   if (vec_len (name) > 63)
14000     {
14001       errmsg ("client name too long");
14002       return -99;
14003     }
14004
14005   M (GET_FIRST_MSG_ID, mp);
14006   clib_memcpy (mp->name, name, vec_len (name));
14007   S (mp);
14008   W (ret);
14009   return ret;
14010 }
14011
14012 static int
14013 api_cop_interface_enable_disable (vat_main_t * vam)
14014 {
14015   unformat_input_t *line_input = vam->input;
14016   vl_api_cop_interface_enable_disable_t *mp;
14017   u32 sw_if_index = ~0;
14018   u8 enable_disable = 1;
14019   int ret;
14020
14021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14022     {
14023       if (unformat (line_input, "disable"))
14024         enable_disable = 0;
14025       if (unformat (line_input, "enable"))
14026         enable_disable = 1;
14027       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14028                          vam, &sw_if_index))
14029         ;
14030       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14031         ;
14032       else
14033         break;
14034     }
14035
14036   if (sw_if_index == ~0)
14037     {
14038       errmsg ("missing interface name or sw_if_index");
14039       return -99;
14040     }
14041
14042   /* Construct the API message */
14043   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14044   mp->sw_if_index = ntohl (sw_if_index);
14045   mp->enable_disable = enable_disable;
14046
14047   /* send it... */
14048   S (mp);
14049   /* Wait for the reply */
14050   W (ret);
14051   return ret;
14052 }
14053
14054 static int
14055 api_cop_whitelist_enable_disable (vat_main_t * vam)
14056 {
14057   unformat_input_t *line_input = vam->input;
14058   vl_api_cop_whitelist_enable_disable_t *mp;
14059   u32 sw_if_index = ~0;
14060   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14061   u32 fib_id = 0;
14062   int ret;
14063
14064   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14065     {
14066       if (unformat (line_input, "ip4"))
14067         ip4 = 1;
14068       else if (unformat (line_input, "ip6"))
14069         ip6 = 1;
14070       else if (unformat (line_input, "default"))
14071         default_cop = 1;
14072       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14073                          vam, &sw_if_index))
14074         ;
14075       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14076         ;
14077       else if (unformat (line_input, "fib-id %d", &fib_id))
14078         ;
14079       else
14080         break;
14081     }
14082
14083   if (sw_if_index == ~0)
14084     {
14085       errmsg ("missing interface name or sw_if_index");
14086       return -99;
14087     }
14088
14089   /* Construct the API message */
14090   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14091   mp->sw_if_index = ntohl (sw_if_index);
14092   mp->fib_id = ntohl (fib_id);
14093   mp->ip4 = ip4;
14094   mp->ip6 = ip6;
14095   mp->default_cop = default_cop;
14096
14097   /* send it... */
14098   S (mp);
14099   /* Wait for the reply */
14100   W (ret);
14101   return ret;
14102 }
14103
14104 static int
14105 api_get_node_graph (vat_main_t * vam)
14106 {
14107   vl_api_get_node_graph_t *mp;
14108   int ret;
14109
14110   M (GET_NODE_GRAPH, mp);
14111
14112   /* send it... */
14113   S (mp);
14114   /* Wait for the reply */
14115   W (ret);
14116   return ret;
14117 }
14118
14119 /* *INDENT-OFF* */
14120 /** Used for parsing LISP eids */
14121 typedef CLIB_PACKED(struct{
14122   union {
14123           ip46_address_t ip;
14124           mac_address_t mac;
14125           lisp_nsh_api_t nsh;
14126   } addr;
14127   u32 len;       /**< prefix length if IP */
14128   u8 type;      /**< type of eid */
14129 }) lisp_eid_vat_t;
14130 /* *INDENT-ON* */
14131
14132 static uword
14133 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14134 {
14135   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14136
14137   clib_memset (a, 0, sizeof (a[0]));
14138
14139   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14140     {
14141       a->type = 0;              /* ip prefix type */
14142     }
14143   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14144     {
14145       a->type = 1;              /* mac type */
14146     }
14147   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14148     {
14149       a->type = 2;              /* NSH type */
14150       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14151     }
14152   else
14153     {
14154       return 0;
14155     }
14156
14157   if (a->type == 0)
14158     {
14159       if (ip46_address_is_ip4 (&a->addr.ip))
14160         return a->len > 32 ? 1 : 0;
14161       else
14162         return a->len > 128 ? 1 : 0;
14163     }
14164
14165   return 1;
14166 }
14167
14168 static void
14169 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14170 {
14171   eid->type = vat_eid->type;
14172   switch (eid->type)
14173     {
14174     case EID_TYPE_API_PREFIX:
14175       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14176         {
14177           clib_memcpy (&eid->address.prefix.address.un.ip4,
14178                        &vat_eid->addr.ip.ip4, 4);
14179           eid->address.prefix.address.af = ADDRESS_IP4;
14180           eid->address.prefix.len = vat_eid->len;
14181         }
14182       else
14183         {
14184           clib_memcpy (&eid->address.prefix.address.un.ip6,
14185                        &vat_eid->addr.ip.ip6, 16);
14186           eid->address.prefix.address.af = ADDRESS_IP6;
14187           eid->address.prefix.len = vat_eid->len;
14188         }
14189       return;
14190     case EID_TYPE_API_MAC:
14191       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14192                    sizeof (eid->address.mac));
14193       return;
14194     case EID_TYPE_API_NSH:
14195       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14196                    sizeof (eid->address.nsh));
14197       return;
14198     default:
14199       ASSERT (0);
14200       return;
14201     }
14202 }
14203
14204 static int
14205 api_one_add_del_locator_set (vat_main_t * vam)
14206 {
14207   unformat_input_t *input = vam->input;
14208   vl_api_one_add_del_locator_set_t *mp;
14209   u8 is_add = 1;
14210   u8 *locator_set_name = NULL;
14211   u8 locator_set_name_set = 0;
14212   vl_api_local_locator_t locator, *locators = 0;
14213   u32 sw_if_index, priority, weight;
14214   u32 data_len = 0;
14215
14216   int ret;
14217   /* Parse args required to build the message */
14218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14219     {
14220       if (unformat (input, "del"))
14221         {
14222           is_add = 0;
14223         }
14224       else if (unformat (input, "locator-set %s", &locator_set_name))
14225         {
14226           locator_set_name_set = 1;
14227         }
14228       else if (unformat (input, "sw_if_index %u p %u w %u",
14229                          &sw_if_index, &priority, &weight))
14230         {
14231           locator.sw_if_index = htonl (sw_if_index);
14232           locator.priority = priority;
14233           locator.weight = weight;
14234           vec_add1 (locators, locator);
14235         }
14236       else
14237         if (unformat
14238             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14239              &sw_if_index, &priority, &weight))
14240         {
14241           locator.sw_if_index = htonl (sw_if_index);
14242           locator.priority = priority;
14243           locator.weight = weight;
14244           vec_add1 (locators, locator);
14245         }
14246       else
14247         break;
14248     }
14249
14250   if (locator_set_name_set == 0)
14251     {
14252       errmsg ("missing locator-set name");
14253       vec_free (locators);
14254       return -99;
14255     }
14256
14257   if (vec_len (locator_set_name) > 64)
14258     {
14259       errmsg ("locator-set name too long");
14260       vec_free (locator_set_name);
14261       vec_free (locators);
14262       return -99;
14263     }
14264   vec_add1 (locator_set_name, 0);
14265
14266   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14267
14268   /* Construct the API message */
14269   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14270
14271   mp->is_add = is_add;
14272   clib_memcpy (mp->locator_set_name, locator_set_name,
14273                vec_len (locator_set_name));
14274   vec_free (locator_set_name);
14275
14276   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14277   if (locators)
14278     clib_memcpy (mp->locators, locators, data_len);
14279   vec_free (locators);
14280
14281   /* send it... */
14282   S (mp);
14283
14284   /* Wait for a reply... */
14285   W (ret);
14286   return ret;
14287 }
14288
14289 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14290
14291 static int
14292 api_one_add_del_locator (vat_main_t * vam)
14293 {
14294   unformat_input_t *input = vam->input;
14295   vl_api_one_add_del_locator_t *mp;
14296   u32 tmp_if_index = ~0;
14297   u32 sw_if_index = ~0;
14298   u8 sw_if_index_set = 0;
14299   u8 sw_if_index_if_name_set = 0;
14300   u32 priority = ~0;
14301   u8 priority_set = 0;
14302   u32 weight = ~0;
14303   u8 weight_set = 0;
14304   u8 is_add = 1;
14305   u8 *locator_set_name = NULL;
14306   u8 locator_set_name_set = 0;
14307   int ret;
14308
14309   /* Parse args required to build the message */
14310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14311     {
14312       if (unformat (input, "del"))
14313         {
14314           is_add = 0;
14315         }
14316       else if (unformat (input, "locator-set %s", &locator_set_name))
14317         {
14318           locator_set_name_set = 1;
14319         }
14320       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14321                          &tmp_if_index))
14322         {
14323           sw_if_index_if_name_set = 1;
14324           sw_if_index = tmp_if_index;
14325         }
14326       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14327         {
14328           sw_if_index_set = 1;
14329           sw_if_index = tmp_if_index;
14330         }
14331       else if (unformat (input, "p %d", &priority))
14332         {
14333           priority_set = 1;
14334         }
14335       else if (unformat (input, "w %d", &weight))
14336         {
14337           weight_set = 1;
14338         }
14339       else
14340         break;
14341     }
14342
14343   if (locator_set_name_set == 0)
14344     {
14345       errmsg ("missing locator-set name");
14346       return -99;
14347     }
14348
14349   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14350     {
14351       errmsg ("missing sw_if_index");
14352       vec_free (locator_set_name);
14353       return -99;
14354     }
14355
14356   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14357     {
14358       errmsg ("cannot use both params interface name and sw_if_index");
14359       vec_free (locator_set_name);
14360       return -99;
14361     }
14362
14363   if (priority_set == 0)
14364     {
14365       errmsg ("missing locator-set priority");
14366       vec_free (locator_set_name);
14367       return -99;
14368     }
14369
14370   if (weight_set == 0)
14371     {
14372       errmsg ("missing locator-set weight");
14373       vec_free (locator_set_name);
14374       return -99;
14375     }
14376
14377   if (vec_len (locator_set_name) > 64)
14378     {
14379       errmsg ("locator-set name too long");
14380       vec_free (locator_set_name);
14381       return -99;
14382     }
14383   vec_add1 (locator_set_name, 0);
14384
14385   /* Construct the API message */
14386   M (ONE_ADD_DEL_LOCATOR, mp);
14387
14388   mp->is_add = is_add;
14389   mp->sw_if_index = ntohl (sw_if_index);
14390   mp->priority = priority;
14391   mp->weight = weight;
14392   clib_memcpy (mp->locator_set_name, locator_set_name,
14393                vec_len (locator_set_name));
14394   vec_free (locator_set_name);
14395
14396   /* send it... */
14397   S (mp);
14398
14399   /* Wait for a reply... */
14400   W (ret);
14401   return ret;
14402 }
14403
14404 #define api_lisp_add_del_locator api_one_add_del_locator
14405
14406 uword
14407 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14408 {
14409   u32 *key_id = va_arg (*args, u32 *);
14410   u8 *s = 0;
14411
14412   if (unformat (input, "%s", &s))
14413     {
14414       if (!strcmp ((char *) s, "sha1"))
14415         key_id[0] = HMAC_SHA_1_96;
14416       else if (!strcmp ((char *) s, "sha256"))
14417         key_id[0] = HMAC_SHA_256_128;
14418       else
14419         {
14420           clib_warning ("invalid key_id: '%s'", s);
14421           key_id[0] = HMAC_NO_KEY;
14422         }
14423     }
14424   else
14425     return 0;
14426
14427   vec_free (s);
14428   return 1;
14429 }
14430
14431 static int
14432 api_one_add_del_local_eid (vat_main_t * vam)
14433 {
14434   unformat_input_t *input = vam->input;
14435   vl_api_one_add_del_local_eid_t *mp;
14436   u8 is_add = 1;
14437   u8 eid_set = 0;
14438   lisp_eid_vat_t _eid, *eid = &_eid;
14439   u8 *locator_set_name = 0;
14440   u8 locator_set_name_set = 0;
14441   u32 vni = 0;
14442   u16 key_id = 0;
14443   u8 *key = 0;
14444   int ret;
14445
14446   /* Parse args required to build the message */
14447   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14448     {
14449       if (unformat (input, "del"))
14450         {
14451           is_add = 0;
14452         }
14453       else if (unformat (input, "vni %d", &vni))
14454         {
14455           ;
14456         }
14457       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14458         {
14459           eid_set = 1;
14460         }
14461       else if (unformat (input, "locator-set %s", &locator_set_name))
14462         {
14463           locator_set_name_set = 1;
14464         }
14465       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14466         ;
14467       else if (unformat (input, "secret-key %_%v%_", &key))
14468         ;
14469       else
14470         break;
14471     }
14472
14473   if (locator_set_name_set == 0)
14474     {
14475       errmsg ("missing locator-set name");
14476       return -99;
14477     }
14478
14479   if (0 == eid_set)
14480     {
14481       errmsg ("EID address not set!");
14482       vec_free (locator_set_name);
14483       return -99;
14484     }
14485
14486   if (key && (0 == key_id))
14487     {
14488       errmsg ("invalid key_id!");
14489       return -99;
14490     }
14491
14492   if (vec_len (key) > 64)
14493     {
14494       errmsg ("key too long");
14495       vec_free (key);
14496       return -99;
14497     }
14498
14499   if (vec_len (locator_set_name) > 64)
14500     {
14501       errmsg ("locator-set name too long");
14502       vec_free (locator_set_name);
14503       return -99;
14504     }
14505   vec_add1 (locator_set_name, 0);
14506
14507   /* Construct the API message */
14508   M (ONE_ADD_DEL_LOCAL_EID, mp);
14509
14510   mp->is_add = is_add;
14511   lisp_eid_put_vat (&mp->eid, eid);
14512   mp->vni = clib_host_to_net_u32 (vni);
14513   mp->key.id = key_id;
14514   clib_memcpy (mp->locator_set_name, locator_set_name,
14515                vec_len (locator_set_name));
14516   clib_memcpy (mp->key.key, key, vec_len (key));
14517
14518   vec_free (locator_set_name);
14519   vec_free (key);
14520
14521   /* send it... */
14522   S (mp);
14523
14524   /* Wait for a reply... */
14525   W (ret);
14526   return ret;
14527 }
14528
14529 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14530
14531 static int
14532 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14533 {
14534   u32 dp_table = 0, vni = 0;;
14535   unformat_input_t *input = vam->input;
14536   vl_api_gpe_add_del_fwd_entry_t *mp;
14537   u8 is_add = 1;
14538   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14539   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14540   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14541   u32 action = ~0, w;
14542   ip4_address_t rmt_rloc4, lcl_rloc4;
14543   ip6_address_t rmt_rloc6, lcl_rloc6;
14544   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14545   int ret;
14546
14547   clib_memset (&rloc, 0, sizeof (rloc));
14548
14549   /* Parse args required to build the message */
14550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14551     {
14552       if (unformat (input, "del"))
14553         is_add = 0;
14554       else if (unformat (input, "add"))
14555         is_add = 1;
14556       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14557         {
14558           rmt_eid_set = 1;
14559         }
14560       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14561         {
14562           lcl_eid_set = 1;
14563         }
14564       else if (unformat (input, "vrf %d", &dp_table))
14565         ;
14566       else if (unformat (input, "bd %d", &dp_table))
14567         ;
14568       else if (unformat (input, "vni %d", &vni))
14569         ;
14570       else if (unformat (input, "w %d", &w))
14571         {
14572           if (!curr_rloc)
14573             {
14574               errmsg ("No RLOC configured for setting priority/weight!");
14575               return -99;
14576             }
14577           curr_rloc->weight = w;
14578         }
14579       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14580                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14581         {
14582           rloc.addr.af = 0;
14583           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14584           rloc.weight = 0;
14585           vec_add1 (lcl_locs, rloc);
14586
14587           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14588           vec_add1 (rmt_locs, rloc);
14589           /* weight saved in rmt loc */
14590           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14591         }
14592       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14593                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14594         {
14595           rloc.addr.af = 1;
14596           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14597           rloc.weight = 0;
14598           vec_add1 (lcl_locs, rloc);
14599
14600           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14601           vec_add1 (rmt_locs, rloc);
14602           /* weight saved in rmt loc */
14603           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14604         }
14605       else if (unformat (input, "action %d", &action))
14606         {
14607           ;
14608         }
14609       else
14610         {
14611           clib_warning ("parse error '%U'", format_unformat_error, input);
14612           return -99;
14613         }
14614     }
14615
14616   if (!rmt_eid_set)
14617     {
14618       errmsg ("remote eid addresses not set");
14619       return -99;
14620     }
14621
14622   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14623     {
14624       errmsg ("eid types don't match");
14625       return -99;
14626     }
14627
14628   if (0 == rmt_locs && (u32) ~ 0 == action)
14629     {
14630       errmsg ("action not set for negative mapping");
14631       return -99;
14632     }
14633
14634   /* Construct the API message */
14635   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14636       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14637
14638   mp->is_add = is_add;
14639   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14640   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14641   mp->dp_table = clib_host_to_net_u32 (dp_table);
14642   mp->vni = clib_host_to_net_u32 (vni);
14643   mp->action = action;
14644
14645   if (0 != rmt_locs && 0 != lcl_locs)
14646     {
14647       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14648       clib_memcpy (mp->locs, lcl_locs,
14649                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14650
14651       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14652       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14653                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14654     }
14655   vec_free (lcl_locs);
14656   vec_free (rmt_locs);
14657
14658   /* send it... */
14659   S (mp);
14660
14661   /* Wait for a reply... */
14662   W (ret);
14663   return ret;
14664 }
14665
14666 static int
14667 api_one_add_del_map_server (vat_main_t * vam)
14668 {
14669   unformat_input_t *input = vam->input;
14670   vl_api_one_add_del_map_server_t *mp;
14671   u8 is_add = 1;
14672   u8 ipv4_set = 0;
14673   u8 ipv6_set = 0;
14674   ip4_address_t ipv4;
14675   ip6_address_t ipv6;
14676   int ret;
14677
14678   /* Parse args required to build the message */
14679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14680     {
14681       if (unformat (input, "del"))
14682         {
14683           is_add = 0;
14684         }
14685       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14686         {
14687           ipv4_set = 1;
14688         }
14689       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14690         {
14691           ipv6_set = 1;
14692         }
14693       else
14694         break;
14695     }
14696
14697   if (ipv4_set && ipv6_set)
14698     {
14699       errmsg ("both eid v4 and v6 addresses set");
14700       return -99;
14701     }
14702
14703   if (!ipv4_set && !ipv6_set)
14704     {
14705       errmsg ("eid addresses not set");
14706       return -99;
14707     }
14708
14709   /* Construct the API message */
14710   M (ONE_ADD_DEL_MAP_SERVER, mp);
14711
14712   mp->is_add = is_add;
14713   if (ipv6_set)
14714     {
14715       mp->ip_address.af = 1;
14716       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14717     }
14718   else
14719     {
14720       mp->ip_address.af = 0;
14721       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14722     }
14723
14724   /* send it... */
14725   S (mp);
14726
14727   /* Wait for a reply... */
14728   W (ret);
14729   return ret;
14730 }
14731
14732 #define api_lisp_add_del_map_server api_one_add_del_map_server
14733
14734 static int
14735 api_one_add_del_map_resolver (vat_main_t * vam)
14736 {
14737   unformat_input_t *input = vam->input;
14738   vl_api_one_add_del_map_resolver_t *mp;
14739   u8 is_add = 1;
14740   u8 ipv4_set = 0;
14741   u8 ipv6_set = 0;
14742   ip4_address_t ipv4;
14743   ip6_address_t ipv6;
14744   int ret;
14745
14746   /* Parse args required to build the message */
14747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14748     {
14749       if (unformat (input, "del"))
14750         {
14751           is_add = 0;
14752         }
14753       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14754         {
14755           ipv4_set = 1;
14756         }
14757       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14758         {
14759           ipv6_set = 1;
14760         }
14761       else
14762         break;
14763     }
14764
14765   if (ipv4_set && ipv6_set)
14766     {
14767       errmsg ("both eid v4 and v6 addresses set");
14768       return -99;
14769     }
14770
14771   if (!ipv4_set && !ipv6_set)
14772     {
14773       errmsg ("eid addresses not set");
14774       return -99;
14775     }
14776
14777   /* Construct the API message */
14778   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14779
14780   mp->is_add = is_add;
14781   if (ipv6_set)
14782     {
14783       mp->ip_address.af = 1;
14784       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14785     }
14786   else
14787     {
14788       mp->ip_address.af = 0;
14789       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14790     }
14791
14792   /* send it... */
14793   S (mp);
14794
14795   /* Wait for a reply... */
14796   W (ret);
14797   return ret;
14798 }
14799
14800 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14801
14802 static int
14803 api_lisp_gpe_enable_disable (vat_main_t * vam)
14804 {
14805   unformat_input_t *input = vam->input;
14806   vl_api_gpe_enable_disable_t *mp;
14807   u8 is_set = 0;
14808   u8 is_enable = 1;
14809   int ret;
14810
14811   /* Parse args required to build the message */
14812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14813     {
14814       if (unformat (input, "enable"))
14815         {
14816           is_set = 1;
14817           is_enable = 1;
14818         }
14819       else if (unformat (input, "disable"))
14820         {
14821           is_set = 1;
14822           is_enable = 0;
14823         }
14824       else
14825         break;
14826     }
14827
14828   if (is_set == 0)
14829     {
14830       errmsg ("Value not set");
14831       return -99;
14832     }
14833
14834   /* Construct the API message */
14835   M (GPE_ENABLE_DISABLE, mp);
14836
14837   mp->is_enable = is_enable;
14838
14839   /* send it... */
14840   S (mp);
14841
14842   /* Wait for a reply... */
14843   W (ret);
14844   return ret;
14845 }
14846
14847 static int
14848 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14849 {
14850   unformat_input_t *input = vam->input;
14851   vl_api_one_rloc_probe_enable_disable_t *mp;
14852   u8 is_set = 0;
14853   u8 is_enable = 0;
14854   int ret;
14855
14856   /* Parse args required to build the message */
14857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14858     {
14859       if (unformat (input, "enable"))
14860         {
14861           is_set = 1;
14862           is_enable = 1;
14863         }
14864       else if (unformat (input, "disable"))
14865         is_set = 1;
14866       else
14867         break;
14868     }
14869
14870   if (!is_set)
14871     {
14872       errmsg ("Value not set");
14873       return -99;
14874     }
14875
14876   /* Construct the API message */
14877   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14878
14879   mp->is_enable = is_enable;
14880
14881   /* send it... */
14882   S (mp);
14883
14884   /* Wait for a reply... */
14885   W (ret);
14886   return ret;
14887 }
14888
14889 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14890
14891 static int
14892 api_one_map_register_enable_disable (vat_main_t * vam)
14893 {
14894   unformat_input_t *input = vam->input;
14895   vl_api_one_map_register_enable_disable_t *mp;
14896   u8 is_set = 0;
14897   u8 is_enable = 0;
14898   int ret;
14899
14900   /* Parse args required to build the message */
14901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14902     {
14903       if (unformat (input, "enable"))
14904         {
14905           is_set = 1;
14906           is_enable = 1;
14907         }
14908       else if (unformat (input, "disable"))
14909         is_set = 1;
14910       else
14911         break;
14912     }
14913
14914   if (!is_set)
14915     {
14916       errmsg ("Value not set");
14917       return -99;
14918     }
14919
14920   /* Construct the API message */
14921   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14922
14923   mp->is_enable = is_enable;
14924
14925   /* send it... */
14926   S (mp);
14927
14928   /* Wait for a reply... */
14929   W (ret);
14930   return ret;
14931 }
14932
14933 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14934
14935 static int
14936 api_one_enable_disable (vat_main_t * vam)
14937 {
14938   unformat_input_t *input = vam->input;
14939   vl_api_one_enable_disable_t *mp;
14940   u8 is_set = 0;
14941   u8 is_enable = 0;
14942   int ret;
14943
14944   /* Parse args required to build the message */
14945   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14946     {
14947       if (unformat (input, "enable"))
14948         {
14949           is_set = 1;
14950           is_enable = 1;
14951         }
14952       else if (unformat (input, "disable"))
14953         {
14954           is_set = 1;
14955         }
14956       else
14957         break;
14958     }
14959
14960   if (!is_set)
14961     {
14962       errmsg ("Value not set");
14963       return -99;
14964     }
14965
14966   /* Construct the API message */
14967   M (ONE_ENABLE_DISABLE, mp);
14968
14969   mp->is_enable = is_enable;
14970
14971   /* send it... */
14972   S (mp);
14973
14974   /* Wait for a reply... */
14975   W (ret);
14976   return ret;
14977 }
14978
14979 #define api_lisp_enable_disable api_one_enable_disable
14980
14981 static int
14982 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14983 {
14984   unformat_input_t *input = vam->input;
14985   vl_api_one_enable_disable_xtr_mode_t *mp;
14986   u8 is_set = 0;
14987   u8 is_enable = 0;
14988   int ret;
14989
14990   /* Parse args required to build the message */
14991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14992     {
14993       if (unformat (input, "enable"))
14994         {
14995           is_set = 1;
14996           is_enable = 1;
14997         }
14998       else if (unformat (input, "disable"))
14999         {
15000           is_set = 1;
15001         }
15002       else
15003         break;
15004     }
15005
15006   if (!is_set)
15007     {
15008       errmsg ("Value not set");
15009       return -99;
15010     }
15011
15012   /* Construct the API message */
15013   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15014
15015   mp->is_enable = is_enable;
15016
15017   /* send it... */
15018   S (mp);
15019
15020   /* Wait for a reply... */
15021   W (ret);
15022   return ret;
15023 }
15024
15025 static int
15026 api_one_show_xtr_mode (vat_main_t * vam)
15027 {
15028   vl_api_one_show_xtr_mode_t *mp;
15029   int ret;
15030
15031   /* Construct the API message */
15032   M (ONE_SHOW_XTR_MODE, mp);
15033
15034   /* send it... */
15035   S (mp);
15036
15037   /* Wait for a reply... */
15038   W (ret);
15039   return ret;
15040 }
15041
15042 static int
15043 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15044 {
15045   unformat_input_t *input = vam->input;
15046   vl_api_one_enable_disable_pitr_mode_t *mp;
15047   u8 is_set = 0;
15048   u8 is_enable = 0;
15049   int ret;
15050
15051   /* Parse args required to build the message */
15052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15053     {
15054       if (unformat (input, "enable"))
15055         {
15056           is_set = 1;
15057           is_enable = 1;
15058         }
15059       else if (unformat (input, "disable"))
15060         {
15061           is_set = 1;
15062         }
15063       else
15064         break;
15065     }
15066
15067   if (!is_set)
15068     {
15069       errmsg ("Value not set");
15070       return -99;
15071     }
15072
15073   /* Construct the API message */
15074   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15075
15076   mp->is_enable = is_enable;
15077
15078   /* send it... */
15079   S (mp);
15080
15081   /* Wait for a reply... */
15082   W (ret);
15083   return ret;
15084 }
15085
15086 static int
15087 api_one_show_pitr_mode (vat_main_t * vam)
15088 {
15089   vl_api_one_show_pitr_mode_t *mp;
15090   int ret;
15091
15092   /* Construct the API message */
15093   M (ONE_SHOW_PITR_MODE, mp);
15094
15095   /* send it... */
15096   S (mp);
15097
15098   /* Wait for a reply... */
15099   W (ret);
15100   return ret;
15101 }
15102
15103 static int
15104 api_one_enable_disable_petr_mode (vat_main_t * vam)
15105 {
15106   unformat_input_t *input = vam->input;
15107   vl_api_one_enable_disable_petr_mode_t *mp;
15108   u8 is_set = 0;
15109   u8 is_enable = 0;
15110   int ret;
15111
15112   /* Parse args required to build the message */
15113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15114     {
15115       if (unformat (input, "enable"))
15116         {
15117           is_set = 1;
15118           is_enable = 1;
15119         }
15120       else if (unformat (input, "disable"))
15121         {
15122           is_set = 1;
15123         }
15124       else
15125         break;
15126     }
15127
15128   if (!is_set)
15129     {
15130       errmsg ("Value not set");
15131       return -99;
15132     }
15133
15134   /* Construct the API message */
15135   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15136
15137   mp->is_enable = is_enable;
15138
15139   /* send it... */
15140   S (mp);
15141
15142   /* Wait for a reply... */
15143   W (ret);
15144   return ret;
15145 }
15146
15147 static int
15148 api_one_show_petr_mode (vat_main_t * vam)
15149 {
15150   vl_api_one_show_petr_mode_t *mp;
15151   int ret;
15152
15153   /* Construct the API message */
15154   M (ONE_SHOW_PETR_MODE, mp);
15155
15156   /* send it... */
15157   S (mp);
15158
15159   /* Wait for a reply... */
15160   W (ret);
15161   return ret;
15162 }
15163
15164 static int
15165 api_show_one_map_register_state (vat_main_t * vam)
15166 {
15167   vl_api_show_one_map_register_state_t *mp;
15168   int ret;
15169
15170   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15171
15172   /* send */
15173   S (mp);
15174
15175   /* wait for reply */
15176   W (ret);
15177   return ret;
15178 }
15179
15180 #define api_show_lisp_map_register_state api_show_one_map_register_state
15181
15182 static int
15183 api_show_one_rloc_probe_state (vat_main_t * vam)
15184 {
15185   vl_api_show_one_rloc_probe_state_t *mp;
15186   int ret;
15187
15188   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15189
15190   /* send */
15191   S (mp);
15192
15193   /* wait for reply */
15194   W (ret);
15195   return ret;
15196 }
15197
15198 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15199
15200 static int
15201 api_one_add_del_ndp_entry (vat_main_t * vam)
15202 {
15203   vl_api_one_add_del_ndp_entry_t *mp;
15204   unformat_input_t *input = vam->input;
15205   u8 is_add = 1;
15206   u8 mac_set = 0;
15207   u8 bd_set = 0;
15208   u8 ip_set = 0;
15209   u8 mac[6] = { 0, };
15210   u8 ip6[16] = { 0, };
15211   u32 bd = ~0;
15212   int ret;
15213
15214   /* Parse args required to build the message */
15215   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15216     {
15217       if (unformat (input, "del"))
15218         is_add = 0;
15219       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15220         mac_set = 1;
15221       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15222         ip_set = 1;
15223       else if (unformat (input, "bd %d", &bd))
15224         bd_set = 1;
15225       else
15226         {
15227           errmsg ("parse error '%U'", format_unformat_error, input);
15228           return -99;
15229         }
15230     }
15231
15232   if (!bd_set || !ip_set || (!mac_set && is_add))
15233     {
15234       errmsg ("Missing BD, IP or MAC!");
15235       return -99;
15236     }
15237
15238   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15239   mp->is_add = is_add;
15240   clib_memcpy (&mp->entry.mac, mac, 6);
15241   mp->bd = clib_host_to_net_u32 (bd);
15242   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15243
15244   /* send */
15245   S (mp);
15246
15247   /* wait for reply */
15248   W (ret);
15249   return ret;
15250 }
15251
15252 static int
15253 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15254 {
15255   vl_api_one_add_del_l2_arp_entry_t *mp;
15256   unformat_input_t *input = vam->input;
15257   u8 is_add = 1;
15258   u8 mac_set = 0;
15259   u8 bd_set = 0;
15260   u8 ip_set = 0;
15261   u8 mac[6] = { 0, };
15262   u32 ip4 = 0, bd = ~0;
15263   int ret;
15264
15265   /* Parse args required to build the message */
15266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15267     {
15268       if (unformat (input, "del"))
15269         is_add = 0;
15270       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15271         mac_set = 1;
15272       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15273         ip_set = 1;
15274       else if (unformat (input, "bd %d", &bd))
15275         bd_set = 1;
15276       else
15277         {
15278           errmsg ("parse error '%U'", format_unformat_error, input);
15279           return -99;
15280         }
15281     }
15282
15283   if (!bd_set || !ip_set || (!mac_set && is_add))
15284     {
15285       errmsg ("Missing BD, IP or MAC!");
15286       return -99;
15287     }
15288
15289   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15290   mp->is_add = is_add;
15291   clib_memcpy (&mp->entry.mac, mac, 6);
15292   mp->bd = clib_host_to_net_u32 (bd);
15293   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15294
15295   /* send */
15296   S (mp);
15297
15298   /* wait for reply */
15299   W (ret);
15300   return ret;
15301 }
15302
15303 static int
15304 api_one_ndp_bd_get (vat_main_t * vam)
15305 {
15306   vl_api_one_ndp_bd_get_t *mp;
15307   int ret;
15308
15309   M (ONE_NDP_BD_GET, mp);
15310
15311   /* send */
15312   S (mp);
15313
15314   /* wait for reply */
15315   W (ret);
15316   return ret;
15317 }
15318
15319 static int
15320 api_one_ndp_entries_get (vat_main_t * vam)
15321 {
15322   vl_api_one_ndp_entries_get_t *mp;
15323   unformat_input_t *input = vam->input;
15324   u8 bd_set = 0;
15325   u32 bd = ~0;
15326   int ret;
15327
15328   /* Parse args required to build the message */
15329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15330     {
15331       if (unformat (input, "bd %d", &bd))
15332         bd_set = 1;
15333       else
15334         {
15335           errmsg ("parse error '%U'", format_unformat_error, input);
15336           return -99;
15337         }
15338     }
15339
15340   if (!bd_set)
15341     {
15342       errmsg ("Expected bridge domain!");
15343       return -99;
15344     }
15345
15346   M (ONE_NDP_ENTRIES_GET, mp);
15347   mp->bd = clib_host_to_net_u32 (bd);
15348
15349   /* send */
15350   S (mp);
15351
15352   /* wait for reply */
15353   W (ret);
15354   return ret;
15355 }
15356
15357 static int
15358 api_one_l2_arp_bd_get (vat_main_t * vam)
15359 {
15360   vl_api_one_l2_arp_bd_get_t *mp;
15361   int ret;
15362
15363   M (ONE_L2_ARP_BD_GET, mp);
15364
15365   /* send */
15366   S (mp);
15367
15368   /* wait for reply */
15369   W (ret);
15370   return ret;
15371 }
15372
15373 static int
15374 api_one_l2_arp_entries_get (vat_main_t * vam)
15375 {
15376   vl_api_one_l2_arp_entries_get_t *mp;
15377   unformat_input_t *input = vam->input;
15378   u8 bd_set = 0;
15379   u32 bd = ~0;
15380   int ret;
15381
15382   /* Parse args required to build the message */
15383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15384     {
15385       if (unformat (input, "bd %d", &bd))
15386         bd_set = 1;
15387       else
15388         {
15389           errmsg ("parse error '%U'", format_unformat_error, input);
15390           return -99;
15391         }
15392     }
15393
15394   if (!bd_set)
15395     {
15396       errmsg ("Expected bridge domain!");
15397       return -99;
15398     }
15399
15400   M (ONE_L2_ARP_ENTRIES_GET, mp);
15401   mp->bd = clib_host_to_net_u32 (bd);
15402
15403   /* send */
15404   S (mp);
15405
15406   /* wait for reply */
15407   W (ret);
15408   return ret;
15409 }
15410
15411 static int
15412 api_one_stats_enable_disable (vat_main_t * vam)
15413 {
15414   vl_api_one_stats_enable_disable_t *mp;
15415   unformat_input_t *input = vam->input;
15416   u8 is_set = 0;
15417   u8 is_enable = 0;
15418   int ret;
15419
15420   /* Parse args required to build the message */
15421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15422     {
15423       if (unformat (input, "enable"))
15424         {
15425           is_set = 1;
15426           is_enable = 1;
15427         }
15428       else if (unformat (input, "disable"))
15429         {
15430           is_set = 1;
15431         }
15432       else
15433         break;
15434     }
15435
15436   if (!is_set)
15437     {
15438       errmsg ("Value not set");
15439       return -99;
15440     }
15441
15442   M (ONE_STATS_ENABLE_DISABLE, mp);
15443   mp->is_enable = is_enable;
15444
15445   /* send */
15446   S (mp);
15447
15448   /* wait for reply */
15449   W (ret);
15450   return ret;
15451 }
15452
15453 static int
15454 api_show_one_stats_enable_disable (vat_main_t * vam)
15455 {
15456   vl_api_show_one_stats_enable_disable_t *mp;
15457   int ret;
15458
15459   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15460
15461   /* send */
15462   S (mp);
15463
15464   /* wait for reply */
15465   W (ret);
15466   return ret;
15467 }
15468
15469 static int
15470 api_show_one_map_request_mode (vat_main_t * vam)
15471 {
15472   vl_api_show_one_map_request_mode_t *mp;
15473   int ret;
15474
15475   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15476
15477   /* send */
15478   S (mp);
15479
15480   /* wait for reply */
15481   W (ret);
15482   return ret;
15483 }
15484
15485 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15486
15487 static int
15488 api_one_map_request_mode (vat_main_t * vam)
15489 {
15490   unformat_input_t *input = vam->input;
15491   vl_api_one_map_request_mode_t *mp;
15492   u8 mode = 0;
15493   int ret;
15494
15495   /* Parse args required to build the message */
15496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15497     {
15498       if (unformat (input, "dst-only"))
15499         mode = 0;
15500       else if (unformat (input, "src-dst"))
15501         mode = 1;
15502       else
15503         {
15504           errmsg ("parse error '%U'", format_unformat_error, input);
15505           return -99;
15506         }
15507     }
15508
15509   M (ONE_MAP_REQUEST_MODE, mp);
15510
15511   mp->mode = mode;
15512
15513   /* send */
15514   S (mp);
15515
15516   /* wait for reply */
15517   W (ret);
15518   return ret;
15519 }
15520
15521 #define api_lisp_map_request_mode api_one_map_request_mode
15522
15523 /**
15524  * Enable/disable ONE proxy ITR.
15525  *
15526  * @param vam vpp API test context
15527  * @return return code
15528  */
15529 static int
15530 api_one_pitr_set_locator_set (vat_main_t * vam)
15531 {
15532   u8 ls_name_set = 0;
15533   unformat_input_t *input = vam->input;
15534   vl_api_one_pitr_set_locator_set_t *mp;
15535   u8 is_add = 1;
15536   u8 *ls_name = 0;
15537   int ret;
15538
15539   /* Parse args required to build the message */
15540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15541     {
15542       if (unformat (input, "del"))
15543         is_add = 0;
15544       else if (unformat (input, "locator-set %s", &ls_name))
15545         ls_name_set = 1;
15546       else
15547         {
15548           errmsg ("parse error '%U'", format_unformat_error, input);
15549           return -99;
15550         }
15551     }
15552
15553   if (!ls_name_set)
15554     {
15555       errmsg ("locator-set name not set!");
15556       return -99;
15557     }
15558
15559   M (ONE_PITR_SET_LOCATOR_SET, mp);
15560
15561   mp->is_add = is_add;
15562   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15563   vec_free (ls_name);
15564
15565   /* send */
15566   S (mp);
15567
15568   /* wait for reply */
15569   W (ret);
15570   return ret;
15571 }
15572
15573 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15574
15575 static int
15576 api_one_nsh_set_locator_set (vat_main_t * vam)
15577 {
15578   u8 ls_name_set = 0;
15579   unformat_input_t *input = vam->input;
15580   vl_api_one_nsh_set_locator_set_t *mp;
15581   u8 is_add = 1;
15582   u8 *ls_name = 0;
15583   int ret;
15584
15585   /* Parse args required to build the message */
15586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15587     {
15588       if (unformat (input, "del"))
15589         is_add = 0;
15590       else if (unformat (input, "ls %s", &ls_name))
15591         ls_name_set = 1;
15592       else
15593         {
15594           errmsg ("parse error '%U'", format_unformat_error, input);
15595           return -99;
15596         }
15597     }
15598
15599   if (!ls_name_set && is_add)
15600     {
15601       errmsg ("locator-set name not set!");
15602       return -99;
15603     }
15604
15605   M (ONE_NSH_SET_LOCATOR_SET, mp);
15606
15607   mp->is_add = is_add;
15608   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15609   vec_free (ls_name);
15610
15611   /* send */
15612   S (mp);
15613
15614   /* wait for reply */
15615   W (ret);
15616   return ret;
15617 }
15618
15619 static int
15620 api_show_one_pitr (vat_main_t * vam)
15621 {
15622   vl_api_show_one_pitr_t *mp;
15623   int ret;
15624
15625   if (!vam->json_output)
15626     {
15627       print (vam->ofp, "%=20s", "lisp status:");
15628     }
15629
15630   M (SHOW_ONE_PITR, mp);
15631   /* send it... */
15632   S (mp);
15633
15634   /* Wait for a reply... */
15635   W (ret);
15636   return ret;
15637 }
15638
15639 #define api_show_lisp_pitr api_show_one_pitr
15640
15641 static int
15642 api_one_use_petr (vat_main_t * vam)
15643 {
15644   unformat_input_t *input = vam->input;
15645   vl_api_one_use_petr_t *mp;
15646   u8 is_add = 0;
15647   ip_address_t ip;
15648   int ret;
15649
15650   clib_memset (&ip, 0, sizeof (ip));
15651
15652   /* Parse args required to build the message */
15653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15654     {
15655       if (unformat (input, "disable"))
15656         is_add = 0;
15657       else
15658         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15659         {
15660           is_add = 1;
15661           ip_addr_version (&ip) = AF_IP4;
15662         }
15663       else
15664         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15665         {
15666           is_add = 1;
15667           ip_addr_version (&ip) = AF_IP6;
15668         }
15669       else
15670         {
15671           errmsg ("parse error '%U'", format_unformat_error, input);
15672           return -99;
15673         }
15674     }
15675
15676   M (ONE_USE_PETR, mp);
15677
15678   mp->is_add = is_add;
15679   if (is_add)
15680     {
15681       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15682       if (mp->ip_address.af)
15683         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15684       else
15685         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15686     }
15687
15688   /* send */
15689   S (mp);
15690
15691   /* wait for reply */
15692   W (ret);
15693   return ret;
15694 }
15695
15696 #define api_lisp_use_petr api_one_use_petr
15697
15698 static int
15699 api_show_one_nsh_mapping (vat_main_t * vam)
15700 {
15701   vl_api_show_one_use_petr_t *mp;
15702   int ret;
15703
15704   if (!vam->json_output)
15705     {
15706       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15707     }
15708
15709   M (SHOW_ONE_NSH_MAPPING, mp);
15710   /* send it... */
15711   S (mp);
15712
15713   /* Wait for a reply... */
15714   W (ret);
15715   return ret;
15716 }
15717
15718 static int
15719 api_show_one_use_petr (vat_main_t * vam)
15720 {
15721   vl_api_show_one_use_petr_t *mp;
15722   int ret;
15723
15724   if (!vam->json_output)
15725     {
15726       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15727     }
15728
15729   M (SHOW_ONE_USE_PETR, mp);
15730   /* send it... */
15731   S (mp);
15732
15733   /* Wait for a reply... */
15734   W (ret);
15735   return ret;
15736 }
15737
15738 #define api_show_lisp_use_petr api_show_one_use_petr
15739
15740 /**
15741  * Add/delete mapping between vni and vrf
15742  */
15743 static int
15744 api_one_eid_table_add_del_map (vat_main_t * vam)
15745 {
15746   unformat_input_t *input = vam->input;
15747   vl_api_one_eid_table_add_del_map_t *mp;
15748   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15749   u32 vni, vrf, bd_index;
15750   int ret;
15751
15752   /* Parse args required to build the message */
15753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15754     {
15755       if (unformat (input, "del"))
15756         is_add = 0;
15757       else if (unformat (input, "vrf %d", &vrf))
15758         vrf_set = 1;
15759       else if (unformat (input, "bd_index %d", &bd_index))
15760         bd_index_set = 1;
15761       else if (unformat (input, "vni %d", &vni))
15762         vni_set = 1;
15763       else
15764         break;
15765     }
15766
15767   if (!vni_set || (!vrf_set && !bd_index_set))
15768     {
15769       errmsg ("missing arguments!");
15770       return -99;
15771     }
15772
15773   if (vrf_set && bd_index_set)
15774     {
15775       errmsg ("error: both vrf and bd entered!");
15776       return -99;
15777     }
15778
15779   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15780
15781   mp->is_add = is_add;
15782   mp->vni = htonl (vni);
15783   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15784   mp->is_l2 = bd_index_set;
15785
15786   /* send */
15787   S (mp);
15788
15789   /* wait for reply */
15790   W (ret);
15791   return ret;
15792 }
15793
15794 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15795
15796 uword
15797 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15798 {
15799   u32 *action = va_arg (*args, u32 *);
15800   u8 *s = 0;
15801
15802   if (unformat (input, "%s", &s))
15803     {
15804       if (!strcmp ((char *) s, "no-action"))
15805         action[0] = 0;
15806       else if (!strcmp ((char *) s, "natively-forward"))
15807         action[0] = 1;
15808       else if (!strcmp ((char *) s, "send-map-request"))
15809         action[0] = 2;
15810       else if (!strcmp ((char *) s, "drop"))
15811         action[0] = 3;
15812       else
15813         {
15814           clib_warning ("invalid action: '%s'", s);
15815           action[0] = 3;
15816         }
15817     }
15818   else
15819     return 0;
15820
15821   vec_free (s);
15822   return 1;
15823 }
15824
15825 /**
15826  * Add/del remote mapping to/from ONE control plane
15827  *
15828  * @param vam vpp API test context
15829  * @return return code
15830  */
15831 static int
15832 api_one_add_del_remote_mapping (vat_main_t * vam)
15833 {
15834   unformat_input_t *input = vam->input;
15835   vl_api_one_add_del_remote_mapping_t *mp;
15836   u32 vni = 0;
15837   lisp_eid_vat_t _eid, *eid = &_eid;
15838   lisp_eid_vat_t _seid, *seid = &_seid;
15839   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15840   u32 action = ~0, p, w, data_len;
15841   ip4_address_t rloc4;
15842   ip6_address_t rloc6;
15843   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15844   int ret;
15845
15846   clib_memset (&rloc, 0, sizeof (rloc));
15847
15848   /* Parse args required to build the message */
15849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15850     {
15851       if (unformat (input, "del-all"))
15852         {
15853           del_all = 1;
15854         }
15855       else if (unformat (input, "del"))
15856         {
15857           is_add = 0;
15858         }
15859       else if (unformat (input, "add"))
15860         {
15861           is_add = 1;
15862         }
15863       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15864         {
15865           eid_set = 1;
15866         }
15867       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15868         {
15869           seid_set = 1;
15870         }
15871       else if (unformat (input, "vni %d", &vni))
15872         {
15873           ;
15874         }
15875       else if (unformat (input, "p %d w %d", &p, &w))
15876         {
15877           if (!curr_rloc)
15878             {
15879               errmsg ("No RLOC configured for setting priority/weight!");
15880               return -99;
15881             }
15882           curr_rloc->priority = p;
15883           curr_rloc->weight = w;
15884         }
15885       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15886         {
15887           rloc.ip_address.af = 0;
15888           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15889           vec_add1 (rlocs, rloc);
15890           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15891         }
15892       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15893         {
15894           rloc.ip_address.af = 1;
15895           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15896           vec_add1 (rlocs, rloc);
15897           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15898         }
15899       else if (unformat (input, "action %U",
15900                          unformat_negative_mapping_action, &action))
15901         {
15902           ;
15903         }
15904       else
15905         {
15906           clib_warning ("parse error '%U'", format_unformat_error, input);
15907           return -99;
15908         }
15909     }
15910
15911   if (0 == eid_set)
15912     {
15913       errmsg ("missing params!");
15914       return -99;
15915     }
15916
15917   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15918     {
15919       errmsg ("no action set for negative map-reply!");
15920       return -99;
15921     }
15922
15923   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15924
15925   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15926   mp->is_add = is_add;
15927   mp->vni = htonl (vni);
15928   mp->action = (u8) action;
15929   mp->is_src_dst = seid_set;
15930   mp->del_all = del_all;
15931   lisp_eid_put_vat (&mp->deid, eid);
15932   lisp_eid_put_vat (&mp->seid, seid);
15933
15934   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15935   clib_memcpy (mp->rlocs, rlocs, data_len);
15936   vec_free (rlocs);
15937
15938   /* send it... */
15939   S (mp);
15940
15941   /* Wait for a reply... */
15942   W (ret);
15943   return ret;
15944 }
15945
15946 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15947
15948 /**
15949  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15950  * forwarding entries in data-plane accordingly.
15951  *
15952  * @param vam vpp API test context
15953  * @return return code
15954  */
15955 static int
15956 api_one_add_del_adjacency (vat_main_t * vam)
15957 {
15958   unformat_input_t *input = vam->input;
15959   vl_api_one_add_del_adjacency_t *mp;
15960   u32 vni = 0;
15961   u8 is_add = 1;
15962   int ret;
15963   lisp_eid_vat_t leid, reid;
15964
15965   leid.type = reid.type = (u8) ~ 0;
15966
15967   /* Parse args required to build the message */
15968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15969     {
15970       if (unformat (input, "del"))
15971         {
15972           is_add = 0;
15973         }
15974       else if (unformat (input, "add"))
15975         {
15976           is_add = 1;
15977         }
15978       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15979                          &reid.addr.ip, &reid.len))
15980         {
15981           reid.type = 0;        /* ipv4 */
15982         }
15983       else if (unformat (input, "reid %U", unformat_ethernet_address,
15984                          &reid.addr.mac))
15985         {
15986           reid.type = 1;        /* mac */
15987         }
15988       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
15989                          &leid.addr.ip, &leid.len))
15990         {
15991           leid.type = 0;        /* ipv4 */
15992         }
15993       else if (unformat (input, "leid %U", unformat_ethernet_address,
15994                          &leid.addr.mac))
15995         {
15996           leid.type = 1;        /* mac */
15997         }
15998       else if (unformat (input, "vni %d", &vni))
15999         {
16000           ;
16001         }
16002       else
16003         {
16004           errmsg ("parse error '%U'", format_unformat_error, input);
16005           return -99;
16006         }
16007     }
16008
16009   if ((u8) ~ 0 == reid.type)
16010     {
16011       errmsg ("missing params!");
16012       return -99;
16013     }
16014
16015   if (leid.type != reid.type)
16016     {
16017       errmsg ("remote and local EIDs are of different types!");
16018       return -99;
16019     }
16020
16021   M (ONE_ADD_DEL_ADJACENCY, mp);
16022   mp->is_add = is_add;
16023   mp->vni = htonl (vni);
16024   lisp_eid_put_vat (&mp->leid, &leid);
16025   lisp_eid_put_vat (&mp->reid, &reid);
16026
16027   /* send it... */
16028   S (mp);
16029
16030   /* Wait for a reply... */
16031   W (ret);
16032   return ret;
16033 }
16034
16035 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16036
16037 uword
16038 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16039 {
16040   u32 *mode = va_arg (*args, u32 *);
16041
16042   if (unformat (input, "lisp"))
16043     *mode = 0;
16044   else if (unformat (input, "vxlan"))
16045     *mode = 1;
16046   else
16047     return 0;
16048
16049   return 1;
16050 }
16051
16052 static int
16053 api_gpe_get_encap_mode (vat_main_t * vam)
16054 {
16055   vl_api_gpe_get_encap_mode_t *mp;
16056   int ret;
16057
16058   /* Construct the API message */
16059   M (GPE_GET_ENCAP_MODE, mp);
16060
16061   /* send it... */
16062   S (mp);
16063
16064   /* Wait for a reply... */
16065   W (ret);
16066   return ret;
16067 }
16068
16069 static int
16070 api_gpe_set_encap_mode (vat_main_t * vam)
16071 {
16072   unformat_input_t *input = vam->input;
16073   vl_api_gpe_set_encap_mode_t *mp;
16074   int ret;
16075   u32 mode = 0;
16076
16077   /* Parse args required to build the message */
16078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16079     {
16080       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16081         ;
16082       else
16083         break;
16084     }
16085
16086   /* Construct the API message */
16087   M (GPE_SET_ENCAP_MODE, mp);
16088
16089   mp->is_vxlan = mode;
16090
16091   /* send it... */
16092   S (mp);
16093
16094   /* Wait for a reply... */
16095   W (ret);
16096   return ret;
16097 }
16098
16099 static int
16100 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16101 {
16102   unformat_input_t *input = vam->input;
16103   vl_api_gpe_add_del_iface_t *mp;
16104   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16105   u32 dp_table = 0, vni = 0;
16106   int ret;
16107
16108   /* Parse args required to build the message */
16109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16110     {
16111       if (unformat (input, "up"))
16112         {
16113           action_set = 1;
16114           is_add = 1;
16115         }
16116       else if (unformat (input, "down"))
16117         {
16118           action_set = 1;
16119           is_add = 0;
16120         }
16121       else if (unformat (input, "table_id %d", &dp_table))
16122         {
16123           dp_table_set = 1;
16124         }
16125       else if (unformat (input, "bd_id %d", &dp_table))
16126         {
16127           dp_table_set = 1;
16128           is_l2 = 1;
16129         }
16130       else if (unformat (input, "vni %d", &vni))
16131         {
16132           vni_set = 1;
16133         }
16134       else
16135         break;
16136     }
16137
16138   if (action_set == 0)
16139     {
16140       errmsg ("Action not set");
16141       return -99;
16142     }
16143   if (dp_table_set == 0 || vni_set == 0)
16144     {
16145       errmsg ("vni and dp_table must be set");
16146       return -99;
16147     }
16148
16149   /* Construct the API message */
16150   M (GPE_ADD_DEL_IFACE, mp);
16151
16152   mp->is_add = is_add;
16153   mp->dp_table = clib_host_to_net_u32 (dp_table);
16154   mp->is_l2 = is_l2;
16155   mp->vni = clib_host_to_net_u32 (vni);
16156
16157   /* send it... */
16158   S (mp);
16159
16160   /* Wait for a reply... */
16161   W (ret);
16162   return ret;
16163 }
16164
16165 static int
16166 api_one_map_register_fallback_threshold (vat_main_t * vam)
16167 {
16168   unformat_input_t *input = vam->input;
16169   vl_api_one_map_register_fallback_threshold_t *mp;
16170   u32 value = 0;
16171   u8 is_set = 0;
16172   int ret;
16173
16174   /* Parse args required to build the message */
16175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16176     {
16177       if (unformat (input, "%u", &value))
16178         is_set = 1;
16179       else
16180         {
16181           clib_warning ("parse error '%U'", format_unformat_error, input);
16182           return -99;
16183         }
16184     }
16185
16186   if (!is_set)
16187     {
16188       errmsg ("fallback threshold value is missing!");
16189       return -99;
16190     }
16191
16192   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16193   mp->value = clib_host_to_net_u32 (value);
16194
16195   /* send it... */
16196   S (mp);
16197
16198   /* Wait for a reply... */
16199   W (ret);
16200   return ret;
16201 }
16202
16203 static int
16204 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16205 {
16206   vl_api_show_one_map_register_fallback_threshold_t *mp;
16207   int ret;
16208
16209   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16210
16211   /* send it... */
16212   S (mp);
16213
16214   /* Wait for a reply... */
16215   W (ret);
16216   return ret;
16217 }
16218
16219 uword
16220 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16221 {
16222   u32 *proto = va_arg (*args, u32 *);
16223
16224   if (unformat (input, "udp"))
16225     *proto = 1;
16226   else if (unformat (input, "api"))
16227     *proto = 2;
16228   else
16229     return 0;
16230
16231   return 1;
16232 }
16233
16234 static int
16235 api_one_set_transport_protocol (vat_main_t * vam)
16236 {
16237   unformat_input_t *input = vam->input;
16238   vl_api_one_set_transport_protocol_t *mp;
16239   u8 is_set = 0;
16240   u32 protocol = 0;
16241   int ret;
16242
16243   /* Parse args required to build the message */
16244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16247         is_set = 1;
16248       else
16249         {
16250           clib_warning ("parse error '%U'", format_unformat_error, input);
16251           return -99;
16252         }
16253     }
16254
16255   if (!is_set)
16256     {
16257       errmsg ("Transport protocol missing!");
16258       return -99;
16259     }
16260
16261   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16262   mp->protocol = (u8) protocol;
16263
16264   /* send it... */
16265   S (mp);
16266
16267   /* Wait for a reply... */
16268   W (ret);
16269   return ret;
16270 }
16271
16272 static int
16273 api_one_get_transport_protocol (vat_main_t * vam)
16274 {
16275   vl_api_one_get_transport_protocol_t *mp;
16276   int ret;
16277
16278   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16279
16280   /* send it... */
16281   S (mp);
16282
16283   /* Wait for a reply... */
16284   W (ret);
16285   return ret;
16286 }
16287
16288 static int
16289 api_one_map_register_set_ttl (vat_main_t * vam)
16290 {
16291   unformat_input_t *input = vam->input;
16292   vl_api_one_map_register_set_ttl_t *mp;
16293   u32 ttl = 0;
16294   u8 is_set = 0;
16295   int ret;
16296
16297   /* Parse args required to build the message */
16298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16299     {
16300       if (unformat (input, "%u", &ttl))
16301         is_set = 1;
16302       else
16303         {
16304           clib_warning ("parse error '%U'", format_unformat_error, input);
16305           return -99;
16306         }
16307     }
16308
16309   if (!is_set)
16310     {
16311       errmsg ("TTL value missing!");
16312       return -99;
16313     }
16314
16315   M (ONE_MAP_REGISTER_SET_TTL, mp);
16316   mp->ttl = clib_host_to_net_u32 (ttl);
16317
16318   /* send it... */
16319   S (mp);
16320
16321   /* Wait for a reply... */
16322   W (ret);
16323   return ret;
16324 }
16325
16326 static int
16327 api_show_one_map_register_ttl (vat_main_t * vam)
16328 {
16329   vl_api_show_one_map_register_ttl_t *mp;
16330   int ret;
16331
16332   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16333
16334   /* send it... */
16335   S (mp);
16336
16337   /* Wait for a reply... */
16338   W (ret);
16339   return ret;
16340 }
16341
16342 /**
16343  * Add/del map request itr rlocs from ONE control plane and updates
16344  *
16345  * @param vam vpp API test context
16346  * @return return code
16347  */
16348 static int
16349 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16350 {
16351   unformat_input_t *input = vam->input;
16352   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16353   u8 *locator_set_name = 0;
16354   u8 locator_set_name_set = 0;
16355   u8 is_add = 1;
16356   int ret;
16357
16358   /* Parse args required to build the message */
16359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16360     {
16361       if (unformat (input, "del"))
16362         {
16363           is_add = 0;
16364         }
16365       else if (unformat (input, "%_%v%_", &locator_set_name))
16366         {
16367           locator_set_name_set = 1;
16368         }
16369       else
16370         {
16371           clib_warning ("parse error '%U'", format_unformat_error, input);
16372           return -99;
16373         }
16374     }
16375
16376   if (is_add && !locator_set_name_set)
16377     {
16378       errmsg ("itr-rloc is not set!");
16379       return -99;
16380     }
16381
16382   if (is_add && vec_len (locator_set_name) > 64)
16383     {
16384       errmsg ("itr-rloc locator-set name too long");
16385       vec_free (locator_set_name);
16386       return -99;
16387     }
16388
16389   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16390   mp->is_add = is_add;
16391   if (is_add)
16392     {
16393       clib_memcpy (mp->locator_set_name, locator_set_name,
16394                    vec_len (locator_set_name));
16395     }
16396   else
16397     {
16398       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16399     }
16400   vec_free (locator_set_name);
16401
16402   /* send it... */
16403   S (mp);
16404
16405   /* Wait for a reply... */
16406   W (ret);
16407   return ret;
16408 }
16409
16410 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16411
16412 static int
16413 api_one_locator_dump (vat_main_t * vam)
16414 {
16415   unformat_input_t *input = vam->input;
16416   vl_api_one_locator_dump_t *mp;
16417   vl_api_control_ping_t *mp_ping;
16418   u8 is_index_set = 0, is_name_set = 0;
16419   u8 *ls_name = 0;
16420   u32 ls_index = ~0;
16421   int ret;
16422
16423   /* Parse args required to build the message */
16424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16425     {
16426       if (unformat (input, "ls_name %_%v%_", &ls_name))
16427         {
16428           is_name_set = 1;
16429         }
16430       else if (unformat (input, "ls_index %d", &ls_index))
16431         {
16432           is_index_set = 1;
16433         }
16434       else
16435         {
16436           errmsg ("parse error '%U'", format_unformat_error, input);
16437           return -99;
16438         }
16439     }
16440
16441   if (!is_index_set && !is_name_set)
16442     {
16443       errmsg ("error: expected one of index or name!");
16444       return -99;
16445     }
16446
16447   if (is_index_set && is_name_set)
16448     {
16449       errmsg ("error: only one param expected!");
16450       return -99;
16451     }
16452
16453   if (vec_len (ls_name) > 62)
16454     {
16455       errmsg ("error: locator set name too long!");
16456       return -99;
16457     }
16458
16459   if (!vam->json_output)
16460     {
16461       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16462     }
16463
16464   M (ONE_LOCATOR_DUMP, mp);
16465   mp->is_index_set = is_index_set;
16466
16467   if (is_index_set)
16468     mp->ls_index = clib_host_to_net_u32 (ls_index);
16469   else
16470     {
16471       vec_add1 (ls_name, 0);
16472       strncpy ((char *) mp->ls_name, (char *) ls_name,
16473                sizeof (mp->ls_name) - 1);
16474     }
16475
16476   /* send it... */
16477   S (mp);
16478
16479   /* Use a control ping for synchronization */
16480   MPING (CONTROL_PING, mp_ping);
16481   S (mp_ping);
16482
16483   /* Wait for a reply... */
16484   W (ret);
16485   return ret;
16486 }
16487
16488 #define api_lisp_locator_dump api_one_locator_dump
16489
16490 static int
16491 api_one_locator_set_dump (vat_main_t * vam)
16492 {
16493   vl_api_one_locator_set_dump_t *mp;
16494   vl_api_control_ping_t *mp_ping;
16495   unformat_input_t *input = vam->input;
16496   u8 filter = 0;
16497   int ret;
16498
16499   /* Parse args required to build the message */
16500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16501     {
16502       if (unformat (input, "local"))
16503         {
16504           filter = 1;
16505         }
16506       else if (unformat (input, "remote"))
16507         {
16508           filter = 2;
16509         }
16510       else
16511         {
16512           errmsg ("parse error '%U'", format_unformat_error, input);
16513           return -99;
16514         }
16515     }
16516
16517   if (!vam->json_output)
16518     {
16519       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16520     }
16521
16522   M (ONE_LOCATOR_SET_DUMP, mp);
16523
16524   mp->filter = filter;
16525
16526   /* send it... */
16527   S (mp);
16528
16529   /* Use a control ping for synchronization */
16530   MPING (CONTROL_PING, mp_ping);
16531   S (mp_ping);
16532
16533   /* Wait for a reply... */
16534   W (ret);
16535   return ret;
16536 }
16537
16538 #define api_lisp_locator_set_dump api_one_locator_set_dump
16539
16540 static int
16541 api_one_eid_table_map_dump (vat_main_t * vam)
16542 {
16543   u8 is_l2 = 0;
16544   u8 mode_set = 0;
16545   unformat_input_t *input = vam->input;
16546   vl_api_one_eid_table_map_dump_t *mp;
16547   vl_api_control_ping_t *mp_ping;
16548   int ret;
16549
16550   /* Parse args required to build the message */
16551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16552     {
16553       if (unformat (input, "l2"))
16554         {
16555           is_l2 = 1;
16556           mode_set = 1;
16557         }
16558       else if (unformat (input, "l3"))
16559         {
16560           is_l2 = 0;
16561           mode_set = 1;
16562         }
16563       else
16564         {
16565           errmsg ("parse error '%U'", format_unformat_error, input);
16566           return -99;
16567         }
16568     }
16569
16570   if (!mode_set)
16571     {
16572       errmsg ("expected one of 'l2' or 'l3' parameter!");
16573       return -99;
16574     }
16575
16576   if (!vam->json_output)
16577     {
16578       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16579     }
16580
16581   M (ONE_EID_TABLE_MAP_DUMP, mp);
16582   mp->is_l2 = is_l2;
16583
16584   /* send it... */
16585   S (mp);
16586
16587   /* Use a control ping for synchronization */
16588   MPING (CONTROL_PING, mp_ping);
16589   S (mp_ping);
16590
16591   /* Wait for a reply... */
16592   W (ret);
16593   return ret;
16594 }
16595
16596 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16597
16598 static int
16599 api_one_eid_table_vni_dump (vat_main_t * vam)
16600 {
16601   vl_api_one_eid_table_vni_dump_t *mp;
16602   vl_api_control_ping_t *mp_ping;
16603   int ret;
16604
16605   if (!vam->json_output)
16606     {
16607       print (vam->ofp, "VNI");
16608     }
16609
16610   M (ONE_EID_TABLE_VNI_DUMP, mp);
16611
16612   /* send it... */
16613   S (mp);
16614
16615   /* Use a control ping for synchronization */
16616   MPING (CONTROL_PING, mp_ping);
16617   S (mp_ping);
16618
16619   /* Wait for a reply... */
16620   W (ret);
16621   return ret;
16622 }
16623
16624 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16625
16626 static int
16627 api_one_eid_table_dump (vat_main_t * vam)
16628 {
16629   unformat_input_t *i = vam->input;
16630   vl_api_one_eid_table_dump_t *mp;
16631   vl_api_control_ping_t *mp_ping;
16632   u8 filter = 0;
16633   int ret;
16634   u32 vni, t = 0;
16635   lisp_eid_vat_t eid;
16636   u8 eid_set = 0;
16637
16638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16639     {
16640       if (unformat
16641           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16642         {
16643           eid_set = 1;
16644           eid.type = 0;
16645         }
16646       else
16647         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16648         {
16649           eid_set = 1;
16650           eid.type = 1;
16651         }
16652       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16653         {
16654           eid_set = 1;
16655           eid.type = 2;
16656         }
16657       else if (unformat (i, "vni %d", &t))
16658         {
16659           vni = t;
16660         }
16661       else if (unformat (i, "local"))
16662         {
16663           filter = 1;
16664         }
16665       else if (unformat (i, "remote"))
16666         {
16667           filter = 2;
16668         }
16669       else
16670         {
16671           errmsg ("parse error '%U'", format_unformat_error, i);
16672           return -99;
16673         }
16674     }
16675
16676   if (!vam->json_output)
16677     {
16678       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16679              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16680     }
16681
16682   M (ONE_EID_TABLE_DUMP, mp);
16683
16684   mp->filter = filter;
16685   if (eid_set)
16686     {
16687       mp->eid_set = 1;
16688       mp->vni = htonl (vni);
16689       lisp_eid_put_vat (&mp->eid, &eid);
16690     }
16691
16692   /* send it... */
16693   S (mp);
16694
16695   /* Use a control ping for synchronization */
16696   MPING (CONTROL_PING, mp_ping);
16697   S (mp_ping);
16698
16699   /* Wait for a reply... */
16700   W (ret);
16701   return ret;
16702 }
16703
16704 #define api_lisp_eid_table_dump api_one_eid_table_dump
16705
16706 static int
16707 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16708 {
16709   unformat_input_t *i = vam->input;
16710   vl_api_gpe_fwd_entries_get_t *mp;
16711   u8 vni_set = 0;
16712   u32 vni = ~0;
16713   int ret;
16714
16715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16716     {
16717       if (unformat (i, "vni %d", &vni))
16718         {
16719           vni_set = 1;
16720         }
16721       else
16722         {
16723           errmsg ("parse error '%U'", format_unformat_error, i);
16724           return -99;
16725         }
16726     }
16727
16728   if (!vni_set)
16729     {
16730       errmsg ("vni not set!");
16731       return -99;
16732     }
16733
16734   if (!vam->json_output)
16735     {
16736       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16737              "leid", "reid");
16738     }
16739
16740   M (GPE_FWD_ENTRIES_GET, mp);
16741   mp->vni = clib_host_to_net_u32 (vni);
16742
16743   /* send it... */
16744   S (mp);
16745
16746   /* Wait for a reply... */
16747   W (ret);
16748   return ret;
16749 }
16750
16751 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16752 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16753 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16754 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16755 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16756 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16757 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16758 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16759
16760 static int
16761 api_one_adjacencies_get (vat_main_t * vam)
16762 {
16763   unformat_input_t *i = vam->input;
16764   vl_api_one_adjacencies_get_t *mp;
16765   u8 vni_set = 0;
16766   u32 vni = ~0;
16767   int ret;
16768
16769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16770     {
16771       if (unformat (i, "vni %d", &vni))
16772         {
16773           vni_set = 1;
16774         }
16775       else
16776         {
16777           errmsg ("parse error '%U'", format_unformat_error, i);
16778           return -99;
16779         }
16780     }
16781
16782   if (!vni_set)
16783     {
16784       errmsg ("vni not set!");
16785       return -99;
16786     }
16787
16788   if (!vam->json_output)
16789     {
16790       print (vam->ofp, "%s %40s", "leid", "reid");
16791     }
16792
16793   M (ONE_ADJACENCIES_GET, mp);
16794   mp->vni = clib_host_to_net_u32 (vni);
16795
16796   /* send it... */
16797   S (mp);
16798
16799   /* Wait for a reply... */
16800   W (ret);
16801   return ret;
16802 }
16803
16804 #define api_lisp_adjacencies_get api_one_adjacencies_get
16805
16806 static int
16807 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16808 {
16809   unformat_input_t *i = vam->input;
16810   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16811   int ret;
16812   u8 ip_family_set = 0, is_ip4 = 1;
16813
16814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16815     {
16816       if (unformat (i, "ip4"))
16817         {
16818           ip_family_set = 1;
16819           is_ip4 = 1;
16820         }
16821       else if (unformat (i, "ip6"))
16822         {
16823           ip_family_set = 1;
16824           is_ip4 = 0;
16825         }
16826       else
16827         {
16828           errmsg ("parse error '%U'", format_unformat_error, i);
16829           return -99;
16830         }
16831     }
16832
16833   if (!ip_family_set)
16834     {
16835       errmsg ("ip family not set!");
16836       return -99;
16837     }
16838
16839   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16840   mp->is_ip4 = is_ip4;
16841
16842   /* send it... */
16843   S (mp);
16844
16845   /* Wait for a reply... */
16846   W (ret);
16847   return ret;
16848 }
16849
16850 static int
16851 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16852 {
16853   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16854   int ret;
16855
16856   if (!vam->json_output)
16857     {
16858       print (vam->ofp, "VNIs");
16859     }
16860
16861   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16862
16863   /* send it... */
16864   S (mp);
16865
16866   /* Wait for a reply... */
16867   W (ret);
16868   return ret;
16869 }
16870
16871 static int
16872 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16873 {
16874   unformat_input_t *i = vam->input;
16875   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16876   int ret = 0;
16877   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16878   struct in_addr ip4;
16879   struct in6_addr ip6;
16880   u32 table_id = 0, nh_sw_if_index = ~0;
16881
16882   clib_memset (&ip4, 0, sizeof (ip4));
16883   clib_memset (&ip6, 0, sizeof (ip6));
16884
16885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16886     {
16887       if (unformat (i, "del"))
16888         is_add = 0;
16889       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16890                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16891         {
16892           ip_set = 1;
16893           is_ip4 = 1;
16894         }
16895       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16896                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16897         {
16898           ip_set = 1;
16899           is_ip4 = 0;
16900         }
16901       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16902         {
16903           ip_set = 1;
16904           is_ip4 = 1;
16905           nh_sw_if_index = ~0;
16906         }
16907       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16908         {
16909           ip_set = 1;
16910           is_ip4 = 0;
16911           nh_sw_if_index = ~0;
16912         }
16913       else if (unformat (i, "table %d", &table_id))
16914         ;
16915       else
16916         {
16917           errmsg ("parse error '%U'", format_unformat_error, i);
16918           return -99;
16919         }
16920     }
16921
16922   if (!ip_set)
16923     {
16924       errmsg ("nh addr not set!");
16925       return -99;
16926     }
16927
16928   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16929   mp->is_add = is_add;
16930   mp->table_id = clib_host_to_net_u32 (table_id);
16931   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16932   mp->nh_addr.af = is_ip4 ? 0 : 1;
16933   if (is_ip4)
16934     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16935   else
16936     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16937
16938   /* send it... */
16939   S (mp);
16940
16941   /* Wait for a reply... */
16942   W (ret);
16943   return ret;
16944 }
16945
16946 static int
16947 api_one_map_server_dump (vat_main_t * vam)
16948 {
16949   vl_api_one_map_server_dump_t *mp;
16950   vl_api_control_ping_t *mp_ping;
16951   int ret;
16952
16953   if (!vam->json_output)
16954     {
16955       print (vam->ofp, "%=20s", "Map server");
16956     }
16957
16958   M (ONE_MAP_SERVER_DUMP, mp);
16959   /* send it... */
16960   S (mp);
16961
16962   /* Use a control ping for synchronization */
16963   MPING (CONTROL_PING, mp_ping);
16964   S (mp_ping);
16965
16966   /* Wait for a reply... */
16967   W (ret);
16968   return ret;
16969 }
16970
16971 #define api_lisp_map_server_dump api_one_map_server_dump
16972
16973 static int
16974 api_one_map_resolver_dump (vat_main_t * vam)
16975 {
16976   vl_api_one_map_resolver_dump_t *mp;
16977   vl_api_control_ping_t *mp_ping;
16978   int ret;
16979
16980   if (!vam->json_output)
16981     {
16982       print (vam->ofp, "%=20s", "Map resolver");
16983     }
16984
16985   M (ONE_MAP_RESOLVER_DUMP, mp);
16986   /* send it... */
16987   S (mp);
16988
16989   /* Use a control ping for synchronization */
16990   MPING (CONTROL_PING, mp_ping);
16991   S (mp_ping);
16992
16993   /* Wait for a reply... */
16994   W (ret);
16995   return ret;
16996 }
16997
16998 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16999
17000 static int
17001 api_one_stats_flush (vat_main_t * vam)
17002 {
17003   vl_api_one_stats_flush_t *mp;
17004   int ret = 0;
17005
17006   M (ONE_STATS_FLUSH, mp);
17007   S (mp);
17008   W (ret);
17009   return ret;
17010 }
17011
17012 static int
17013 api_one_stats_dump (vat_main_t * vam)
17014 {
17015   vl_api_one_stats_dump_t *mp;
17016   vl_api_control_ping_t *mp_ping;
17017   int ret;
17018
17019   M (ONE_STATS_DUMP, mp);
17020   /* send it... */
17021   S (mp);
17022
17023   /* Use a control ping for synchronization */
17024   MPING (CONTROL_PING, mp_ping);
17025   S (mp_ping);
17026
17027   /* Wait for a reply... */
17028   W (ret);
17029   return ret;
17030 }
17031
17032 static int
17033 api_show_one_status (vat_main_t * vam)
17034 {
17035   vl_api_show_one_status_t *mp;
17036   int ret;
17037
17038   if (!vam->json_output)
17039     {
17040       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17041     }
17042
17043   M (SHOW_ONE_STATUS, mp);
17044   /* send it... */
17045   S (mp);
17046   /* Wait for a reply... */
17047   W (ret);
17048   return ret;
17049 }
17050
17051 #define api_show_lisp_status api_show_one_status
17052
17053 static int
17054 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17055 {
17056   vl_api_gpe_fwd_entry_path_dump_t *mp;
17057   vl_api_control_ping_t *mp_ping;
17058   unformat_input_t *i = vam->input;
17059   u32 fwd_entry_index = ~0;
17060   int ret;
17061
17062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17063     {
17064       if (unformat (i, "index %d", &fwd_entry_index))
17065         ;
17066       else
17067         break;
17068     }
17069
17070   if (~0 == fwd_entry_index)
17071     {
17072       errmsg ("no index specified!");
17073       return -99;
17074     }
17075
17076   if (!vam->json_output)
17077     {
17078       print (vam->ofp, "first line");
17079     }
17080
17081   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17082
17083   /* send it... */
17084   S (mp);
17085   /* Use a control ping for synchronization */
17086   MPING (CONTROL_PING, mp_ping);
17087   S (mp_ping);
17088
17089   /* Wait for a reply... */
17090   W (ret);
17091   return ret;
17092 }
17093
17094 static int
17095 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17096 {
17097   vl_api_one_get_map_request_itr_rlocs_t *mp;
17098   int ret;
17099
17100   if (!vam->json_output)
17101     {
17102       print (vam->ofp, "%=20s", "itr-rlocs:");
17103     }
17104
17105   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17106   /* send it... */
17107   S (mp);
17108   /* Wait for a reply... */
17109   W (ret);
17110   return ret;
17111 }
17112
17113 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17114
17115 static int
17116 api_af_packet_create (vat_main_t * vam)
17117 {
17118   unformat_input_t *i = vam->input;
17119   vl_api_af_packet_create_t *mp;
17120   u8 *host_if_name = 0;
17121   u8 hw_addr[6];
17122   u8 random_hw_addr = 1;
17123   int ret;
17124
17125   clib_memset (hw_addr, 0, sizeof (hw_addr));
17126
17127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17128     {
17129       if (unformat (i, "name %s", &host_if_name))
17130         vec_add1 (host_if_name, 0);
17131       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17132         random_hw_addr = 0;
17133       else
17134         break;
17135     }
17136
17137   if (!vec_len (host_if_name))
17138     {
17139       errmsg ("host-interface name must be specified");
17140       return -99;
17141     }
17142
17143   if (vec_len (host_if_name) > 64)
17144     {
17145       errmsg ("host-interface name too long");
17146       return -99;
17147     }
17148
17149   M (AF_PACKET_CREATE, mp);
17150
17151   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17152   clib_memcpy (mp->hw_addr, hw_addr, 6);
17153   mp->use_random_hw_addr = random_hw_addr;
17154   vec_free (host_if_name);
17155
17156   S (mp);
17157
17158   /* *INDENT-OFF* */
17159   W2 (ret,
17160       ({
17161         if (ret == 0)
17162           fprintf (vam->ofp ? vam->ofp : stderr,
17163                    " new sw_if_index = %d\n", vam->sw_if_index);
17164       }));
17165   /* *INDENT-ON* */
17166   return ret;
17167 }
17168
17169 static int
17170 api_af_packet_delete (vat_main_t * vam)
17171 {
17172   unformat_input_t *i = vam->input;
17173   vl_api_af_packet_delete_t *mp;
17174   u8 *host_if_name = 0;
17175   int ret;
17176
17177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17178     {
17179       if (unformat (i, "name %s", &host_if_name))
17180         vec_add1 (host_if_name, 0);
17181       else
17182         break;
17183     }
17184
17185   if (!vec_len (host_if_name))
17186     {
17187       errmsg ("host-interface name must be specified");
17188       return -99;
17189     }
17190
17191   if (vec_len (host_if_name) > 64)
17192     {
17193       errmsg ("host-interface name too long");
17194       return -99;
17195     }
17196
17197   M (AF_PACKET_DELETE, mp);
17198
17199   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17200   vec_free (host_if_name);
17201
17202   S (mp);
17203   W (ret);
17204   return ret;
17205 }
17206
17207 static void vl_api_af_packet_details_t_handler
17208   (vl_api_af_packet_details_t * mp)
17209 {
17210   vat_main_t *vam = &vat_main;
17211
17212   print (vam->ofp, "%-16s %d",
17213          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17214 }
17215
17216 static void vl_api_af_packet_details_t_handler_json
17217   (vl_api_af_packet_details_t * mp)
17218 {
17219   vat_main_t *vam = &vat_main;
17220   vat_json_node_t *node = NULL;
17221
17222   if (VAT_JSON_ARRAY != vam->json_tree.type)
17223     {
17224       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17225       vat_json_init_array (&vam->json_tree);
17226     }
17227   node = vat_json_array_add (&vam->json_tree);
17228
17229   vat_json_init_object (node);
17230   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17231   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17232 }
17233
17234 static int
17235 api_af_packet_dump (vat_main_t * vam)
17236 {
17237   vl_api_af_packet_dump_t *mp;
17238   vl_api_control_ping_t *mp_ping;
17239   int ret;
17240
17241   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17242   /* Get list of tap interfaces */
17243   M (AF_PACKET_DUMP, mp);
17244   S (mp);
17245
17246   /* Use a control ping for synchronization */
17247   MPING (CONTROL_PING, mp_ping);
17248   S (mp_ping);
17249
17250   W (ret);
17251   return ret;
17252 }
17253
17254 static int
17255 api_policer_add_del (vat_main_t * vam)
17256 {
17257   unformat_input_t *i = vam->input;
17258   vl_api_policer_add_del_t *mp;
17259   u8 is_add = 1;
17260   u8 *name = 0;
17261   u32 cir = 0;
17262   u32 eir = 0;
17263   u64 cb = 0;
17264   u64 eb = 0;
17265   u8 rate_type = 0;
17266   u8 round_type = 0;
17267   u8 type = 0;
17268   u8 color_aware = 0;
17269   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17270   int ret;
17271
17272   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17273   conform_action.dscp = 0;
17274   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17275   exceed_action.dscp = 0;
17276   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17277   violate_action.dscp = 0;
17278
17279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17280     {
17281       if (unformat (i, "del"))
17282         is_add = 0;
17283       else if (unformat (i, "name %s", &name))
17284         vec_add1 (name, 0);
17285       else if (unformat (i, "cir %u", &cir))
17286         ;
17287       else if (unformat (i, "eir %u", &eir))
17288         ;
17289       else if (unformat (i, "cb %u", &cb))
17290         ;
17291       else if (unformat (i, "eb %u", &eb))
17292         ;
17293       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17294                          &rate_type))
17295         ;
17296       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17297                          &round_type))
17298         ;
17299       else if (unformat (i, "type %U", unformat_policer_type, &type))
17300         ;
17301       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17302                          &conform_action))
17303         ;
17304       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17305                          &exceed_action))
17306         ;
17307       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17308                          &violate_action))
17309         ;
17310       else if (unformat (i, "color-aware"))
17311         color_aware = 1;
17312       else
17313         break;
17314     }
17315
17316   if (!vec_len (name))
17317     {
17318       errmsg ("policer name must be specified");
17319       return -99;
17320     }
17321
17322   if (vec_len (name) > 64)
17323     {
17324       errmsg ("policer name too long");
17325       return -99;
17326     }
17327
17328   M (POLICER_ADD_DEL, mp);
17329
17330   clib_memcpy (mp->name, name, vec_len (name));
17331   vec_free (name);
17332   mp->is_add = is_add;
17333   mp->cir = ntohl (cir);
17334   mp->eir = ntohl (eir);
17335   mp->cb = clib_net_to_host_u64 (cb);
17336   mp->eb = clib_net_to_host_u64 (eb);
17337   mp->rate_type = rate_type;
17338   mp->round_type = round_type;
17339   mp->type = type;
17340   mp->conform_action.type = conform_action.action_type;
17341   mp->conform_action.dscp = conform_action.dscp;
17342   mp->exceed_action.type = exceed_action.action_type;
17343   mp->exceed_action.dscp = exceed_action.dscp;
17344   mp->violate_action.type = violate_action.action_type;
17345   mp->violate_action.dscp = violate_action.dscp;
17346   mp->color_aware = color_aware;
17347
17348   S (mp);
17349   W (ret);
17350   return ret;
17351 }
17352
17353 static int
17354 api_policer_dump (vat_main_t * vam)
17355 {
17356   unformat_input_t *i = vam->input;
17357   vl_api_policer_dump_t *mp;
17358   vl_api_control_ping_t *mp_ping;
17359   u8 *match_name = 0;
17360   u8 match_name_valid = 0;
17361   int ret;
17362
17363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17364     {
17365       if (unformat (i, "name %s", &match_name))
17366         {
17367           vec_add1 (match_name, 0);
17368           match_name_valid = 1;
17369         }
17370       else
17371         break;
17372     }
17373
17374   M (POLICER_DUMP, mp);
17375   mp->match_name_valid = match_name_valid;
17376   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17377   vec_free (match_name);
17378   /* send it... */
17379   S (mp);
17380
17381   /* Use a control ping for synchronization */
17382   MPING (CONTROL_PING, mp_ping);
17383   S (mp_ping);
17384
17385   /* Wait for a reply... */
17386   W (ret);
17387   return ret;
17388 }
17389
17390 static int
17391 api_policer_classify_set_interface (vat_main_t * vam)
17392 {
17393   unformat_input_t *i = vam->input;
17394   vl_api_policer_classify_set_interface_t *mp;
17395   u32 sw_if_index;
17396   int sw_if_index_set;
17397   u32 ip4_table_index = ~0;
17398   u32 ip6_table_index = ~0;
17399   u32 l2_table_index = ~0;
17400   u8 is_add = 1;
17401   int ret;
17402
17403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17404     {
17405       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17406         sw_if_index_set = 1;
17407       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17408         sw_if_index_set = 1;
17409       else if (unformat (i, "del"))
17410         is_add = 0;
17411       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17412         ;
17413       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17414         ;
17415       else if (unformat (i, "l2-table %d", &l2_table_index))
17416         ;
17417       else
17418         {
17419           clib_warning ("parse error '%U'", format_unformat_error, i);
17420           return -99;
17421         }
17422     }
17423
17424   if (sw_if_index_set == 0)
17425     {
17426       errmsg ("missing interface name or sw_if_index");
17427       return -99;
17428     }
17429
17430   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17431
17432   mp->sw_if_index = ntohl (sw_if_index);
17433   mp->ip4_table_index = ntohl (ip4_table_index);
17434   mp->ip6_table_index = ntohl (ip6_table_index);
17435   mp->l2_table_index = ntohl (l2_table_index);
17436   mp->is_add = is_add;
17437
17438   S (mp);
17439   W (ret);
17440   return ret;
17441 }
17442
17443 static int
17444 api_policer_classify_dump (vat_main_t * vam)
17445 {
17446   unformat_input_t *i = vam->input;
17447   vl_api_policer_classify_dump_t *mp;
17448   vl_api_control_ping_t *mp_ping;
17449   u8 type = POLICER_CLASSIFY_N_TABLES;
17450   int ret;
17451
17452   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17453     ;
17454   else
17455     {
17456       errmsg ("classify table type must be specified");
17457       return -99;
17458     }
17459
17460   if (!vam->json_output)
17461     {
17462       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17463     }
17464
17465   M (POLICER_CLASSIFY_DUMP, mp);
17466   mp->type = type;
17467   /* send it... */
17468   S (mp);
17469
17470   /* Use a control ping for synchronization */
17471   MPING (CONTROL_PING, mp_ping);
17472   S (mp_ping);
17473
17474   /* Wait for a reply... */
17475   W (ret);
17476   return ret;
17477 }
17478
17479 static u8 *
17480 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17481 {
17482   vl_api_fib_path_nh_proto_t proto =
17483     va_arg (*args, vl_api_fib_path_nh_proto_t);
17484
17485   switch (proto)
17486     {
17487     case FIB_API_PATH_NH_PROTO_IP4:
17488       s = format (s, "ip4");
17489       break;
17490     case FIB_API_PATH_NH_PROTO_IP6:
17491       s = format (s, "ip6");
17492       break;
17493     case FIB_API_PATH_NH_PROTO_MPLS:
17494       s = format (s, "mpls");
17495       break;
17496     case FIB_API_PATH_NH_PROTO_BIER:
17497       s = format (s, "bier");
17498       break;
17499     case FIB_API_PATH_NH_PROTO_ETHERNET:
17500       s = format (s, "ethernet");
17501       break;
17502     }
17503
17504   return (s);
17505 }
17506
17507 static u8 *
17508 format_vl_api_ip_address_union (u8 * s, va_list * args)
17509 {
17510   vl_api_address_family_t af = va_arg (*args, int);
17511   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17512
17513   switch (af)
17514     {
17515     case ADDRESS_IP4:
17516       s = format (s, "%U", format_ip4_address, u->ip4);
17517       break;
17518     case ADDRESS_IP6:
17519       s = format (s, "%U", format_ip6_address, u->ip6);
17520       break;
17521     }
17522   return (s);
17523 }
17524
17525 static u8 *
17526 format_vl_api_fib_path_type (u8 * s, va_list * args)
17527 {
17528   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17529
17530   switch (t)
17531     {
17532     case FIB_API_PATH_TYPE_NORMAL:
17533       s = format (s, "normal");
17534       break;
17535     case FIB_API_PATH_TYPE_LOCAL:
17536       s = format (s, "local");
17537       break;
17538     case FIB_API_PATH_TYPE_DROP:
17539       s = format (s, "drop");
17540       break;
17541     case FIB_API_PATH_TYPE_UDP_ENCAP:
17542       s = format (s, "udp-encap");
17543       break;
17544     case FIB_API_PATH_TYPE_BIER_IMP:
17545       s = format (s, "bier-imp");
17546       break;
17547     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17548       s = format (s, "unreach");
17549       break;
17550     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17551       s = format (s, "prohibit");
17552       break;
17553     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17554       s = format (s, "src-lookup");
17555       break;
17556     case FIB_API_PATH_TYPE_DVR:
17557       s = format (s, "dvr");
17558       break;
17559     case FIB_API_PATH_TYPE_INTERFACE_RX:
17560       s = format (s, "interface-rx");
17561       break;
17562     case FIB_API_PATH_TYPE_CLASSIFY:
17563       s = format (s, "classify");
17564       break;
17565     }
17566
17567   return (s);
17568 }
17569
17570 static void
17571 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17572 {
17573   print (vam->ofp,
17574          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17575          ntohl (fp->weight), ntohl (fp->sw_if_index),
17576          format_vl_api_fib_path_type, fp->type,
17577          format_fib_api_path_nh_proto, fp->proto,
17578          format_vl_api_ip_address_union, &fp->nh.address);
17579 }
17580
17581 static void
17582 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17583                                  vl_api_fib_path_t * fp)
17584 {
17585   struct in_addr ip4;
17586   struct in6_addr ip6;
17587
17588   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17589   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17590   vat_json_object_add_uint (node, "type", fp->type);
17591   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17592   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17593     {
17594       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17595       vat_json_object_add_ip4 (node, "next_hop", ip4);
17596     }
17597   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17598     {
17599       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17600       vat_json_object_add_ip6 (node, "next_hop", ip6);
17601     }
17602 }
17603
17604 static void
17605 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17606 {
17607   vat_main_t *vam = &vat_main;
17608   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17609   vl_api_fib_path_t *fp;
17610   i32 i;
17611
17612   print (vam->ofp, "sw_if_index %d via:",
17613          ntohl (mp->mt_tunnel.mt_sw_if_index));
17614   fp = mp->mt_tunnel.mt_paths;
17615   for (i = 0; i < count; i++)
17616     {
17617       vl_api_fib_path_print (vam, fp);
17618       fp++;
17619     }
17620
17621   print (vam->ofp, "");
17622 }
17623
17624 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17625 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17626
17627 static void
17628 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17629 {
17630   vat_main_t *vam = &vat_main;
17631   vat_json_node_t *node = NULL;
17632   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17633   vl_api_fib_path_t *fp;
17634   i32 i;
17635
17636   if (VAT_JSON_ARRAY != vam->json_tree.type)
17637     {
17638       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17639       vat_json_init_array (&vam->json_tree);
17640     }
17641   node = vat_json_array_add (&vam->json_tree);
17642
17643   vat_json_init_object (node);
17644   vat_json_object_add_uint (node, "sw_if_index",
17645                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17646
17647   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17648
17649   fp = mp->mt_tunnel.mt_paths;
17650   for (i = 0; i < count; i++)
17651     {
17652       vl_api_mpls_fib_path_json_print (node, fp);
17653       fp++;
17654     }
17655 }
17656
17657 static int
17658 api_mpls_tunnel_dump (vat_main_t * vam)
17659 {
17660   vl_api_mpls_tunnel_dump_t *mp;
17661   vl_api_control_ping_t *mp_ping;
17662   int ret;
17663
17664   M (MPLS_TUNNEL_DUMP, mp);
17665
17666   S (mp);
17667
17668   /* Use a control ping for synchronization */
17669   MPING (CONTROL_PING, mp_ping);
17670   S (mp_ping);
17671
17672   W (ret);
17673   return ret;
17674 }
17675
17676 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17677 #define vl_api_mpls_table_details_t_print vl_noop_handler
17678
17679
17680 static void
17681 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17682 {
17683   vat_main_t *vam = &vat_main;
17684
17685   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17686 }
17687
17688 static void vl_api_mpls_table_details_t_handler_json
17689   (vl_api_mpls_table_details_t * mp)
17690 {
17691   vat_main_t *vam = &vat_main;
17692   vat_json_node_t *node = NULL;
17693
17694   if (VAT_JSON_ARRAY != vam->json_tree.type)
17695     {
17696       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17697       vat_json_init_array (&vam->json_tree);
17698     }
17699   node = vat_json_array_add (&vam->json_tree);
17700
17701   vat_json_init_object (node);
17702   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17703 }
17704
17705 static int
17706 api_mpls_table_dump (vat_main_t * vam)
17707 {
17708   vl_api_mpls_table_dump_t *mp;
17709   vl_api_control_ping_t *mp_ping;
17710   int ret;
17711
17712   M (MPLS_TABLE_DUMP, mp);
17713   S (mp);
17714
17715   /* Use a control ping for synchronization */
17716   MPING (CONTROL_PING, mp_ping);
17717   S (mp_ping);
17718
17719   W (ret);
17720   return ret;
17721 }
17722
17723 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17724 #define vl_api_mpls_route_details_t_print vl_noop_handler
17725
17726 static void
17727 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17728 {
17729   vat_main_t *vam = &vat_main;
17730   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17731   vl_api_fib_path_t *fp;
17732   int i;
17733
17734   print (vam->ofp,
17735          "table-id %d, label %u, ess_bit %u",
17736          ntohl (mp->mr_route.mr_table_id),
17737          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17738   fp = mp->mr_route.mr_paths;
17739   for (i = 0; i < count; i++)
17740     {
17741       vl_api_fib_path_print (vam, fp);
17742       fp++;
17743     }
17744 }
17745
17746 static void vl_api_mpls_route_details_t_handler_json
17747   (vl_api_mpls_route_details_t * mp)
17748 {
17749   vat_main_t *vam = &vat_main;
17750   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17751   vat_json_node_t *node = NULL;
17752   vl_api_fib_path_t *fp;
17753   int i;
17754
17755   if (VAT_JSON_ARRAY != vam->json_tree.type)
17756     {
17757       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17758       vat_json_init_array (&vam->json_tree);
17759     }
17760   node = vat_json_array_add (&vam->json_tree);
17761
17762   vat_json_init_object (node);
17763   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17764   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17765   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17766   vat_json_object_add_uint (node, "path_count", count);
17767   fp = mp->mr_route.mr_paths;
17768   for (i = 0; i < count; i++)
17769     {
17770       vl_api_mpls_fib_path_json_print (node, fp);
17771       fp++;
17772     }
17773 }
17774
17775 static int
17776 api_mpls_route_dump (vat_main_t * vam)
17777 {
17778   unformat_input_t *input = vam->input;
17779   vl_api_mpls_route_dump_t *mp;
17780   vl_api_control_ping_t *mp_ping;
17781   u32 table_id;
17782   int ret;
17783
17784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17785     {
17786       if (unformat (input, "table_id %d", &table_id))
17787         ;
17788       else
17789         break;
17790     }
17791   if (table_id == ~0)
17792     {
17793       errmsg ("missing table id");
17794       return -99;
17795     }
17796
17797   M (MPLS_ROUTE_DUMP, mp);
17798
17799   mp->table.mt_table_id = ntohl (table_id);
17800   S (mp);
17801
17802   /* Use a control ping for synchronization */
17803   MPING (CONTROL_PING, mp_ping);
17804   S (mp_ping);
17805
17806   W (ret);
17807   return ret;
17808 }
17809
17810 #define vl_api_ip_table_details_t_endian vl_noop_handler
17811 #define vl_api_ip_table_details_t_print vl_noop_handler
17812
17813 static void
17814 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17815 {
17816   vat_main_t *vam = &vat_main;
17817
17818   print (vam->ofp,
17819          "%s; table-id %d, prefix %U/%d",
17820          mp->table.name, ntohl (mp->table.table_id));
17821 }
17822
17823
17824 static void vl_api_ip_table_details_t_handler_json
17825   (vl_api_ip_table_details_t * mp)
17826 {
17827   vat_main_t *vam = &vat_main;
17828   vat_json_node_t *node = NULL;
17829
17830   if (VAT_JSON_ARRAY != vam->json_tree.type)
17831     {
17832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17833       vat_json_init_array (&vam->json_tree);
17834     }
17835   node = vat_json_array_add (&vam->json_tree);
17836
17837   vat_json_init_object (node);
17838   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17839 }
17840
17841 static int
17842 api_ip_table_dump (vat_main_t * vam)
17843 {
17844   vl_api_ip_table_dump_t *mp;
17845   vl_api_control_ping_t *mp_ping;
17846   int ret;
17847
17848   M (IP_TABLE_DUMP, mp);
17849   S (mp);
17850
17851   /* Use a control ping for synchronization */
17852   MPING (CONTROL_PING, mp_ping);
17853   S (mp_ping);
17854
17855   W (ret);
17856   return ret;
17857 }
17858
17859 static int
17860 api_ip_mtable_dump (vat_main_t * vam)
17861 {
17862   vl_api_ip_mtable_dump_t *mp;
17863   vl_api_control_ping_t *mp_ping;
17864   int ret;
17865
17866   M (IP_MTABLE_DUMP, mp);
17867   S (mp);
17868
17869   /* Use a control ping for synchronization */
17870   MPING (CONTROL_PING, mp_ping);
17871   S (mp_ping);
17872
17873   W (ret);
17874   return ret;
17875 }
17876
17877 static int
17878 api_ip_mroute_dump (vat_main_t * vam)
17879 {
17880   unformat_input_t *input = vam->input;
17881   vl_api_control_ping_t *mp_ping;
17882   vl_api_ip_mroute_dump_t *mp;
17883   int ret, is_ip6;
17884   u32 table_id;
17885
17886   is_ip6 = 0;
17887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17888     {
17889       if (unformat (input, "table_id %d", &table_id))
17890         ;
17891       else if (unformat (input, "ip6"))
17892         is_ip6 = 1;
17893       else if (unformat (input, "ip4"))
17894         is_ip6 = 0;
17895       else
17896         break;
17897     }
17898   if (table_id == ~0)
17899     {
17900       errmsg ("missing table id");
17901       return -99;
17902     }
17903
17904   M (IP_MROUTE_DUMP, mp);
17905   mp->table.table_id = table_id;
17906   mp->table.is_ip6 = is_ip6;
17907   S (mp);
17908
17909   /* Use a control ping for synchronization */
17910   MPING (CONTROL_PING, mp_ping);
17911   S (mp_ping);
17912
17913   W (ret);
17914   return ret;
17915 }
17916
17917 #define vl_api_ip_route_details_t_endian vl_noop_handler
17918 #define vl_api_ip_route_details_t_print vl_noop_handler
17919
17920 static void
17921 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17922 {
17923   vat_main_t *vam = &vat_main;
17924   u8 count = mp->route.n_paths;
17925   vl_api_fib_path_t *fp;
17926   int i;
17927
17928   print (vam->ofp,
17929          "table-id %d, prefix %U/%d",
17930          ntohl (mp->route.table_id),
17931          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17932   for (i = 0; i < count; i++)
17933     {
17934       fp = &mp->route.paths[i];
17935
17936       vl_api_fib_path_print (vam, fp);
17937       fp++;
17938     }
17939 }
17940
17941 static void vl_api_ip_route_details_t_handler_json
17942   (vl_api_ip_route_details_t * mp)
17943 {
17944   vat_main_t *vam = &vat_main;
17945   u8 count = mp->route.n_paths;
17946   vat_json_node_t *node = NULL;
17947   struct in_addr ip4;
17948   struct in6_addr ip6;
17949   vl_api_fib_path_t *fp;
17950   int i;
17951
17952   if (VAT_JSON_ARRAY != vam->json_tree.type)
17953     {
17954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17955       vat_json_init_array (&vam->json_tree);
17956     }
17957   node = vat_json_array_add (&vam->json_tree);
17958
17959   vat_json_init_object (node);
17960   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17961   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17962     {
17963       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17964       vat_json_object_add_ip6 (node, "prefix", ip6);
17965     }
17966   else
17967     {
17968       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17969       vat_json_object_add_ip4 (node, "prefix", ip4);
17970     }
17971   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17972   vat_json_object_add_uint (node, "path_count", count);
17973   for (i = 0; i < count; i++)
17974     {
17975       fp = &mp->route.paths[i];
17976       vl_api_mpls_fib_path_json_print (node, fp);
17977     }
17978 }
17979
17980 static int
17981 api_ip_route_dump (vat_main_t * vam)
17982 {
17983   unformat_input_t *input = vam->input;
17984   vl_api_ip_route_dump_t *mp;
17985   vl_api_control_ping_t *mp_ping;
17986   u32 table_id;
17987   u8 is_ip6;
17988   int ret;
17989
17990   is_ip6 = 0;
17991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17992     {
17993       if (unformat (input, "table_id %d", &table_id))
17994         ;
17995       else if (unformat (input, "ip6"))
17996         is_ip6 = 1;
17997       else if (unformat (input, "ip4"))
17998         is_ip6 = 0;
17999       else
18000         break;
18001     }
18002   if (table_id == ~0)
18003     {
18004       errmsg ("missing table id");
18005       return -99;
18006     }
18007
18008   M (IP_ROUTE_DUMP, mp);
18009
18010   mp->table.table_id = table_id;
18011   mp->table.is_ip6 = is_ip6;
18012
18013   S (mp);
18014
18015   /* Use a control ping for synchronization */
18016   MPING (CONTROL_PING, mp_ping);
18017   S (mp_ping);
18018
18019   W (ret);
18020   return ret;
18021 }
18022
18023 int
18024 api_classify_table_ids (vat_main_t * vam)
18025 {
18026   vl_api_classify_table_ids_t *mp;
18027   int ret;
18028
18029   /* Construct the API message */
18030   M (CLASSIFY_TABLE_IDS, mp);
18031   mp->context = 0;
18032
18033   S (mp);
18034   W (ret);
18035   return ret;
18036 }
18037
18038 int
18039 api_classify_table_by_interface (vat_main_t * vam)
18040 {
18041   unformat_input_t *input = vam->input;
18042   vl_api_classify_table_by_interface_t *mp;
18043
18044   u32 sw_if_index = ~0;
18045   int ret;
18046   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18047     {
18048       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18049         ;
18050       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18051         ;
18052       else
18053         break;
18054     }
18055   if (sw_if_index == ~0)
18056     {
18057       errmsg ("missing interface name or sw_if_index");
18058       return -99;
18059     }
18060
18061   /* Construct the API message */
18062   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18063   mp->context = 0;
18064   mp->sw_if_index = ntohl (sw_if_index);
18065
18066   S (mp);
18067   W (ret);
18068   return ret;
18069 }
18070
18071 int
18072 api_classify_table_info (vat_main_t * vam)
18073 {
18074   unformat_input_t *input = vam->input;
18075   vl_api_classify_table_info_t *mp;
18076
18077   u32 table_id = ~0;
18078   int ret;
18079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18080     {
18081       if (unformat (input, "table_id %d", &table_id))
18082         ;
18083       else
18084         break;
18085     }
18086   if (table_id == ~0)
18087     {
18088       errmsg ("missing table id");
18089       return -99;
18090     }
18091
18092   /* Construct the API message */
18093   M (CLASSIFY_TABLE_INFO, mp);
18094   mp->context = 0;
18095   mp->table_id = ntohl (table_id);
18096
18097   S (mp);
18098   W (ret);
18099   return ret;
18100 }
18101
18102 int
18103 api_classify_session_dump (vat_main_t * vam)
18104 {
18105   unformat_input_t *input = vam->input;
18106   vl_api_classify_session_dump_t *mp;
18107   vl_api_control_ping_t *mp_ping;
18108
18109   u32 table_id = ~0;
18110   int ret;
18111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18112     {
18113       if (unformat (input, "table_id %d", &table_id))
18114         ;
18115       else
18116         break;
18117     }
18118   if (table_id == ~0)
18119     {
18120       errmsg ("missing table id");
18121       return -99;
18122     }
18123
18124   /* Construct the API message */
18125   M (CLASSIFY_SESSION_DUMP, mp);
18126   mp->context = 0;
18127   mp->table_id = ntohl (table_id);
18128   S (mp);
18129
18130   /* Use a control ping for synchronization */
18131   MPING (CONTROL_PING, mp_ping);
18132   S (mp_ping);
18133
18134   W (ret);
18135   return ret;
18136 }
18137
18138 static void
18139 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18140 {
18141   vat_main_t *vam = &vat_main;
18142
18143   print (vam->ofp, "collector_address %U, collector_port %d, "
18144          "src_address %U, vrf_id %d, path_mtu %u, "
18145          "template_interval %u, udp_checksum %d",
18146          format_ip4_address, mp->collector_address,
18147          ntohs (mp->collector_port),
18148          format_ip4_address, mp->src_address,
18149          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18150          ntohl (mp->template_interval), mp->udp_checksum);
18151
18152   vam->retval = 0;
18153   vam->result_ready = 1;
18154 }
18155
18156 static void
18157   vl_api_ipfix_exporter_details_t_handler_json
18158   (vl_api_ipfix_exporter_details_t * mp)
18159 {
18160   vat_main_t *vam = &vat_main;
18161   vat_json_node_t node;
18162   struct in_addr collector_address;
18163   struct in_addr src_address;
18164
18165   vat_json_init_object (&node);
18166   clib_memcpy (&collector_address, &mp->collector_address,
18167                sizeof (collector_address));
18168   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18169   vat_json_object_add_uint (&node, "collector_port",
18170                             ntohs (mp->collector_port));
18171   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18172   vat_json_object_add_ip4 (&node, "src_address", src_address);
18173   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18174   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18175   vat_json_object_add_uint (&node, "template_interval",
18176                             ntohl (mp->template_interval));
18177   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18178
18179   vat_json_print (vam->ofp, &node);
18180   vat_json_free (&node);
18181   vam->retval = 0;
18182   vam->result_ready = 1;
18183 }
18184
18185 int
18186 api_ipfix_exporter_dump (vat_main_t * vam)
18187 {
18188   vl_api_ipfix_exporter_dump_t *mp;
18189   int ret;
18190
18191   /* Construct the API message */
18192   M (IPFIX_EXPORTER_DUMP, mp);
18193   mp->context = 0;
18194
18195   S (mp);
18196   W (ret);
18197   return ret;
18198 }
18199
18200 static int
18201 api_ipfix_classify_stream_dump (vat_main_t * vam)
18202 {
18203   vl_api_ipfix_classify_stream_dump_t *mp;
18204   int ret;
18205
18206   /* Construct the API message */
18207   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18208   mp->context = 0;
18209
18210   S (mp);
18211   W (ret);
18212   return ret;
18213   /* NOTREACHED */
18214   return 0;
18215 }
18216
18217 static void
18218   vl_api_ipfix_classify_stream_details_t_handler
18219   (vl_api_ipfix_classify_stream_details_t * mp)
18220 {
18221   vat_main_t *vam = &vat_main;
18222   print (vam->ofp, "domain_id %d, src_port %d",
18223          ntohl (mp->domain_id), ntohs (mp->src_port));
18224   vam->retval = 0;
18225   vam->result_ready = 1;
18226 }
18227
18228 static void
18229   vl_api_ipfix_classify_stream_details_t_handler_json
18230   (vl_api_ipfix_classify_stream_details_t * mp)
18231 {
18232   vat_main_t *vam = &vat_main;
18233   vat_json_node_t node;
18234
18235   vat_json_init_object (&node);
18236   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18237   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18238
18239   vat_json_print (vam->ofp, &node);
18240   vat_json_free (&node);
18241   vam->retval = 0;
18242   vam->result_ready = 1;
18243 }
18244
18245 static int
18246 api_ipfix_classify_table_dump (vat_main_t * vam)
18247 {
18248   vl_api_ipfix_classify_table_dump_t *mp;
18249   vl_api_control_ping_t *mp_ping;
18250   int ret;
18251
18252   if (!vam->json_output)
18253     {
18254       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18255              "transport_protocol");
18256     }
18257
18258   /* Construct the API message */
18259   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18260
18261   /* send it... */
18262   S (mp);
18263
18264   /* Use a control ping for synchronization */
18265   MPING (CONTROL_PING, mp_ping);
18266   S (mp_ping);
18267
18268   W (ret);
18269   return ret;
18270 }
18271
18272 static void
18273   vl_api_ipfix_classify_table_details_t_handler
18274   (vl_api_ipfix_classify_table_details_t * mp)
18275 {
18276   vat_main_t *vam = &vat_main;
18277   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18278          mp->transport_protocol);
18279 }
18280
18281 static void
18282   vl_api_ipfix_classify_table_details_t_handler_json
18283   (vl_api_ipfix_classify_table_details_t * mp)
18284 {
18285   vat_json_node_t *node = NULL;
18286   vat_main_t *vam = &vat_main;
18287
18288   if (VAT_JSON_ARRAY != vam->json_tree.type)
18289     {
18290       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18291       vat_json_init_array (&vam->json_tree);
18292     }
18293
18294   node = vat_json_array_add (&vam->json_tree);
18295   vat_json_init_object (node);
18296
18297   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18298   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18299   vat_json_object_add_uint (node, "transport_protocol",
18300                             mp->transport_protocol);
18301 }
18302
18303 static int
18304 api_sw_interface_span_enable_disable (vat_main_t * vam)
18305 {
18306   unformat_input_t *i = vam->input;
18307   vl_api_sw_interface_span_enable_disable_t *mp;
18308   u32 src_sw_if_index = ~0;
18309   u32 dst_sw_if_index = ~0;
18310   u8 state = 3;
18311   int ret;
18312   u8 is_l2 = 0;
18313
18314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18315     {
18316       if (unformat
18317           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18318         ;
18319       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18320         ;
18321       else
18322         if (unformat
18323             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18324         ;
18325       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18326         ;
18327       else if (unformat (i, "disable"))
18328         state = 0;
18329       else if (unformat (i, "rx"))
18330         state = 1;
18331       else if (unformat (i, "tx"))
18332         state = 2;
18333       else if (unformat (i, "both"))
18334         state = 3;
18335       else if (unformat (i, "l2"))
18336         is_l2 = 1;
18337       else
18338         break;
18339     }
18340
18341   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18342
18343   mp->sw_if_index_from = htonl (src_sw_if_index);
18344   mp->sw_if_index_to = htonl (dst_sw_if_index);
18345   mp->state = state;
18346   mp->is_l2 = is_l2;
18347
18348   S (mp);
18349   W (ret);
18350   return ret;
18351 }
18352
18353 static void
18354 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18355                                             * mp)
18356 {
18357   vat_main_t *vam = &vat_main;
18358   u8 *sw_if_from_name = 0;
18359   u8 *sw_if_to_name = 0;
18360   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18361   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18362   char *states[] = { "none", "rx", "tx", "both" };
18363   hash_pair_t *p;
18364
18365   /* *INDENT-OFF* */
18366   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18367   ({
18368     if ((u32) p->value[0] == sw_if_index_from)
18369       {
18370         sw_if_from_name = (u8 *)(p->key);
18371         if (sw_if_to_name)
18372           break;
18373       }
18374     if ((u32) p->value[0] == sw_if_index_to)
18375       {
18376         sw_if_to_name = (u8 *)(p->key);
18377         if (sw_if_from_name)
18378           break;
18379       }
18380   }));
18381   /* *INDENT-ON* */
18382   print (vam->ofp, "%20s => %20s (%s) %s",
18383          sw_if_from_name, sw_if_to_name, states[mp->state],
18384          mp->is_l2 ? "l2" : "device");
18385 }
18386
18387 static void
18388   vl_api_sw_interface_span_details_t_handler_json
18389   (vl_api_sw_interface_span_details_t * mp)
18390 {
18391   vat_main_t *vam = &vat_main;
18392   vat_json_node_t *node = NULL;
18393   u8 *sw_if_from_name = 0;
18394   u8 *sw_if_to_name = 0;
18395   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18396   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18397   hash_pair_t *p;
18398
18399   /* *INDENT-OFF* */
18400   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18401   ({
18402     if ((u32) p->value[0] == sw_if_index_from)
18403       {
18404         sw_if_from_name = (u8 *)(p->key);
18405         if (sw_if_to_name)
18406           break;
18407       }
18408     if ((u32) p->value[0] == sw_if_index_to)
18409       {
18410         sw_if_to_name = (u8 *)(p->key);
18411         if (sw_if_from_name)
18412           break;
18413       }
18414   }));
18415   /* *INDENT-ON* */
18416
18417   if (VAT_JSON_ARRAY != vam->json_tree.type)
18418     {
18419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18420       vat_json_init_array (&vam->json_tree);
18421     }
18422   node = vat_json_array_add (&vam->json_tree);
18423
18424   vat_json_init_object (node);
18425   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18426   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18427   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18428   if (0 != sw_if_to_name)
18429     {
18430       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18431     }
18432   vat_json_object_add_uint (node, "state", mp->state);
18433   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18434 }
18435
18436 static int
18437 api_sw_interface_span_dump (vat_main_t * vam)
18438 {
18439   unformat_input_t *input = vam->input;
18440   vl_api_sw_interface_span_dump_t *mp;
18441   vl_api_control_ping_t *mp_ping;
18442   u8 is_l2 = 0;
18443   int ret;
18444
18445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18446     {
18447       if (unformat (input, "l2"))
18448         is_l2 = 1;
18449       else
18450         break;
18451     }
18452
18453   M (SW_INTERFACE_SPAN_DUMP, mp);
18454   mp->is_l2 = is_l2;
18455   S (mp);
18456
18457   /* Use a control ping for synchronization */
18458   MPING (CONTROL_PING, mp_ping);
18459   S (mp_ping);
18460
18461   W (ret);
18462   return ret;
18463 }
18464
18465 int
18466 api_pg_create_interface (vat_main_t * vam)
18467 {
18468   unformat_input_t *input = vam->input;
18469   vl_api_pg_create_interface_t *mp;
18470
18471   u32 if_id = ~0, gso_size = 0;
18472   u8 gso_enabled = 0;
18473   int ret;
18474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18475     {
18476       if (unformat (input, "if_id %d", &if_id))
18477         ;
18478       else if (unformat (input, "gso-enabled"))
18479         {
18480           gso_enabled = 1;
18481           if (unformat (input, "gso-size %u", &gso_size))
18482             ;
18483           else
18484             {
18485               errmsg ("missing gso-size");
18486               return -99;
18487             }
18488         }
18489       else
18490         break;
18491     }
18492   if (if_id == ~0)
18493     {
18494       errmsg ("missing pg interface index");
18495       return -99;
18496     }
18497
18498   /* Construct the API message */
18499   M (PG_CREATE_INTERFACE, mp);
18500   mp->context = 0;
18501   mp->interface_id = ntohl (if_id);
18502   mp->gso_enabled = gso_enabled;
18503
18504   S (mp);
18505   W (ret);
18506   return ret;
18507 }
18508
18509 int
18510 api_pg_capture (vat_main_t * vam)
18511 {
18512   unformat_input_t *input = vam->input;
18513   vl_api_pg_capture_t *mp;
18514
18515   u32 if_id = ~0;
18516   u8 enable = 1;
18517   u32 count = 1;
18518   u8 pcap_file_set = 0;
18519   u8 *pcap_file = 0;
18520   int ret;
18521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18522     {
18523       if (unformat (input, "if_id %d", &if_id))
18524         ;
18525       else if (unformat (input, "pcap %s", &pcap_file))
18526         pcap_file_set = 1;
18527       else if (unformat (input, "count %d", &count))
18528         ;
18529       else if (unformat (input, "disable"))
18530         enable = 0;
18531       else
18532         break;
18533     }
18534   if (if_id == ~0)
18535     {
18536       errmsg ("missing pg interface index");
18537       return -99;
18538     }
18539   if (pcap_file_set > 0)
18540     {
18541       if (vec_len (pcap_file) > 255)
18542         {
18543           errmsg ("pcap file name is too long");
18544           return -99;
18545         }
18546     }
18547
18548   /* Construct the API message */
18549   M (PG_CAPTURE, mp);
18550   mp->context = 0;
18551   mp->interface_id = ntohl (if_id);
18552   mp->is_enabled = enable;
18553   mp->count = ntohl (count);
18554   if (pcap_file_set != 0)
18555     {
18556       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18557     }
18558   vec_free (pcap_file);
18559
18560   S (mp);
18561   W (ret);
18562   return ret;
18563 }
18564
18565 int
18566 api_pg_enable_disable (vat_main_t * vam)
18567 {
18568   unformat_input_t *input = vam->input;
18569   vl_api_pg_enable_disable_t *mp;
18570
18571   u8 enable = 1;
18572   u8 stream_name_set = 0;
18573   u8 *stream_name = 0;
18574   int ret;
18575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18576     {
18577       if (unformat (input, "stream %s", &stream_name))
18578         stream_name_set = 1;
18579       else if (unformat (input, "disable"))
18580         enable = 0;
18581       else
18582         break;
18583     }
18584
18585   if (stream_name_set > 0)
18586     {
18587       if (vec_len (stream_name) > 255)
18588         {
18589           errmsg ("stream name too long");
18590           return -99;
18591         }
18592     }
18593
18594   /* Construct the API message */
18595   M (PG_ENABLE_DISABLE, mp);
18596   mp->context = 0;
18597   mp->is_enabled = enable;
18598   if (stream_name_set != 0)
18599     {
18600       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18601     }
18602   vec_free (stream_name);
18603
18604   S (mp);
18605   W (ret);
18606   return ret;
18607 }
18608
18609 int
18610 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18611 {
18612   unformat_input_t *input = vam->input;
18613   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18614
18615   u16 *low_ports = 0;
18616   u16 *high_ports = 0;
18617   u16 this_low;
18618   u16 this_hi;
18619   vl_api_prefix_t prefix;
18620   u32 tmp, tmp2;
18621   u8 prefix_set = 0;
18622   u32 vrf_id = ~0;
18623   u8 is_add = 1;
18624   int ret;
18625
18626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18629         prefix_set = 1;
18630       else if (unformat (input, "vrf %d", &vrf_id))
18631         ;
18632       else if (unformat (input, "del"))
18633         is_add = 0;
18634       else if (unformat (input, "port %d", &tmp))
18635         {
18636           if (tmp == 0 || tmp > 65535)
18637             {
18638               errmsg ("port %d out of range", tmp);
18639               return -99;
18640             }
18641           this_low = tmp;
18642           this_hi = this_low + 1;
18643           vec_add1 (low_ports, this_low);
18644           vec_add1 (high_ports, this_hi);
18645         }
18646       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18647         {
18648           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18649             {
18650               errmsg ("incorrect range parameters");
18651               return -99;
18652             }
18653           this_low = tmp;
18654           /* Note: in debug CLI +1 is added to high before
18655              passing to real fn that does "the work"
18656              (ip_source_and_port_range_check_add_del).
18657              This fn is a wrapper around the binary API fn a
18658              control plane will call, which expects this increment
18659              to have occurred. Hence letting the binary API control
18660              plane fn do the increment for consistency between VAT
18661              and other control planes.
18662            */
18663           this_hi = tmp2;
18664           vec_add1 (low_ports, this_low);
18665           vec_add1 (high_ports, this_hi);
18666         }
18667       else
18668         break;
18669     }
18670
18671   if (prefix_set == 0)
18672     {
18673       errmsg ("<address>/<mask> not specified");
18674       return -99;
18675     }
18676
18677   if (vrf_id == ~0)
18678     {
18679       errmsg ("VRF ID required, not specified");
18680       return -99;
18681     }
18682
18683   if (vrf_id == 0)
18684     {
18685       errmsg
18686         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18687       return -99;
18688     }
18689
18690   if (vec_len (low_ports) == 0)
18691     {
18692       errmsg ("At least one port or port range required");
18693       return -99;
18694     }
18695
18696   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18697
18698   mp->is_add = is_add;
18699
18700   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18701
18702   mp->number_of_ranges = vec_len (low_ports);
18703
18704   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18705   vec_free (low_ports);
18706
18707   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18708   vec_free (high_ports);
18709
18710   mp->vrf_id = ntohl (vrf_id);
18711
18712   S (mp);
18713   W (ret);
18714   return ret;
18715 }
18716
18717 int
18718 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18719 {
18720   unformat_input_t *input = vam->input;
18721   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18722   u32 sw_if_index = ~0;
18723   int vrf_set = 0;
18724   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18725   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18726   u8 is_add = 1;
18727   int ret;
18728
18729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18730     {
18731       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18732         ;
18733       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18734         ;
18735       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18736         vrf_set = 1;
18737       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18738         vrf_set = 1;
18739       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18740         vrf_set = 1;
18741       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18742         vrf_set = 1;
18743       else if (unformat (input, "del"))
18744         is_add = 0;
18745       else
18746         break;
18747     }
18748
18749   if (sw_if_index == ~0)
18750     {
18751       errmsg ("Interface required but not specified");
18752       return -99;
18753     }
18754
18755   if (vrf_set == 0)
18756     {
18757       errmsg ("VRF ID required but not specified");
18758       return -99;
18759     }
18760
18761   if (tcp_out_vrf_id == 0
18762       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18763     {
18764       errmsg
18765         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18766       return -99;
18767     }
18768
18769   /* Construct the API message */
18770   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18771
18772   mp->sw_if_index = ntohl (sw_if_index);
18773   mp->is_add = is_add;
18774   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18775   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18776   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18777   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18778
18779   /* send it... */
18780   S (mp);
18781
18782   /* Wait for a reply... */
18783   W (ret);
18784   return ret;
18785 }
18786
18787 static int
18788 api_set_punt (vat_main_t * vam)
18789 {
18790   unformat_input_t *i = vam->input;
18791   vl_api_address_family_t af;
18792   vl_api_set_punt_t *mp;
18793   u32 protocol = ~0;
18794   u32 port = ~0;
18795   int is_add = 1;
18796   int ret;
18797
18798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18799     {
18800       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18801         ;
18802       else if (unformat (i, "protocol %d", &protocol))
18803         ;
18804       else if (unformat (i, "port %d", &port))
18805         ;
18806       else if (unformat (i, "del"))
18807         is_add = 0;
18808       else
18809         {
18810           clib_warning ("parse error '%U'", format_unformat_error, i);
18811           return -99;
18812         }
18813     }
18814
18815   M (SET_PUNT, mp);
18816
18817   mp->is_add = (u8) is_add;
18818   mp->punt.type = PUNT_API_TYPE_L4;
18819   mp->punt.punt.l4.af = af;
18820   mp->punt.punt.l4.protocol = (u8) protocol;
18821   mp->punt.punt.l4.port = htons ((u16) port);
18822
18823   S (mp);
18824   W (ret);
18825   return ret;
18826 }
18827
18828 static int
18829 api_delete_subif (vat_main_t * vam)
18830 {
18831   unformat_input_t *i = vam->input;
18832   vl_api_delete_subif_t *mp;
18833   u32 sw_if_index = ~0;
18834   int ret;
18835
18836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18837     {
18838       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18839         ;
18840       if (unformat (i, "sw_if_index %d", &sw_if_index))
18841         ;
18842       else
18843         break;
18844     }
18845
18846   if (sw_if_index == ~0)
18847     {
18848       errmsg ("missing sw_if_index");
18849       return -99;
18850     }
18851
18852   /* Construct the API message */
18853   M (DELETE_SUBIF, mp);
18854   mp->sw_if_index = ntohl (sw_if_index);
18855
18856   S (mp);
18857   W (ret);
18858   return ret;
18859 }
18860
18861 #define foreach_pbb_vtr_op      \
18862 _("disable",  L2_VTR_DISABLED)  \
18863 _("pop",  L2_VTR_POP_2)         \
18864 _("push",  L2_VTR_PUSH_2)
18865
18866 static int
18867 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18868 {
18869   unformat_input_t *i = vam->input;
18870   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18871   u32 sw_if_index = ~0, vtr_op = ~0;
18872   u16 outer_tag = ~0;
18873   u8 dmac[6], smac[6];
18874   u8 dmac_set = 0, smac_set = 0;
18875   u16 vlanid = 0;
18876   u32 sid = ~0;
18877   u32 tmp;
18878   int ret;
18879
18880   /* Shut up coverity */
18881   clib_memset (dmac, 0, sizeof (dmac));
18882   clib_memset (smac, 0, sizeof (smac));
18883
18884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18885     {
18886       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18887         ;
18888       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18889         ;
18890       else if (unformat (i, "vtr_op %d", &vtr_op))
18891         ;
18892 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18893       foreach_pbb_vtr_op
18894 #undef _
18895         else if (unformat (i, "translate_pbb_stag"))
18896         {
18897           if (unformat (i, "%d", &tmp))
18898             {
18899               vtr_op = L2_VTR_TRANSLATE_2_1;
18900               outer_tag = tmp;
18901             }
18902           else
18903             {
18904               errmsg
18905                 ("translate_pbb_stag operation requires outer tag definition");
18906               return -99;
18907             }
18908         }
18909       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18910         dmac_set++;
18911       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18912         smac_set++;
18913       else if (unformat (i, "sid %d", &sid))
18914         ;
18915       else if (unformat (i, "vlanid %d", &tmp))
18916         vlanid = tmp;
18917       else
18918         {
18919           clib_warning ("parse error '%U'", format_unformat_error, i);
18920           return -99;
18921         }
18922     }
18923
18924   if ((sw_if_index == ~0) || (vtr_op == ~0))
18925     {
18926       errmsg ("missing sw_if_index or vtr operation");
18927       return -99;
18928     }
18929   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18930       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18931     {
18932       errmsg
18933         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18934       return -99;
18935     }
18936
18937   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18938   mp->sw_if_index = ntohl (sw_if_index);
18939   mp->vtr_op = ntohl (vtr_op);
18940   mp->outer_tag = ntohs (outer_tag);
18941   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18942   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18943   mp->b_vlanid = ntohs (vlanid);
18944   mp->i_sid = ntohl (sid);
18945
18946   S (mp);
18947   W (ret);
18948   return ret;
18949 }
18950
18951 static int
18952 api_flow_classify_set_interface (vat_main_t * vam)
18953 {
18954   unformat_input_t *i = vam->input;
18955   vl_api_flow_classify_set_interface_t *mp;
18956   u32 sw_if_index;
18957   int sw_if_index_set;
18958   u32 ip4_table_index = ~0;
18959   u32 ip6_table_index = ~0;
18960   u8 is_add = 1;
18961   int ret;
18962
18963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18964     {
18965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18966         sw_if_index_set = 1;
18967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18968         sw_if_index_set = 1;
18969       else if (unformat (i, "del"))
18970         is_add = 0;
18971       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18972         ;
18973       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18974         ;
18975       else
18976         {
18977           clib_warning ("parse error '%U'", format_unformat_error, i);
18978           return -99;
18979         }
18980     }
18981
18982   if (sw_if_index_set == 0)
18983     {
18984       errmsg ("missing interface name or sw_if_index");
18985       return -99;
18986     }
18987
18988   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18989
18990   mp->sw_if_index = ntohl (sw_if_index);
18991   mp->ip4_table_index = ntohl (ip4_table_index);
18992   mp->ip6_table_index = ntohl (ip6_table_index);
18993   mp->is_add = is_add;
18994
18995   S (mp);
18996   W (ret);
18997   return ret;
18998 }
18999
19000 static int
19001 api_flow_classify_dump (vat_main_t * vam)
19002 {
19003   unformat_input_t *i = vam->input;
19004   vl_api_flow_classify_dump_t *mp;
19005   vl_api_control_ping_t *mp_ping;
19006   u8 type = FLOW_CLASSIFY_N_TABLES;
19007   int ret;
19008
19009   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19010     ;
19011   else
19012     {
19013       errmsg ("classify table type must be specified");
19014       return -99;
19015     }
19016
19017   if (!vam->json_output)
19018     {
19019       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19020     }
19021
19022   M (FLOW_CLASSIFY_DUMP, mp);
19023   mp->type = type;
19024   /* send it... */
19025   S (mp);
19026
19027   /* Use a control ping for synchronization */
19028   MPING (CONTROL_PING, mp_ping);
19029   S (mp_ping);
19030
19031   /* Wait for a reply... */
19032   W (ret);
19033   return ret;
19034 }
19035
19036 static int
19037 api_feature_enable_disable (vat_main_t * vam)
19038 {
19039   unformat_input_t *i = vam->input;
19040   vl_api_feature_enable_disable_t *mp;
19041   u8 *arc_name = 0;
19042   u8 *feature_name = 0;
19043   u32 sw_if_index = ~0;
19044   u8 enable = 1;
19045   int ret;
19046
19047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19048     {
19049       if (unformat (i, "arc_name %s", &arc_name))
19050         ;
19051       else if (unformat (i, "feature_name %s", &feature_name))
19052         ;
19053       else
19054         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19055         ;
19056       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19057         ;
19058       else if (unformat (i, "disable"))
19059         enable = 0;
19060       else
19061         break;
19062     }
19063
19064   if (arc_name == 0)
19065     {
19066       errmsg ("missing arc name");
19067       return -99;
19068     }
19069   if (vec_len (arc_name) > 63)
19070     {
19071       errmsg ("arc name too long");
19072     }
19073
19074   if (feature_name == 0)
19075     {
19076       errmsg ("missing feature name");
19077       return -99;
19078     }
19079   if (vec_len (feature_name) > 63)
19080     {
19081       errmsg ("feature name too long");
19082     }
19083
19084   if (sw_if_index == ~0)
19085     {
19086       errmsg ("missing interface name or sw_if_index");
19087       return -99;
19088     }
19089
19090   /* Construct the API message */
19091   M (FEATURE_ENABLE_DISABLE, mp);
19092   mp->sw_if_index = ntohl (sw_if_index);
19093   mp->enable = enable;
19094   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19095   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19096   vec_free (arc_name);
19097   vec_free (feature_name);
19098
19099   S (mp);
19100   W (ret);
19101   return ret;
19102 }
19103
19104 static int
19105 api_feature_gso_enable_disable (vat_main_t * vam)
19106 {
19107   unformat_input_t *i = vam->input;
19108   vl_api_feature_gso_enable_disable_t *mp;
19109   u32 sw_if_index = ~0;
19110   u8 enable = 1;
19111   int ret;
19112
19113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19114     {
19115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19116         ;
19117       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19118         ;
19119       else if (unformat (i, "enable"))
19120         enable = 1;
19121       else if (unformat (i, "disable"))
19122         enable = 0;
19123       else
19124         break;
19125     }
19126
19127   if (sw_if_index == ~0)
19128     {
19129       errmsg ("missing interface name or sw_if_index");
19130       return -99;
19131     }
19132
19133   /* Construct the API message */
19134   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19135   mp->sw_if_index = ntohl (sw_if_index);
19136   mp->enable_disable = enable;
19137
19138   S (mp);
19139   W (ret);
19140   return ret;
19141 }
19142
19143 static int
19144 api_sw_interface_tag_add_del (vat_main_t * vam)
19145 {
19146   unformat_input_t *i = vam->input;
19147   vl_api_sw_interface_tag_add_del_t *mp;
19148   u32 sw_if_index = ~0;
19149   u8 *tag = 0;
19150   u8 enable = 1;
19151   int ret;
19152
19153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19154     {
19155       if (unformat (i, "tag %s", &tag))
19156         ;
19157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19158         ;
19159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19160         ;
19161       else if (unformat (i, "del"))
19162         enable = 0;
19163       else
19164         break;
19165     }
19166
19167   if (sw_if_index == ~0)
19168     {
19169       errmsg ("missing interface name or sw_if_index");
19170       return -99;
19171     }
19172
19173   if (enable && (tag == 0))
19174     {
19175       errmsg ("no tag specified");
19176       return -99;
19177     }
19178
19179   /* Construct the API message */
19180   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19181   mp->sw_if_index = ntohl (sw_if_index);
19182   mp->is_add = enable;
19183   if (enable)
19184     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19185   vec_free (tag);
19186
19187   S (mp);
19188   W (ret);
19189   return ret;
19190 }
19191
19192 static int
19193 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19194 {
19195   unformat_input_t *i = vam->input;
19196   vl_api_mac_address_t mac = { 0 };
19197   vl_api_sw_interface_add_del_mac_address_t *mp;
19198   u32 sw_if_index = ~0;
19199   u8 is_add = 1;
19200   u8 mac_set = 0;
19201   int ret;
19202
19203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19204     {
19205       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19206         ;
19207       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19208         ;
19209       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19210         mac_set++;
19211       else if (unformat (i, "del"))
19212         is_add = 0;
19213       else
19214         break;
19215     }
19216
19217   if (sw_if_index == ~0)
19218     {
19219       errmsg ("missing interface name or sw_if_index");
19220       return -99;
19221     }
19222
19223   if (!mac_set)
19224     {
19225       errmsg ("missing MAC address");
19226       return -99;
19227     }
19228
19229   /* Construct the API message */
19230   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19231   mp->sw_if_index = ntohl (sw_if_index);
19232   mp->is_add = is_add;
19233   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19234
19235   S (mp);
19236   W (ret);
19237   return ret;
19238 }
19239
19240 static void vl_api_l2_xconnect_details_t_handler
19241   (vl_api_l2_xconnect_details_t * mp)
19242 {
19243   vat_main_t *vam = &vat_main;
19244
19245   print (vam->ofp, "%15d%15d",
19246          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19247 }
19248
19249 static void vl_api_l2_xconnect_details_t_handler_json
19250   (vl_api_l2_xconnect_details_t * mp)
19251 {
19252   vat_main_t *vam = &vat_main;
19253   vat_json_node_t *node = NULL;
19254
19255   if (VAT_JSON_ARRAY != vam->json_tree.type)
19256     {
19257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19258       vat_json_init_array (&vam->json_tree);
19259     }
19260   node = vat_json_array_add (&vam->json_tree);
19261
19262   vat_json_init_object (node);
19263   vat_json_object_add_uint (node, "rx_sw_if_index",
19264                             ntohl (mp->rx_sw_if_index));
19265   vat_json_object_add_uint (node, "tx_sw_if_index",
19266                             ntohl (mp->tx_sw_if_index));
19267 }
19268
19269 static int
19270 api_l2_xconnect_dump (vat_main_t * vam)
19271 {
19272   vl_api_l2_xconnect_dump_t *mp;
19273   vl_api_control_ping_t *mp_ping;
19274   int ret;
19275
19276   if (!vam->json_output)
19277     {
19278       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19279     }
19280
19281   M (L2_XCONNECT_DUMP, mp);
19282
19283   S (mp);
19284
19285   /* Use a control ping for synchronization */
19286   MPING (CONTROL_PING, mp_ping);
19287   S (mp_ping);
19288
19289   W (ret);
19290   return ret;
19291 }
19292
19293 static int
19294 api_hw_interface_set_mtu (vat_main_t * vam)
19295 {
19296   unformat_input_t *i = vam->input;
19297   vl_api_hw_interface_set_mtu_t *mp;
19298   u32 sw_if_index = ~0;
19299   u32 mtu = 0;
19300   int ret;
19301
19302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19303     {
19304       if (unformat (i, "mtu %d", &mtu))
19305         ;
19306       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19307         ;
19308       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19309         ;
19310       else
19311         break;
19312     }
19313
19314   if (sw_if_index == ~0)
19315     {
19316       errmsg ("missing interface name or sw_if_index");
19317       return -99;
19318     }
19319
19320   if (mtu == 0)
19321     {
19322       errmsg ("no mtu specified");
19323       return -99;
19324     }
19325
19326   /* Construct the API message */
19327   M (HW_INTERFACE_SET_MTU, mp);
19328   mp->sw_if_index = ntohl (sw_if_index);
19329   mp->mtu = ntohs ((u16) mtu);
19330
19331   S (mp);
19332   W (ret);
19333   return ret;
19334 }
19335
19336 static int
19337 api_p2p_ethernet_add (vat_main_t * vam)
19338 {
19339   unformat_input_t *i = vam->input;
19340   vl_api_p2p_ethernet_add_t *mp;
19341   u32 parent_if_index = ~0;
19342   u32 sub_id = ~0;
19343   u8 remote_mac[6];
19344   u8 mac_set = 0;
19345   int ret;
19346
19347   clib_memset (remote_mac, 0, sizeof (remote_mac));
19348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19349     {
19350       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19351         ;
19352       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19353         ;
19354       else
19355         if (unformat
19356             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19357         mac_set++;
19358       else if (unformat (i, "sub_id %d", &sub_id))
19359         ;
19360       else
19361         {
19362           clib_warning ("parse error '%U'", format_unformat_error, i);
19363           return -99;
19364         }
19365     }
19366
19367   if (parent_if_index == ~0)
19368     {
19369       errmsg ("missing interface name or sw_if_index");
19370       return -99;
19371     }
19372   if (mac_set == 0)
19373     {
19374       errmsg ("missing remote mac address");
19375       return -99;
19376     }
19377   if (sub_id == ~0)
19378     {
19379       errmsg ("missing sub-interface id");
19380       return -99;
19381     }
19382
19383   M (P2P_ETHERNET_ADD, mp);
19384   mp->parent_if_index = ntohl (parent_if_index);
19385   mp->subif_id = ntohl (sub_id);
19386   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19387
19388   S (mp);
19389   W (ret);
19390   return ret;
19391 }
19392
19393 static int
19394 api_p2p_ethernet_del (vat_main_t * vam)
19395 {
19396   unformat_input_t *i = vam->input;
19397   vl_api_p2p_ethernet_del_t *mp;
19398   u32 parent_if_index = ~0;
19399   u8 remote_mac[6];
19400   u8 mac_set = 0;
19401   int ret;
19402
19403   clib_memset (remote_mac, 0, sizeof (remote_mac));
19404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19405     {
19406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19407         ;
19408       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19409         ;
19410       else
19411         if (unformat
19412             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19413         mac_set++;
19414       else
19415         {
19416           clib_warning ("parse error '%U'", format_unformat_error, i);
19417           return -99;
19418         }
19419     }
19420
19421   if (parent_if_index == ~0)
19422     {
19423       errmsg ("missing interface name or sw_if_index");
19424       return -99;
19425     }
19426   if (mac_set == 0)
19427     {
19428       errmsg ("missing remote mac address");
19429       return -99;
19430     }
19431
19432   M (P2P_ETHERNET_DEL, mp);
19433   mp->parent_if_index = ntohl (parent_if_index);
19434   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19435
19436   S (mp);
19437   W (ret);
19438   return ret;
19439 }
19440
19441 static int
19442 api_lldp_config (vat_main_t * vam)
19443 {
19444   unformat_input_t *i = vam->input;
19445   vl_api_lldp_config_t *mp;
19446   int tx_hold = 0;
19447   int tx_interval = 0;
19448   u8 *sys_name = NULL;
19449   int ret;
19450
19451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19452     {
19453       if (unformat (i, "system-name %s", &sys_name))
19454         ;
19455       else if (unformat (i, "tx-hold %d", &tx_hold))
19456         ;
19457       else if (unformat (i, "tx-interval %d", &tx_interval))
19458         ;
19459       else
19460         {
19461           clib_warning ("parse error '%U'", format_unformat_error, i);
19462           return -99;
19463         }
19464     }
19465
19466   vec_add1 (sys_name, 0);
19467
19468   M (LLDP_CONFIG, mp);
19469   mp->tx_hold = htonl (tx_hold);
19470   mp->tx_interval = htonl (tx_interval);
19471   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19472   vec_free (sys_name);
19473
19474   S (mp);
19475   W (ret);
19476   return ret;
19477 }
19478
19479 static int
19480 api_sw_interface_set_lldp (vat_main_t * vam)
19481 {
19482   unformat_input_t *i = vam->input;
19483   vl_api_sw_interface_set_lldp_t *mp;
19484   u32 sw_if_index = ~0;
19485   u32 enable = 1;
19486   u8 *port_desc = NULL, *mgmt_oid = NULL;
19487   ip4_address_t ip4_addr;
19488   ip6_address_t ip6_addr;
19489   int ret;
19490
19491   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19492   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19493
19494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19495     {
19496       if (unformat (i, "disable"))
19497         enable = 0;
19498       else
19499         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19500         ;
19501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19502         ;
19503       else if (unformat (i, "port-desc %s", &port_desc))
19504         ;
19505       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19506         ;
19507       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19508         ;
19509       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19510         ;
19511       else
19512         break;
19513     }
19514
19515   if (sw_if_index == ~0)
19516     {
19517       errmsg ("missing interface name or sw_if_index");
19518       return -99;
19519     }
19520
19521   /* Construct the API message */
19522   vec_add1 (port_desc, 0);
19523   vec_add1 (mgmt_oid, 0);
19524   M (SW_INTERFACE_SET_LLDP, mp);
19525   mp->sw_if_index = ntohl (sw_if_index);
19526   mp->enable = enable;
19527   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19528   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19529   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19530   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19531   vec_free (port_desc);
19532   vec_free (mgmt_oid);
19533
19534   S (mp);
19535   W (ret);
19536   return ret;
19537 }
19538
19539 static int
19540 api_tcp_configure_src_addresses (vat_main_t * vam)
19541 {
19542   vl_api_tcp_configure_src_addresses_t *mp;
19543   unformat_input_t *i = vam->input;
19544   vl_api_address_t first, last;
19545   u8 range_set = 0;
19546   u32 vrf_id = 0;
19547   int ret;
19548
19549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19550     {
19551       if (unformat (i, "%U - %U",
19552                     unformat_vl_api_address, &first,
19553                     unformat_vl_api_address, &last))
19554         {
19555           if (range_set)
19556             {
19557               errmsg ("one range per message (range already set)");
19558               return -99;
19559             }
19560           range_set = 1;
19561         }
19562       else if (unformat (i, "vrf %d", &vrf_id))
19563         ;
19564       else
19565         break;
19566     }
19567
19568   if (range_set == 0)
19569     {
19570       errmsg ("address range not set");
19571       return -99;
19572     }
19573
19574   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19575
19576   mp->vrf_id = ntohl (vrf_id);
19577   clib_memcpy (&mp->first_address, &first, sizeof (first));
19578   clib_memcpy (&mp->last_address, &last, sizeof (last));
19579
19580   S (mp);
19581   W (ret);
19582   return ret;
19583 }
19584
19585 static void vl_api_app_namespace_add_del_reply_t_handler
19586   (vl_api_app_namespace_add_del_reply_t * mp)
19587 {
19588   vat_main_t *vam = &vat_main;
19589   i32 retval = ntohl (mp->retval);
19590   if (vam->async_mode)
19591     {
19592       vam->async_errors += (retval < 0);
19593     }
19594   else
19595     {
19596       vam->retval = retval;
19597       if (retval == 0)
19598         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19599       vam->result_ready = 1;
19600     }
19601 }
19602
19603 static void vl_api_app_namespace_add_del_reply_t_handler_json
19604   (vl_api_app_namespace_add_del_reply_t * mp)
19605 {
19606   vat_main_t *vam = &vat_main;
19607   vat_json_node_t node;
19608
19609   vat_json_init_object (&node);
19610   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19611   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19612
19613   vat_json_print (vam->ofp, &node);
19614   vat_json_free (&node);
19615
19616   vam->retval = ntohl (mp->retval);
19617   vam->result_ready = 1;
19618 }
19619
19620 static int
19621 api_app_namespace_add_del (vat_main_t * vam)
19622 {
19623   vl_api_app_namespace_add_del_t *mp;
19624   unformat_input_t *i = vam->input;
19625   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19626   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19627   u64 secret;
19628   int ret;
19629
19630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19631     {
19632       if (unformat (i, "id %_%v%_", &ns_id))
19633         ;
19634       else if (unformat (i, "secret %lu", &secret))
19635         secret_set = 1;
19636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19637         sw_if_index_set = 1;
19638       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19639         ;
19640       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19641         ;
19642       else
19643         break;
19644     }
19645   if (!ns_id || !secret_set || !sw_if_index_set)
19646     {
19647       errmsg ("namespace id, secret and sw_if_index must be set");
19648       return -99;
19649     }
19650   if (vec_len (ns_id) > 64)
19651     {
19652       errmsg ("namespace id too long");
19653       return -99;
19654     }
19655   M (APP_NAMESPACE_ADD_DEL, mp);
19656
19657   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19658   mp->secret = clib_host_to_net_u64 (secret);
19659   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19660   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19661   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19662   vec_free (ns_id);
19663   S (mp);
19664   W (ret);
19665   return ret;
19666 }
19667
19668 static int
19669 api_sock_init_shm (vat_main_t * vam)
19670 {
19671 #if VPP_API_TEST_BUILTIN == 0
19672   unformat_input_t *i = vam->input;
19673   vl_api_shm_elem_config_t *config = 0;
19674   u64 size = 64 << 20;
19675   int rv;
19676
19677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19678     {
19679       if (unformat (i, "size %U", unformat_memory_size, &size))
19680         ;
19681       else
19682         break;
19683     }
19684
19685   /*
19686    * Canned custom ring allocator config.
19687    * Should probably parse all of this
19688    */
19689   vec_validate (config, 6);
19690   config[0].type = VL_API_VLIB_RING;
19691   config[0].size = 256;
19692   config[0].count = 32;
19693
19694   config[1].type = VL_API_VLIB_RING;
19695   config[1].size = 1024;
19696   config[1].count = 16;
19697
19698   config[2].type = VL_API_VLIB_RING;
19699   config[2].size = 4096;
19700   config[2].count = 2;
19701
19702   config[3].type = VL_API_CLIENT_RING;
19703   config[3].size = 256;
19704   config[3].count = 32;
19705
19706   config[4].type = VL_API_CLIENT_RING;
19707   config[4].size = 1024;
19708   config[4].count = 16;
19709
19710   config[5].type = VL_API_CLIENT_RING;
19711   config[5].size = 4096;
19712   config[5].count = 2;
19713
19714   config[6].type = VL_API_QUEUE;
19715   config[6].count = 128;
19716   config[6].size = sizeof (uword);
19717
19718   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19719   if (!rv)
19720     vam->client_index_invalid = 1;
19721   return rv;
19722 #else
19723   return -99;
19724 #endif
19725 }
19726
19727 static void
19728 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19729 {
19730   vat_main_t *vam = &vat_main;
19731   fib_prefix_t lcl, rmt;
19732
19733   ip_prefix_decode (&mp->lcl, &lcl);
19734   ip_prefix_decode (&mp->rmt, &rmt);
19735
19736   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19737     {
19738       print (vam->ofp,
19739              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19740              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19741              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19742              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19743              &rmt.fp_addr.ip4, rmt.fp_len,
19744              clib_net_to_host_u16 (mp->rmt_port),
19745              clib_net_to_host_u32 (mp->action_index), mp->tag);
19746     }
19747   else
19748     {
19749       print (vam->ofp,
19750              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19751              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19752              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19753              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19754              &rmt.fp_addr.ip6, rmt.fp_len,
19755              clib_net_to_host_u16 (mp->rmt_port),
19756              clib_net_to_host_u32 (mp->action_index), mp->tag);
19757     }
19758 }
19759
19760 static void
19761 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19762                                              mp)
19763 {
19764   vat_main_t *vam = &vat_main;
19765   vat_json_node_t *node = NULL;
19766   struct in6_addr ip6;
19767   struct in_addr ip4;
19768
19769   fib_prefix_t lcl, rmt;
19770
19771   ip_prefix_decode (&mp->lcl, &lcl);
19772   ip_prefix_decode (&mp->rmt, &rmt);
19773
19774   if (VAT_JSON_ARRAY != vam->json_tree.type)
19775     {
19776       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19777       vat_json_init_array (&vam->json_tree);
19778     }
19779   node = vat_json_array_add (&vam->json_tree);
19780   vat_json_init_object (node);
19781
19782   vat_json_object_add_uint (node, "appns_index",
19783                             clib_net_to_host_u32 (mp->appns_index));
19784   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19785   vat_json_object_add_uint (node, "scope", mp->scope);
19786   vat_json_object_add_uint (node, "action_index",
19787                             clib_net_to_host_u32 (mp->action_index));
19788   vat_json_object_add_uint (node, "lcl_port",
19789                             clib_net_to_host_u16 (mp->lcl_port));
19790   vat_json_object_add_uint (node, "rmt_port",
19791                             clib_net_to_host_u16 (mp->rmt_port));
19792   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19793   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19794   vat_json_object_add_string_copy (node, "tag", mp->tag);
19795   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19796     {
19797       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19798       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19799       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19800       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19801     }
19802   else
19803     {
19804       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19805       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19806       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19807       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19808     }
19809 }
19810
19811 static int
19812 api_session_rule_add_del (vat_main_t * vam)
19813 {
19814   vl_api_session_rule_add_del_t *mp;
19815   unformat_input_t *i = vam->input;
19816   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19817   u32 appns_index = 0, scope = 0;
19818   ip4_address_t lcl_ip4, rmt_ip4;
19819   ip6_address_t lcl_ip6, rmt_ip6;
19820   u8 is_ip4 = 1, conn_set = 0;
19821   u8 is_add = 1, *tag = 0;
19822   int ret;
19823   fib_prefix_t lcl, rmt;
19824
19825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19826     {
19827       if (unformat (i, "del"))
19828         is_add = 0;
19829       else if (unformat (i, "add"))
19830         ;
19831       else if (unformat (i, "proto tcp"))
19832         proto = 0;
19833       else if (unformat (i, "proto udp"))
19834         proto = 1;
19835       else if (unformat (i, "appns %d", &appns_index))
19836         ;
19837       else if (unformat (i, "scope %d", &scope))
19838         ;
19839       else if (unformat (i, "tag %_%v%_", &tag))
19840         ;
19841       else
19842         if (unformat
19843             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19844              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19845              &rmt_port))
19846         {
19847           is_ip4 = 1;
19848           conn_set = 1;
19849         }
19850       else
19851         if (unformat
19852             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19853              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19854              &rmt_port))
19855         {
19856           is_ip4 = 0;
19857           conn_set = 1;
19858         }
19859       else if (unformat (i, "action %d", &action))
19860         ;
19861       else
19862         break;
19863     }
19864   if (proto == ~0 || !conn_set || action == ~0)
19865     {
19866       errmsg ("transport proto, connection and action must be set");
19867       return -99;
19868     }
19869
19870   if (scope > 3)
19871     {
19872       errmsg ("scope should be 0-3");
19873       return -99;
19874     }
19875
19876   M (SESSION_RULE_ADD_DEL, mp);
19877
19878   clib_memset (&lcl, 0, sizeof (lcl));
19879   clib_memset (&rmt, 0, sizeof (rmt));
19880   if (is_ip4)
19881     {
19882       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19883       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19884       lcl.fp_len = lcl_plen;
19885       rmt.fp_len = rmt_plen;
19886     }
19887   else
19888     {
19889       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19890       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19891       lcl.fp_len = lcl_plen;
19892       rmt.fp_len = rmt_plen;
19893     }
19894
19895
19896   ip_prefix_encode (&lcl, &mp->lcl);
19897   ip_prefix_encode (&rmt, &mp->rmt);
19898   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19899   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19900   mp->transport_proto =
19901     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19902   mp->action_index = clib_host_to_net_u32 (action);
19903   mp->appns_index = clib_host_to_net_u32 (appns_index);
19904   mp->scope = scope;
19905   mp->is_add = is_add;
19906   if (tag)
19907     {
19908       clib_memcpy (mp->tag, tag, vec_len (tag));
19909       vec_free (tag);
19910     }
19911
19912   S (mp);
19913   W (ret);
19914   return ret;
19915 }
19916
19917 static int
19918 api_session_rules_dump (vat_main_t * vam)
19919 {
19920   vl_api_session_rules_dump_t *mp;
19921   vl_api_control_ping_t *mp_ping;
19922   int ret;
19923
19924   if (!vam->json_output)
19925     {
19926       print (vam->ofp, "%=20s", "Session Rules");
19927     }
19928
19929   M (SESSION_RULES_DUMP, mp);
19930   /* send it... */
19931   S (mp);
19932
19933   /* Use a control ping for synchronization */
19934   MPING (CONTROL_PING, mp_ping);
19935   S (mp_ping);
19936
19937   /* Wait for a reply... */
19938   W (ret);
19939   return ret;
19940 }
19941
19942 static int
19943 api_ip_container_proxy_add_del (vat_main_t * vam)
19944 {
19945   vl_api_ip_container_proxy_add_del_t *mp;
19946   unformat_input_t *i = vam->input;
19947   u32 sw_if_index = ~0;
19948   vl_api_prefix_t pfx = { };
19949   u8 is_add = 1;
19950   int ret;
19951
19952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19953     {
19954       if (unformat (i, "del"))
19955         is_add = 0;
19956       else if (unformat (i, "add"))
19957         ;
19958       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19959         ;
19960       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19961         ;
19962       else
19963         break;
19964     }
19965   if (sw_if_index == ~0 || pfx.len == 0)
19966     {
19967       errmsg ("address and sw_if_index must be set");
19968       return -99;
19969     }
19970
19971   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19972
19973   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19974   mp->is_add = is_add;
19975   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19976
19977   S (mp);
19978   W (ret);
19979   return ret;
19980 }
19981
19982 static int
19983 api_qos_record_enable_disable (vat_main_t * vam)
19984 {
19985   unformat_input_t *i = vam->input;
19986   vl_api_qos_record_enable_disable_t *mp;
19987   u32 sw_if_index, qs = 0xff;
19988   u8 sw_if_index_set = 0;
19989   u8 enable = 1;
19990   int ret;
19991
19992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19993     {
19994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19995         sw_if_index_set = 1;
19996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19997         sw_if_index_set = 1;
19998       else if (unformat (i, "%U", unformat_qos_source, &qs))
19999         ;
20000       else if (unformat (i, "disable"))
20001         enable = 0;
20002       else
20003         {
20004           clib_warning ("parse error '%U'", format_unformat_error, i);
20005           return -99;
20006         }
20007     }
20008
20009   if (sw_if_index_set == 0)
20010     {
20011       errmsg ("missing interface name or sw_if_index");
20012       return -99;
20013     }
20014   if (qs == 0xff)
20015     {
20016       errmsg ("input location must be specified");
20017       return -99;
20018     }
20019
20020   M (QOS_RECORD_ENABLE_DISABLE, mp);
20021
20022   mp->record.sw_if_index = ntohl (sw_if_index);
20023   mp->record.input_source = qs;
20024   mp->enable = enable;
20025
20026   S (mp);
20027   W (ret);
20028   return ret;
20029 }
20030
20031
20032 static int
20033 q_or_quit (vat_main_t * vam)
20034 {
20035 #if VPP_API_TEST_BUILTIN == 0
20036   longjmp (vam->jump_buf, 1);
20037 #endif
20038   return 0;                     /* not so much */
20039 }
20040
20041 static int
20042 q (vat_main_t * vam)
20043 {
20044   return q_or_quit (vam);
20045 }
20046
20047 static int
20048 quit (vat_main_t * vam)
20049 {
20050   return q_or_quit (vam);
20051 }
20052
20053 static int
20054 comment (vat_main_t * vam)
20055 {
20056   return 0;
20057 }
20058
20059 static int
20060 elog_save (vat_main_t * vam)
20061 {
20062 #if VPP_API_TEST_BUILTIN == 0
20063   elog_main_t *em = &vam->elog_main;
20064   unformat_input_t *i = vam->input;
20065   char *file, *chroot_file;
20066   clib_error_t *error;
20067
20068   if (!unformat (i, "%s", &file))
20069     {
20070       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20071       return 0;
20072     }
20073
20074   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20075   if (strstr (file, "..") || index (file, '/'))
20076     {
20077       errmsg ("illegal characters in filename '%s'", file);
20078       return 0;
20079     }
20080
20081   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20082
20083   vec_free (file);
20084
20085   errmsg ("Saving %wd of %wd events to %s",
20086           elog_n_events_in_buffer (em),
20087           elog_buffer_capacity (em), chroot_file);
20088
20089   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20090   vec_free (chroot_file);
20091
20092   if (error)
20093     clib_error_report (error);
20094 #else
20095   errmsg ("Use the vpp event loger...");
20096 #endif
20097
20098   return 0;
20099 }
20100
20101 static int
20102 elog_setup (vat_main_t * vam)
20103 {
20104 #if VPP_API_TEST_BUILTIN == 0
20105   elog_main_t *em = &vam->elog_main;
20106   unformat_input_t *i = vam->input;
20107   u32 nevents = 128 << 10;
20108
20109   (void) unformat (i, "nevents %d", &nevents);
20110
20111   elog_init (em, nevents);
20112   vl_api_set_elog_main (em);
20113   vl_api_set_elog_trace_api_messages (1);
20114   errmsg ("Event logger initialized with %u events", nevents);
20115 #else
20116   errmsg ("Use the vpp event loger...");
20117 #endif
20118   return 0;
20119 }
20120
20121 static int
20122 elog_enable (vat_main_t * vam)
20123 {
20124 #if VPP_API_TEST_BUILTIN == 0
20125   elog_main_t *em = &vam->elog_main;
20126
20127   elog_enable_disable (em, 1 /* enable */ );
20128   vl_api_set_elog_trace_api_messages (1);
20129   errmsg ("Event logger enabled...");
20130 #else
20131   errmsg ("Use the vpp event loger...");
20132 #endif
20133   return 0;
20134 }
20135
20136 static int
20137 elog_disable (vat_main_t * vam)
20138 {
20139 #if VPP_API_TEST_BUILTIN == 0
20140   elog_main_t *em = &vam->elog_main;
20141
20142   elog_enable_disable (em, 0 /* enable */ );
20143   vl_api_set_elog_trace_api_messages (1);
20144   errmsg ("Event logger disabled...");
20145 #else
20146   errmsg ("Use the vpp event loger...");
20147 #endif
20148   return 0;
20149 }
20150
20151 static int
20152 statseg (vat_main_t * vam)
20153 {
20154   ssvm_private_t *ssvmp = &vam->stat_segment;
20155   ssvm_shared_header_t *shared_header = ssvmp->sh;
20156   vlib_counter_t **counters;
20157   u64 thread0_index1_packets;
20158   u64 thread0_index1_bytes;
20159   f64 vector_rate, input_rate;
20160   uword *p;
20161
20162   uword *counter_vector_by_name;
20163   if (vam->stat_segment_lockp == 0)
20164     {
20165       errmsg ("Stat segment not mapped...");
20166       return -99;
20167     }
20168
20169   /* look up "/if/rx for sw_if_index 1 as a test */
20170
20171   clib_spinlock_lock (vam->stat_segment_lockp);
20172
20173   counter_vector_by_name = (uword *) shared_header->opaque[1];
20174
20175   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20176   if (p == 0)
20177     {
20178       clib_spinlock_unlock (vam->stat_segment_lockp);
20179       errmsg ("/if/tx not found?");
20180       return -99;
20181     }
20182
20183   /* Fish per-thread vector of combined counters from shared memory */
20184   counters = (vlib_counter_t **) p[0];
20185
20186   if (vec_len (counters[0]) < 2)
20187     {
20188       clib_spinlock_unlock (vam->stat_segment_lockp);
20189       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20190       return -99;
20191     }
20192
20193   /* Read thread 0 sw_if_index 1 counter */
20194   thread0_index1_packets = counters[0][1].packets;
20195   thread0_index1_bytes = counters[0][1].bytes;
20196
20197   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20198   if (p == 0)
20199     {
20200       clib_spinlock_unlock (vam->stat_segment_lockp);
20201       errmsg ("vector_rate not found?");
20202       return -99;
20203     }
20204
20205   vector_rate = *(f64 *) (p[0]);
20206   p = hash_get_mem (counter_vector_by_name, "input_rate");
20207   if (p == 0)
20208     {
20209       clib_spinlock_unlock (vam->stat_segment_lockp);
20210       errmsg ("input_rate not found?");
20211       return -99;
20212     }
20213   input_rate = *(f64 *) (p[0]);
20214
20215   clib_spinlock_unlock (vam->stat_segment_lockp);
20216
20217   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20218          vector_rate, input_rate);
20219   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20220          thread0_index1_packets, thread0_index1_bytes);
20221
20222   return 0;
20223 }
20224
20225 static int
20226 cmd_cmp (void *a1, void *a2)
20227 {
20228   u8 **c1 = a1;
20229   u8 **c2 = a2;
20230
20231   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20232 }
20233
20234 static int
20235 help (vat_main_t * vam)
20236 {
20237   u8 **cmds = 0;
20238   u8 *name = 0;
20239   hash_pair_t *p;
20240   unformat_input_t *i = vam->input;
20241   int j;
20242
20243   if (unformat (i, "%s", &name))
20244     {
20245       uword *hs;
20246
20247       vec_add1 (name, 0);
20248
20249       hs = hash_get_mem (vam->help_by_name, name);
20250       if (hs)
20251         print (vam->ofp, "usage: %s %s", name, hs[0]);
20252       else
20253         print (vam->ofp, "No such msg / command '%s'", name);
20254       vec_free (name);
20255       return 0;
20256     }
20257
20258   print (vam->ofp, "Help is available for the following:");
20259
20260     /* *INDENT-OFF* */
20261     hash_foreach_pair (p, vam->function_by_name,
20262     ({
20263       vec_add1 (cmds, (u8 *)(p->key));
20264     }));
20265     /* *INDENT-ON* */
20266
20267   vec_sort_with_function (cmds, cmd_cmp);
20268
20269   for (j = 0; j < vec_len (cmds); j++)
20270     print (vam->ofp, "%s", cmds[j]);
20271
20272   vec_free (cmds);
20273   return 0;
20274 }
20275
20276 static int
20277 set (vat_main_t * vam)
20278 {
20279   u8 *name = 0, *value = 0;
20280   unformat_input_t *i = vam->input;
20281
20282   if (unformat (i, "%s", &name))
20283     {
20284       /* The input buffer is a vector, not a string. */
20285       value = vec_dup (i->buffer);
20286       vec_delete (value, i->index, 0);
20287       /* Almost certainly has a trailing newline */
20288       if (value[vec_len (value) - 1] == '\n')
20289         value[vec_len (value) - 1] = 0;
20290       /* Make sure it's a proper string, one way or the other */
20291       vec_add1 (value, 0);
20292       (void) clib_macro_set_value (&vam->macro_main,
20293                                    (char *) name, (char *) value);
20294     }
20295   else
20296     errmsg ("usage: set <name> <value>");
20297
20298   vec_free (name);
20299   vec_free (value);
20300   return 0;
20301 }
20302
20303 static int
20304 unset (vat_main_t * vam)
20305 {
20306   u8 *name = 0;
20307
20308   if (unformat (vam->input, "%s", &name))
20309     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20310       errmsg ("unset: %s wasn't set", name);
20311   vec_free (name);
20312   return 0;
20313 }
20314
20315 typedef struct
20316 {
20317   u8 *name;
20318   u8 *value;
20319 } macro_sort_t;
20320
20321
20322 static int
20323 macro_sort_cmp (void *a1, void *a2)
20324 {
20325   macro_sort_t *s1 = a1;
20326   macro_sort_t *s2 = a2;
20327
20328   return strcmp ((char *) (s1->name), (char *) (s2->name));
20329 }
20330
20331 static int
20332 dump_macro_table (vat_main_t * vam)
20333 {
20334   macro_sort_t *sort_me = 0, *sm;
20335   int i;
20336   hash_pair_t *p;
20337
20338     /* *INDENT-OFF* */
20339     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20340     ({
20341       vec_add2 (sort_me, sm, 1);
20342       sm->name = (u8 *)(p->key);
20343       sm->value = (u8 *) (p->value[0]);
20344     }));
20345     /* *INDENT-ON* */
20346
20347   vec_sort_with_function (sort_me, macro_sort_cmp);
20348
20349   if (vec_len (sort_me))
20350     print (vam->ofp, "%-15s%s", "Name", "Value");
20351   else
20352     print (vam->ofp, "The macro table is empty...");
20353
20354   for (i = 0; i < vec_len (sort_me); i++)
20355     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20356   return 0;
20357 }
20358
20359 static int
20360 dump_node_table (vat_main_t * vam)
20361 {
20362   int i, j;
20363   vlib_node_t *node, *next_node;
20364
20365   if (vec_len (vam->graph_nodes) == 0)
20366     {
20367       print (vam->ofp, "Node table empty, issue get_node_graph...");
20368       return 0;
20369     }
20370
20371   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20372     {
20373       node = vam->graph_nodes[0][i];
20374       print (vam->ofp, "[%d] %s", i, node->name);
20375       for (j = 0; j < vec_len (node->next_nodes); j++)
20376         {
20377           if (node->next_nodes[j] != ~0)
20378             {
20379               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20380               print (vam->ofp, "  [%d] %s", j, next_node->name);
20381             }
20382         }
20383     }
20384   return 0;
20385 }
20386
20387 static int
20388 value_sort_cmp (void *a1, void *a2)
20389 {
20390   name_sort_t *n1 = a1;
20391   name_sort_t *n2 = a2;
20392
20393   if (n1->value < n2->value)
20394     return -1;
20395   if (n1->value > n2->value)
20396     return 1;
20397   return 0;
20398 }
20399
20400
20401 static int
20402 dump_msg_api_table (vat_main_t * vam)
20403 {
20404   api_main_t *am = vlibapi_get_main ();
20405   name_sort_t *nses = 0, *ns;
20406   hash_pair_t *hp;
20407   int i;
20408
20409   /* *INDENT-OFF* */
20410   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20411   ({
20412     vec_add2 (nses, ns, 1);
20413     ns->name = (u8 *)(hp->key);
20414     ns->value = (u32) hp->value[0];
20415   }));
20416   /* *INDENT-ON* */
20417
20418   vec_sort_with_function (nses, value_sort_cmp);
20419
20420   for (i = 0; i < vec_len (nses); i++)
20421     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20422   vec_free (nses);
20423   return 0;
20424 }
20425
20426 static int
20427 get_msg_id (vat_main_t * vam)
20428 {
20429   u8 *name_and_crc;
20430   u32 message_index;
20431
20432   if (unformat (vam->input, "%s", &name_and_crc))
20433     {
20434       message_index = vl_msg_api_get_msg_index (name_and_crc);
20435       if (message_index == ~0)
20436         {
20437           print (vam->ofp, " '%s' not found", name_and_crc);
20438           return 0;
20439         }
20440       print (vam->ofp, " '%s' has message index %d",
20441              name_and_crc, message_index);
20442       return 0;
20443     }
20444   errmsg ("name_and_crc required...");
20445   return 0;
20446 }
20447
20448 static int
20449 search_node_table (vat_main_t * vam)
20450 {
20451   unformat_input_t *line_input = vam->input;
20452   u8 *node_to_find;
20453   int j;
20454   vlib_node_t *node, *next_node;
20455   uword *p;
20456
20457   if (vam->graph_node_index_by_name == 0)
20458     {
20459       print (vam->ofp, "Node table empty, issue get_node_graph...");
20460       return 0;
20461     }
20462
20463   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20464     {
20465       if (unformat (line_input, "%s", &node_to_find))
20466         {
20467           vec_add1 (node_to_find, 0);
20468           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20469           if (p == 0)
20470             {
20471               print (vam->ofp, "%s not found...", node_to_find);
20472               goto out;
20473             }
20474           node = vam->graph_nodes[0][p[0]];
20475           print (vam->ofp, "[%d] %s", p[0], node->name);
20476           for (j = 0; j < vec_len (node->next_nodes); j++)
20477             {
20478               if (node->next_nodes[j] != ~0)
20479                 {
20480                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20481                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20482                 }
20483             }
20484         }
20485
20486       else
20487         {
20488           clib_warning ("parse error '%U'", format_unformat_error,
20489                         line_input);
20490           return -99;
20491         }
20492
20493     out:
20494       vec_free (node_to_find);
20495
20496     }
20497
20498   return 0;
20499 }
20500
20501
20502 static int
20503 script (vat_main_t * vam)
20504 {
20505 #if (VPP_API_TEST_BUILTIN==0)
20506   u8 *s = 0;
20507   char *save_current_file;
20508   unformat_input_t save_input;
20509   jmp_buf save_jump_buf;
20510   u32 save_line_number;
20511
20512   FILE *new_fp, *save_ifp;
20513
20514   if (unformat (vam->input, "%s", &s))
20515     {
20516       new_fp = fopen ((char *) s, "r");
20517       if (new_fp == 0)
20518         {
20519           errmsg ("Couldn't open script file %s", s);
20520           vec_free (s);
20521           return -99;
20522         }
20523     }
20524   else
20525     {
20526       errmsg ("Missing script name");
20527       return -99;
20528     }
20529
20530   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20531   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20532   save_ifp = vam->ifp;
20533   save_line_number = vam->input_line_number;
20534   save_current_file = (char *) vam->current_file;
20535
20536   vam->input_line_number = 0;
20537   vam->ifp = new_fp;
20538   vam->current_file = s;
20539   do_one_file (vam);
20540
20541   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20542   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20543   vam->ifp = save_ifp;
20544   vam->input_line_number = save_line_number;
20545   vam->current_file = (u8 *) save_current_file;
20546   vec_free (s);
20547
20548   return 0;
20549 #else
20550   clib_warning ("use the exec command...");
20551   return -99;
20552 #endif
20553 }
20554
20555 static int
20556 echo (vat_main_t * vam)
20557 {
20558   print (vam->ofp, "%v", vam->input->buffer);
20559   return 0;
20560 }
20561
20562 /* List of API message constructors, CLI names map to api_xxx */
20563 #define foreach_vpe_api_msg                                             \
20564 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20565 _(sw_interface_dump,"")                                                 \
20566 _(sw_interface_set_flags,                                               \
20567   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20568 _(sw_interface_add_del_address,                                         \
20569   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20570 _(sw_interface_set_rx_mode,                                             \
20571   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20572 _(sw_interface_set_rx_placement,                                        \
20573   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20574 _(sw_interface_rx_placement_dump,                                       \
20575   "[<intfc> | sw_if_index <id>]")                                         \
20576 _(sw_interface_set_table,                                               \
20577   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20578 _(sw_interface_set_mpls_enable,                                         \
20579   "<intfc> | sw_if_index [disable | dis]")                              \
20580 _(sw_interface_set_vpath,                                               \
20581   "<intfc> | sw_if_index <id> enable | disable")                        \
20582 _(sw_interface_set_vxlan_bypass,                                        \
20583   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20584 _(sw_interface_set_geneve_bypass,                                       \
20585   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20586 _(sw_interface_set_l2_xconnect,                                         \
20587   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20588   "enable | disable")                                                   \
20589 _(sw_interface_set_l2_bridge,                                           \
20590   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20591   "[shg <split-horizon-group>] [bvi]\n"                                 \
20592   "enable | disable")                                                   \
20593 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20594 _(bridge_domain_add_del,                                                \
20595   "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") \
20596 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20597 _(l2fib_add_del,                                                        \
20598   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20599 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20600 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20601 _(l2_flags,                                                             \
20602   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20603 _(bridge_flags,                                                         \
20604   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20605 _(tap_create_v2,                                                        \
20606   "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]") \
20607 _(tap_delete_v2,                                                        \
20608   "<vpp-if-name> | sw_if_index <id>")                                   \
20609 _(sw_interface_tap_v2_dump, "")                                         \
20610 _(virtio_pci_create,                                                    \
20611   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20612 _(virtio_pci_delete,                                                    \
20613   "<vpp-if-name> | sw_if_index <id>")                                   \
20614 _(sw_interface_virtio_pci_dump, "")                                     \
20615 _(bond_create,                                                          \
20616   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20617   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20618   "[id <if-id>]")                                                       \
20619 _(bond_delete,                                                          \
20620   "<vpp-if-name> | sw_if_index <id>")                                   \
20621 _(bond_enslave,                                                         \
20622   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20623 _(bond_detach_slave,                                                    \
20624   "sw_if_index <n>")                                                    \
20625  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20626 _(sw_interface_bond_dump, "")                                           \
20627 _(sw_interface_slave_dump,                                              \
20628   "<vpp-if-name> | sw_if_index <id>")                                   \
20629 _(ip_table_add_del,                                                     \
20630   "table <n> [ipv6] [add | del]\n")                                     \
20631 _(ip_route_add_del,                                                     \
20632   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20633   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20634   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20635   "[multipath] [count <n>] [del]")                                      \
20636 _(ip_mroute_add_del,                                                    \
20637   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20638   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20639 _(mpls_table_add_del,                                                   \
20640   "table <n> [add | del]\n")                                            \
20641 _(mpls_route_add_del,                                                   \
20642   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20643   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20644   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20645   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20646   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20647   "[count <n>] [del]")                                                  \
20648 _(mpls_ip_bind_unbind,                                                  \
20649   "<label> <addr/len>")                                                 \
20650 _(mpls_tunnel_add_del,                                                  \
20651   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20652   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20653   "[l2-only]  [out-label <n>]")                                         \
20654 _(sr_mpls_policy_add,                                                   \
20655   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20656 _(sr_mpls_policy_del,                                                   \
20657   "bsid <id>")                                                          \
20658 _(bier_table_add_del,                                                   \
20659   "<label> <sub-domain> <set> <bsl> [del]")                             \
20660 _(bier_route_add_del,                                                   \
20661   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20662   "[<intfc> | sw_if_index <id>]"                                        \
20663   "[weight <n>] [del] [multipath]")                                     \
20664 _(sw_interface_set_unnumbered,                                          \
20665   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20666 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20667 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20668   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20669   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20670   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20671 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20672 _(ip_table_flush, "table <n> [ipv6]")                                   \
20673 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20674 _(set_ip_flow_hash,                                                     \
20675   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20676 _(sw_interface_ip6_enable_disable,                                      \
20677   "<intfc> | sw_if_index <id> enable | disable")                        \
20678 _(l2_patch_add_del,                                                     \
20679   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20680   "enable | disable")                                                   \
20681 _(sr_localsid_add_del,                                                  \
20682   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20683   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20684 _(classify_add_del_table,                                               \
20685   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20686   " [del] [del-chain] mask <mask-value>\n"                              \
20687   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20688   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20689 _(classify_add_del_session,                                             \
20690   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20691   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20692   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20693   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20694 _(classify_set_interface_ip_table,                                      \
20695   "<intfc> | sw_if_index <nn> table <nn>")                              \
20696 _(classify_set_interface_l2_tables,                                     \
20697   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20698   "  [other-table <nn>]")                                               \
20699 _(get_node_index, "node <node-name")                                    \
20700 _(add_node_next, "node <node-name> next <next-node-name>")              \
20701 _(l2tpv3_create_tunnel,                                                 \
20702   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20703   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20704   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20705 _(l2tpv3_set_tunnel_cookies,                                            \
20706   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20707   "[new_remote_cookie <nn>]\n")                                         \
20708 _(l2tpv3_interface_enable_disable,                                      \
20709   "<intfc> | sw_if_index <nn> enable | disable")                        \
20710 _(l2tpv3_set_lookup_key,                                                \
20711   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20712 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20713 _(vxlan_offload_rx,                                                     \
20714   "hw { <interface name> | hw_if_index <nn>} "                          \
20715   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20716 _(vxlan_add_del_tunnel,                                                 \
20717   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20718   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20719   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20720 _(geneve_add_del_tunnel,                                                \
20721   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20722   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20723   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20724 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20725 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20726 _(gre_tunnel_add_del,                                                   \
20727   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20728   "[teb | erspan <session-id>] [del]")                                  \
20729 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20730 _(l2_fib_clear_table, "")                                               \
20731 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20732 _(l2_interface_vlan_tag_rewrite,                                        \
20733   "<intfc> | sw_if_index <nn> \n"                                       \
20734   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20735   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20736 _(create_vhost_user_if,                                                 \
20737         "socket <filename> [server] [renumber <dev_instance>] "         \
20738         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20739         "[mac <mac_address>] [packed]")                                 \
20740 _(modify_vhost_user_if,                                                 \
20741         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20742         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20743 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20744 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20745 _(show_version, "")                                                     \
20746 _(show_threads, "")                                                     \
20747 _(vxlan_gpe_add_del_tunnel,                                             \
20748   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20749   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20750   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20751   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20752 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20753 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20754 _(interface_name_renumber,                                              \
20755   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20756 _(input_acl_set_interface,                                              \
20757   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20758   "  [l2-table <nn>] [del]")                                            \
20759 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20760 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20761 _(ip_dump, "ipv4 | ipv6")                                               \
20762 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20763 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20764   "  spid_id <n> ")                                                     \
20765 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20766   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20767   "  integ_alg <alg> integ_key <hex>")                                  \
20768 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20769   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20770   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20771   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20772 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20773   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20774   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20775   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20776   "  [instance <n>]")     \
20777 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20778 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20779 _(delete_loopback,"sw_if_index <nn>")                                   \
20780 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20781 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20782 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20783 _(want_interface_events,  "enable|disable")                             \
20784 _(get_first_msg_id, "client <name>")                                    \
20785 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20786 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20787   "fib-id <nn> [ip4][ip6][default]")                                    \
20788 _(get_node_graph, " ")                                                  \
20789 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20790 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20791 _(ioam_disable, "")                                                     \
20792 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20793                             " sw_if_index <sw_if_index> p <priority> "  \
20794                             "w <weight>] [del]")                        \
20795 _(one_add_del_locator, "locator-set <locator_name> "                    \
20796                         "iface <intf> | sw_if_index <sw_if_index> "     \
20797                         "p <priority> w <weight> [del]")                \
20798 _(one_add_del_local_eid,"vni <vni> eid "                                \
20799                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20800                          "locator-set <locator_name> [del]"             \
20801                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20802 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20803 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20804 _(one_enable_disable, "enable|disable")                                 \
20805 _(one_map_register_enable_disable, "enable|disable")                    \
20806 _(one_map_register_fallback_threshold, "<value>")                       \
20807 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20808 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20809                                "[seid <seid>] "                         \
20810                                "rloc <locator> p <prio> "               \
20811                                "w <weight> [rloc <loc> ... ] "          \
20812                                "action <action> [del-all]")             \
20813 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20814                           "<local-eid>")                                \
20815 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20816 _(one_use_petr, "ip-address> | disable")                                \
20817 _(one_map_request_mode, "src-dst|dst-only")                             \
20818 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20819 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20820 _(one_locator_set_dump, "[local | remote]")                             \
20821 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20822 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20823                        "[local] | [remote]")                            \
20824 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20825 _(one_ndp_bd_get, "")                                                   \
20826 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20827 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20828 _(one_l2_arp_bd_get, "")                                                \
20829 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20830 _(one_stats_enable_disable, "enable|disable")                           \
20831 _(show_one_stats_enable_disable, "")                                    \
20832 _(one_eid_table_vni_dump, "")                                           \
20833 _(one_eid_table_map_dump, "l2|l3")                                      \
20834 _(one_map_resolver_dump, "")                                            \
20835 _(one_map_server_dump, "")                                              \
20836 _(one_adjacencies_get, "vni <vni>")                                     \
20837 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20838 _(show_one_rloc_probe_state, "")                                        \
20839 _(show_one_map_register_state, "")                                      \
20840 _(show_one_status, "")                                                  \
20841 _(one_stats_dump, "")                                                   \
20842 _(one_stats_flush, "")                                                  \
20843 _(one_get_map_request_itr_rlocs, "")                                    \
20844 _(one_map_register_set_ttl, "<ttl>")                                    \
20845 _(one_set_transport_protocol, "udp|api")                                \
20846 _(one_get_transport_protocol, "")                                       \
20847 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20848 _(one_show_xtr_mode, "")                                                \
20849 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20850 _(one_show_pitr_mode, "")                                               \
20851 _(one_enable_disable_petr_mode, "enable|disable")                       \
20852 _(one_show_petr_mode, "")                                               \
20853 _(show_one_nsh_mapping, "")                                             \
20854 _(show_one_pitr, "")                                                    \
20855 _(show_one_use_petr, "")                                                \
20856 _(show_one_map_request_mode, "")                                        \
20857 _(show_one_map_register_ttl, "")                                        \
20858 _(show_one_map_register_fallback_threshold, "")                         \
20859 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20860                             " sw_if_index <sw_if_index> p <priority> "  \
20861                             "w <weight>] [del]")                        \
20862 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20863                         "iface <intf> | sw_if_index <sw_if_index> "     \
20864                         "p <priority> w <weight> [del]")                \
20865 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20866                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20867                          "locator-set <locator_name> [del]"             \
20868                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20869 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20870 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20871 _(lisp_enable_disable, "enable|disable")                                \
20872 _(lisp_map_register_enable_disable, "enable|disable")                   \
20873 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20874 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20875                                "[seid <seid>] "                         \
20876                                "rloc <locator> p <prio> "               \
20877                                "w <weight> [rloc <loc> ... ] "          \
20878                                "action <action> [del-all]")             \
20879 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20880                           "<local-eid>")                                \
20881 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20882 _(lisp_use_petr, "<ip-address> | disable")                              \
20883 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20884 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20885 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20886 _(lisp_locator_set_dump, "[local | remote]")                            \
20887 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20888 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20889                        "[local] | [remote]")                            \
20890 _(lisp_eid_table_vni_dump, "")                                          \
20891 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20892 _(lisp_map_resolver_dump, "")                                           \
20893 _(lisp_map_server_dump, "")                                             \
20894 _(lisp_adjacencies_get, "vni <vni>")                                    \
20895 _(gpe_fwd_entry_vnis_get, "")                                           \
20896 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20897 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20898                                 "[table <table-id>]")                   \
20899 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20900 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20901 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20902 _(gpe_get_encap_mode, "")                                               \
20903 _(lisp_gpe_add_del_iface, "up|down")                                    \
20904 _(lisp_gpe_enable_disable, "enable|disable")                            \
20905 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20906   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20907 _(show_lisp_rloc_probe_state, "")                                       \
20908 _(show_lisp_map_register_state, "")                                     \
20909 _(show_lisp_status, "")                                                 \
20910 _(lisp_get_map_request_itr_rlocs, "")                                   \
20911 _(show_lisp_pitr, "")                                                   \
20912 _(show_lisp_use_petr, "")                                               \
20913 _(show_lisp_map_request_mode, "")                                       \
20914 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20915 _(af_packet_delete, "name <host interface name>")                       \
20916 _(af_packet_dump, "")                                                   \
20917 _(policer_add_del, "name <policer name> <params> [del]")                \
20918 _(policer_dump, "[name <policer name>]")                                \
20919 _(policer_classify_set_interface,                                       \
20920   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20921   "  [l2-table <nn>] [del]")                                            \
20922 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20923 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20924 _(mpls_table_dump, "")                                                  \
20925 _(mpls_route_dump, "table-id <ID>")                                     \
20926 _(classify_table_ids, "")                                               \
20927 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20928 _(classify_table_info, "table_id <nn>")                                 \
20929 _(classify_session_dump, "table_id <nn>")                               \
20930 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20931     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20932     "[template_interval <nn>] [udp_checksum]")                          \
20933 _(ipfix_exporter_dump, "")                                              \
20934 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20935 _(ipfix_classify_stream_dump, "")                                       \
20936 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20937 _(ipfix_classify_table_dump, "")                                        \
20938 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20939 _(sw_interface_span_dump, "[l2]")                                           \
20940 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20941 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20942 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20943 _(pg_enable_disable, "[stream <id>] disable")                           \
20944 _(ip_source_and_port_range_check_add_del,                               \
20945   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20946 _(ip_source_and_port_range_check_interface_add_del,                     \
20947   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20948   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20949 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20950 _(l2_interface_pbb_tag_rewrite,                                         \
20951   "<intfc> | sw_if_index <nn> \n"                                       \
20952   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20953   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20954 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20955 _(flow_classify_set_interface,                                          \
20956   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20957 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20958 _(ip_table_dump, "")                                                    \
20959 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20960 _(ip_mtable_dump, "")                                                   \
20961 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20962 _(feature_enable_disable, "arc_name <arc_name> "                        \
20963   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20964 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20965   "[enable | disable] ")                                                \
20966 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20967 "[disable]")                                                            \
20968 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20969   "mac <mac-address> [del]")                                            \
20970 _(l2_xconnect_dump, "")                                                 \
20971 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20972 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20973 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20974 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20975 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20976 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
20977   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
20978 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
20979 _(sock_init_shm, "size <nnn>")                                          \
20980 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
20981 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
20982   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
20983 _(session_rules_dump, "")                                               \
20984 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
20985 _(output_acl_set_interface,                                             \
20986   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20987   "  [l2-table <nn>] [del]")                                            \
20988 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
20989
20990 /* List of command functions, CLI names map directly to functions */
20991 #define foreach_cli_function                                    \
20992 _(comment, "usage: comment <ignore-rest-of-line>")              \
20993 _(dump_interface_table, "usage: dump_interface_table")          \
20994 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20995 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20996 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20997 _(dump_macro_table, "usage: dump_macro_table ")                 \
20998 _(dump_node_table, "usage: dump_node_table")                    \
20999 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21000 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21001 _(elog_disable, "usage: elog_disable")                          \
21002 _(elog_enable, "usage: elog_enable")                            \
21003 _(elog_save, "usage: elog_save <filename>")                     \
21004 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21005 _(echo, "usage: echo <message>")                                \
21006 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21007 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21008 _(help, "usage: help")                                          \
21009 _(q, "usage: quit")                                             \
21010 _(quit, "usage: quit")                                          \
21011 _(search_node_table, "usage: search_node_table <name>...")      \
21012 _(set, "usage: set <variable-name> <value>")                    \
21013 _(script, "usage: script <file-name>")                          \
21014 _(statseg, "usage: statseg")                                    \
21015 _(unset, "usage: unset <variable-name>")
21016
21017 #define _(N,n)                                  \
21018     static void vl_api_##n##_t_handler_uni      \
21019     (vl_api_##n##_t * mp)                       \
21020     {                                           \
21021         vat_main_t * vam = &vat_main;           \
21022         if (vam->json_output) {                 \
21023             vl_api_##n##_t_handler_json(mp);    \
21024         } else {                                \
21025             vl_api_##n##_t_handler(mp);         \
21026         }                                       \
21027     }
21028 foreach_vpe_api_reply_msg;
21029 #if VPP_API_TEST_BUILTIN == 0
21030 foreach_standalone_reply_msg;
21031 #endif
21032 #undef _
21033
21034 void
21035 vat_api_hookup (vat_main_t * vam)
21036 {
21037 #define _(N,n)                                                  \
21038     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21039                            vl_api_##n##_t_handler_uni,          \
21040                            vl_noop_handler,                     \
21041                            vl_api_##n##_t_endian,               \
21042                            vl_api_##n##_t_print,                \
21043                            sizeof(vl_api_##n##_t), 1);
21044   foreach_vpe_api_reply_msg;
21045 #if VPP_API_TEST_BUILTIN == 0
21046   foreach_standalone_reply_msg;
21047 #endif
21048 #undef _
21049
21050 #if (VPP_API_TEST_BUILTIN==0)
21051   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21052
21053   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21054
21055   vam->function_by_name = hash_create_string (0, sizeof (uword));
21056
21057   vam->help_by_name = hash_create_string (0, sizeof (uword));
21058 #endif
21059
21060   /* API messages we can send */
21061 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21062   foreach_vpe_api_msg;
21063 #undef _
21064
21065   /* Help strings */
21066 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21067   foreach_vpe_api_msg;
21068 #undef _
21069
21070   /* CLI functions */
21071 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21072   foreach_cli_function;
21073 #undef _
21074
21075   /* Help strings */
21076 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21077   foreach_cli_function;
21078 #undef _
21079 }
21080
21081 #if VPP_API_TEST_BUILTIN
21082 static clib_error_t *
21083 vat_api_hookup_shim (vlib_main_t * vm)
21084 {
21085   vat_api_hookup (&vat_main);
21086   return 0;
21087 }
21088
21089 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21090 #endif
21091
21092 /*
21093  * fd.io coding-style-patch-verification: ON
21094  *
21095  * Local Variables:
21096  * eval: (c-set-style "gnu")
21097  * End:
21098  */