VPP-1506: dump local punts and registered punt sockets
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/l2/l2_input.h>
28 #include <vnet/l2tp/l2tp.h>
29 #include <vnet/vxlan/vxlan.h>
30 #include <vnet/geneve/geneve.h>
31 #include <vnet/gre/gre.h>
32 #include <vnet/vxlan-gpe/vxlan_gpe.h>
33 #include <vnet/lisp-gpe/lisp_gpe.h>
34
35 #include <vpp/api/vpe_msg_enum.h>
36 #include <vnet/l2/l2_classify.h>
37 #include <vnet/l2/l2_vtr.h>
38 #include <vnet/classify/in_out_acl.h>
39 #include <vnet/classify/policer_classify.h>
40 #include <vnet/classify/flow_classify.h>
41 #include <vnet/mpls/mpls.h>
42 #include <vnet/ipsec/ipsec.h>
43 #include <vnet/ipsec/ikev2.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.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/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #define vl_print(handle, ...)
75 #define vl_printfun
76 #include <vpp/api/vpe_all_api_h.h>
77 #undef vl_printfun
78
79 #define __plugin_msg_base 0
80 #include <vlibapi/vat_helper_macros.h>
81
82 #if VPP_API_TEST_BUILTIN == 0
83 #include <netdb.h>
84
85 /* *INDENT-OFF* */
86 const mac_address_t ZERO_MAC_ADDRESS = {
87   .bytes = {
88     0, 0, 0, 0, 0, 0,
89   },
90 };
91 /* *INDENT-ON* */
92
93 u32
94 vl (void *p)
95 {
96   return vec_len (p);
97 }
98
99 int
100 vat_socket_connect (vat_main_t * vam)
101 {
102   vam->socket_client_main = &socket_client_main;
103   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
104                                    0 /* default socket rx, tx buffer */ );
105 }
106 #else /* vpp built-in case, we don't do sockets... */
107 int
108 vat_socket_connect (vat_main_t * vam)
109 {
110   return 0;
111 }
112
113 int
114 vl_socket_client_read (int wait)
115 {
116   return -1;
117 };
118
119 int
120 vl_socket_client_write ()
121 {
122   return -1;
123 };
124
125 void *
126 vl_socket_client_msg_alloc (int nbytes)
127 {
128   return 0;
129 }
130 #endif
131
132
133 f64
134 vat_time_now (vat_main_t * vam)
135 {
136 #if VPP_API_TEST_BUILTIN
137   return vlib_time_now (vam->vlib_main);
138 #else
139   return clib_time_now (&vam->clib_time);
140 #endif
141 }
142
143 void
144 errmsg (char *fmt, ...)
145 {
146   vat_main_t *vam = &vat_main;
147   va_list va;
148   u8 *s;
149
150   va_start (va, fmt);
151   s = va_format (0, fmt, &va);
152   va_end (va);
153
154   vec_add1 (s, 0);
155
156 #if VPP_API_TEST_BUILTIN
157   vlib_cli_output (vam->vlib_main, (char *) s);
158 #else
159   {
160     if (vam->ifp != stdin)
161       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
162                vam->input_line_number);
163     fformat (vam->ofp, (char *) s);
164     fflush (vam->ofp);
165   }
166 #endif
167
168   vec_free (s);
169 }
170
171 #if VPP_API_TEST_BUILTIN == 0
172 static uword
173 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
174 {
175   vat_main_t *vam = va_arg (*args, vat_main_t *);
176   u32 *result = va_arg (*args, u32 *);
177   u8 *if_name;
178   uword *p;
179
180   if (!unformat (input, "%s", &if_name))
181     return 0;
182
183   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
184   if (p == 0)
185     return 0;
186   *result = p[0];
187   return 1;
188 }
189
190 static uword
191 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
192 {
193   return 0;
194 }
195
196 /* Parse an IP4 address %d.%d.%d.%d. */
197 uword
198 unformat_ip4_address (unformat_input_t * input, va_list * args)
199 {
200   u8 *result = va_arg (*args, u8 *);
201   unsigned a[4];
202
203   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
204     return 0;
205
206   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
207     return 0;
208
209   result[0] = a[0];
210   result[1] = a[1];
211   result[2] = a[2];
212   result[3] = a[3];
213
214   return 1;
215 }
216
217 uword
218 unformat_ethernet_address (unformat_input_t * input, va_list * args)
219 {
220   u8 *result = va_arg (*args, u8 *);
221   u32 i, a[6];
222
223   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
224                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
225     return 0;
226
227   /* Check range. */
228   for (i = 0; i < 6; i++)
229     if (a[i] >= (1 << 8))
230       return 0;
231
232   for (i = 0; i < 6; i++)
233     result[i] = a[i];
234
235   return 1;
236 }
237
238 /* Returns ethernet type as an int in host byte order. */
239 uword
240 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
241                                         va_list * args)
242 {
243   u16 *result = va_arg (*args, u16 *);
244   int type;
245
246   /* Numeric type. */
247   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
248     {
249       if (type >= (1 << 16))
250         return 0;
251       *result = type;
252       return 1;
253     }
254   return 0;
255 }
256
257 /* Parse an IP6 address. */
258 uword
259 unformat_ip6_address (unformat_input_t * input, va_list * args)
260 {
261   ip6_address_t *result = va_arg (*args, ip6_address_t *);
262   u16 hex_quads[8];
263   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
264   uword c, n_colon, double_colon_index;
265
266   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
267   double_colon_index = ARRAY_LEN (hex_quads);
268   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
269     {
270       hex_digit = 16;
271       if (c >= '0' && c <= '9')
272         hex_digit = c - '0';
273       else if (c >= 'a' && c <= 'f')
274         hex_digit = c + 10 - 'a';
275       else if (c >= 'A' && c <= 'F')
276         hex_digit = c + 10 - 'A';
277       else if (c == ':' && n_colon < 2)
278         n_colon++;
279       else
280         {
281           unformat_put_input (input);
282           break;
283         }
284
285       /* Too many hex quads. */
286       if (n_hex_quads >= ARRAY_LEN (hex_quads))
287         return 0;
288
289       if (hex_digit < 16)
290         {
291           hex_quad = (hex_quad << 4) | hex_digit;
292
293           /* Hex quad must fit in 16 bits. */
294           if (n_hex_digits >= 4)
295             return 0;
296
297           n_colon = 0;
298           n_hex_digits++;
299         }
300
301       /* Save position of :: */
302       if (n_colon == 2)
303         {
304           /* More than one :: ? */
305           if (double_colon_index < ARRAY_LEN (hex_quads))
306             return 0;
307           double_colon_index = n_hex_quads;
308         }
309
310       if (n_colon > 0 && n_hex_digits > 0)
311         {
312           hex_quads[n_hex_quads++] = hex_quad;
313           hex_quad = 0;
314           n_hex_digits = 0;
315         }
316     }
317
318   if (n_hex_digits > 0)
319     hex_quads[n_hex_quads++] = hex_quad;
320
321   {
322     word i;
323
324     /* Expand :: to appropriate number of zero hex quads. */
325     if (double_colon_index < ARRAY_LEN (hex_quads))
326       {
327         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
328
329         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
330           hex_quads[n_zero + i] = hex_quads[i];
331
332         for (i = 0; i < n_zero; i++)
333           hex_quads[double_colon_index + i] = 0;
334
335         n_hex_quads = ARRAY_LEN (hex_quads);
336       }
337
338     /* Too few hex quads given. */
339     if (n_hex_quads < ARRAY_LEN (hex_quads))
340       return 0;
341
342     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
343       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
344
345     return 1;
346   }
347 }
348
349 uword
350 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
351 {
352   u32 *r = va_arg (*args, u32 *);
353
354   if (0);
355 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
356   foreach_ipsec_policy_action
357 #undef _
358     else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
370   foreach_ipsec_crypto_alg
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 u8 *
378 format_ipsec_crypto_alg (u8 * s, va_list * args)
379 {
380   u32 i = va_arg (*args, u32);
381   u8 *t = 0;
382
383   switch (i)
384     {
385 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
386       foreach_ipsec_crypto_alg
387 #undef _
388     default:
389       return format (s, "unknown");
390     }
391   return format (s, "%s", t);
392 }
393
394 uword
395 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
396 {
397   u32 *r = va_arg (*args, u32 *);
398
399   if (0);
400 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
401   foreach_ipsec_integ_alg
402 #undef _
403     else
404     return 0;
405   return 1;
406 }
407
408 u8 *
409 format_ipsec_integ_alg (u8 * s, va_list * args)
410 {
411   u32 i = va_arg (*args, u32);
412   u8 *t = 0;
413
414   switch (i)
415     {
416 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
417       foreach_ipsec_integ_alg
418 #undef _
419     default:
420       return format (s, "unknown");
421     }
422   return format (s, "%s", t);
423 }
424
425 uword
426 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
427 {
428   u32 *r = va_arg (*args, u32 *);
429
430   if (0);
431 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
432   foreach_ikev2_auth_method
433 #undef _
434     else
435     return 0;
436   return 1;
437 }
438
439 uword
440 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
441 {
442   u32 *r = va_arg (*args, u32 *);
443
444   if (0);
445 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
446   foreach_ikev2_id_type
447 #undef _
448     else
449     return 0;
450   return 1;
451 }
452 #else /* VPP_API_TEST_BUILTIN == 1 */
453 static uword
454 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
455 {
456   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
457   vnet_main_t *vnm = vnet_get_main ();
458   u32 *result = va_arg (*args, u32 *);
459
460   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
461 }
462
463 static uword
464 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
465 {
466   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
467   vnet_main_t *vnm = vnet_get_main ();
468   u32 *result = va_arg (*args, u32 *);
469
470   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
471 }
472
473 #endif /* VPP_API_TEST_BUILTIN */
474
475 static uword
476 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
477 {
478   u8 *r = va_arg (*args, u8 *);
479
480   if (unformat (input, "kbps"))
481     *r = SSE2_QOS_RATE_KBPS;
482   else if (unformat (input, "pps"))
483     *r = SSE2_QOS_RATE_PPS;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_policer_round_type (unformat_input_t * input, va_list * args)
491 {
492   u8 *r = va_arg (*args, u8 *);
493
494   if (unformat (input, "closest"))
495     *r = SSE2_QOS_ROUND_TO_CLOSEST;
496   else if (unformat (input, "up"))
497     *r = SSE2_QOS_ROUND_TO_UP;
498   else if (unformat (input, "down"))
499     *r = SSE2_QOS_ROUND_TO_DOWN;
500   else
501     return 0;
502   return 1;
503 }
504
505 static uword
506 unformat_policer_type (unformat_input_t * input, va_list * args)
507 {
508   u8 *r = va_arg (*args, u8 *);
509
510   if (unformat (input, "1r2c"))
511     *r = SSE2_QOS_POLICER_TYPE_1R2C;
512   else if (unformat (input, "1r3c"))
513     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
514   else if (unformat (input, "2r3c-2698"))
515     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
516   else if (unformat (input, "2r3c-4115"))
517     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
518   else if (unformat (input, "2r3c-mef5cf1"))
519     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
520   else
521     return 0;
522   return 1;
523 }
524
525 static uword
526 unformat_dscp (unformat_input_t * input, va_list * va)
527 {
528   u8 *r = va_arg (*va, u8 *);
529
530   if (0);
531 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
532   foreach_vnet_dscp
533 #undef _
534     else
535     return 0;
536   return 1;
537 }
538
539 static uword
540 unformat_policer_action_type (unformat_input_t * input, va_list * va)
541 {
542   sse2_qos_pol_action_params_st *a
543     = va_arg (*va, sse2_qos_pol_action_params_st *);
544
545   if (unformat (input, "drop"))
546     a->action_type = SSE2_QOS_ACTION_DROP;
547   else if (unformat (input, "transmit"))
548     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
549   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
550     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
551   else
552     return 0;
553   return 1;
554 }
555
556 static uword
557 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
558 {
559   u32 *r = va_arg (*va, u32 *);
560   u32 tid;
561
562   if (unformat (input, "ip4"))
563     tid = POLICER_CLASSIFY_TABLE_IP4;
564   else if (unformat (input, "ip6"))
565     tid = POLICER_CLASSIFY_TABLE_IP6;
566   else if (unformat (input, "l2"))
567     tid = POLICER_CLASSIFY_TABLE_L2;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 static uword
576 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
577 {
578   u32 *r = va_arg (*va, u32 *);
579   u32 tid;
580
581   if (unformat (input, "ip4"))
582     tid = FLOW_CLASSIFY_TABLE_IP4;
583   else if (unformat (input, "ip6"))
584     tid = FLOW_CLASSIFY_TABLE_IP6;
585   else
586     return 0;
587
588   *r = tid;
589   return 1;
590 }
591
592 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
593 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
594 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
595 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
596
597 #if (VPP_API_TEST_BUILTIN==0)
598 uword
599 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
600 {
601   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
602   mfib_itf_attribute_t attr;
603
604   old = *iflags;
605   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
606   {
607     if (unformat (input, mfib_itf_flag_long_names[attr]))
608       *iflags |= (1 << attr);
609   }
610   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_itf_flag_names[attr]))
613       *iflags |= (1 << attr);
614   }
615
616   return (old == *iflags ? 0 : 1);
617 }
618
619 uword
620 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
621 {
622   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
623   mfib_entry_attribute_t attr;
624
625   old = *eflags;
626   FOR_EACH_MFIB_ATTRIBUTE (attr)
627   {
628     if (unformat (input, mfib_flag_long_names[attr]))
629       *eflags |= (1 << attr);
630   }
631   FOR_EACH_MFIB_ATTRIBUTE (attr)
632   {
633     if (unformat (input, mfib_flag_names[attr]))
634       *eflags |= (1 << attr);
635   }
636
637   return (old == *eflags ? 0 : 1);
638 }
639
640 u8 *
641 format_ip4_address (u8 * s, va_list * args)
642 {
643   u8 *a = va_arg (*args, u8 *);
644   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
645 }
646
647 u8 *
648 format_ip6_address (u8 * s, va_list * args)
649 {
650   ip6_address_t *a = va_arg (*args, ip6_address_t *);
651   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
652
653   i_max_n_zero = ARRAY_LEN (a->as_u16);
654   max_n_zeros = 0;
655   i_first_zero = i_max_n_zero;
656   n_zeros = 0;
657   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
658     {
659       u32 is_zero = a->as_u16[i] == 0;
660       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
661         {
662           i_first_zero = i;
663           n_zeros = 0;
664         }
665       n_zeros += is_zero;
666       if ((!is_zero && n_zeros > max_n_zeros)
667           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
668         {
669           i_max_n_zero = i_first_zero;
670           max_n_zeros = n_zeros;
671           i_first_zero = ARRAY_LEN (a->as_u16);
672           n_zeros = 0;
673         }
674     }
675
676   last_double_colon = 0;
677   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
678     {
679       if (i == i_max_n_zero && max_n_zeros > 1)
680         {
681           s = format (s, "::");
682           i += max_n_zeros - 1;
683           last_double_colon = 1;
684         }
685       else
686         {
687           s = format (s, "%s%x",
688                       (last_double_colon || i == 0) ? "" : ":",
689                       clib_net_to_host_u16 (a->as_u16[i]));
690           last_double_colon = 0;
691         }
692     }
693
694   return s;
695 }
696
697 /* Format an IP46 address. */
698 u8 *
699 format_ip46_address (u8 * s, va_list * args)
700 {
701   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
702   ip46_type_t type = va_arg (*args, ip46_type_t);
703   int is_ip4 = 1;
704
705   switch (type)
706     {
707     case IP46_TYPE_ANY:
708       is_ip4 = ip46_address_is_ip4 (ip46);
709       break;
710     case IP46_TYPE_IP4:
711       is_ip4 = 1;
712       break;
713     case IP46_TYPE_IP6:
714       is_ip4 = 0;
715       break;
716     }
717
718   return is_ip4 ?
719     format (s, "%U", format_ip4_address, &ip46->ip4) :
720     format (s, "%U", format_ip6_address, &ip46->ip6);
721 }
722
723 u8 *
724 format_ethernet_address (u8 * s, va_list * args)
725 {
726   u8 *a = va_arg (*args, u8 *);
727
728   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
729                  a[0], a[1], a[2], a[3], a[4], a[5]);
730 }
731 #endif
732
733 static void
734 increment_v4_address (ip4_address_t * a)
735 {
736   u32 v;
737
738   v = ntohl (a->as_u32) + 1;
739   a->as_u32 = ntohl (v);
740 }
741
742 static void
743 increment_v6_address (ip6_address_t * a)
744 {
745   u64 v0, v1;
746
747   v0 = clib_net_to_host_u64 (a->as_u64[0]);
748   v1 = clib_net_to_host_u64 (a->as_u64[1]);
749
750   v1 += 1;
751   if (v1 == 0)
752     v0 += 1;
753   a->as_u64[0] = clib_net_to_host_u64 (v0);
754   a->as_u64[1] = clib_net_to_host_u64 (v1);
755 }
756
757 static void
758 increment_mac_address (u8 * mac)
759 {
760   u64 tmp = *((u64 *) mac);
761   tmp = clib_net_to_host_u64 (tmp);
762   tmp += 1 << 16;               /* skip unused (least significant) octets */
763   tmp = clib_host_to_net_u64 (tmp);
764
765   clib_memcpy (mac, &tmp, 6);
766 }
767
768 static void vl_api_create_loopback_reply_t_handler
769   (vl_api_create_loopback_reply_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   i32 retval = ntohl (mp->retval);
773
774   vam->retval = retval;
775   vam->regenerate_interface_table = 1;
776   vam->sw_if_index = ntohl (mp->sw_if_index);
777   vam->result_ready = 1;
778 }
779
780 static void vl_api_create_loopback_reply_t_handler_json
781   (vl_api_create_loopback_reply_t * mp)
782 {
783   vat_main_t *vam = &vat_main;
784   vat_json_node_t node;
785
786   vat_json_init_object (&node);
787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
788   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
789
790   vat_json_print (vam->ofp, &node);
791   vat_json_free (&node);
792   vam->retval = ntohl (mp->retval);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_loopback_instance_reply_t_handler
797   (vl_api_create_loopback_instance_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   i32 retval = ntohl (mp->retval);
801
802   vam->retval = retval;
803   vam->regenerate_interface_table = 1;
804   vam->sw_if_index = ntohl (mp->sw_if_index);
805   vam->result_ready = 1;
806 }
807
808 static void vl_api_create_loopback_instance_reply_t_handler_json
809   (vl_api_create_loopback_instance_reply_t * mp)
810 {
811   vat_main_t *vam = &vat_main;
812   vat_json_node_t node;
813
814   vat_json_init_object (&node);
815   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
816   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
817
818   vat_json_print (vam->ofp, &node);
819   vat_json_free (&node);
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_af_packet_create_reply_t_handler
825   (vl_api_af_packet_create_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_af_packet_create_reply_t_handler_json
837   (vl_api_af_packet_create_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848
849   vam->retval = ntohl (mp->retval);
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_create_vlan_subif_reply_t_handler
854   (vl_api_create_vlan_subif_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   i32 retval = ntohl (mp->retval);
858
859   vam->retval = retval;
860   vam->regenerate_interface_table = 1;
861   vam->sw_if_index = ntohl (mp->sw_if_index);
862   vam->result_ready = 1;
863 }
864
865 static void vl_api_create_vlan_subif_reply_t_handler_json
866   (vl_api_create_vlan_subif_reply_t * mp)
867 {
868   vat_main_t *vam = &vat_main;
869   vat_json_node_t node;
870
871   vat_json_init_object (&node);
872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875   vat_json_print (vam->ofp, &node);
876   vat_json_free (&node);
877
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_create_subif_reply_t_handler
883   (vl_api_create_subif_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->sw_if_index = ntohl (mp->sw_if_index);
891   vam->result_ready = 1;
892 }
893
894 static void vl_api_create_subif_reply_t_handler_json
895   (vl_api_create_subif_reply_t * mp)
896 {
897   vat_main_t *vam = &vat_main;
898   vat_json_node_t node;
899
900   vat_json_init_object (&node);
901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
902   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
903
904   vat_json_print (vam->ofp, &node);
905   vat_json_free (&node);
906
907   vam->retval = ntohl (mp->retval);
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_interface_name_renumber_reply_t_handler
912   (vl_api_interface_name_renumber_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   i32 retval = ntohl (mp->retval);
916
917   vam->retval = retval;
918   vam->regenerate_interface_table = 1;
919   vam->result_ready = 1;
920 }
921
922 static void vl_api_interface_name_renumber_reply_t_handler_json
923   (vl_api_interface_name_renumber_reply_t * mp)
924 {
925   vat_main_t *vam = &vat_main;
926   vat_json_node_t node;
927
928   vat_json_init_object (&node);
929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
930
931   vat_json_print (vam->ofp, &node);
932   vat_json_free (&node);
933
934   vam->retval = ntohl (mp->retval);
935   vam->result_ready = 1;
936 }
937
938 /*
939  * Special-case: build the interface table, maintain
940  * the next loopback sw_if_index vbl.
941  */
942 static void vl_api_sw_interface_details_t_handler
943   (vl_api_sw_interface_details_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   u8 *s = format (0, "%s%c", mp->interface_name, 0);
947
948   hash_set_mem (vam->sw_if_index_by_interface_name, s,
949                 ntohl (mp->sw_if_index));
950
951   /* In sub interface case, fill the sub interface table entry */
952   if (mp->sw_if_index != mp->sup_sw_if_index)
953     {
954       sw_interface_subif_t *sub = NULL;
955
956       vec_add2 (vam->sw_if_subif_table, sub, 1);
957
958       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
959       strncpy ((char *) sub->interface_name, (char *) s,
960                vec_len (sub->interface_name));
961       sub->sw_if_index = ntohl (mp->sw_if_index);
962       sub->sub_id = ntohl (mp->sub_id);
963
964       sub->sub_dot1ad = mp->sub_dot1ad;
965       sub->sub_number_of_tags = mp->sub_number_of_tags;
966       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
967       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
968       sub->sub_exact_match = mp->sub_exact_match;
969       sub->sub_default = mp->sub_default;
970       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
971       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
972
973       /* vlan tag rewrite */
974       sub->vtr_op = ntohl (mp->vtr_op);
975       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
976       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
977       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
978     }
979 }
980
981 static void vl_api_sw_interface_details_t_handler_json
982   (vl_api_sw_interface_details_t * mp)
983 {
984   vat_main_t *vam = &vat_main;
985   vat_json_node_t *node = NULL;
986
987   if (VAT_JSON_ARRAY != vam->json_tree.type)
988     {
989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
990       vat_json_init_array (&vam->json_tree);
991     }
992   node = vat_json_array_add (&vam->json_tree);
993
994   vat_json_init_object (node);
995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
996   vat_json_object_add_uint (node, "sup_sw_if_index",
997                             ntohl (mp->sup_sw_if_index));
998   vat_json_object_add_uint (node, "l2_address_length",
999                             ntohl (mp->l2_address_length));
1000   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1001                              sizeof (mp->l2_address));
1002   vat_json_object_add_string_copy (node, "interface_name",
1003                                    mp->interface_name);
1004   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1005   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1006   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1007   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1008   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1009   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1010   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1011   vat_json_object_add_uint (node, "sub_number_of_tags",
1012                             mp->sub_number_of_tags);
1013   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1014                             ntohs (mp->sub_outer_vlan_id));
1015   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1016                             ntohs (mp->sub_inner_vlan_id));
1017   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1018   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1019   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1020                             mp->sub_outer_vlan_id_any);
1021   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1022                             mp->sub_inner_vlan_id_any);
1023   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1024   vat_json_object_add_uint (node, "vtr_push_dot1q",
1025                             ntohl (mp->vtr_push_dot1q));
1026   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1027   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1028   if (mp->sub_dot1ah)
1029     {
1030       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1031                                        format (0, "%U",
1032                                                format_ethernet_address,
1033                                                &mp->b_dmac));
1034       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1035                                        format (0, "%U",
1036                                                format_ethernet_address,
1037                                                &mp->b_smac));
1038       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1039       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1040     }
1041 }
1042
1043 #if VPP_API_TEST_BUILTIN == 0
1044 static void vl_api_sw_interface_event_t_handler
1045   (vl_api_sw_interface_event_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   if (vam->interface_event_display)
1049     errmsg ("interface flags: sw_if_index %d %s %s",
1050             ntohl (mp->sw_if_index),
1051             mp->admin_up_down ? "admin-up" : "admin-down",
1052             mp->link_up_down ? "link-up" : "link-down");
1053 }
1054 #endif
1055
1056 static void vl_api_sw_interface_event_t_handler_json
1057   (vl_api_sw_interface_event_t * mp)
1058 {
1059   /* JSON output not supported */
1060 }
1061
1062 static void
1063 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067
1068   vam->retval = retval;
1069   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1070   vam->result_ready = 1;
1071 }
1072
1073 static void
1074 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1075 {
1076   vat_main_t *vam = &vat_main;
1077   vat_json_node_t node;
1078   api_main_t *am = &api_main;
1079   void *oldheap;
1080   u8 *reply;
1081
1082   vat_json_init_object (&node);
1083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1084   vat_json_object_add_uint (&node, "reply_in_shmem",
1085                             ntohl (mp->reply_in_shmem));
1086   /* Toss the shared-memory original... */
1087   pthread_mutex_lock (&am->vlib_rp->mutex);
1088   oldheap = svm_push_data_heap (am->vlib_rp);
1089
1090   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1091   vec_free (reply);
1092
1093   svm_pop_heap (oldheap);
1094   pthread_mutex_unlock (&am->vlib_rp->mutex);
1095
1096   vat_json_print (vam->ofp, &node);
1097   vat_json_free (&node);
1098
1099   vam->retval = ntohl (mp->retval);
1100   vam->result_ready = 1;
1101 }
1102
1103 static void
1104 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1105 {
1106   vat_main_t *vam = &vat_main;
1107   i32 retval = ntohl (mp->retval);
1108   u32 length = ntohl (mp->length);
1109
1110   vec_reset_length (vam->cmd_reply);
1111
1112   vam->retval = retval;
1113   if (retval == 0)
1114     {
1115       vec_validate (vam->cmd_reply, length);
1116       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1117       vam->cmd_reply[length] = 0;
1118     }
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   vat_json_node_t node;
1127
1128   vec_reset_length (vam->cmd_reply);
1129
1130   vat_json_init_object (&node);
1131   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1132   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1133
1134   vat_json_print (vam->ofp, &node);
1135   vat_json_free (&node);
1136
1137   vam->retval = ntohl (mp->retval);
1138   vam->result_ready = 1;
1139 }
1140
1141 static void vl_api_classify_add_del_table_reply_t_handler
1142   (vl_api_classify_add_del_table_reply_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   i32 retval = ntohl (mp->retval);
1146   if (vam->async_mode)
1147     {
1148       vam->async_errors += (retval < 0);
1149     }
1150   else
1151     {
1152       vam->retval = retval;
1153       if (retval == 0 &&
1154           ((mp->new_table_index != 0xFFFFFFFF) ||
1155            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1156            (mp->match_n_vectors != 0xFFFFFFFF)))
1157         /*
1158          * Note: this is just barely thread-safe, depends on
1159          * the main thread spinning waiting for an answer...
1160          */
1161         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1162                 ntohl (mp->new_table_index),
1163                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1164       vam->result_ready = 1;
1165     }
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler_json
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   vat_json_node_t node;
1173
1174   vat_json_init_object (&node);
1175   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1176   vat_json_object_add_uint (&node, "new_table_index",
1177                             ntohl (mp->new_table_index));
1178   vat_json_object_add_uint (&node, "skip_n_vectors",
1179                             ntohl (mp->skip_n_vectors));
1180   vat_json_object_add_uint (&node, "match_n_vectors",
1181                             ntohl (mp->match_n_vectors));
1182
1183   vat_json_print (vam->ofp, &node);
1184   vat_json_free (&node);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_get_node_index_reply_t_handler
1191   (vl_api_get_node_index_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0)
1203         errmsg ("node index %d", ntohl (mp->node_index));
1204       vam->result_ready = 1;
1205     }
1206 }
1207
1208 static void vl_api_get_node_index_reply_t_handler_json
1209   (vl_api_get_node_index_reply_t * mp)
1210 {
1211   vat_main_t *vam = &vat_main;
1212   vat_json_node_t node;
1213
1214   vat_json_init_object (&node);
1215   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1216   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void vl_api_get_next_index_reply_t_handler
1226   (vl_api_get_next_index_reply_t * mp)
1227 {
1228   vat_main_t *vam = &vat_main;
1229   i32 retval = ntohl (mp->retval);
1230   if (vam->async_mode)
1231     {
1232       vam->async_errors += (retval < 0);
1233     }
1234   else
1235     {
1236       vam->retval = retval;
1237       if (retval == 0)
1238         errmsg ("next node index %d", ntohl (mp->next_index));
1239       vam->result_ready = 1;
1240     }
1241 }
1242
1243 static void vl_api_get_next_index_reply_t_handler_json
1244   (vl_api_get_next_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   vat_json_node_t node;
1248
1249   vat_json_init_object (&node);
1250   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1251   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1252
1253   vat_json_print (vam->ofp, &node);
1254   vat_json_free (&node);
1255
1256   vam->retval = ntohl (mp->retval);
1257   vam->result_ready = 1;
1258 }
1259
1260 static void vl_api_add_node_next_reply_t_handler
1261   (vl_api_add_node_next_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   i32 retval = ntohl (mp->retval);
1265   if (vam->async_mode)
1266     {
1267       vam->async_errors += (retval < 0);
1268     }
1269   else
1270     {
1271       vam->retval = retval;
1272       if (retval == 0)
1273         errmsg ("next index %d", ntohl (mp->next_index));
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_add_node_next_reply_t_handler_json
1279   (vl_api_add_node_next_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   vat_json_node_t node;
1283
1284   vat_json_init_object (&node);
1285   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1286   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1287
1288   vat_json_print (vam->ofp, &node);
1289   vat_json_free (&node);
1290
1291   vam->retval = ntohl (mp->retval);
1292   vam->result_ready = 1;
1293 }
1294
1295 static void vl_api_show_version_reply_t_handler
1296   (vl_api_show_version_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   i32 retval = ntohl (mp->retval);
1300
1301   if (retval >= 0)
1302     {
1303       errmsg ("        program: %s", mp->program);
1304       errmsg ("        version: %s", mp->version);
1305       errmsg ("     build date: %s", mp->build_date);
1306       errmsg ("build directory: %s", mp->build_directory);
1307     }
1308   vam->retval = retval;
1309   vam->result_ready = 1;
1310 }
1311
1312 static void vl_api_show_version_reply_t_handler_json
1313   (vl_api_show_version_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   vat_json_node_t node;
1317
1318   vat_json_init_object (&node);
1319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1320   vat_json_object_add_string_copy (&node, "program", mp->program);
1321   vat_json_object_add_string_copy (&node, "version", mp->version);
1322   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1323   vat_json_object_add_string_copy (&node, "build_directory",
1324                                    mp->build_directory);
1325
1326   vat_json_print (vam->ofp, &node);
1327   vat_json_free (&node);
1328
1329   vam->retval = ntohl (mp->retval);
1330   vam->result_ready = 1;
1331 }
1332
1333 static void vl_api_show_threads_reply_t_handler
1334   (vl_api_show_threads_reply_t * mp)
1335 {
1336   vat_main_t *vam = &vat_main;
1337   i32 retval = ntohl (mp->retval);
1338   int i, count = 0;
1339
1340   if (retval >= 0)
1341     count = ntohl (mp->count);
1342
1343   for (i = 0; i < count; i++)
1344     print (vam->ofp,
1345            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1346            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1347            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1348            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1349            ntohl (mp->thread_data[i].cpu_socket));
1350
1351   vam->retval = retval;
1352   vam->result_ready = 1;
1353 }
1354
1355 static void vl_api_show_threads_reply_t_handler_json
1356   (vl_api_show_threads_reply_t * mp)
1357 {
1358   vat_main_t *vam = &vat_main;
1359   vat_json_node_t node;
1360   vl_api_thread_data_t *td;
1361   i32 retval = ntohl (mp->retval);
1362   int i, count = 0;
1363
1364   if (retval >= 0)
1365     count = ntohl (mp->count);
1366
1367   vat_json_init_object (&node);
1368   vat_json_object_add_int (&node, "retval", retval);
1369   vat_json_object_add_uint (&node, "count", count);
1370
1371   for (i = 0; i < count; i++)
1372     {
1373       td = &mp->thread_data[i];
1374       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1375       vat_json_object_add_string_copy (&node, "name", td->name);
1376       vat_json_object_add_string_copy (&node, "type", td->type);
1377       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1378       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1379       vat_json_object_add_int (&node, "core", ntohl (td->id));
1380       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1381     }
1382
1383   vat_json_print (vam->ofp, &node);
1384   vat_json_free (&node);
1385
1386   vam->retval = retval;
1387   vam->result_ready = 1;
1388 }
1389
1390 static int
1391 api_show_threads (vat_main_t * vam)
1392 {
1393   vl_api_show_threads_t *mp;
1394   int ret;
1395
1396   print (vam->ofp,
1397          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1398          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1399
1400   M (SHOW_THREADS, mp);
1401
1402   S (mp);
1403   W (ret);
1404   return ret;
1405 }
1406
1407 static void
1408 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1409 {
1410   u32 sw_if_index = ntohl (mp->sw_if_index);
1411   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1412           mp->mac_ip ? "mac/ip binding" : "address resolution",
1413           ntohl (mp->pid), format_ip4_address, &mp->address,
1414           format_ethernet_address, mp->new_mac, sw_if_index);
1415 }
1416
1417 static void
1418 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1419 {
1420   /* JSON output not supported */
1421 }
1422
1423 static void
1424 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1425 {
1426   u32 sw_if_index = ntohl (mp->sw_if_index);
1427   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1428           mp->mac_ip ? "mac/ip binding" : "address resolution",
1429           ntohl (mp->pid), format_ip6_address, mp->address,
1430           format_ethernet_address, mp->new_mac, sw_if_index);
1431 }
1432
1433 static void
1434 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1435 {
1436   /* JSON output not supported */
1437 }
1438
1439 static void
1440 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1441 {
1442   u32 n_macs = ntohl (mp->n_macs);
1443   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1444           ntohl (mp->pid), mp->client_index, n_macs);
1445   int i;
1446   for (i = 0; i < n_macs; i++)
1447     {
1448       vl_api_mac_entry_t *mac = &mp->mac[i];
1449       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1450               i + 1, ntohl (mac->sw_if_index),
1451               format_ethernet_address, mac->mac_addr, mac->action);
1452       if (i == 1000)
1453         break;
1454     }
1455 }
1456
1457 static void
1458 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1459 {
1460   /* JSON output not supported */
1461 }
1462
1463 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1464 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1465
1466 /*
1467  * Special-case: build the bridge domain table, maintain
1468  * the next bd id vbl.
1469  */
1470 static void vl_api_bridge_domain_details_t_handler
1471   (vl_api_bridge_domain_details_t * mp)
1472 {
1473   vat_main_t *vam = &vat_main;
1474   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1475   int i;
1476
1477   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1478          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1479
1480   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1481          ntohl (mp->bd_id), mp->learn, mp->forward,
1482          mp->flood, ntohl (mp->bvi_sw_if_index),
1483          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1484
1485   if (n_sw_ifs)
1486     {
1487       vl_api_bridge_domain_sw_if_t *sw_ifs;
1488       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1489              "Interface Name");
1490
1491       sw_ifs = mp->sw_if_details;
1492       for (i = 0; i < n_sw_ifs; i++)
1493         {
1494           u8 *sw_if_name = 0;
1495           u32 sw_if_index;
1496           hash_pair_t *p;
1497
1498           sw_if_index = ntohl (sw_ifs->sw_if_index);
1499
1500           /* *INDENT-OFF* */
1501           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1502                              ({
1503                                if ((u32) p->value[0] == sw_if_index)
1504                                  {
1505                                    sw_if_name = (u8 *)(p->key);
1506                                    break;
1507                                  }
1508                              }));
1509           /* *INDENT-ON* */
1510           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1511                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1512                  "sw_if_index not found!");
1513
1514           sw_ifs++;
1515         }
1516     }
1517 }
1518
1519 static void vl_api_bridge_domain_details_t_handler_json
1520   (vl_api_bridge_domain_details_t * mp)
1521 {
1522   vat_main_t *vam = &vat_main;
1523   vat_json_node_t *node, *array = NULL;
1524   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1525
1526   if (VAT_JSON_ARRAY != vam->json_tree.type)
1527     {
1528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1529       vat_json_init_array (&vam->json_tree);
1530     }
1531   node = vat_json_array_add (&vam->json_tree);
1532
1533   vat_json_init_object (node);
1534   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1535   vat_json_object_add_uint (node, "flood", mp->flood);
1536   vat_json_object_add_uint (node, "forward", mp->forward);
1537   vat_json_object_add_uint (node, "learn", mp->learn);
1538   vat_json_object_add_uint (node, "bvi_sw_if_index",
1539                             ntohl (mp->bvi_sw_if_index));
1540   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1541   array = vat_json_object_add (node, "sw_if");
1542   vat_json_init_array (array);
1543
1544
1545
1546   if (n_sw_ifs)
1547     {
1548       vl_api_bridge_domain_sw_if_t *sw_ifs;
1549       int i;
1550
1551       sw_ifs = mp->sw_if_details;
1552       for (i = 0; i < n_sw_ifs; i++)
1553         {
1554           node = vat_json_array_add (array);
1555           vat_json_init_object (node);
1556           vat_json_object_add_uint (node, "sw_if_index",
1557                                     ntohl (sw_ifs->sw_if_index));
1558           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1559           sw_ifs++;
1560         }
1561     }
1562 }
1563
1564 static void vl_api_control_ping_reply_t_handler
1565   (vl_api_control_ping_reply_t * mp)
1566 {
1567   vat_main_t *vam = &vat_main;
1568   i32 retval = ntohl (mp->retval);
1569   if (vam->async_mode)
1570     {
1571       vam->async_errors += (retval < 0);
1572     }
1573   else
1574     {
1575       vam->retval = retval;
1576       vam->result_ready = 1;
1577     }
1578   if (vam->socket_client_main)
1579     vam->socket_client_main->control_pings_outstanding--;
1580 }
1581
1582 static void vl_api_control_ping_reply_t_handler_json
1583   (vl_api_control_ping_reply_t * mp)
1584 {
1585   vat_main_t *vam = &vat_main;
1586   i32 retval = ntohl (mp->retval);
1587
1588   if (VAT_JSON_NONE != vam->json_tree.type)
1589     {
1590       vat_json_print (vam->ofp, &vam->json_tree);
1591       vat_json_free (&vam->json_tree);
1592       vam->json_tree.type = VAT_JSON_NONE;
1593     }
1594   else
1595     {
1596       /* just print [] */
1597       vat_json_init_array (&vam->json_tree);
1598       vat_json_print (vam->ofp, &vam->json_tree);
1599       vam->json_tree.type = VAT_JSON_NONE;
1600     }
1601
1602   vam->retval = retval;
1603   vam->result_ready = 1;
1604 }
1605
1606 static void
1607   vl_api_bridge_domain_set_mac_age_reply_t_handler
1608   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612   if (vam->async_mode)
1613     {
1614       vam->async_errors += (retval < 0);
1615     }
1616   else
1617     {
1618       vam->retval = retval;
1619       vam->result_ready = 1;
1620     }
1621 }
1622
1623 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1624   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1625 {
1626   vat_main_t *vam = &vat_main;
1627   vat_json_node_t node;
1628
1629   vat_json_init_object (&node);
1630   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1631
1632   vat_json_print (vam->ofp, &node);
1633   vat_json_free (&node);
1634
1635   vam->retval = ntohl (mp->retval);
1636   vam->result_ready = 1;
1637 }
1638
1639 static void
1640 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   i32 retval = ntohl (mp->retval);
1644   if (vam->async_mode)
1645     {
1646       vam->async_errors += (retval < 0);
1647     }
1648   else
1649     {
1650       vam->retval = retval;
1651       vam->result_ready = 1;
1652     }
1653 }
1654
1655 static void vl_api_l2_flags_reply_t_handler_json
1656   (vl_api_l2_flags_reply_t * mp)
1657 {
1658   vat_main_t *vam = &vat_main;
1659   vat_json_node_t node;
1660
1661   vat_json_init_object (&node);
1662   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1663   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1664                             ntohl (mp->resulting_feature_bitmap));
1665
1666   vat_json_print (vam->ofp, &node);
1667   vat_json_free (&node);
1668
1669   vam->retval = ntohl (mp->retval);
1670   vam->result_ready = 1;
1671 }
1672
1673 static void vl_api_bridge_flags_reply_t_handler
1674   (vl_api_bridge_flags_reply_t * mp)
1675 {
1676   vat_main_t *vam = &vat_main;
1677   i32 retval = ntohl (mp->retval);
1678   if (vam->async_mode)
1679     {
1680       vam->async_errors += (retval < 0);
1681     }
1682   else
1683     {
1684       vam->retval = retval;
1685       vam->result_ready = 1;
1686     }
1687 }
1688
1689 static void vl_api_bridge_flags_reply_t_handler_json
1690   (vl_api_bridge_flags_reply_t * mp)
1691 {
1692   vat_main_t *vam = &vat_main;
1693   vat_json_node_t node;
1694
1695   vat_json_init_object (&node);
1696   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1697   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1698                             ntohl (mp->resulting_feature_bitmap));
1699
1700   vat_json_print (vam->ofp, &node);
1701   vat_json_free (&node);
1702
1703   vam->retval = ntohl (mp->retval);
1704   vam->result_ready = 1;
1705 }
1706
1707 static void vl_api_tap_connect_reply_t_handler
1708   (vl_api_tap_connect_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   i32 retval = ntohl (mp->retval);
1712   if (vam->async_mode)
1713     {
1714       vam->async_errors += (retval < 0);
1715     }
1716   else
1717     {
1718       vam->retval = retval;
1719       vam->sw_if_index = ntohl (mp->sw_if_index);
1720       vam->result_ready = 1;
1721     }
1722
1723 }
1724
1725 static void vl_api_tap_connect_reply_t_handler_json
1726   (vl_api_tap_connect_reply_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   vat_json_node_t node;
1730
1731   vat_json_init_object (&node);
1732   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1733   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1734
1735   vat_json_print (vam->ofp, &node);
1736   vat_json_free (&node);
1737
1738   vam->retval = ntohl (mp->retval);
1739   vam->result_ready = 1;
1740
1741 }
1742
1743 static void
1744 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1745 {
1746   vat_main_t *vam = &vat_main;
1747   i32 retval = ntohl (mp->retval);
1748   if (vam->async_mode)
1749     {
1750       vam->async_errors += (retval < 0);
1751     }
1752   else
1753     {
1754       vam->retval = retval;
1755       vam->sw_if_index = ntohl (mp->sw_if_index);
1756       vam->result_ready = 1;
1757     }
1758 }
1759
1760 static void vl_api_tap_modify_reply_t_handler_json
1761   (vl_api_tap_modify_reply_t * mp)
1762 {
1763   vat_main_t *vam = &vat_main;
1764   vat_json_node_t node;
1765
1766   vat_json_init_object (&node);
1767   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1768   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1769
1770   vat_json_print (vam->ofp, &node);
1771   vat_json_free (&node);
1772
1773   vam->retval = ntohl (mp->retval);
1774   vam->result_ready = 1;
1775 }
1776
1777 static void
1778 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1779 {
1780   vat_main_t *vam = &vat_main;
1781   i32 retval = ntohl (mp->retval);
1782   if (vam->async_mode)
1783     {
1784       vam->async_errors += (retval < 0);
1785     }
1786   else
1787     {
1788       vam->retval = retval;
1789       vam->result_ready = 1;
1790     }
1791 }
1792
1793 static void vl_api_tap_delete_reply_t_handler_json
1794   (vl_api_tap_delete_reply_t * mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   vat_json_node_t node;
1798
1799   vat_json_init_object (&node);
1800   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1801
1802   vat_json_print (vam->ofp, &node);
1803   vat_json_free (&node);
1804
1805   vam->retval = ntohl (mp->retval);
1806   vam->result_ready = 1;
1807 }
1808
1809 static void
1810 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813   i32 retval = ntohl (mp->retval);
1814   if (vam->async_mode)
1815     {
1816       vam->async_errors += (retval < 0);
1817     }
1818   else
1819     {
1820       vam->retval = retval;
1821       vam->sw_if_index = ntohl (mp->sw_if_index);
1822       vam->result_ready = 1;
1823     }
1824
1825 }
1826
1827 static void vl_api_tap_create_v2_reply_t_handler_json
1828   (vl_api_tap_create_v2_reply_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   vat_json_node_t node;
1832
1833   vat_json_init_object (&node);
1834   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1835   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1836
1837   vat_json_print (vam->ofp, &node);
1838   vat_json_free (&node);
1839
1840   vam->retval = ntohl (mp->retval);
1841   vam->result_ready = 1;
1842
1843 }
1844
1845 static void
1846 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1847 {
1848   vat_main_t *vam = &vat_main;
1849   i32 retval = ntohl (mp->retval);
1850   if (vam->async_mode)
1851     {
1852       vam->async_errors += (retval < 0);
1853     }
1854   else
1855     {
1856       vam->retval = retval;
1857       vam->result_ready = 1;
1858     }
1859 }
1860
1861 static void vl_api_tap_delete_v2_reply_t_handler_json
1862   (vl_api_tap_delete_v2_reply_t * mp)
1863 {
1864   vat_main_t *vam = &vat_main;
1865   vat_json_node_t node;
1866
1867   vat_json_init_object (&node);
1868   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1869
1870   vat_json_print (vam->ofp, &node);
1871   vat_json_free (&node);
1872
1873   vam->retval = ntohl (mp->retval);
1874   vam->result_ready = 1;
1875 }
1876
1877 static void
1878 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1879 {
1880   vat_main_t *vam = &vat_main;
1881   i32 retval = ntohl (mp->retval);
1882
1883   if (vam->async_mode)
1884     {
1885       vam->async_errors += (retval < 0);
1886     }
1887   else
1888     {
1889       vam->retval = retval;
1890       vam->sw_if_index = ntohl (mp->sw_if_index);
1891       vam->result_ready = 1;
1892     }
1893 }
1894
1895 static void vl_api_bond_create_reply_t_handler_json
1896   (vl_api_bond_create_reply_t * mp)
1897 {
1898   vat_main_t *vam = &vat_main;
1899   vat_json_node_t node;
1900
1901   vat_json_init_object (&node);
1902   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1903   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1904
1905   vat_json_print (vam->ofp, &node);
1906   vat_json_free (&node);
1907
1908   vam->retval = ntohl (mp->retval);
1909   vam->result_ready = 1;
1910 }
1911
1912 static void
1913 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1914 {
1915   vat_main_t *vam = &vat_main;
1916   i32 retval = ntohl (mp->retval);
1917
1918   if (vam->async_mode)
1919     {
1920       vam->async_errors += (retval < 0);
1921     }
1922   else
1923     {
1924       vam->retval = retval;
1925       vam->result_ready = 1;
1926     }
1927 }
1928
1929 static void vl_api_bond_delete_reply_t_handler_json
1930   (vl_api_bond_delete_reply_t * mp)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   vat_json_node_t node;
1934
1935   vat_json_init_object (&node);
1936   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1937
1938   vat_json_print (vam->ofp, &node);
1939   vat_json_free (&node);
1940
1941   vam->retval = ntohl (mp->retval);
1942   vam->result_ready = 1;
1943 }
1944
1945 static void
1946 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   i32 retval = ntohl (mp->retval);
1950
1951   if (vam->async_mode)
1952     {
1953       vam->async_errors += (retval < 0);
1954     }
1955   else
1956     {
1957       vam->retval = retval;
1958       vam->result_ready = 1;
1959     }
1960 }
1961
1962 static void vl_api_bond_enslave_reply_t_handler_json
1963   (vl_api_bond_enslave_reply_t * mp)
1964 {
1965   vat_main_t *vam = &vat_main;
1966   vat_json_node_t node;
1967
1968   vat_json_init_object (&node);
1969   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1970
1971   vat_json_print (vam->ofp, &node);
1972   vat_json_free (&node);
1973
1974   vam->retval = ntohl (mp->retval);
1975   vam->result_ready = 1;
1976 }
1977
1978 static void
1979 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1980                                           mp)
1981 {
1982   vat_main_t *vam = &vat_main;
1983   i32 retval = ntohl (mp->retval);
1984
1985   if (vam->async_mode)
1986     {
1987       vam->async_errors += (retval < 0);
1988     }
1989   else
1990     {
1991       vam->retval = retval;
1992       vam->result_ready = 1;
1993     }
1994 }
1995
1996 static void vl_api_bond_detach_slave_reply_t_handler_json
1997   (vl_api_bond_detach_slave_reply_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vat_json_node_t node;
2001
2002   vat_json_init_object (&node);
2003   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2004
2005   vat_json_print (vam->ofp, &node);
2006   vat_json_free (&node);
2007
2008   vam->retval = ntohl (mp->retval);
2009   vam->result_ready = 1;
2010 }
2011
2012 static void vl_api_sw_interface_bond_details_t_handler
2013   (vl_api_sw_interface_bond_details_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016
2017   print (vam->ofp,
2018          "%-16s %-12d %-12U %-13U %-14u %-14u",
2019          mp->interface_name, ntohl (mp->sw_if_index),
2020          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2021          ntohl (mp->active_slaves), ntohl (mp->slaves));
2022 }
2023
2024 static void vl_api_sw_interface_bond_details_t_handler_json
2025   (vl_api_sw_interface_bond_details_t * mp)
2026 {
2027   vat_main_t *vam = &vat_main;
2028   vat_json_node_t *node = NULL;
2029
2030   if (VAT_JSON_ARRAY != vam->json_tree.type)
2031     {
2032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2033       vat_json_init_array (&vam->json_tree);
2034     }
2035   node = vat_json_array_add (&vam->json_tree);
2036
2037   vat_json_init_object (node);
2038   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2039   vat_json_object_add_string_copy (node, "interface_name",
2040                                    mp->interface_name);
2041   vat_json_object_add_uint (node, "mode", mp->mode);
2042   vat_json_object_add_uint (node, "load_balance", mp->lb);
2043   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2044   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2045 }
2046
2047 static int
2048 api_sw_interface_bond_dump (vat_main_t * vam)
2049 {
2050   vl_api_sw_interface_bond_dump_t *mp;
2051   vl_api_control_ping_t *mp_ping;
2052   int ret;
2053
2054   print (vam->ofp,
2055          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2056          "interface name", "sw_if_index", "mode", "load balance",
2057          "active slaves", "slaves");
2058
2059   /* Get list of bond interfaces */
2060   M (SW_INTERFACE_BOND_DUMP, mp);
2061   S (mp);
2062
2063   /* Use a control ping for synchronization */
2064   MPING (CONTROL_PING, mp_ping);
2065   S (mp_ping);
2066
2067   W (ret);
2068   return ret;
2069 }
2070
2071 static void vl_api_sw_interface_slave_details_t_handler
2072   (vl_api_sw_interface_slave_details_t * mp)
2073 {
2074   vat_main_t *vam = &vat_main;
2075
2076   print (vam->ofp,
2077          "%-25s %-12d %-12d %d", mp->interface_name,
2078          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2079 }
2080
2081 static void vl_api_sw_interface_slave_details_t_handler_json
2082   (vl_api_sw_interface_slave_details_t * mp)
2083 {
2084   vat_main_t *vam = &vat_main;
2085   vat_json_node_t *node = NULL;
2086
2087   if (VAT_JSON_ARRAY != vam->json_tree.type)
2088     {
2089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2090       vat_json_init_array (&vam->json_tree);
2091     }
2092   node = vat_json_array_add (&vam->json_tree);
2093
2094   vat_json_init_object (node);
2095   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2096   vat_json_object_add_string_copy (node, "interface_name",
2097                                    mp->interface_name);
2098   vat_json_object_add_uint (node, "passive", mp->is_passive);
2099   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2100 }
2101
2102 static int
2103 api_sw_interface_slave_dump (vat_main_t * vam)
2104 {
2105   unformat_input_t *i = vam->input;
2106   vl_api_sw_interface_slave_dump_t *mp;
2107   vl_api_control_ping_t *mp_ping;
2108   u32 sw_if_index = ~0;
2109   u8 sw_if_index_set = 0;
2110   int ret;
2111
2112   /* Parse args required to build the message */
2113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2114     {
2115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2116         sw_if_index_set = 1;
2117       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2118         sw_if_index_set = 1;
2119       else
2120         break;
2121     }
2122
2123   if (sw_if_index_set == 0)
2124     {
2125       errmsg ("missing vpp interface name. ");
2126       return -99;
2127     }
2128
2129   print (vam->ofp,
2130          "\n%-25s %-12s %-12s %s",
2131          "slave interface name", "sw_if_index", "passive", "long_timeout");
2132
2133   /* Get list of bond interfaces */
2134   M (SW_INTERFACE_SLAVE_DUMP, mp);
2135   mp->sw_if_index = ntohl (sw_if_index);
2136   S (mp);
2137
2138   /* Use a control ping for synchronization */
2139   MPING (CONTROL_PING, mp_ping);
2140   S (mp_ping);
2141
2142   W (ret);
2143   return ret;
2144 }
2145
2146 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2147   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2148 {
2149   vat_main_t *vam = &vat_main;
2150   i32 retval = ntohl (mp->retval);
2151   if (vam->async_mode)
2152     {
2153       vam->async_errors += (retval < 0);
2154     }
2155   else
2156     {
2157       vam->retval = retval;
2158       vam->sw_if_index = ntohl (mp->sw_if_index);
2159       vam->result_ready = 1;
2160     }
2161   vam->regenerate_interface_table = 1;
2162 }
2163
2164 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2165   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vat_json_node_t node;
2169
2170   vat_json_init_object (&node);
2171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2172   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2173                             ntohl (mp->sw_if_index));
2174
2175   vat_json_print (vam->ofp, &node);
2176   vat_json_free (&node);
2177
2178   vam->retval = ntohl (mp->retval);
2179   vam->result_ready = 1;
2180 }
2181
2182 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2183   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   i32 retval = ntohl (mp->retval);
2187   if (vam->async_mode)
2188     {
2189       vam->async_errors += (retval < 0);
2190     }
2191   else
2192     {
2193       vam->retval = retval;
2194       vam->sw_if_index = ntohl (mp->sw_if_index);
2195       vam->result_ready = 1;
2196     }
2197 }
2198
2199 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2200   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vat_json_node_t node;
2204
2205   vat_json_init_object (&node);
2206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2207   vat_json_object_add_uint (&node, "sw_if_index", 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_gpe_add_del_fwd_entry_reply_t_handler
2217   (vl_api_gpe_add_del_fwd_entry_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->result_ready = 1;
2229     }
2230 }
2231
2232 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2233   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   vat_json_node_t node;
2237
2238   vat_json_init_object (&node);
2239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2240   vat_json_object_add_uint (&node, "fwd_entry_index",
2241                             clib_net_to_host_u32 (mp->fwd_entry_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 u8 *
2251 format_lisp_transport_protocol (u8 * s, va_list * args)
2252 {
2253   u32 proto = va_arg (*args, u32);
2254
2255   switch (proto)
2256     {
2257     case 1:
2258       return format (s, "udp");
2259     case 2:
2260       return format (s, "api");
2261     default:
2262       return 0;
2263     }
2264   return 0;
2265 }
2266
2267 static void vl_api_one_get_transport_protocol_reply_t_handler
2268   (vl_api_one_get_transport_protocol_reply_t * mp)
2269 {
2270   vat_main_t *vam = &vat_main;
2271   i32 retval = ntohl (mp->retval);
2272   if (vam->async_mode)
2273     {
2274       vam->async_errors += (retval < 0);
2275     }
2276   else
2277     {
2278       u32 proto = mp->protocol;
2279       print (vam->ofp, "Transport protocol: %U",
2280              format_lisp_transport_protocol, proto);
2281       vam->retval = retval;
2282       vam->result_ready = 1;
2283     }
2284 }
2285
2286 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2287   (vl_api_one_get_transport_protocol_reply_t * mp)
2288 {
2289   vat_main_t *vam = &vat_main;
2290   vat_json_node_t node;
2291   u8 *s;
2292
2293   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2294   vec_add1 (s, 0);
2295
2296   vat_json_init_object (&node);
2297   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2298   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2299
2300   vec_free (s);
2301   vat_json_print (vam->ofp, &node);
2302   vat_json_free (&node);
2303
2304   vam->retval = ntohl (mp->retval);
2305   vam->result_ready = 1;
2306 }
2307
2308 static void vl_api_one_add_del_locator_set_reply_t_handler
2309   (vl_api_one_add_del_locator_set_reply_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   i32 retval = ntohl (mp->retval);
2313   if (vam->async_mode)
2314     {
2315       vam->async_errors += (retval < 0);
2316     }
2317   else
2318     {
2319       vam->retval = retval;
2320       vam->result_ready = 1;
2321     }
2322 }
2323
2324 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2325   (vl_api_one_add_del_locator_set_reply_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t node;
2329
2330   vat_json_init_object (&node);
2331   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2332   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2333
2334   vat_json_print (vam->ofp, &node);
2335   vat_json_free (&node);
2336
2337   vam->retval = ntohl (mp->retval);
2338   vam->result_ready = 1;
2339 }
2340
2341 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2342   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   i32 retval = ntohl (mp->retval);
2346   if (vam->async_mode)
2347     {
2348       vam->async_errors += (retval < 0);
2349     }
2350   else
2351     {
2352       vam->retval = retval;
2353       vam->sw_if_index = ntohl (mp->sw_if_index);
2354       vam->result_ready = 1;
2355     }
2356   vam->regenerate_interface_table = 1;
2357 }
2358
2359 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2360   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   vat_json_node_t node;
2364
2365   vat_json_init_object (&node);
2366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2368
2369   vat_json_print (vam->ofp, &node);
2370   vat_json_free (&node);
2371
2372   vam->retval = ntohl (mp->retval);
2373   vam->result_ready = 1;
2374 }
2375
2376 static void vl_api_vxlan_offload_rx_reply_t_handler
2377   (vl_api_vxlan_offload_rx_reply_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   i32 retval = ntohl (mp->retval);
2381   if (vam->async_mode)
2382     {
2383       vam->async_errors += (retval < 0);
2384     }
2385   else
2386     {
2387       vam->retval = retval;
2388       vam->result_ready = 1;
2389     }
2390 }
2391
2392 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2393   (vl_api_vxlan_offload_rx_reply_t * mp)
2394 {
2395   vat_main_t *vam = &vat_main;
2396   vat_json_node_t node;
2397
2398   vat_json_init_object (&node);
2399   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2400
2401   vat_json_print (vam->ofp, &node);
2402   vat_json_free (&node);
2403
2404   vam->retval = ntohl (mp->retval);
2405   vam->result_ready = 1;
2406 }
2407
2408 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2409   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   i32 retval = ntohl (mp->retval);
2413   if (vam->async_mode)
2414     {
2415       vam->async_errors += (retval < 0);
2416     }
2417   else
2418     {
2419       vam->retval = retval;
2420       vam->sw_if_index = ntohl (mp->sw_if_index);
2421       vam->result_ready = 1;
2422     }
2423 }
2424
2425 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2426   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   vat_json_node_t node;
2430
2431   vat_json_init_object (&node);
2432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2433   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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_vxlan_gpe_add_del_tunnel_reply_t_handler
2443   (vl_api_vxlan_gpe_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   vam->regenerate_interface_table = 1;
2458 }
2459
2460 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2461   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464   vat_json_node_t node;
2465
2466   vat_json_init_object (&node);
2467   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2468   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void vl_api_gre_add_del_tunnel_reply_t_handler
2478   (vl_api_gre_add_del_tunnel_reply_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   i32 retval = ntohl (mp->retval);
2482   if (vam->async_mode)
2483     {
2484       vam->async_errors += (retval < 0);
2485     }
2486   else
2487     {
2488       vam->retval = retval;
2489       vam->sw_if_index = ntohl (mp->sw_if_index);
2490       vam->result_ready = 1;
2491     }
2492 }
2493
2494 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2495   (vl_api_gre_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_create_vhost_user_if_reply_t_handler
2512   (vl_api_create_vhost_user_if_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   vam->regenerate_interface_table = 1;
2527 }
2528
2529 static void vl_api_create_vhost_user_if_reply_t_handler_json
2530   (vl_api_create_vhost_user_if_reply_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   vat_json_node_t node;
2534
2535   vat_json_init_object (&node);
2536   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2537   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2538
2539   vat_json_print (vam->ofp, &node);
2540   vat_json_free (&node);
2541
2542   vam->retval = ntohl (mp->retval);
2543   vam->result_ready = 1;
2544 }
2545
2546 static void vl_api_dns_resolve_name_reply_t_handler
2547   (vl_api_dns_resolve_name_reply_t * mp)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   i32 retval = ntohl (mp->retval);
2551   if (vam->async_mode)
2552     {
2553       vam->async_errors += (retval < 0);
2554     }
2555   else
2556     {
2557       vam->retval = retval;
2558       vam->result_ready = 1;
2559
2560       if (retval == 0)
2561         {
2562           if (mp->ip4_set)
2563             clib_warning ("ip4 address %U", format_ip4_address,
2564                           (ip4_address_t *) mp->ip4_address);
2565           if (mp->ip6_set)
2566             clib_warning ("ip6 address %U", format_ip6_address,
2567                           (ip6_address_t *) mp->ip6_address);
2568         }
2569       else
2570         clib_warning ("retval %d", retval);
2571     }
2572 }
2573
2574 static void vl_api_dns_resolve_name_reply_t_handler_json
2575   (vl_api_dns_resolve_name_reply_t * mp)
2576 {
2577   clib_warning ("not implemented");
2578 }
2579
2580 static void vl_api_dns_resolve_ip_reply_t_handler
2581   (vl_api_dns_resolve_ip_reply_t * mp)
2582 {
2583   vat_main_t *vam = &vat_main;
2584   i32 retval = ntohl (mp->retval);
2585   if (vam->async_mode)
2586     {
2587       vam->async_errors += (retval < 0);
2588     }
2589   else
2590     {
2591       vam->retval = retval;
2592       vam->result_ready = 1;
2593
2594       if (retval == 0)
2595         {
2596           clib_warning ("canonical name %s", mp->name);
2597         }
2598       else
2599         clib_warning ("retval %d", retval);
2600     }
2601 }
2602
2603 static void vl_api_dns_resolve_ip_reply_t_handler_json
2604   (vl_api_dns_resolve_ip_reply_t * mp)
2605 {
2606   clib_warning ("not implemented");
2607 }
2608
2609
2610 static void vl_api_ip_address_details_t_handler
2611   (vl_api_ip_address_details_t * mp)
2612 {
2613   vat_main_t *vam = &vat_main;
2614   static ip_address_details_t empty_ip_address_details = { {0} };
2615   ip_address_details_t *address = NULL;
2616   ip_details_t *current_ip_details = NULL;
2617   ip_details_t *details = NULL;
2618
2619   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2620
2621   if (!details || vam->current_sw_if_index >= vec_len (details)
2622       || !details[vam->current_sw_if_index].present)
2623     {
2624       errmsg ("ip address details arrived but not stored");
2625       errmsg ("ip_dump should be called first");
2626       return;
2627     }
2628
2629   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2630
2631 #define addresses (current_ip_details->addr)
2632
2633   vec_validate_init_empty (addresses, vec_len (addresses),
2634                            empty_ip_address_details);
2635
2636   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2637
2638   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2639   address->prefix_length = mp->prefix_length;
2640 #undef addresses
2641 }
2642
2643 static void vl_api_ip_address_details_t_handler_json
2644   (vl_api_ip_address_details_t * mp)
2645 {
2646   vat_main_t *vam = &vat_main;
2647   vat_json_node_t *node = NULL;
2648   struct in6_addr ip6;
2649   struct in_addr ip4;
2650
2651   if (VAT_JSON_ARRAY != vam->json_tree.type)
2652     {
2653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2654       vat_json_init_array (&vam->json_tree);
2655     }
2656   node = vat_json_array_add (&vam->json_tree);
2657
2658   vat_json_init_object (node);
2659   if (vam->is_ipv6)
2660     {
2661       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2662       vat_json_object_add_ip6 (node, "ip", ip6);
2663     }
2664   else
2665     {
2666       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2667       vat_json_object_add_ip4 (node, "ip", ip4);
2668     }
2669   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2670 }
2671
2672 static void
2673 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2674 {
2675   vat_main_t *vam = &vat_main;
2676   static ip_details_t empty_ip_details = { 0 };
2677   ip_details_t *ip = NULL;
2678   u32 sw_if_index = ~0;
2679
2680   sw_if_index = ntohl (mp->sw_if_index);
2681
2682   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2683                            sw_if_index, empty_ip_details);
2684
2685   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2686                          sw_if_index);
2687
2688   ip->present = 1;
2689 }
2690
2691 static void
2692 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695
2696   if (VAT_JSON_ARRAY != vam->json_tree.type)
2697     {
2698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2699       vat_json_init_array (&vam->json_tree);
2700     }
2701   vat_json_array_add_uint (&vam->json_tree,
2702                            clib_net_to_host_u32 (mp->sw_if_index));
2703 }
2704
2705 static void
2706 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2707 {
2708   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2709           "router_addr %U host_mac %U",
2710           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2711           mp->lease.hostname,
2712           format_ip4_address, &mp->lease.host_address,
2713           format_ip4_address, &mp->lease.router_address,
2714           format_ethernet_address, mp->lease.host_mac);
2715 }
2716
2717 static void vl_api_dhcp_compl_event_t_handler_json
2718   (vl_api_dhcp_compl_event_t * mp)
2719 {
2720   /* JSON output not supported */
2721 }
2722
2723 static void
2724 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2725                               u32 counter)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   static u64 default_counter = 0;
2729
2730   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2731                            NULL);
2732   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2733                            sw_if_index, default_counter);
2734   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2735 }
2736
2737 static void
2738 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2739                                 interface_counter_t counter)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   static interface_counter_t default_counter = { 0, };
2743
2744   vec_validate_init_empty (vam->combined_interface_counters,
2745                            vnet_counter_type, NULL);
2746   vec_validate_init_empty (vam->combined_interface_counters
2747                            [vnet_counter_type], sw_if_index, default_counter);
2748   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2749 }
2750
2751 static void vl_api_vnet_interface_simple_counters_t_handler
2752   (vl_api_vnet_interface_simple_counters_t * mp)
2753 {
2754   /* not supported */
2755 }
2756
2757 static void vl_api_vnet_interface_combined_counters_t_handler
2758   (vl_api_vnet_interface_combined_counters_t * mp)
2759 {
2760   /* not supported */
2761 }
2762
2763 static void vl_api_vnet_interface_simple_counters_t_handler_json
2764   (vl_api_vnet_interface_simple_counters_t * mp)
2765 {
2766   u64 *v_packets;
2767   u64 packets;
2768   u32 count;
2769   u32 first_sw_if_index;
2770   int i;
2771
2772   count = ntohl (mp->count);
2773   first_sw_if_index = ntohl (mp->first_sw_if_index);
2774
2775   v_packets = (u64 *) & mp->data;
2776   for (i = 0; i < count; i++)
2777     {
2778       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2779       set_simple_interface_counter (mp->vnet_counter_type,
2780                                     first_sw_if_index + i, packets);
2781       v_packets++;
2782     }
2783 }
2784
2785 static void vl_api_vnet_interface_combined_counters_t_handler_json
2786   (vl_api_vnet_interface_combined_counters_t * mp)
2787 {
2788   interface_counter_t counter;
2789   vlib_counter_t *v;
2790   u32 first_sw_if_index;
2791   int i;
2792   u32 count;
2793
2794   count = ntohl (mp->count);
2795   first_sw_if_index = ntohl (mp->first_sw_if_index);
2796
2797   v = (vlib_counter_t *) & mp->data;
2798   for (i = 0; i < count; i++)
2799     {
2800       counter.packets =
2801         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2802       counter.bytes =
2803         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2804       set_combined_interface_counter (mp->vnet_counter_type,
2805                                       first_sw_if_index + i, counter);
2806       v++;
2807     }
2808 }
2809
2810 static u32
2811 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2812 {
2813   vat_main_t *vam = &vat_main;
2814   u32 i;
2815
2816   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2817     {
2818       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2819         {
2820           return i;
2821         }
2822     }
2823   return ~0;
2824 }
2825
2826 static u32
2827 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   u32 i;
2831
2832   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2833     {
2834       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2835         {
2836           return i;
2837         }
2838     }
2839   return ~0;
2840 }
2841
2842 static void vl_api_vnet_ip4_fib_counters_t_handler
2843   (vl_api_vnet_ip4_fib_counters_t * mp)
2844 {
2845   /* not supported */
2846 }
2847
2848 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2849   (vl_api_vnet_ip4_fib_counters_t * mp)
2850 {
2851   vat_main_t *vam = &vat_main;
2852   vl_api_ip4_fib_counter_t *v;
2853   ip4_fib_counter_t *counter;
2854   struct in_addr ip4;
2855   u32 vrf_id;
2856   u32 vrf_index;
2857   u32 count;
2858   int i;
2859
2860   vrf_id = ntohl (mp->vrf_id);
2861   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2862   if (~0 == vrf_index)
2863     {
2864       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2865       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2866       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2867       vec_validate (vam->ip4_fib_counters, vrf_index);
2868       vam->ip4_fib_counters[vrf_index] = NULL;
2869     }
2870
2871   vec_free (vam->ip4_fib_counters[vrf_index]);
2872   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2873   count = ntohl (mp->count);
2874   for (i = 0; i < count; i++)
2875     {
2876       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2877       counter = &vam->ip4_fib_counters[vrf_index][i];
2878       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2879       counter->address = ip4;
2880       counter->address_length = v->address_length;
2881       counter->packets = clib_net_to_host_u64 (v->packets);
2882       counter->bytes = clib_net_to_host_u64 (v->bytes);
2883       v++;
2884     }
2885 }
2886
2887 static void vl_api_vnet_ip4_nbr_counters_t_handler
2888   (vl_api_vnet_ip4_nbr_counters_t * mp)
2889 {
2890   /* not supported */
2891 }
2892
2893 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2894   (vl_api_vnet_ip4_nbr_counters_t * mp)
2895 {
2896   vat_main_t *vam = &vat_main;
2897   vl_api_ip4_nbr_counter_t *v;
2898   ip4_nbr_counter_t *counter;
2899   u32 sw_if_index;
2900   u32 count;
2901   int i;
2902
2903   sw_if_index = ntohl (mp->sw_if_index);
2904   count = ntohl (mp->count);
2905   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2906
2907   if (mp->begin)
2908     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2909
2910   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2911   for (i = 0; i < count; i++)
2912     {
2913       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2914       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2915       counter->address.s_addr = v->address;
2916       counter->packets = clib_net_to_host_u64 (v->packets);
2917       counter->bytes = clib_net_to_host_u64 (v->bytes);
2918       counter->linkt = v->link_type;
2919       v++;
2920     }
2921 }
2922
2923 static void vl_api_vnet_ip6_fib_counters_t_handler
2924   (vl_api_vnet_ip6_fib_counters_t * mp)
2925 {
2926   /* not supported */
2927 }
2928
2929 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2930   (vl_api_vnet_ip6_fib_counters_t * mp)
2931 {
2932   vat_main_t *vam = &vat_main;
2933   vl_api_ip6_fib_counter_t *v;
2934   ip6_fib_counter_t *counter;
2935   struct in6_addr ip6;
2936   u32 vrf_id;
2937   u32 vrf_index;
2938   u32 count;
2939   int i;
2940
2941   vrf_id = ntohl (mp->vrf_id);
2942   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2943   if (~0 == vrf_index)
2944     {
2945       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2946       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2947       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2948       vec_validate (vam->ip6_fib_counters, vrf_index);
2949       vam->ip6_fib_counters[vrf_index] = NULL;
2950     }
2951
2952   vec_free (vam->ip6_fib_counters[vrf_index]);
2953   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2954   count = ntohl (mp->count);
2955   for (i = 0; i < count; i++)
2956     {
2957       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2958       counter = &vam->ip6_fib_counters[vrf_index][i];
2959       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2960       counter->address = ip6;
2961       counter->address_length = v->address_length;
2962       counter->packets = clib_net_to_host_u64 (v->packets);
2963       counter->bytes = clib_net_to_host_u64 (v->bytes);
2964       v++;
2965     }
2966 }
2967
2968 static void vl_api_vnet_ip6_nbr_counters_t_handler
2969   (vl_api_vnet_ip6_nbr_counters_t * mp)
2970 {
2971   /* not supported */
2972 }
2973
2974 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2975   (vl_api_vnet_ip6_nbr_counters_t * mp)
2976 {
2977   vat_main_t *vam = &vat_main;
2978   vl_api_ip6_nbr_counter_t *v;
2979   ip6_nbr_counter_t *counter;
2980   struct in6_addr ip6;
2981   u32 sw_if_index;
2982   u32 count;
2983   int i;
2984
2985   sw_if_index = ntohl (mp->sw_if_index);
2986   count = ntohl (mp->count);
2987   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2988
2989   if (mp->begin)
2990     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2991
2992   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2993   for (i = 0; i < count; i++)
2994     {
2995       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2996       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2997       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2998       counter->address = ip6;
2999       counter->packets = clib_net_to_host_u64 (v->packets);
3000       counter->bytes = clib_net_to_host_u64 (v->bytes);
3001       v++;
3002     }
3003 }
3004
3005 static void vl_api_get_first_msg_id_reply_t_handler
3006   (vl_api_get_first_msg_id_reply_t * mp)
3007 {
3008   vat_main_t *vam = &vat_main;
3009   i32 retval = ntohl (mp->retval);
3010
3011   if (vam->async_mode)
3012     {
3013       vam->async_errors += (retval < 0);
3014     }
3015   else
3016     {
3017       vam->retval = retval;
3018       vam->result_ready = 1;
3019     }
3020   if (retval >= 0)
3021     {
3022       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3023     }
3024 }
3025
3026 static void vl_api_get_first_msg_id_reply_t_handler_json
3027   (vl_api_get_first_msg_id_reply_t * mp)
3028 {
3029   vat_main_t *vam = &vat_main;
3030   vat_json_node_t node;
3031
3032   vat_json_init_object (&node);
3033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3034   vat_json_object_add_uint (&node, "first_msg_id",
3035                             (uint) ntohs (mp->first_msg_id));
3036
3037   vat_json_print (vam->ofp, &node);
3038   vat_json_free (&node);
3039
3040   vam->retval = ntohl (mp->retval);
3041   vam->result_ready = 1;
3042 }
3043
3044 static void vl_api_get_node_graph_reply_t_handler
3045   (vl_api_get_node_graph_reply_t * mp)
3046 {
3047   vat_main_t *vam = &vat_main;
3048   api_main_t *am = &api_main;
3049   i32 retval = ntohl (mp->retval);
3050   u8 *pvt_copy, *reply;
3051   void *oldheap;
3052   vlib_node_t *node;
3053   int i;
3054
3055   if (vam->async_mode)
3056     {
3057       vam->async_errors += (retval < 0);
3058     }
3059   else
3060     {
3061       vam->retval = retval;
3062       vam->result_ready = 1;
3063     }
3064
3065   /* "Should never happen..." */
3066   if (retval != 0)
3067     return;
3068
3069   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3070   pvt_copy = vec_dup (reply);
3071
3072   /* Toss the shared-memory original... */
3073   pthread_mutex_lock (&am->vlib_rp->mutex);
3074   oldheap = svm_push_data_heap (am->vlib_rp);
3075
3076   vec_free (reply);
3077
3078   svm_pop_heap (oldheap);
3079   pthread_mutex_unlock (&am->vlib_rp->mutex);
3080
3081   if (vam->graph_nodes)
3082     {
3083       hash_free (vam->graph_node_index_by_name);
3084
3085       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3086         {
3087           node = vam->graph_nodes[0][i];
3088           vec_free (node->name);
3089           vec_free (node->next_nodes);
3090           vec_free (node);
3091         }
3092       vec_free (vam->graph_nodes[0]);
3093       vec_free (vam->graph_nodes);
3094     }
3095
3096   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3097   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3098   vec_free (pvt_copy);
3099
3100   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3101     {
3102       node = vam->graph_nodes[0][i];
3103       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3104     }
3105 }
3106
3107 static void vl_api_get_node_graph_reply_t_handler_json
3108   (vl_api_get_node_graph_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   api_main_t *am = &api_main;
3112   void *oldheap;
3113   vat_json_node_t node;
3114   u8 *reply;
3115
3116   /* $$$$ make this real? */
3117   vat_json_init_object (&node);
3118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3119   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3120
3121   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3122
3123   /* Toss the shared-memory original... */
3124   pthread_mutex_lock (&am->vlib_rp->mutex);
3125   oldheap = svm_push_data_heap (am->vlib_rp);
3126
3127   vec_free (reply);
3128
3129   svm_pop_heap (oldheap);
3130   pthread_mutex_unlock (&am->vlib_rp->mutex);
3131
3132   vat_json_print (vam->ofp, &node);
3133   vat_json_free (&node);
3134
3135   vam->retval = ntohl (mp->retval);
3136   vam->result_ready = 1;
3137 }
3138
3139 static void
3140 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3141 {
3142   vat_main_t *vam = &vat_main;
3143   u8 *s = 0;
3144
3145   if (mp->local)
3146     {
3147       s = format (s, "%=16d%=16d%=16d",
3148                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3149     }
3150   else
3151     {
3152       s = format (s, "%=16U%=16d%=16d",
3153                   mp->is_ipv6 ? format_ip6_address :
3154                   format_ip4_address,
3155                   mp->ip_address, mp->priority, mp->weight);
3156     }
3157
3158   print (vam->ofp, "%v", s);
3159   vec_free (s);
3160 }
3161
3162 static void
3163 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t *node = NULL;
3167   struct in6_addr ip6;
3168   struct in_addr ip4;
3169
3170   if (VAT_JSON_ARRAY != vam->json_tree.type)
3171     {
3172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3173       vat_json_init_array (&vam->json_tree);
3174     }
3175   node = vat_json_array_add (&vam->json_tree);
3176   vat_json_init_object (node);
3177
3178   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3179   vat_json_object_add_uint (node, "priority", mp->priority);
3180   vat_json_object_add_uint (node, "weight", mp->weight);
3181
3182   if (mp->local)
3183     vat_json_object_add_uint (node, "sw_if_index",
3184                               clib_net_to_host_u32 (mp->sw_if_index));
3185   else
3186     {
3187       if (mp->is_ipv6)
3188         {
3189           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3190           vat_json_object_add_ip6 (node, "address", ip6);
3191         }
3192       else
3193         {
3194           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3195           vat_json_object_add_ip4 (node, "address", ip4);
3196         }
3197     }
3198 }
3199
3200 static void
3201 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3202                                           mp)
3203 {
3204   vat_main_t *vam = &vat_main;
3205   u8 *ls_name = 0;
3206
3207   ls_name = format (0, "%s", mp->ls_name);
3208
3209   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3210          ls_name);
3211   vec_free (ls_name);
3212 }
3213
3214 static void
3215   vl_api_one_locator_set_details_t_handler_json
3216   (vl_api_one_locator_set_details_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t *node = 0;
3220   u8 *ls_name = 0;
3221
3222   ls_name = format (0, "%s", mp->ls_name);
3223   vec_add1 (ls_name, 0);
3224
3225   if (VAT_JSON_ARRAY != vam->json_tree.type)
3226     {
3227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3228       vat_json_init_array (&vam->json_tree);
3229     }
3230   node = vat_json_array_add (&vam->json_tree);
3231
3232   vat_json_init_object (node);
3233   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3234   vat_json_object_add_uint (node, "ls_index",
3235                             clib_net_to_host_u32 (mp->ls_index));
3236   vec_free (ls_name);
3237 }
3238
3239 typedef struct
3240 {
3241   u32 spi;
3242   u8 si;
3243 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3244
3245 uword
3246 unformat_nsh_address (unformat_input_t * input, va_list * args)
3247 {
3248   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3249   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3250 }
3251
3252 u8 *
3253 format_nsh_address_vat (u8 * s, va_list * args)
3254 {
3255   nsh_t *a = va_arg (*args, nsh_t *);
3256   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3257 }
3258
3259 static u8 *
3260 format_lisp_flat_eid (u8 * s, va_list * args)
3261 {
3262   u32 type = va_arg (*args, u32);
3263   u8 *eid = va_arg (*args, u8 *);
3264   u32 eid_len = va_arg (*args, u32);
3265
3266   switch (type)
3267     {
3268     case 0:
3269       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3270     case 1:
3271       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3272     case 2:
3273       return format (s, "%U", format_ethernet_address, eid);
3274     case 3:
3275       return format (s, "%U", format_nsh_address_vat, eid);
3276     }
3277   return 0;
3278 }
3279
3280 static u8 *
3281 format_lisp_eid_vat (u8 * s, va_list * args)
3282 {
3283   u32 type = va_arg (*args, u32);
3284   u8 *eid = va_arg (*args, u8 *);
3285   u32 eid_len = va_arg (*args, u32);
3286   u8 *seid = va_arg (*args, u8 *);
3287   u32 seid_len = va_arg (*args, u32);
3288   u32 is_src_dst = va_arg (*args, u32);
3289
3290   if (is_src_dst)
3291     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3292
3293   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3294
3295   return s;
3296 }
3297
3298 static void
3299 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3300 {
3301   vat_main_t *vam = &vat_main;
3302   u8 *s = 0, *eid = 0;
3303
3304   if (~0 == mp->locator_set_index)
3305     s = format (0, "action: %d", mp->action);
3306   else
3307     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3308
3309   eid = format (0, "%U", format_lisp_eid_vat,
3310                 mp->eid_type,
3311                 mp->eid,
3312                 mp->eid_prefix_len,
3313                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3314   vec_add1 (eid, 0);
3315
3316   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3317          clib_net_to_host_u32 (mp->vni),
3318          eid,
3319          mp->is_local ? "local" : "remote",
3320          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3321          clib_net_to_host_u16 (mp->key_id), mp->key);
3322
3323   vec_free (s);
3324   vec_free (eid);
3325 }
3326
3327 static void
3328 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3329                                              * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332   vat_json_node_t *node = 0;
3333   u8 *eid = 0;
3334
3335   if (VAT_JSON_ARRAY != vam->json_tree.type)
3336     {
3337       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3338       vat_json_init_array (&vam->json_tree);
3339     }
3340   node = vat_json_array_add (&vam->json_tree);
3341
3342   vat_json_init_object (node);
3343   if (~0 == mp->locator_set_index)
3344     vat_json_object_add_uint (node, "action", mp->action);
3345   else
3346     vat_json_object_add_uint (node, "locator_set_index",
3347                               clib_net_to_host_u32 (mp->locator_set_index));
3348
3349   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3350   if (mp->eid_type == 3)
3351     {
3352       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3353       vat_json_init_object (nsh_json);
3354       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3355       vat_json_object_add_uint (nsh_json, "spi",
3356                                 clib_net_to_host_u32 (nsh->spi));
3357       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3358     }
3359   else
3360     {
3361       eid = format (0, "%U", format_lisp_eid_vat,
3362                     mp->eid_type,
3363                     mp->eid,
3364                     mp->eid_prefix_len,
3365                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3366       vec_add1 (eid, 0);
3367       vat_json_object_add_string_copy (node, "eid", eid);
3368       vec_free (eid);
3369     }
3370   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3371   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3372   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3373
3374   if (mp->key_id)
3375     {
3376       vat_json_object_add_uint (node, "key_id",
3377                                 clib_net_to_host_u16 (mp->key_id));
3378       vat_json_object_add_string_copy (node, "key", mp->key);
3379     }
3380 }
3381
3382 static void
3383 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3384 {
3385   vat_main_t *vam = &vat_main;
3386   u8 *seid = 0, *deid = 0;
3387   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3388
3389   deid = format (0, "%U", format_lisp_eid_vat,
3390                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3391
3392   seid = format (0, "%U", format_lisp_eid_vat,
3393                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3394
3395   vec_add1 (deid, 0);
3396   vec_add1 (seid, 0);
3397
3398   if (mp->is_ip4)
3399     format_ip_address_fcn = format_ip4_address;
3400   else
3401     format_ip_address_fcn = format_ip6_address;
3402
3403
3404   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3405          clib_net_to_host_u32 (mp->vni),
3406          seid, deid,
3407          format_ip_address_fcn, mp->lloc,
3408          format_ip_address_fcn, mp->rloc,
3409          clib_net_to_host_u32 (mp->pkt_count),
3410          clib_net_to_host_u32 (mp->bytes));
3411
3412   vec_free (deid);
3413   vec_free (seid);
3414 }
3415
3416 static void
3417 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3418 {
3419   struct in6_addr ip6;
3420   struct in_addr ip4;
3421   vat_main_t *vam = &vat_main;
3422   vat_json_node_t *node = 0;
3423   u8 *deid = 0, *seid = 0;
3424
3425   if (VAT_JSON_ARRAY != vam->json_tree.type)
3426     {
3427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3428       vat_json_init_array (&vam->json_tree);
3429     }
3430   node = vat_json_array_add (&vam->json_tree);
3431
3432   vat_json_init_object (node);
3433   deid = format (0, "%U", format_lisp_eid_vat,
3434                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3435
3436   seid = format (0, "%U", format_lisp_eid_vat,
3437                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3438
3439   vec_add1 (deid, 0);
3440   vec_add1 (seid, 0);
3441
3442   vat_json_object_add_string_copy (node, "seid", seid);
3443   vat_json_object_add_string_copy (node, "deid", deid);
3444   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3445
3446   if (mp->is_ip4)
3447     {
3448       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3449       vat_json_object_add_ip4 (node, "lloc", ip4);
3450       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3451       vat_json_object_add_ip4 (node, "rloc", ip4);
3452     }
3453   else
3454     {
3455       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3456       vat_json_object_add_ip6 (node, "lloc", ip6);
3457       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3458       vat_json_object_add_ip6 (node, "rloc", ip6);
3459     }
3460   vat_json_object_add_uint (node, "pkt_count",
3461                             clib_net_to_host_u32 (mp->pkt_count));
3462   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3463
3464   vec_free (deid);
3465   vec_free (seid);
3466 }
3467
3468 static void
3469   vl_api_one_eid_table_map_details_t_handler
3470   (vl_api_one_eid_table_map_details_t * mp)
3471 {
3472   vat_main_t *vam = &vat_main;
3473
3474   u8 *line = format (0, "%=10d%=10d",
3475                      clib_net_to_host_u32 (mp->vni),
3476                      clib_net_to_host_u32 (mp->dp_table));
3477   print (vam->ofp, "%v", line);
3478   vec_free (line);
3479 }
3480
3481 static void
3482   vl_api_one_eid_table_map_details_t_handler_json
3483   (vl_api_one_eid_table_map_details_t * mp)
3484 {
3485   vat_main_t *vam = &vat_main;
3486   vat_json_node_t *node = NULL;
3487
3488   if (VAT_JSON_ARRAY != vam->json_tree.type)
3489     {
3490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3491       vat_json_init_array (&vam->json_tree);
3492     }
3493   node = vat_json_array_add (&vam->json_tree);
3494   vat_json_init_object (node);
3495   vat_json_object_add_uint (node, "dp_table",
3496                             clib_net_to_host_u32 (mp->dp_table));
3497   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3498 }
3499
3500 static void
3501   vl_api_one_eid_table_vni_details_t_handler
3502   (vl_api_one_eid_table_vni_details_t * mp)
3503 {
3504   vat_main_t *vam = &vat_main;
3505
3506   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3507   print (vam->ofp, "%v", line);
3508   vec_free (line);
3509 }
3510
3511 static void
3512   vl_api_one_eid_table_vni_details_t_handler_json
3513   (vl_api_one_eid_table_vni_details_t * mp)
3514 {
3515   vat_main_t *vam = &vat_main;
3516   vat_json_node_t *node = NULL;
3517
3518   if (VAT_JSON_ARRAY != vam->json_tree.type)
3519     {
3520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3521       vat_json_init_array (&vam->json_tree);
3522     }
3523   node = vat_json_array_add (&vam->json_tree);
3524   vat_json_init_object (node);
3525   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3526 }
3527
3528 static void
3529   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3530   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3531 {
3532   vat_main_t *vam = &vat_main;
3533   int retval = clib_net_to_host_u32 (mp->retval);
3534
3535   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3536   print (vam->ofp, "fallback threshold value: %d", mp->value);
3537
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540 }
3541
3542 static void
3543   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3544   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3545 {
3546   vat_main_t *vam = &vat_main;
3547   vat_json_node_t _node, *node = &_node;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549
3550   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3551   vat_json_init_object (node);
3552   vat_json_object_add_uint (node, "value", mp->value);
3553
3554   vat_json_print (vam->ofp, node);
3555   vat_json_free (node);
3556
3557   vam->retval = retval;
3558   vam->result_ready = 1;
3559 }
3560
3561 static void
3562   vl_api_show_one_map_register_state_reply_t_handler
3563   (vl_api_show_one_map_register_state_reply_t * mp)
3564 {
3565   vat_main_t *vam = &vat_main;
3566   int retval = clib_net_to_host_u32 (mp->retval);
3567
3568   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3569
3570   vam->retval = retval;
3571   vam->result_ready = 1;
3572 }
3573
3574 static void
3575   vl_api_show_one_map_register_state_reply_t_handler_json
3576   (vl_api_show_one_map_register_state_reply_t * mp)
3577 {
3578   vat_main_t *vam = &vat_main;
3579   vat_json_node_t _node, *node = &_node;
3580   int retval = clib_net_to_host_u32 (mp->retval);
3581
3582   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3583
3584   vat_json_init_object (node);
3585   vat_json_object_add_string_copy (node, "state", s);
3586
3587   vat_json_print (vam->ofp, node);
3588   vat_json_free (node);
3589
3590   vam->retval = retval;
3591   vam->result_ready = 1;
3592   vec_free (s);
3593 }
3594
3595 static void
3596   vl_api_show_one_rloc_probe_state_reply_t_handler
3597   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3598 {
3599   vat_main_t *vam = &vat_main;
3600   int retval = clib_net_to_host_u32 (mp->retval);
3601
3602   if (retval)
3603     goto end;
3604
3605   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3606 end:
3607   vam->retval = retval;
3608   vam->result_ready = 1;
3609 }
3610
3611 static void
3612   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3613   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3614 {
3615   vat_main_t *vam = &vat_main;
3616   vat_json_node_t _node, *node = &_node;
3617   int retval = clib_net_to_host_u32 (mp->retval);
3618
3619   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3620   vat_json_init_object (node);
3621   vat_json_object_add_string_copy (node, "state", s);
3622
3623   vat_json_print (vam->ofp, node);
3624   vat_json_free (node);
3625
3626   vam->retval = retval;
3627   vam->result_ready = 1;
3628   vec_free (s);
3629 }
3630
3631 static void
3632   vl_api_show_one_stats_enable_disable_reply_t_handler
3633   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3634 {
3635   vat_main_t *vam = &vat_main;
3636   int retval = clib_net_to_host_u32 (mp->retval);
3637
3638   if (retval)
3639     goto end;
3640
3641   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3642 end:
3643   vam->retval = retval;
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3649   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   vat_json_node_t _node, *node = &_node;
3653   int retval = clib_net_to_host_u32 (mp->retval);
3654
3655   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3656   vat_json_init_object (node);
3657   vat_json_object_add_string_copy (node, "state", s);
3658
3659   vat_json_print (vam->ofp, node);
3660   vat_json_free (node);
3661
3662   vam->retval = retval;
3663   vam->result_ready = 1;
3664   vec_free (s);
3665 }
3666
3667 static void
3668 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3669 {
3670   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3671   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3672   e->vni = clib_net_to_host_u32 (e->vni);
3673 }
3674
3675 static void
3676   gpe_fwd_entries_get_reply_t_net_to_host
3677   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3678 {
3679   u32 i;
3680
3681   mp->count = clib_net_to_host_u32 (mp->count);
3682   for (i = 0; i < mp->count; i++)
3683     {
3684       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3685     }
3686 }
3687
3688 static u8 *
3689 format_gpe_encap_mode (u8 * s, va_list * args)
3690 {
3691   u32 mode = va_arg (*args, u32);
3692
3693   switch (mode)
3694     {
3695     case 0:
3696       return format (s, "lisp");
3697     case 1:
3698       return format (s, "vxlan");
3699     }
3700   return 0;
3701 }
3702
3703 static void
3704   vl_api_gpe_get_encap_mode_reply_t_handler
3705   (vl_api_gpe_get_encap_mode_reply_t * mp)
3706 {
3707   vat_main_t *vam = &vat_main;
3708
3709   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3710   vam->retval = ntohl (mp->retval);
3711   vam->result_ready = 1;
3712 }
3713
3714 static void
3715   vl_api_gpe_get_encap_mode_reply_t_handler_json
3716   (vl_api_gpe_get_encap_mode_reply_t * mp)
3717 {
3718   vat_main_t *vam = &vat_main;
3719   vat_json_node_t node;
3720
3721   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3722   vec_add1 (encap_mode, 0);
3723
3724   vat_json_init_object (&node);
3725   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3726
3727   vec_free (encap_mode);
3728   vat_json_print (vam->ofp, &node);
3729   vat_json_free (&node);
3730
3731   vam->retval = ntohl (mp->retval);
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_fwd_entry_path_details_t_handler
3737   (vl_api_gpe_fwd_entry_path_details_t * mp)
3738 {
3739   vat_main_t *vam = &vat_main;
3740   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3741
3742   if (mp->lcl_loc.is_ip4)
3743     format_ip_address_fcn = format_ip4_address;
3744   else
3745     format_ip_address_fcn = format_ip6_address;
3746
3747   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3748          format_ip_address_fcn, &mp->lcl_loc,
3749          format_ip_address_fcn, &mp->rmt_loc);
3750 }
3751
3752 static void
3753 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3754 {
3755   struct in6_addr ip6;
3756   struct in_addr ip4;
3757
3758   if (loc->is_ip4)
3759     {
3760       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3761       vat_json_object_add_ip4 (n, "address", ip4);
3762     }
3763   else
3764     {
3765       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3766       vat_json_object_add_ip6 (n, "address", ip6);
3767     }
3768   vat_json_object_add_uint (n, "weight", loc->weight);
3769 }
3770
3771 static void
3772   vl_api_gpe_fwd_entry_path_details_t_handler_json
3773   (vl_api_gpe_fwd_entry_path_details_t * mp)
3774 {
3775   vat_main_t *vam = &vat_main;
3776   vat_json_node_t *node = NULL;
3777   vat_json_node_t *loc_node;
3778
3779   if (VAT_JSON_ARRAY != vam->json_tree.type)
3780     {
3781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3782       vat_json_init_array (&vam->json_tree);
3783     }
3784   node = vat_json_array_add (&vam->json_tree);
3785   vat_json_init_object (node);
3786
3787   loc_node = vat_json_object_add (node, "local_locator");
3788   vat_json_init_object (loc_node);
3789   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3790
3791   loc_node = vat_json_object_add (node, "remote_locator");
3792   vat_json_init_object (loc_node);
3793   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3794 }
3795
3796 static void
3797   vl_api_gpe_fwd_entries_get_reply_t_handler
3798   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3799 {
3800   vat_main_t *vam = &vat_main;
3801   u32 i;
3802   int retval = clib_net_to_host_u32 (mp->retval);
3803   vl_api_gpe_fwd_entry_t *e;
3804
3805   if (retval)
3806     goto end;
3807
3808   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3809
3810   for (i = 0; i < mp->count; i++)
3811     {
3812       e = &mp->entries[i];
3813       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3814              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3815              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3816     }
3817
3818 end:
3819   vam->retval = retval;
3820   vam->result_ready = 1;
3821 }
3822
3823 static void
3824   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3825   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3826 {
3827   u8 *s = 0;
3828   vat_main_t *vam = &vat_main;
3829   vat_json_node_t *e = 0, root;
3830   u32 i;
3831   int retval = clib_net_to_host_u32 (mp->retval);
3832   vl_api_gpe_fwd_entry_t *fwd;
3833
3834   if (retval)
3835     goto end;
3836
3837   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3838   vat_json_init_array (&root);
3839
3840   for (i = 0; i < mp->count; i++)
3841     {
3842       e = vat_json_array_add (&root);
3843       fwd = &mp->entries[i];
3844
3845       vat_json_init_object (e);
3846       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3847       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3848       vat_json_object_add_int (e, "vni", fwd->vni);
3849       vat_json_object_add_int (e, "action", fwd->action);
3850
3851       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3852                   fwd->leid_prefix_len);
3853       vec_add1 (s, 0);
3854       vat_json_object_add_string_copy (e, "leid", s);
3855       vec_free (s);
3856
3857       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3858                   fwd->reid_prefix_len);
3859       vec_add1 (s, 0);
3860       vat_json_object_add_string_copy (e, "reid", s);
3861       vec_free (s);
3862     }
3863
3864   vat_json_print (vam->ofp, &root);
3865   vat_json_free (&root);
3866
3867 end:
3868   vam->retval = retval;
3869   vam->result_ready = 1;
3870 }
3871
3872 static void
3873   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3874   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3875 {
3876   vat_main_t *vam = &vat_main;
3877   u32 i, n;
3878   int retval = clib_net_to_host_u32 (mp->retval);
3879   vl_api_gpe_native_fwd_rpath_t *r;
3880
3881   if (retval)
3882     goto end;
3883
3884   n = clib_net_to_host_u32 (mp->count);
3885
3886   for (i = 0; i < n; i++)
3887     {
3888       r = &mp->entries[i];
3889       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3890              clib_net_to_host_u32 (r->fib_index),
3891              clib_net_to_host_u32 (r->nh_sw_if_index),
3892              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3893     }
3894
3895 end:
3896   vam->retval = retval;
3897   vam->result_ready = 1;
3898 }
3899
3900 static void
3901   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3902   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3903 {
3904   vat_main_t *vam = &vat_main;
3905   vat_json_node_t root, *e;
3906   u32 i, n;
3907   int retval = clib_net_to_host_u32 (mp->retval);
3908   vl_api_gpe_native_fwd_rpath_t *r;
3909   u8 *s;
3910
3911   if (retval)
3912     goto end;
3913
3914   n = clib_net_to_host_u32 (mp->count);
3915   vat_json_init_array (&root);
3916
3917   for (i = 0; i < n; i++)
3918     {
3919       e = vat_json_array_add (&root);
3920       vat_json_init_object (e);
3921       r = &mp->entries[i];
3922       s =
3923         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3924                 r->nh_addr);
3925       vec_add1 (s, 0);
3926       vat_json_object_add_string_copy (e, "ip4", s);
3927       vec_free (s);
3928
3929       vat_json_object_add_uint (e, "fib_index",
3930                                 clib_net_to_host_u32 (r->fib_index));
3931       vat_json_object_add_uint (e, "nh_sw_if_index",
3932                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3933     }
3934
3935   vat_json_print (vam->ofp, &root);
3936   vat_json_free (&root);
3937
3938 end:
3939   vam->retval = retval;
3940   vam->result_ready = 1;
3941 }
3942
3943 static void
3944   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3945   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3946 {
3947   vat_main_t *vam = &vat_main;
3948   u32 i, n;
3949   int retval = clib_net_to_host_u32 (mp->retval);
3950
3951   if (retval)
3952     goto end;
3953
3954   n = clib_net_to_host_u32 (mp->count);
3955
3956   for (i = 0; i < n; i++)
3957     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3958
3959 end:
3960   vam->retval = retval;
3961   vam->result_ready = 1;
3962 }
3963
3964 static void
3965   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3966   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3967 {
3968   vat_main_t *vam = &vat_main;
3969   vat_json_node_t root;
3970   u32 i, n;
3971   int retval = clib_net_to_host_u32 (mp->retval);
3972
3973   if (retval)
3974     goto end;
3975
3976   n = clib_net_to_host_u32 (mp->count);
3977   vat_json_init_array (&root);
3978
3979   for (i = 0; i < n; i++)
3980     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3981
3982   vat_json_print (vam->ofp, &root);
3983   vat_json_free (&root);
3984
3985 end:
3986   vam->retval = retval;
3987   vam->result_ready = 1;
3988 }
3989
3990 static void
3991   vl_api_one_ndp_entries_get_reply_t_handler
3992   (vl_api_one_ndp_entries_get_reply_t * mp)
3993 {
3994   vat_main_t *vam = &vat_main;
3995   u32 i, n;
3996   int retval = clib_net_to_host_u32 (mp->retval);
3997
3998   if (retval)
3999     goto end;
4000
4001   n = clib_net_to_host_u32 (mp->count);
4002
4003   for (i = 0; i < n; i++)
4004     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
4005            format_ethernet_address, mp->entries[i].mac);
4006
4007 end:
4008   vam->retval = retval;
4009   vam->result_ready = 1;
4010 }
4011
4012 static void
4013   vl_api_one_ndp_entries_get_reply_t_handler_json
4014   (vl_api_one_ndp_entries_get_reply_t * mp)
4015 {
4016   u8 *s = 0;
4017   vat_main_t *vam = &vat_main;
4018   vat_json_node_t *e = 0, root;
4019   u32 i, n;
4020   int retval = clib_net_to_host_u32 (mp->retval);
4021   vl_api_one_ndp_entry_t *arp_entry;
4022
4023   if (retval)
4024     goto end;
4025
4026   n = clib_net_to_host_u32 (mp->count);
4027   vat_json_init_array (&root);
4028
4029   for (i = 0; i < n; i++)
4030     {
4031       e = vat_json_array_add (&root);
4032       arp_entry = &mp->entries[i];
4033
4034       vat_json_init_object (e);
4035       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4036       vec_add1 (s, 0);
4037
4038       vat_json_object_add_string_copy (e, "mac", s);
4039       vec_free (s);
4040
4041       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4042       vec_add1 (s, 0);
4043       vat_json_object_add_string_copy (e, "ip6", s);
4044       vec_free (s);
4045     }
4046
4047   vat_json_print (vam->ofp, &root);
4048   vat_json_free (&root);
4049
4050 end:
4051   vam->retval = retval;
4052   vam->result_ready = 1;
4053 }
4054
4055 static void
4056   vl_api_one_l2_arp_entries_get_reply_t_handler
4057   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4058 {
4059   vat_main_t *vam = &vat_main;
4060   u32 i, n;
4061   int retval = clib_net_to_host_u32 (mp->retval);
4062
4063   if (retval)
4064     goto end;
4065
4066   n = clib_net_to_host_u32 (mp->count);
4067
4068   for (i = 0; i < n; i++)
4069     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4070            format_ethernet_address, mp->entries[i].mac);
4071
4072 end:
4073   vam->retval = retval;
4074   vam->result_ready = 1;
4075 }
4076
4077 static void
4078   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4079   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4080 {
4081   u8 *s = 0;
4082   vat_main_t *vam = &vat_main;
4083   vat_json_node_t *e = 0, root;
4084   u32 i, n;
4085   int retval = clib_net_to_host_u32 (mp->retval);
4086   vl_api_one_l2_arp_entry_t *arp_entry;
4087
4088   if (retval)
4089     goto end;
4090
4091   n = clib_net_to_host_u32 (mp->count);
4092   vat_json_init_array (&root);
4093
4094   for (i = 0; i < n; i++)
4095     {
4096       e = vat_json_array_add (&root);
4097       arp_entry = &mp->entries[i];
4098
4099       vat_json_init_object (e);
4100       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4101       vec_add1 (s, 0);
4102
4103       vat_json_object_add_string_copy (e, "mac", s);
4104       vec_free (s);
4105
4106       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4107       vec_add1 (s, 0);
4108       vat_json_object_add_string_copy (e, "ip4", s);
4109       vec_free (s);
4110     }
4111
4112   vat_json_print (vam->ofp, &root);
4113   vat_json_free (&root);
4114
4115 end:
4116   vam->retval = retval;
4117   vam->result_ready = 1;
4118 }
4119
4120 static void
4121 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4122 {
4123   vat_main_t *vam = &vat_main;
4124   u32 i, n;
4125   int retval = clib_net_to_host_u32 (mp->retval);
4126
4127   if (retval)
4128     goto end;
4129
4130   n = clib_net_to_host_u32 (mp->count);
4131
4132   for (i = 0; i < n; i++)
4133     {
4134       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4135     }
4136
4137 end:
4138   vam->retval = retval;
4139   vam->result_ready = 1;
4140 }
4141
4142 static void
4143   vl_api_one_ndp_bd_get_reply_t_handler_json
4144   (vl_api_one_ndp_bd_get_reply_t * mp)
4145 {
4146   vat_main_t *vam = &vat_main;
4147   vat_json_node_t root;
4148   u32 i, n;
4149   int retval = clib_net_to_host_u32 (mp->retval);
4150
4151   if (retval)
4152     goto end;
4153
4154   n = clib_net_to_host_u32 (mp->count);
4155   vat_json_init_array (&root);
4156
4157   for (i = 0; i < n; i++)
4158     {
4159       vat_json_array_add_uint (&root,
4160                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4161     }
4162
4163   vat_json_print (vam->ofp, &root);
4164   vat_json_free (&root);
4165
4166 end:
4167   vam->retval = retval;
4168   vam->result_ready = 1;
4169 }
4170
4171 static void
4172   vl_api_one_l2_arp_bd_get_reply_t_handler
4173   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4174 {
4175   vat_main_t *vam = &vat_main;
4176   u32 i, n;
4177   int retval = clib_net_to_host_u32 (mp->retval);
4178
4179   if (retval)
4180     goto end;
4181
4182   n = clib_net_to_host_u32 (mp->count);
4183
4184   for (i = 0; i < n; i++)
4185     {
4186       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4187     }
4188
4189 end:
4190   vam->retval = retval;
4191   vam->result_ready = 1;
4192 }
4193
4194 static void
4195   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4196   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   vat_json_node_t root;
4200   u32 i, n;
4201   int retval = clib_net_to_host_u32 (mp->retval);
4202
4203   if (retval)
4204     goto end;
4205
4206   n = clib_net_to_host_u32 (mp->count);
4207   vat_json_init_array (&root);
4208
4209   for (i = 0; i < n; i++)
4210     {
4211       vat_json_array_add_uint (&root,
4212                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4213     }
4214
4215   vat_json_print (vam->ofp, &root);
4216   vat_json_free (&root);
4217
4218 end:
4219   vam->retval = retval;
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_one_adjacencies_get_reply_t_handler
4225   (vl_api_one_adjacencies_get_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   u32 i, n;
4229   int retval = clib_net_to_host_u32 (mp->retval);
4230   vl_api_one_adjacency_t *a;
4231
4232   if (retval)
4233     goto end;
4234
4235   n = clib_net_to_host_u32 (mp->count);
4236
4237   for (i = 0; i < n; i++)
4238     {
4239       a = &mp->adjacencies[i];
4240       print (vam->ofp, "%U %40U",
4241              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4242              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4243     }
4244
4245 end:
4246   vam->retval = retval;
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_adjacencies_get_reply_t_handler_json
4252   (vl_api_one_adjacencies_get_reply_t * mp)
4253 {
4254   u8 *s = 0;
4255   vat_main_t *vam = &vat_main;
4256   vat_json_node_t *e = 0, root;
4257   u32 i, n;
4258   int retval = clib_net_to_host_u32 (mp->retval);
4259   vl_api_one_adjacency_t *a;
4260
4261   if (retval)
4262     goto end;
4263
4264   n = clib_net_to_host_u32 (mp->count);
4265   vat_json_init_array (&root);
4266
4267   for (i = 0; i < n; i++)
4268     {
4269       e = vat_json_array_add (&root);
4270       a = &mp->adjacencies[i];
4271
4272       vat_json_init_object (e);
4273       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4274                   a->leid_prefix_len);
4275       vec_add1 (s, 0);
4276       vat_json_object_add_string_copy (e, "leid", s);
4277       vec_free (s);
4278
4279       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4280                   a->reid_prefix_len);
4281       vec_add1 (s, 0);
4282       vat_json_object_add_string_copy (e, "reid", s);
4283       vec_free (s);
4284     }
4285
4286   vat_json_print (vam->ofp, &root);
4287   vat_json_free (&root);
4288
4289 end:
4290   vam->retval = retval;
4291   vam->result_ready = 1;
4292 }
4293
4294 static void
4295 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4296 {
4297   vat_main_t *vam = &vat_main;
4298
4299   print (vam->ofp, "%=20U",
4300          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4301          mp->ip_address);
4302 }
4303
4304 static void
4305   vl_api_one_map_server_details_t_handler_json
4306   (vl_api_one_map_server_details_t * mp)
4307 {
4308   vat_main_t *vam = &vat_main;
4309   vat_json_node_t *node = NULL;
4310   struct in6_addr ip6;
4311   struct in_addr ip4;
4312
4313   if (VAT_JSON_ARRAY != vam->json_tree.type)
4314     {
4315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4316       vat_json_init_array (&vam->json_tree);
4317     }
4318   node = vat_json_array_add (&vam->json_tree);
4319
4320   vat_json_init_object (node);
4321   if (mp->is_ipv6)
4322     {
4323       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4324       vat_json_object_add_ip6 (node, "map-server", ip6);
4325     }
4326   else
4327     {
4328       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4329       vat_json_object_add_ip4 (node, "map-server", ip4);
4330     }
4331 }
4332
4333 static void
4334 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4335                                            * mp)
4336 {
4337   vat_main_t *vam = &vat_main;
4338
4339   print (vam->ofp, "%=20U",
4340          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4341          mp->ip_address);
4342 }
4343
4344 static void
4345   vl_api_one_map_resolver_details_t_handler_json
4346   (vl_api_one_map_resolver_details_t * mp)
4347 {
4348   vat_main_t *vam = &vat_main;
4349   vat_json_node_t *node = NULL;
4350   struct in6_addr ip6;
4351   struct in_addr ip4;
4352
4353   if (VAT_JSON_ARRAY != vam->json_tree.type)
4354     {
4355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4356       vat_json_init_array (&vam->json_tree);
4357     }
4358   node = vat_json_array_add (&vam->json_tree);
4359
4360   vat_json_init_object (node);
4361   if (mp->is_ipv6)
4362     {
4363       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4364       vat_json_object_add_ip6 (node, "map resolver", ip6);
4365     }
4366   else
4367     {
4368       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4369       vat_json_object_add_ip4 (node, "map resolver", ip4);
4370     }
4371 }
4372
4373 static void
4374 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4375 {
4376   vat_main_t *vam = &vat_main;
4377   i32 retval = ntohl (mp->retval);
4378
4379   if (0 <= retval)
4380     {
4381       print (vam->ofp, "feature: %s\ngpe: %s",
4382              mp->feature_status ? "enabled" : "disabled",
4383              mp->gpe_status ? "enabled" : "disabled");
4384     }
4385
4386   vam->retval = retval;
4387   vam->result_ready = 1;
4388 }
4389
4390 static void
4391   vl_api_show_one_status_reply_t_handler_json
4392   (vl_api_show_one_status_reply_t * mp)
4393 {
4394   vat_main_t *vam = &vat_main;
4395   vat_json_node_t node;
4396   u8 *gpe_status = NULL;
4397   u8 *feature_status = NULL;
4398
4399   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4400   feature_status = format (0, "%s",
4401                            mp->feature_status ? "enabled" : "disabled");
4402   vec_add1 (gpe_status, 0);
4403   vec_add1 (feature_status, 0);
4404
4405   vat_json_init_object (&node);
4406   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4407   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4408
4409   vec_free (gpe_status);
4410   vec_free (feature_status);
4411
4412   vat_json_print (vam->ofp, &node);
4413   vat_json_free (&node);
4414
4415   vam->retval = ntohl (mp->retval);
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4421   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   i32 retval = ntohl (mp->retval);
4425
4426   if (retval >= 0)
4427     {
4428       print (vam->ofp, "%=20s", mp->locator_set_name);
4429     }
4430
4431   vam->retval = retval;
4432   vam->result_ready = 1;
4433 }
4434
4435 static void
4436   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4437   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4438 {
4439   vat_main_t *vam = &vat_main;
4440   vat_json_node_t *node = NULL;
4441
4442   if (VAT_JSON_ARRAY != vam->json_tree.type)
4443     {
4444       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4445       vat_json_init_array (&vam->json_tree);
4446     }
4447   node = vat_json_array_add (&vam->json_tree);
4448
4449   vat_json_init_object (node);
4450   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4451
4452   vat_json_print (vam->ofp, node);
4453   vat_json_free (node);
4454
4455   vam->retval = ntohl (mp->retval);
4456   vam->result_ready = 1;
4457 }
4458
4459 static u8 *
4460 format_lisp_map_request_mode (u8 * s, va_list * args)
4461 {
4462   u32 mode = va_arg (*args, u32);
4463
4464   switch (mode)
4465     {
4466     case 0:
4467       return format (0, "dst-only");
4468     case 1:
4469       return format (0, "src-dst");
4470     }
4471   return 0;
4472 }
4473
4474 static void
4475   vl_api_show_one_map_request_mode_reply_t_handler
4476   (vl_api_show_one_map_request_mode_reply_t * mp)
4477 {
4478   vat_main_t *vam = &vat_main;
4479   i32 retval = ntohl (mp->retval);
4480
4481   if (0 <= retval)
4482     {
4483       u32 mode = mp->mode;
4484       print (vam->ofp, "map_request_mode: %U",
4485              format_lisp_map_request_mode, mode);
4486     }
4487
4488   vam->retval = retval;
4489   vam->result_ready = 1;
4490 }
4491
4492 static void
4493   vl_api_show_one_map_request_mode_reply_t_handler_json
4494   (vl_api_show_one_map_request_mode_reply_t * mp)
4495 {
4496   vat_main_t *vam = &vat_main;
4497   vat_json_node_t node;
4498   u8 *s = 0;
4499   u32 mode;
4500
4501   mode = mp->mode;
4502   s = format (0, "%U", format_lisp_map_request_mode, mode);
4503   vec_add1 (s, 0);
4504
4505   vat_json_init_object (&node);
4506   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4507   vat_json_print (vam->ofp, &node);
4508   vat_json_free (&node);
4509
4510   vec_free (s);
4511   vam->retval = ntohl (mp->retval);
4512   vam->result_ready = 1;
4513 }
4514
4515 static void
4516   vl_api_one_show_xtr_mode_reply_t_handler
4517   (vl_api_one_show_xtr_mode_reply_t * mp)
4518 {
4519   vat_main_t *vam = &vat_main;
4520   i32 retval = ntohl (mp->retval);
4521
4522   if (0 <= retval)
4523     {
4524       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4525     }
4526
4527   vam->retval = retval;
4528   vam->result_ready = 1;
4529 }
4530
4531 static void
4532   vl_api_one_show_xtr_mode_reply_t_handler_json
4533   (vl_api_one_show_xtr_mode_reply_t * mp)
4534 {
4535   vat_main_t *vam = &vat_main;
4536   vat_json_node_t node;
4537   u8 *status = 0;
4538
4539   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4540   vec_add1 (status, 0);
4541
4542   vat_json_init_object (&node);
4543   vat_json_object_add_string_copy (&node, "status", status);
4544
4545   vec_free (status);
4546
4547   vat_json_print (vam->ofp, &node);
4548   vat_json_free (&node);
4549
4550   vam->retval = ntohl (mp->retval);
4551   vam->result_ready = 1;
4552 }
4553
4554 static void
4555   vl_api_one_show_pitr_mode_reply_t_handler
4556   (vl_api_one_show_pitr_mode_reply_t * mp)
4557 {
4558   vat_main_t *vam = &vat_main;
4559   i32 retval = ntohl (mp->retval);
4560
4561   if (0 <= retval)
4562     {
4563       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4564     }
4565
4566   vam->retval = retval;
4567   vam->result_ready = 1;
4568 }
4569
4570 static void
4571   vl_api_one_show_pitr_mode_reply_t_handler_json
4572   (vl_api_one_show_pitr_mode_reply_t * mp)
4573 {
4574   vat_main_t *vam = &vat_main;
4575   vat_json_node_t node;
4576   u8 *status = 0;
4577
4578   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4579   vec_add1 (status, 0);
4580
4581   vat_json_init_object (&node);
4582   vat_json_object_add_string_copy (&node, "status", status);
4583
4584   vec_free (status);
4585
4586   vat_json_print (vam->ofp, &node);
4587   vat_json_free (&node);
4588
4589   vam->retval = ntohl (mp->retval);
4590   vam->result_ready = 1;
4591 }
4592
4593 static void
4594   vl_api_one_show_petr_mode_reply_t_handler
4595   (vl_api_one_show_petr_mode_reply_t * mp)
4596 {
4597   vat_main_t *vam = &vat_main;
4598   i32 retval = ntohl (mp->retval);
4599
4600   if (0 <= retval)
4601     {
4602       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4603     }
4604
4605   vam->retval = retval;
4606   vam->result_ready = 1;
4607 }
4608
4609 static void
4610   vl_api_one_show_petr_mode_reply_t_handler_json
4611   (vl_api_one_show_petr_mode_reply_t * mp)
4612 {
4613   vat_main_t *vam = &vat_main;
4614   vat_json_node_t node;
4615   u8 *status = 0;
4616
4617   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4618   vec_add1 (status, 0);
4619
4620   vat_json_init_object (&node);
4621   vat_json_object_add_string_copy (&node, "status", status);
4622
4623   vec_free (status);
4624
4625   vat_json_print (vam->ofp, &node);
4626   vat_json_free (&node);
4627
4628   vam->retval = ntohl (mp->retval);
4629   vam->result_ready = 1;
4630 }
4631
4632 static void
4633   vl_api_show_one_use_petr_reply_t_handler
4634   (vl_api_show_one_use_petr_reply_t * mp)
4635 {
4636   vat_main_t *vam = &vat_main;
4637   i32 retval = ntohl (mp->retval);
4638
4639   if (0 <= retval)
4640     {
4641       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4642       if (mp->status)
4643         {
4644           print (vam->ofp, "Proxy-ETR address; %U",
4645                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4646                  mp->address);
4647         }
4648     }
4649
4650   vam->retval = retval;
4651   vam->result_ready = 1;
4652 }
4653
4654 static void
4655   vl_api_show_one_use_petr_reply_t_handler_json
4656   (vl_api_show_one_use_petr_reply_t * mp)
4657 {
4658   vat_main_t *vam = &vat_main;
4659   vat_json_node_t node;
4660   u8 *status = 0;
4661   struct in_addr ip4;
4662   struct in6_addr ip6;
4663
4664   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4665   vec_add1 (status, 0);
4666
4667   vat_json_init_object (&node);
4668   vat_json_object_add_string_copy (&node, "status", status);
4669   if (mp->status)
4670     {
4671       if (mp->is_ip4)
4672         {
4673           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4674           vat_json_object_add_ip6 (&node, "address", ip6);
4675         }
4676       else
4677         {
4678           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4679           vat_json_object_add_ip4 (&node, "address", ip4);
4680         }
4681     }
4682
4683   vec_free (status);
4684
4685   vat_json_print (vam->ofp, &node);
4686   vat_json_free (&node);
4687
4688   vam->retval = ntohl (mp->retval);
4689   vam->result_ready = 1;
4690 }
4691
4692 static void
4693   vl_api_show_one_nsh_mapping_reply_t_handler
4694   (vl_api_show_one_nsh_mapping_reply_t * mp)
4695 {
4696   vat_main_t *vam = &vat_main;
4697   i32 retval = ntohl (mp->retval);
4698
4699   if (0 <= retval)
4700     {
4701       print (vam->ofp, "%-20s%-16s",
4702              mp->is_set ? "set" : "not-set",
4703              mp->is_set ? (char *) mp->locator_set_name : "");
4704     }
4705
4706   vam->retval = retval;
4707   vam->result_ready = 1;
4708 }
4709
4710 static void
4711   vl_api_show_one_nsh_mapping_reply_t_handler_json
4712   (vl_api_show_one_nsh_mapping_reply_t * mp)
4713 {
4714   vat_main_t *vam = &vat_main;
4715   vat_json_node_t node;
4716   u8 *status = 0;
4717
4718   status = format (0, "%s", mp->is_set ? "yes" : "no");
4719   vec_add1 (status, 0);
4720
4721   vat_json_init_object (&node);
4722   vat_json_object_add_string_copy (&node, "is_set", status);
4723   if (mp->is_set)
4724     {
4725       vat_json_object_add_string_copy (&node, "locator_set",
4726                                        mp->locator_set_name);
4727     }
4728
4729   vec_free (status);
4730
4731   vat_json_print (vam->ofp, &node);
4732   vat_json_free (&node);
4733
4734   vam->retval = ntohl (mp->retval);
4735   vam->result_ready = 1;
4736 }
4737
4738 static void
4739   vl_api_show_one_map_register_ttl_reply_t_handler
4740   (vl_api_show_one_map_register_ttl_reply_t * mp)
4741 {
4742   vat_main_t *vam = &vat_main;
4743   i32 retval = ntohl (mp->retval);
4744
4745   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4746
4747   if (0 <= retval)
4748     {
4749       print (vam->ofp, "ttl: %u", mp->ttl);
4750     }
4751
4752   vam->retval = retval;
4753   vam->result_ready = 1;
4754 }
4755
4756 static void
4757   vl_api_show_one_map_register_ttl_reply_t_handler_json
4758   (vl_api_show_one_map_register_ttl_reply_t * mp)
4759 {
4760   vat_main_t *vam = &vat_main;
4761   vat_json_node_t node;
4762
4763   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4764   vat_json_init_object (&node);
4765   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4766
4767   vat_json_print (vam->ofp, &node);
4768   vat_json_free (&node);
4769
4770   vam->retval = ntohl (mp->retval);
4771   vam->result_ready = 1;
4772 }
4773
4774 static void
4775 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   i32 retval = ntohl (mp->retval);
4779
4780   if (0 <= retval)
4781     {
4782       print (vam->ofp, "%-20s%-16s",
4783              mp->status ? "enabled" : "disabled",
4784              mp->status ? (char *) mp->locator_set_name : "");
4785     }
4786
4787   vam->retval = retval;
4788   vam->result_ready = 1;
4789 }
4790
4791 static void
4792 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4793 {
4794   vat_main_t *vam = &vat_main;
4795   vat_json_node_t node;
4796   u8 *status = 0;
4797
4798   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4799   vec_add1 (status, 0);
4800
4801   vat_json_init_object (&node);
4802   vat_json_object_add_string_copy (&node, "status", status);
4803   if (mp->status)
4804     {
4805       vat_json_object_add_string_copy (&node, "locator_set",
4806                                        mp->locator_set_name);
4807     }
4808
4809   vec_free (status);
4810
4811   vat_json_print (vam->ofp, &node);
4812   vat_json_free (&node);
4813
4814   vam->retval = ntohl (mp->retval);
4815   vam->result_ready = 1;
4816 }
4817
4818 static u8 *
4819 format_policer_type (u8 * s, va_list * va)
4820 {
4821   u32 i = va_arg (*va, u32);
4822
4823   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4824     s = format (s, "1r2c");
4825   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4826     s = format (s, "1r3c");
4827   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4828     s = format (s, "2r3c-2698");
4829   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4830     s = format (s, "2r3c-4115");
4831   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4832     s = format (s, "2r3c-mef5cf1");
4833   else
4834     s = format (s, "ILLEGAL");
4835   return s;
4836 }
4837
4838 static u8 *
4839 format_policer_rate_type (u8 * s, va_list * va)
4840 {
4841   u32 i = va_arg (*va, u32);
4842
4843   if (i == SSE2_QOS_RATE_KBPS)
4844     s = format (s, "kbps");
4845   else if (i == SSE2_QOS_RATE_PPS)
4846     s = format (s, "pps");
4847   else
4848     s = format (s, "ILLEGAL");
4849   return s;
4850 }
4851
4852 static u8 *
4853 format_policer_round_type (u8 * s, va_list * va)
4854 {
4855   u32 i = va_arg (*va, u32);
4856
4857   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4858     s = format (s, "closest");
4859   else if (i == SSE2_QOS_ROUND_TO_UP)
4860     s = format (s, "up");
4861   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4862     s = format (s, "down");
4863   else
4864     s = format (s, "ILLEGAL");
4865   return s;
4866 }
4867
4868 static u8 *
4869 format_policer_action_type (u8 * s, va_list * va)
4870 {
4871   u32 i = va_arg (*va, u32);
4872
4873   if (i == SSE2_QOS_ACTION_DROP)
4874     s = format (s, "drop");
4875   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4876     s = format (s, "transmit");
4877   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4878     s = format (s, "mark-and-transmit");
4879   else
4880     s = format (s, "ILLEGAL");
4881   return s;
4882 }
4883
4884 static u8 *
4885 format_dscp (u8 * s, va_list * va)
4886 {
4887   u32 i = va_arg (*va, u32);
4888   char *t = 0;
4889
4890   switch (i)
4891     {
4892 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4893       foreach_vnet_dscp
4894 #undef _
4895     default:
4896       return format (s, "ILLEGAL");
4897     }
4898   s = format (s, "%s", t);
4899   return s;
4900 }
4901
4902 static void
4903 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4904 {
4905   vat_main_t *vam = &vat_main;
4906   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4907
4908   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4909     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4910   else
4911     conform_dscp_str = format (0, "");
4912
4913   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4914     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4915   else
4916     exceed_dscp_str = format (0, "");
4917
4918   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4919     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4920   else
4921     violate_dscp_str = format (0, "");
4922
4923   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4924          "rate type %U, round type %U, %s rate, %s color-aware, "
4925          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4926          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4927          "conform action %U%s, exceed action %U%s, violate action %U%s",
4928          mp->name,
4929          format_policer_type, mp->type,
4930          ntohl (mp->cir),
4931          ntohl (mp->eir),
4932          clib_net_to_host_u64 (mp->cb),
4933          clib_net_to_host_u64 (mp->eb),
4934          format_policer_rate_type, mp->rate_type,
4935          format_policer_round_type, mp->round_type,
4936          mp->single_rate ? "single" : "dual",
4937          mp->color_aware ? "is" : "not",
4938          ntohl (mp->cir_tokens_per_period),
4939          ntohl (mp->pir_tokens_per_period),
4940          ntohl (mp->scale),
4941          ntohl (mp->current_limit),
4942          ntohl (mp->current_bucket),
4943          ntohl (mp->extended_limit),
4944          ntohl (mp->extended_bucket),
4945          clib_net_to_host_u64 (mp->last_update_time),
4946          format_policer_action_type, mp->conform_action_type,
4947          conform_dscp_str,
4948          format_policer_action_type, mp->exceed_action_type,
4949          exceed_dscp_str,
4950          format_policer_action_type, mp->violate_action_type,
4951          violate_dscp_str);
4952
4953   vec_free (conform_dscp_str);
4954   vec_free (exceed_dscp_str);
4955   vec_free (violate_dscp_str);
4956 }
4957
4958 static void vl_api_policer_details_t_handler_json
4959   (vl_api_policer_details_t * mp)
4960 {
4961   vat_main_t *vam = &vat_main;
4962   vat_json_node_t *node;
4963   u8 *rate_type_str, *round_type_str, *type_str;
4964   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4965
4966   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4967   round_type_str =
4968     format (0, "%U", format_policer_round_type, mp->round_type);
4969   type_str = format (0, "%U", format_policer_type, mp->type);
4970   conform_action_str = format (0, "%U", format_policer_action_type,
4971                                mp->conform_action_type);
4972   exceed_action_str = format (0, "%U", format_policer_action_type,
4973                               mp->exceed_action_type);
4974   violate_action_str = format (0, "%U", format_policer_action_type,
4975                                mp->violate_action_type);
4976
4977   if (VAT_JSON_ARRAY != vam->json_tree.type)
4978     {
4979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4980       vat_json_init_array (&vam->json_tree);
4981     }
4982   node = vat_json_array_add (&vam->json_tree);
4983
4984   vat_json_init_object (node);
4985   vat_json_object_add_string_copy (node, "name", mp->name);
4986   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4987   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4988   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4989   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4990   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4991   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4992   vat_json_object_add_string_copy (node, "type", type_str);
4993   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4994   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4995   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4996   vat_json_object_add_uint (node, "cir_tokens_per_period",
4997                             ntohl (mp->cir_tokens_per_period));
4998   vat_json_object_add_uint (node, "eir_tokens_per_period",
4999                             ntohl (mp->pir_tokens_per_period));
5000   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
5001   vat_json_object_add_uint (node, "current_bucket",
5002                             ntohl (mp->current_bucket));
5003   vat_json_object_add_uint (node, "extended_limit",
5004                             ntohl (mp->extended_limit));
5005   vat_json_object_add_uint (node, "extended_bucket",
5006                             ntohl (mp->extended_bucket));
5007   vat_json_object_add_uint (node, "last_update_time",
5008                             ntohl (mp->last_update_time));
5009   vat_json_object_add_string_copy (node, "conform_action",
5010                                    conform_action_str);
5011   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5012     {
5013       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5014       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5015       vec_free (dscp_str);
5016     }
5017   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5018   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5019     {
5020       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5021       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5022       vec_free (dscp_str);
5023     }
5024   vat_json_object_add_string_copy (node, "violate_action",
5025                                    violate_action_str);
5026   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5027     {
5028       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5029       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5030       vec_free (dscp_str);
5031     }
5032
5033   vec_free (rate_type_str);
5034   vec_free (round_type_str);
5035   vec_free (type_str);
5036   vec_free (conform_action_str);
5037   vec_free (exceed_action_str);
5038   vec_free (violate_action_str);
5039 }
5040
5041 static void
5042 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5043                                            mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046   int i, count = ntohl (mp->count);
5047
5048   if (count > 0)
5049     print (vam->ofp, "classify table ids (%d) : ", count);
5050   for (i = 0; i < count; i++)
5051     {
5052       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5053       print (vam->ofp, (i < count - 1) ? "," : "");
5054     }
5055   vam->retval = ntohl (mp->retval);
5056   vam->result_ready = 1;
5057 }
5058
5059 static void
5060   vl_api_classify_table_ids_reply_t_handler_json
5061   (vl_api_classify_table_ids_reply_t * mp)
5062 {
5063   vat_main_t *vam = &vat_main;
5064   int i, count = ntohl (mp->count);
5065
5066   if (count > 0)
5067     {
5068       vat_json_node_t node;
5069
5070       vat_json_init_object (&node);
5071       for (i = 0; i < count; i++)
5072         {
5073           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5074         }
5075       vat_json_print (vam->ofp, &node);
5076       vat_json_free (&node);
5077     }
5078   vam->retval = ntohl (mp->retval);
5079   vam->result_ready = 1;
5080 }
5081
5082 static void
5083   vl_api_classify_table_by_interface_reply_t_handler
5084   (vl_api_classify_table_by_interface_reply_t * mp)
5085 {
5086   vat_main_t *vam = &vat_main;
5087   u32 table_id;
5088
5089   table_id = ntohl (mp->l2_table_id);
5090   if (table_id != ~0)
5091     print (vam->ofp, "l2 table id : %d", table_id);
5092   else
5093     print (vam->ofp, "l2 table id : No input ACL tables configured");
5094   table_id = ntohl (mp->ip4_table_id);
5095   if (table_id != ~0)
5096     print (vam->ofp, "ip4 table id : %d", table_id);
5097   else
5098     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5099   table_id = ntohl (mp->ip6_table_id);
5100   if (table_id != ~0)
5101     print (vam->ofp, "ip6 table id : %d", table_id);
5102   else
5103     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5104   vam->retval = ntohl (mp->retval);
5105   vam->result_ready = 1;
5106 }
5107
5108 static void
5109   vl_api_classify_table_by_interface_reply_t_handler_json
5110   (vl_api_classify_table_by_interface_reply_t * mp)
5111 {
5112   vat_main_t *vam = &vat_main;
5113   vat_json_node_t node;
5114
5115   vat_json_init_object (&node);
5116
5117   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5118   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5119   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5120
5121   vat_json_print (vam->ofp, &node);
5122   vat_json_free (&node);
5123
5124   vam->retval = ntohl (mp->retval);
5125   vam->result_ready = 1;
5126 }
5127
5128 static void vl_api_policer_add_del_reply_t_handler
5129   (vl_api_policer_add_del_reply_t * mp)
5130 {
5131   vat_main_t *vam = &vat_main;
5132   i32 retval = ntohl (mp->retval);
5133   if (vam->async_mode)
5134     {
5135       vam->async_errors += (retval < 0);
5136     }
5137   else
5138     {
5139       vam->retval = retval;
5140       vam->result_ready = 1;
5141       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5142         /*
5143          * Note: this is just barely thread-safe, depends on
5144          * the main thread spinning waiting for an answer...
5145          */
5146         errmsg ("policer index %d", ntohl (mp->policer_index));
5147     }
5148 }
5149
5150 static void vl_api_policer_add_del_reply_t_handler_json
5151   (vl_api_policer_add_del_reply_t * mp)
5152 {
5153   vat_main_t *vam = &vat_main;
5154   vat_json_node_t node;
5155
5156   vat_json_init_object (&node);
5157   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5158   vat_json_object_add_uint (&node, "policer_index",
5159                             ntohl (mp->policer_index));
5160
5161   vat_json_print (vam->ofp, &node);
5162   vat_json_free (&node);
5163
5164   vam->retval = ntohl (mp->retval);
5165   vam->result_ready = 1;
5166 }
5167
5168 /* Format hex dump. */
5169 u8 *
5170 format_hex_bytes (u8 * s, va_list * va)
5171 {
5172   u8 *bytes = va_arg (*va, u8 *);
5173   int n_bytes = va_arg (*va, int);
5174   uword i;
5175
5176   /* Print short or long form depending on byte count. */
5177   uword short_form = n_bytes <= 32;
5178   u32 indent = format_get_indent (s);
5179
5180   if (n_bytes == 0)
5181     return s;
5182
5183   for (i = 0; i < n_bytes; i++)
5184     {
5185       if (!short_form && (i % 32) == 0)
5186         s = format (s, "%08x: ", i);
5187       s = format (s, "%02x", bytes[i]);
5188       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5189         s = format (s, "\n%U", format_white_space, indent);
5190     }
5191
5192   return s;
5193 }
5194
5195 static void
5196 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5197                                             * mp)
5198 {
5199   vat_main_t *vam = &vat_main;
5200   i32 retval = ntohl (mp->retval);
5201   if (retval == 0)
5202     {
5203       print (vam->ofp, "classify table info :");
5204       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5205              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5206              ntohl (mp->miss_next_index));
5207       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5208              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5209              ntohl (mp->match_n_vectors));
5210       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5211              ntohl (mp->mask_length));
5212     }
5213   vam->retval = retval;
5214   vam->result_ready = 1;
5215 }
5216
5217 static void
5218   vl_api_classify_table_info_reply_t_handler_json
5219   (vl_api_classify_table_info_reply_t * mp)
5220 {
5221   vat_main_t *vam = &vat_main;
5222   vat_json_node_t node;
5223
5224   i32 retval = ntohl (mp->retval);
5225   if (retval == 0)
5226     {
5227       vat_json_init_object (&node);
5228
5229       vat_json_object_add_int (&node, "sessions",
5230                                ntohl (mp->active_sessions));
5231       vat_json_object_add_int (&node, "nexttbl",
5232                                ntohl (mp->next_table_index));
5233       vat_json_object_add_int (&node, "nextnode",
5234                                ntohl (mp->miss_next_index));
5235       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5236       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5237       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5238       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5239                       ntohl (mp->mask_length), 0);
5240       vat_json_object_add_string_copy (&node, "mask", s);
5241
5242       vat_json_print (vam->ofp, &node);
5243       vat_json_free (&node);
5244     }
5245   vam->retval = ntohl (mp->retval);
5246   vam->result_ready = 1;
5247 }
5248
5249 static void
5250 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5251                                            mp)
5252 {
5253   vat_main_t *vam = &vat_main;
5254
5255   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5256          ntohl (mp->hit_next_index), ntohl (mp->advance),
5257          ntohl (mp->opaque_index));
5258   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5259          ntohl (mp->match_length));
5260 }
5261
5262 static void
5263   vl_api_classify_session_details_t_handler_json
5264   (vl_api_classify_session_details_t * mp)
5265 {
5266   vat_main_t *vam = &vat_main;
5267   vat_json_node_t *node = NULL;
5268
5269   if (VAT_JSON_ARRAY != vam->json_tree.type)
5270     {
5271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5272       vat_json_init_array (&vam->json_tree);
5273     }
5274   node = vat_json_array_add (&vam->json_tree);
5275
5276   vat_json_init_object (node);
5277   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5278   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5279   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5280   u8 *s =
5281     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5282             0);
5283   vat_json_object_add_string_copy (node, "match", s);
5284 }
5285
5286 static void vl_api_pg_create_interface_reply_t_handler
5287   (vl_api_pg_create_interface_reply_t * mp)
5288 {
5289   vat_main_t *vam = &vat_main;
5290
5291   vam->retval = ntohl (mp->retval);
5292   vam->result_ready = 1;
5293 }
5294
5295 static void vl_api_pg_create_interface_reply_t_handler_json
5296   (vl_api_pg_create_interface_reply_t * mp)
5297 {
5298   vat_main_t *vam = &vat_main;
5299   vat_json_node_t node;
5300
5301   i32 retval = ntohl (mp->retval);
5302   if (retval == 0)
5303     {
5304       vat_json_init_object (&node);
5305
5306       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5307
5308       vat_json_print (vam->ofp, &node);
5309       vat_json_free (&node);
5310     }
5311   vam->retval = ntohl (mp->retval);
5312   vam->result_ready = 1;
5313 }
5314
5315 static void vl_api_policer_classify_details_t_handler
5316   (vl_api_policer_classify_details_t * mp)
5317 {
5318   vat_main_t *vam = &vat_main;
5319
5320   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5321          ntohl (mp->table_index));
5322 }
5323
5324 static void vl_api_policer_classify_details_t_handler_json
5325   (vl_api_policer_classify_details_t * mp)
5326 {
5327   vat_main_t *vam = &vat_main;
5328   vat_json_node_t *node;
5329
5330   if (VAT_JSON_ARRAY != vam->json_tree.type)
5331     {
5332       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5333       vat_json_init_array (&vam->json_tree);
5334     }
5335   node = vat_json_array_add (&vam->json_tree);
5336
5337   vat_json_init_object (node);
5338   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5339   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5340 }
5341
5342 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5343   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5344 {
5345   vat_main_t *vam = &vat_main;
5346   i32 retval = ntohl (mp->retval);
5347   if (vam->async_mode)
5348     {
5349       vam->async_errors += (retval < 0);
5350     }
5351   else
5352     {
5353       vam->retval = retval;
5354       vam->sw_if_index = ntohl (mp->sw_if_index);
5355       vam->result_ready = 1;
5356     }
5357   vam->regenerate_interface_table = 1;
5358 }
5359
5360 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5361   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5362 {
5363   vat_main_t *vam = &vat_main;
5364   vat_json_node_t node;
5365
5366   vat_json_init_object (&node);
5367   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5368   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5369
5370   vat_json_print (vam->ofp, &node);
5371   vat_json_free (&node);
5372
5373   vam->retval = ntohl (mp->retval);
5374   vam->result_ready = 1;
5375 }
5376
5377 static void vl_api_flow_classify_details_t_handler
5378   (vl_api_flow_classify_details_t * mp)
5379 {
5380   vat_main_t *vam = &vat_main;
5381
5382   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5383          ntohl (mp->table_index));
5384 }
5385
5386 static void vl_api_flow_classify_details_t_handler_json
5387   (vl_api_flow_classify_details_t * mp)
5388 {
5389   vat_main_t *vam = &vat_main;
5390   vat_json_node_t *node;
5391
5392   if (VAT_JSON_ARRAY != vam->json_tree.type)
5393     {
5394       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5395       vat_json_init_array (&vam->json_tree);
5396     }
5397   node = vat_json_array_add (&vam->json_tree);
5398
5399   vat_json_init_object (node);
5400   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5401   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5402 }
5403
5404 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5405 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5406 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5407 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5408 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5409 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5410 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5411 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5412 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5413 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5414 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5415 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5416 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5417 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5418 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5419 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5420 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5421 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5422 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5423 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5424 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5425 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5426
5427 /*
5428  * Generate boilerplate reply handlers, which
5429  * dig the return value out of the xxx_reply_t API message,
5430  * stick it into vam->retval, and set vam->result_ready
5431  *
5432  * Could also do this by pointing N message decode slots at
5433  * a single function, but that could break in subtle ways.
5434  */
5435
5436 #define foreach_standard_reply_retval_handler           \
5437 _(sw_interface_set_flags_reply)                         \
5438 _(sw_interface_add_del_address_reply)                   \
5439 _(sw_interface_set_rx_mode_reply)                       \
5440 _(sw_interface_set_rx_placement_reply)                  \
5441 _(sw_interface_set_table_reply)                         \
5442 _(sw_interface_set_mpls_enable_reply)                   \
5443 _(sw_interface_set_vpath_reply)                         \
5444 _(sw_interface_set_vxlan_bypass_reply)                  \
5445 _(sw_interface_set_geneve_bypass_reply)                 \
5446 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5447 _(sw_interface_set_l2_bridge_reply)                     \
5448 _(bridge_domain_add_del_reply)                          \
5449 _(sw_interface_set_l2_xconnect_reply)                   \
5450 _(l2fib_add_del_reply)                                  \
5451 _(l2fib_flush_int_reply)                                \
5452 _(l2fib_flush_bd_reply)                                 \
5453 _(ip_add_del_route_reply)                               \
5454 _(ip_table_add_del_reply)                               \
5455 _(ip_mroute_add_del_reply)                              \
5456 _(mpls_route_add_del_reply)                             \
5457 _(mpls_table_add_del_reply)                             \
5458 _(mpls_ip_bind_unbind_reply)                            \
5459 _(bier_route_add_del_reply)                             \
5460 _(bier_table_add_del_reply)                             \
5461 _(proxy_arp_add_del_reply)                              \
5462 _(proxy_arp_intfc_enable_disable_reply)                 \
5463 _(sw_interface_set_unnumbered_reply)                    \
5464 _(ip_neighbor_add_del_reply)                            \
5465 _(oam_add_del_reply)                                    \
5466 _(reset_fib_reply)                                      \
5467 _(dhcp_proxy_config_reply)                              \
5468 _(dhcp_proxy_set_vss_reply)                             \
5469 _(dhcp_client_config_reply)                             \
5470 _(set_ip_flow_hash_reply)                               \
5471 _(sw_interface_ip6_enable_disable_reply)                \
5472 _(ip6nd_proxy_add_del_reply)                            \
5473 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5474 _(sw_interface_ip6nd_ra_config_reply)                   \
5475 _(set_arp_neighbor_limit_reply)                         \
5476 _(l2_patch_add_del_reply)                               \
5477 _(sr_mpls_policy_add_reply)                             \
5478 _(sr_mpls_policy_mod_reply)                             \
5479 _(sr_mpls_policy_del_reply)                             \
5480 _(sr_policy_add_reply)                                  \
5481 _(sr_policy_mod_reply)                                  \
5482 _(sr_policy_del_reply)                                  \
5483 _(sr_localsid_add_del_reply)                            \
5484 _(sr_steering_add_del_reply)                            \
5485 _(classify_add_del_session_reply)                       \
5486 _(classify_set_interface_ip_table_reply)                \
5487 _(classify_set_interface_l2_tables_reply)               \
5488 _(l2tpv3_set_tunnel_cookies_reply)                      \
5489 _(l2tpv3_interface_enable_disable_reply)                \
5490 _(l2tpv3_set_lookup_key_reply)                          \
5491 _(l2_fib_clear_table_reply)                             \
5492 _(l2_interface_efp_filter_reply)                        \
5493 _(l2_interface_vlan_tag_rewrite_reply)                  \
5494 _(modify_vhost_user_if_reply)                           \
5495 _(delete_vhost_user_if_reply)                           \
5496 _(ip_probe_neighbor_reply)                              \
5497 _(ip_scan_neighbor_enable_disable_reply)                \
5498 _(want_ip4_arp_events_reply)                            \
5499 _(want_ip6_nd_events_reply)                             \
5500 _(want_l2_macs_events_reply)                            \
5501 _(input_acl_set_interface_reply)                        \
5502 _(ipsec_spd_add_del_reply)                              \
5503 _(ipsec_interface_add_del_spd_reply)                    \
5504 _(ipsec_spd_add_del_entry_reply)                        \
5505 _(ipsec_sad_add_del_entry_reply)                        \
5506 _(ipsec_sa_set_key_reply)                               \
5507 _(ipsec_tunnel_if_add_del_reply)                        \
5508 _(ipsec_tunnel_if_set_key_reply)                        \
5509 _(ipsec_tunnel_if_set_sa_reply)                         \
5510 _(ikev2_profile_add_del_reply)                          \
5511 _(ikev2_profile_set_auth_reply)                         \
5512 _(ikev2_profile_set_id_reply)                           \
5513 _(ikev2_profile_set_ts_reply)                           \
5514 _(ikev2_set_local_key_reply)                            \
5515 _(ikev2_set_responder_reply)                            \
5516 _(ikev2_set_ike_transforms_reply)                       \
5517 _(ikev2_set_esp_transforms_reply)                       \
5518 _(ikev2_set_sa_lifetime_reply)                          \
5519 _(ikev2_initiate_sa_init_reply)                         \
5520 _(ikev2_initiate_del_ike_sa_reply)                      \
5521 _(ikev2_initiate_del_child_sa_reply)                    \
5522 _(ikev2_initiate_rekey_child_sa_reply)                  \
5523 _(delete_loopback_reply)                                \
5524 _(bd_ip_mac_add_del_reply)                              \
5525 _(want_interface_events_reply)                          \
5526 _(want_stats_reply)                                     \
5527 _(cop_interface_enable_disable_reply)                   \
5528 _(cop_whitelist_enable_disable_reply)                   \
5529 _(sw_interface_clear_stats_reply)                       \
5530 _(ioam_enable_reply)                                    \
5531 _(ioam_disable_reply)                                   \
5532 _(one_add_del_locator_reply)                            \
5533 _(one_add_del_local_eid_reply)                          \
5534 _(one_add_del_remote_mapping_reply)                     \
5535 _(one_add_del_adjacency_reply)                          \
5536 _(one_add_del_map_resolver_reply)                       \
5537 _(one_add_del_map_server_reply)                         \
5538 _(one_enable_disable_reply)                             \
5539 _(one_rloc_probe_enable_disable_reply)                  \
5540 _(one_map_register_enable_disable_reply)                \
5541 _(one_map_register_set_ttl_reply)                       \
5542 _(one_set_transport_protocol_reply)                     \
5543 _(one_map_register_fallback_threshold_reply)            \
5544 _(one_pitr_set_locator_set_reply)                       \
5545 _(one_map_request_mode_reply)                           \
5546 _(one_add_del_map_request_itr_rlocs_reply)              \
5547 _(one_eid_table_add_del_map_reply)                      \
5548 _(one_use_petr_reply)                                   \
5549 _(one_stats_enable_disable_reply)                       \
5550 _(one_add_del_l2_arp_entry_reply)                       \
5551 _(one_add_del_ndp_entry_reply)                          \
5552 _(one_stats_flush_reply)                                \
5553 _(one_enable_disable_xtr_mode_reply)                    \
5554 _(one_enable_disable_pitr_mode_reply)                   \
5555 _(one_enable_disable_petr_mode_reply)                   \
5556 _(gpe_enable_disable_reply)                             \
5557 _(gpe_set_encap_mode_reply)                             \
5558 _(gpe_add_del_iface_reply)                              \
5559 _(gpe_add_del_native_fwd_rpath_reply)                   \
5560 _(af_packet_delete_reply)                               \
5561 _(policer_classify_set_interface_reply)                 \
5562 _(netmap_create_reply)                                  \
5563 _(netmap_delete_reply)                                  \
5564 _(set_ipfix_exporter_reply)                             \
5565 _(set_ipfix_classify_stream_reply)                      \
5566 _(ipfix_classify_table_add_del_reply)                   \
5567 _(flow_classify_set_interface_reply)                    \
5568 _(sw_interface_span_enable_disable_reply)               \
5569 _(pg_capture_reply)                                     \
5570 _(pg_enable_disable_reply)                              \
5571 _(ip_source_and_port_range_check_add_del_reply)         \
5572 _(ip_source_and_port_range_check_interface_add_del_reply)\
5573 _(delete_subif_reply)                                   \
5574 _(l2_interface_pbb_tag_rewrite_reply)                   \
5575 _(set_punt_reply)                                       \
5576 _(feature_enable_disable_reply)                         \
5577 _(sw_interface_tag_add_del_reply)                       \
5578 _(hw_interface_set_mtu_reply)                           \
5579 _(p2p_ethernet_add_reply)                               \
5580 _(p2p_ethernet_del_reply)                               \
5581 _(lldp_config_reply)                                    \
5582 _(sw_interface_set_lldp_reply)                          \
5583 _(tcp_configure_src_addresses_reply)                    \
5584 _(dns_enable_disable_reply)                             \
5585 _(dns_name_server_add_del_reply)                        \
5586 _(session_rule_add_del_reply)                           \
5587 _(ip_container_proxy_add_del_reply)                     \
5588 _(output_acl_set_interface_reply)                       \
5589 _(qos_record_enable_disable_reply)
5590
5591 #define _(n)                                    \
5592     static void vl_api_##n##_t_handler          \
5593     (vl_api_##n##_t * mp)                       \
5594     {                                           \
5595         vat_main_t * vam = &vat_main;           \
5596         i32 retval = ntohl(mp->retval);         \
5597         if (vam->async_mode) {                  \
5598             vam->async_errors += (retval < 0);  \
5599         } else {                                \
5600             vam->retval = retval;               \
5601             vam->result_ready = 1;              \
5602         }                                       \
5603     }
5604 foreach_standard_reply_retval_handler;
5605 #undef _
5606
5607 #define _(n)                                    \
5608     static void vl_api_##n##_t_handler_json     \
5609     (vl_api_##n##_t * mp)                       \
5610     {                                           \
5611         vat_main_t * vam = &vat_main;           \
5612         vat_json_node_t node;                   \
5613         vat_json_init_object(&node);            \
5614         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5615         vat_json_print(vam->ofp, &node);        \
5616         vam->retval = ntohl(mp->retval);        \
5617         vam->result_ready = 1;                  \
5618     }
5619 foreach_standard_reply_retval_handler;
5620 #undef _
5621
5622 /*
5623  * Table of message reply handlers, must include boilerplate handlers
5624  * we just generated
5625  */
5626
5627 #define foreach_vpe_api_reply_msg                                       \
5628 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5629 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5630 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5631 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5632 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5633 _(CLI_REPLY, cli_reply)                                                 \
5634 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5635 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5636   sw_interface_add_del_address_reply)                                   \
5637 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5638 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5639 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5640 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5641 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5642 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5643 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5644 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5645 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5646 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5647   sw_interface_set_l2_xconnect_reply)                                   \
5648 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5649   sw_interface_set_l2_bridge_reply)                                     \
5650 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5651 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5652 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5653 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5654 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5655 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5656 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5657 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5658 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5659 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5660 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5661 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5662 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5663 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5664 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5665 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5666 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5667 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5668 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5669 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5670 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5671 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5672 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5673 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5674 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5675 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5676 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5677 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5678 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5679 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5680 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5681   proxy_arp_intfc_enable_disable_reply)                                 \
5682 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5683 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5684   sw_interface_set_unnumbered_reply)                                    \
5685 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5686 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5687 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5688 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5689 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5690 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5691 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5692 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5693 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5694 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5695 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5696   sw_interface_ip6_enable_disable_reply)                                \
5697 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5698 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5699 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5700   sw_interface_ip6nd_ra_prefix_reply)                                   \
5701 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5702   sw_interface_ip6nd_ra_config_reply)                                   \
5703 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5704 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5705 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5706 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5707 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5708 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5709 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5710 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5711 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5712 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5713 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5714 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5715 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5716 classify_set_interface_ip_table_reply)                                  \
5717 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5718   classify_set_interface_l2_tables_reply)                               \
5719 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5720 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5721 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5722 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5723 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5724   l2tpv3_interface_enable_disable_reply)                                \
5725 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5726 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5727 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5728 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5729 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5730 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5731 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5732 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5733 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5734 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5735 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5736 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5737 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5738 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5739 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5740 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5741 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5742 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5743 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5744 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5745 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5746 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5747 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5748 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5749 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5750 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5751 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5752 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5753 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5754 _(L2_MACS_EVENT, l2_macs_event)                                         \
5755 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5756 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5757 _(IP_DETAILS, ip_details)                                               \
5758 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5759 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5760 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5761 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5762 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5763 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5764 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5765 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5766 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5767 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5768 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5769 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5770 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5771 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5772 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5773 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5774 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5775 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5776 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5777 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5778 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5779 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5780 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5781 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5782 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5783 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5784 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5785 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5786 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5787 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5788 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5789 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5790 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5791 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5792 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5793 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5794 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5795 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5796 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5797 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5798 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5799 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5800 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5801 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5802   one_map_register_enable_disable_reply)                                \
5803 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5804 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5805 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5806 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5807   one_map_register_fallback_threshold_reply)                            \
5808 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5809   one_rloc_probe_enable_disable_reply)                                  \
5810 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5811 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5812 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5813 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5814 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5815 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5816 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5817 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5818 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5819 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5820 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5821 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5822 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5823 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5824 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5825 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5826   show_one_stats_enable_disable_reply)                                  \
5827 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5828 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5829 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5830 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5831 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5832 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5833 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5834 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5835   one_enable_disable_pitr_mode_reply)                                   \
5836 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5837   one_enable_disable_petr_mode_reply)                                   \
5838 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5839 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5840 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5841 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5842 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5843 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5844 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5845 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5846 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5847 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5848 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5849 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5850   gpe_add_del_native_fwd_rpath_reply)                                   \
5851 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5852   gpe_fwd_entry_path_details)                                           \
5853 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5854 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5855   one_add_del_map_request_itr_rlocs_reply)                              \
5856 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5857   one_get_map_request_itr_rlocs_reply)                                  \
5858 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5859 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5860 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5861 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5862 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5863 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5864   show_one_map_register_state_reply)                                    \
5865 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5866 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5867   show_one_map_register_fallback_threshold_reply)                       \
5868 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5869 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5870 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5871 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5872 _(POLICER_DETAILS, policer_details)                                     \
5873 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5874 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5875 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5876 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5877 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5878 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5879 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5880 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5881 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5882 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5883 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5884 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5885 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5886 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5887 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5888 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5889 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5890 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5891 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5892 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5893 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5894 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5895 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5896 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5897 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5898  ip_source_and_port_range_check_add_del_reply)                          \
5899 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5900  ip_source_and_port_range_check_interface_add_del_reply)                \
5901 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5902 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5903 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5904 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5905 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5906 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5907 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5908 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5909 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5910 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5911 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5912 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5913 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5914 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5915 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5916 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5917 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5918 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5919 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5920 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5921 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5922 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5923 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5924 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5925 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5926 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5927 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5928 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5929
5930 #define foreach_standalone_reply_msg                                    \
5931 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5932 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5933 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5934 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5935 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5936 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5937 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5938
5939 typedef struct
5940 {
5941   u8 *name;
5942   u32 value;
5943 } name_sort_t;
5944
5945 #define STR_VTR_OP_CASE(op)     \
5946     case L2_VTR_ ## op:         \
5947         return "" # op;
5948
5949 static const char *
5950 str_vtr_op (u32 vtr_op)
5951 {
5952   switch (vtr_op)
5953     {
5954       STR_VTR_OP_CASE (DISABLED);
5955       STR_VTR_OP_CASE (PUSH_1);
5956       STR_VTR_OP_CASE (PUSH_2);
5957       STR_VTR_OP_CASE (POP_1);
5958       STR_VTR_OP_CASE (POP_2);
5959       STR_VTR_OP_CASE (TRANSLATE_1_1);
5960       STR_VTR_OP_CASE (TRANSLATE_1_2);
5961       STR_VTR_OP_CASE (TRANSLATE_2_1);
5962       STR_VTR_OP_CASE (TRANSLATE_2_2);
5963     }
5964
5965   return "UNKNOWN";
5966 }
5967
5968 static int
5969 dump_sub_interface_table (vat_main_t * vam)
5970 {
5971   const sw_interface_subif_t *sub = NULL;
5972
5973   if (vam->json_output)
5974     {
5975       clib_warning
5976         ("JSON output supported only for VPE API calls and dump_stats_table");
5977       return -99;
5978     }
5979
5980   print (vam->ofp,
5981          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5982          "Interface", "sw_if_index",
5983          "sub id", "dot1ad", "tags", "outer id",
5984          "inner id", "exact", "default", "outer any", "inner any");
5985
5986   vec_foreach (sub, vam->sw_if_subif_table)
5987   {
5988     print (vam->ofp,
5989            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5990            sub->interface_name,
5991            sub->sw_if_index,
5992            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5993            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5994            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5995            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5996     if (sub->vtr_op != L2_VTR_DISABLED)
5997       {
5998         print (vam->ofp,
5999                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6000                "tag1: %d tag2: %d ]",
6001                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6002                sub->vtr_tag1, sub->vtr_tag2);
6003       }
6004   }
6005
6006   return 0;
6007 }
6008
6009 static int
6010 name_sort_cmp (void *a1, void *a2)
6011 {
6012   name_sort_t *n1 = a1;
6013   name_sort_t *n2 = a2;
6014
6015   return strcmp ((char *) n1->name, (char *) n2->name);
6016 }
6017
6018 static int
6019 dump_interface_table (vat_main_t * vam)
6020 {
6021   hash_pair_t *p;
6022   name_sort_t *nses = 0, *ns;
6023
6024   if (vam->json_output)
6025     {
6026       clib_warning
6027         ("JSON output supported only for VPE API calls and dump_stats_table");
6028       return -99;
6029     }
6030
6031   /* *INDENT-OFF* */
6032   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6033   ({
6034     vec_add2 (nses, ns, 1);
6035     ns->name = (u8 *)(p->key);
6036     ns->value = (u32) p->value[0];
6037   }));
6038   /* *INDENT-ON* */
6039
6040   vec_sort_with_function (nses, name_sort_cmp);
6041
6042   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6043   vec_foreach (ns, nses)
6044   {
6045     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6046   }
6047   vec_free (nses);
6048   return 0;
6049 }
6050
6051 static int
6052 dump_ip_table (vat_main_t * vam, int is_ipv6)
6053 {
6054   const ip_details_t *det = NULL;
6055   const ip_address_details_t *address = NULL;
6056   u32 i = ~0;
6057
6058   print (vam->ofp, "%-12s", "sw_if_index");
6059
6060   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6061   {
6062     i++;
6063     if (!det->present)
6064       {
6065         continue;
6066       }
6067     print (vam->ofp, "%-12d", i);
6068     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6069     if (!det->addr)
6070       {
6071         continue;
6072       }
6073     vec_foreach (address, det->addr)
6074     {
6075       print (vam->ofp,
6076              "            %-30U%-13d",
6077              is_ipv6 ? format_ip6_address : format_ip4_address,
6078              address->ip, address->prefix_length);
6079     }
6080   }
6081
6082   return 0;
6083 }
6084
6085 static int
6086 dump_ipv4_table (vat_main_t * vam)
6087 {
6088   if (vam->json_output)
6089     {
6090       clib_warning
6091         ("JSON output supported only for VPE API calls and dump_stats_table");
6092       return -99;
6093     }
6094
6095   return dump_ip_table (vam, 0);
6096 }
6097
6098 static int
6099 dump_ipv6_table (vat_main_t * vam)
6100 {
6101   if (vam->json_output)
6102     {
6103       clib_warning
6104         ("JSON output supported only for VPE API calls and dump_stats_table");
6105       return -99;
6106     }
6107
6108   return dump_ip_table (vam, 1);
6109 }
6110
6111 static char *
6112 counter_type_to_str (u8 counter_type, u8 is_combined)
6113 {
6114   if (!is_combined)
6115     {
6116       switch (counter_type)
6117         {
6118         case VNET_INTERFACE_COUNTER_DROP:
6119           return "drop";
6120         case VNET_INTERFACE_COUNTER_PUNT:
6121           return "punt";
6122         case VNET_INTERFACE_COUNTER_IP4:
6123           return "ip4";
6124         case VNET_INTERFACE_COUNTER_IP6:
6125           return "ip6";
6126         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6127           return "rx-no-buf";
6128         case VNET_INTERFACE_COUNTER_RX_MISS:
6129           return "rx-miss";
6130         case VNET_INTERFACE_COUNTER_RX_ERROR:
6131           return "rx-error";
6132         case VNET_INTERFACE_COUNTER_TX_ERROR:
6133           return "tx-error";
6134         default:
6135           return "INVALID-COUNTER-TYPE";
6136         }
6137     }
6138   else
6139     {
6140       switch (counter_type)
6141         {
6142         case VNET_INTERFACE_COUNTER_RX:
6143           return "rx";
6144         case VNET_INTERFACE_COUNTER_TX:
6145           return "tx";
6146         default:
6147           return "INVALID-COUNTER-TYPE";
6148         }
6149     }
6150 }
6151
6152 static int
6153 dump_stats_table (vat_main_t * vam)
6154 {
6155   vat_json_node_t node;
6156   vat_json_node_t *msg_array;
6157   vat_json_node_t *msg;
6158   vat_json_node_t *counter_array;
6159   vat_json_node_t *counter;
6160   interface_counter_t c;
6161   u64 packets;
6162   ip4_fib_counter_t *c4;
6163   ip6_fib_counter_t *c6;
6164   ip4_nbr_counter_t *n4;
6165   ip6_nbr_counter_t *n6;
6166   int i, j;
6167
6168   if (!vam->json_output)
6169     {
6170       clib_warning ("dump_stats_table supported only in JSON format");
6171       return -99;
6172     }
6173
6174   vat_json_init_object (&node);
6175
6176   /* interface counters */
6177   msg_array = vat_json_object_add (&node, "interface_counters");
6178   vat_json_init_array (msg_array);
6179   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6180     {
6181       msg = vat_json_array_add (msg_array);
6182       vat_json_init_object (msg);
6183       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6184                                        (u8 *) counter_type_to_str (i, 0));
6185       vat_json_object_add_int (msg, "is_combined", 0);
6186       counter_array = vat_json_object_add (msg, "data");
6187       vat_json_init_array (counter_array);
6188       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6189         {
6190           packets = vam->simple_interface_counters[i][j];
6191           vat_json_array_add_uint (counter_array, packets);
6192         }
6193     }
6194   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6195     {
6196       msg = vat_json_array_add (msg_array);
6197       vat_json_init_object (msg);
6198       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6199                                        (u8 *) counter_type_to_str (i, 1));
6200       vat_json_object_add_int (msg, "is_combined", 1);
6201       counter_array = vat_json_object_add (msg, "data");
6202       vat_json_init_array (counter_array);
6203       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6204         {
6205           c = vam->combined_interface_counters[i][j];
6206           counter = vat_json_array_add (counter_array);
6207           vat_json_init_object (counter);
6208           vat_json_object_add_uint (counter, "packets", c.packets);
6209           vat_json_object_add_uint (counter, "bytes", c.bytes);
6210         }
6211     }
6212
6213   /* ip4 fib counters */
6214   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6215   vat_json_init_array (msg_array);
6216   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6217     {
6218       msg = vat_json_array_add (msg_array);
6219       vat_json_init_object (msg);
6220       vat_json_object_add_uint (msg, "vrf_id",
6221                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6222       counter_array = vat_json_object_add (msg, "c");
6223       vat_json_init_array (counter_array);
6224       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6225         {
6226           counter = vat_json_array_add (counter_array);
6227           vat_json_init_object (counter);
6228           c4 = &vam->ip4_fib_counters[i][j];
6229           vat_json_object_add_ip4 (counter, "address", c4->address);
6230           vat_json_object_add_uint (counter, "address_length",
6231                                     c4->address_length);
6232           vat_json_object_add_uint (counter, "packets", c4->packets);
6233           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6234         }
6235     }
6236
6237   /* ip6 fib counters */
6238   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6239   vat_json_init_array (msg_array);
6240   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6241     {
6242       msg = vat_json_array_add (msg_array);
6243       vat_json_init_object (msg);
6244       vat_json_object_add_uint (msg, "vrf_id",
6245                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6246       counter_array = vat_json_object_add (msg, "c");
6247       vat_json_init_array (counter_array);
6248       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6249         {
6250           counter = vat_json_array_add (counter_array);
6251           vat_json_init_object (counter);
6252           c6 = &vam->ip6_fib_counters[i][j];
6253           vat_json_object_add_ip6 (counter, "address", c6->address);
6254           vat_json_object_add_uint (counter, "address_length",
6255                                     c6->address_length);
6256           vat_json_object_add_uint (counter, "packets", c6->packets);
6257           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6258         }
6259     }
6260
6261   /* ip4 nbr counters */
6262   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6263   vat_json_init_array (msg_array);
6264   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6265     {
6266       msg = vat_json_array_add (msg_array);
6267       vat_json_init_object (msg);
6268       vat_json_object_add_uint (msg, "sw_if_index", i);
6269       counter_array = vat_json_object_add (msg, "c");
6270       vat_json_init_array (counter_array);
6271       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6272         {
6273           counter = vat_json_array_add (counter_array);
6274           vat_json_init_object (counter);
6275           n4 = &vam->ip4_nbr_counters[i][j];
6276           vat_json_object_add_ip4 (counter, "address", n4->address);
6277           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6278           vat_json_object_add_uint (counter, "packets", n4->packets);
6279           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6280         }
6281     }
6282
6283   /* ip6 nbr counters */
6284   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6285   vat_json_init_array (msg_array);
6286   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6287     {
6288       msg = vat_json_array_add (msg_array);
6289       vat_json_init_object (msg);
6290       vat_json_object_add_uint (msg, "sw_if_index", i);
6291       counter_array = vat_json_object_add (msg, "c");
6292       vat_json_init_array (counter_array);
6293       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6294         {
6295           counter = vat_json_array_add (counter_array);
6296           vat_json_init_object (counter);
6297           n6 = &vam->ip6_nbr_counters[i][j];
6298           vat_json_object_add_ip6 (counter, "address", n6->address);
6299           vat_json_object_add_uint (counter, "packets", n6->packets);
6300           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6301         }
6302     }
6303
6304   vat_json_print (vam->ofp, &node);
6305   vat_json_free (&node);
6306
6307   return 0;
6308 }
6309
6310 /*
6311  * Pass CLI buffers directly in the CLI_INBAND API message,
6312  * instead of an additional shared memory area.
6313  */
6314 static int
6315 exec_inband (vat_main_t * vam)
6316 {
6317   vl_api_cli_inband_t *mp;
6318   unformat_input_t *i = vam->input;
6319   int ret;
6320
6321   if (vec_len (i->buffer) == 0)
6322     return -1;
6323
6324   if (vam->exec_mode == 0 && unformat (i, "mode"))
6325     {
6326       vam->exec_mode = 1;
6327       return 0;
6328     }
6329   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6330     {
6331       vam->exec_mode = 0;
6332       return 0;
6333     }
6334
6335   /*
6336    * In order for the CLI command to work, it
6337    * must be a vector ending in \n, not a C-string ending
6338    * in \n\0.
6339    */
6340   u32 len = vec_len (vam->input->buffer);
6341   M2 (CLI_INBAND, mp, len);
6342   clib_memcpy (mp->cmd, vam->input->buffer, len);
6343   mp->length = htonl (len);
6344
6345   S (mp);
6346   W (ret);
6347   /* json responses may or may not include a useful reply... */
6348   if (vec_len (vam->cmd_reply))
6349     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6350   return ret;
6351 }
6352
6353 int
6354 exec (vat_main_t * vam)
6355 {
6356   return exec_inband (vam);
6357 }
6358
6359 static int
6360 api_create_loopback (vat_main_t * vam)
6361 {
6362   unformat_input_t *i = vam->input;
6363   vl_api_create_loopback_t *mp;
6364   vl_api_create_loopback_instance_t *mp_lbi;
6365   u8 mac_address[6];
6366   u8 mac_set = 0;
6367   u8 is_specified = 0;
6368   u32 user_instance = 0;
6369   int ret;
6370
6371   clib_memset (mac_address, 0, sizeof (mac_address));
6372
6373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6374     {
6375       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6376         mac_set = 1;
6377       if (unformat (i, "instance %d", &user_instance))
6378         is_specified = 1;
6379       else
6380         break;
6381     }
6382
6383   if (is_specified)
6384     {
6385       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6386       mp_lbi->is_specified = is_specified;
6387       if (is_specified)
6388         mp_lbi->user_instance = htonl (user_instance);
6389       if (mac_set)
6390         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6391       S (mp_lbi);
6392     }
6393   else
6394     {
6395       /* Construct the API message */
6396       M (CREATE_LOOPBACK, mp);
6397       if (mac_set)
6398         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6399       S (mp);
6400     }
6401
6402   W (ret);
6403   return ret;
6404 }
6405
6406 static int
6407 api_delete_loopback (vat_main_t * vam)
6408 {
6409   unformat_input_t *i = vam->input;
6410   vl_api_delete_loopback_t *mp;
6411   u32 sw_if_index = ~0;
6412   int ret;
6413
6414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6415     {
6416       if (unformat (i, "sw_if_index %d", &sw_if_index))
6417         ;
6418       else
6419         break;
6420     }
6421
6422   if (sw_if_index == ~0)
6423     {
6424       errmsg ("missing sw_if_index");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (DELETE_LOOPBACK, mp);
6430   mp->sw_if_index = ntohl (sw_if_index);
6431
6432   S (mp);
6433   W (ret);
6434   return ret;
6435 }
6436
6437 static int
6438 api_want_stats (vat_main_t * vam)
6439 {
6440   unformat_input_t *i = vam->input;
6441   vl_api_want_stats_t *mp;
6442   int enable = -1;
6443   int ret;
6444
6445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6446     {
6447       if (unformat (i, "enable"))
6448         enable = 1;
6449       else if (unformat (i, "disable"))
6450         enable = 0;
6451       else
6452         break;
6453     }
6454
6455   if (enable == -1)
6456     {
6457       errmsg ("missing enable|disable");
6458       return -99;
6459     }
6460
6461   M (WANT_STATS, mp);
6462   mp->enable_disable = enable;
6463
6464   S (mp);
6465   W (ret);
6466   return ret;
6467 }
6468
6469 static int
6470 api_want_interface_events (vat_main_t * vam)
6471 {
6472   unformat_input_t *i = vam->input;
6473   vl_api_want_interface_events_t *mp;
6474   int enable = -1;
6475   int ret;
6476
6477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6478     {
6479       if (unformat (i, "enable"))
6480         enable = 1;
6481       else if (unformat (i, "disable"))
6482         enable = 0;
6483       else
6484         break;
6485     }
6486
6487   if (enable == -1)
6488     {
6489       errmsg ("missing enable|disable");
6490       return -99;
6491     }
6492
6493   M (WANT_INTERFACE_EVENTS, mp);
6494   mp->enable_disable = enable;
6495
6496   vam->interface_event_display = enable;
6497
6498   S (mp);
6499   W (ret);
6500   return ret;
6501 }
6502
6503
6504 /* Note: non-static, called once to set up the initial intfc table */
6505 int
6506 api_sw_interface_dump (vat_main_t * vam)
6507 {
6508   vl_api_sw_interface_dump_t *mp;
6509   vl_api_control_ping_t *mp_ping;
6510   hash_pair_t *p;
6511   name_sort_t *nses = 0, *ns;
6512   sw_interface_subif_t *sub = NULL;
6513   int ret;
6514
6515   /* Toss the old name table */
6516   /* *INDENT-OFF* */
6517   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6518   ({
6519     vec_add2 (nses, ns, 1);
6520     ns->name = (u8 *)(p->key);
6521     ns->value = (u32) p->value[0];
6522   }));
6523   /* *INDENT-ON* */
6524
6525   hash_free (vam->sw_if_index_by_interface_name);
6526
6527   vec_foreach (ns, nses) vec_free (ns->name);
6528
6529   vec_free (nses);
6530
6531   vec_foreach (sub, vam->sw_if_subif_table)
6532   {
6533     vec_free (sub->interface_name);
6534   }
6535   vec_free (vam->sw_if_subif_table);
6536
6537   /* recreate the interface name hash table */
6538   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6539
6540   /*
6541    * Ask for all interface names. Otherwise, the epic catalog of
6542    * name filters becomes ridiculously long, and vat ends up needing
6543    * to be taught about new interface types.
6544    */
6545   M (SW_INTERFACE_DUMP, mp);
6546   S (mp);
6547
6548   /* Use a control ping for synchronization */
6549   MPING (CONTROL_PING, mp_ping);
6550   S (mp_ping);
6551
6552   W (ret);
6553   return ret;
6554 }
6555
6556 static int
6557 api_sw_interface_set_flags (vat_main_t * vam)
6558 {
6559   unformat_input_t *i = vam->input;
6560   vl_api_sw_interface_set_flags_t *mp;
6561   u32 sw_if_index;
6562   u8 sw_if_index_set = 0;
6563   u8 admin_up = 0;
6564   int ret;
6565
6566   /* Parse args required to build the message */
6567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6568     {
6569       if (unformat (i, "admin-up"))
6570         admin_up = 1;
6571       else if (unformat (i, "admin-down"))
6572         admin_up = 0;
6573       else
6574         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6575         sw_if_index_set = 1;
6576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6577         sw_if_index_set = 1;
6578       else
6579         break;
6580     }
6581
6582   if (sw_if_index_set == 0)
6583     {
6584       errmsg ("missing interface name or sw_if_index");
6585       return -99;
6586     }
6587
6588   /* Construct the API message */
6589   M (SW_INTERFACE_SET_FLAGS, mp);
6590   mp->sw_if_index = ntohl (sw_if_index);
6591   mp->admin_up_down = admin_up;
6592
6593   /* send it... */
6594   S (mp);
6595
6596   /* Wait for a reply, return the good/bad news... */
6597   W (ret);
6598   return ret;
6599 }
6600
6601 static int
6602 api_sw_interface_set_rx_mode (vat_main_t * vam)
6603 {
6604   unformat_input_t *i = vam->input;
6605   vl_api_sw_interface_set_rx_mode_t *mp;
6606   u32 sw_if_index;
6607   u8 sw_if_index_set = 0;
6608   int ret;
6609   u8 queue_id_valid = 0;
6610   u32 queue_id;
6611   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6612
6613   /* Parse args required to build the message */
6614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6615     {
6616       if (unformat (i, "queue %d", &queue_id))
6617         queue_id_valid = 1;
6618       else if (unformat (i, "polling"))
6619         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6620       else if (unformat (i, "interrupt"))
6621         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6622       else if (unformat (i, "adaptive"))
6623         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6624       else
6625         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6626         sw_if_index_set = 1;
6627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6628         sw_if_index_set = 1;
6629       else
6630         break;
6631     }
6632
6633   if (sw_if_index_set == 0)
6634     {
6635       errmsg ("missing interface name or sw_if_index");
6636       return -99;
6637     }
6638   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6639     {
6640       errmsg ("missing rx-mode");
6641       return -99;
6642     }
6643
6644   /* Construct the API message */
6645   M (SW_INTERFACE_SET_RX_MODE, mp);
6646   mp->sw_if_index = ntohl (sw_if_index);
6647   mp->mode = mode;
6648   mp->queue_id_valid = queue_id_valid;
6649   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6650
6651   /* send it... */
6652   S (mp);
6653
6654   /* Wait for a reply, return the good/bad news... */
6655   W (ret);
6656   return ret;
6657 }
6658
6659 static int
6660 api_sw_interface_set_rx_placement (vat_main_t * vam)
6661 {
6662   unformat_input_t *i = vam->input;
6663   vl_api_sw_interface_set_rx_placement_t *mp;
6664   u32 sw_if_index;
6665   u8 sw_if_index_set = 0;
6666   int ret;
6667   u8 is_main = 0;
6668   u32 queue_id, thread_index;
6669
6670   /* Parse args required to build the message */
6671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6672     {
6673       if (unformat (i, "queue %d", &queue_id))
6674         ;
6675       else if (unformat (i, "main"))
6676         is_main = 1;
6677       else if (unformat (i, "worker %d", &thread_index))
6678         ;
6679       else
6680         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6681         sw_if_index_set = 1;
6682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6683         sw_if_index_set = 1;
6684       else
6685         break;
6686     }
6687
6688   if (sw_if_index_set == 0)
6689     {
6690       errmsg ("missing interface name or sw_if_index");
6691       return -99;
6692     }
6693
6694   if (is_main)
6695     thread_index = 0;
6696   /* Construct the API message */
6697   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6698   mp->sw_if_index = ntohl (sw_if_index);
6699   mp->worker_id = ntohl (thread_index);
6700   mp->queue_id = ntohl (queue_id);
6701   mp->is_main = is_main;
6702
6703   /* send it... */
6704   S (mp);
6705   /* Wait for a reply, return the good/bad news... */
6706   W (ret);
6707   return ret;
6708 }
6709
6710 static void vl_api_sw_interface_rx_placement_details_t_handler
6711   (vl_api_sw_interface_rx_placement_details_t * mp)
6712 {
6713   vat_main_t *vam = &vat_main;
6714   u32 worker_id = ntohl (mp->worker_id);
6715
6716   print (vam->ofp,
6717          "\n%-11d %-11s %-6d %-5d %-9s",
6718          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6719          worker_id, ntohl (mp->queue_id),
6720          (mp->mode ==
6721           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6722 }
6723
6724 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6725   (vl_api_sw_interface_rx_placement_details_t * mp)
6726 {
6727   vat_main_t *vam = &vat_main;
6728   vat_json_node_t *node = NULL;
6729
6730   if (VAT_JSON_ARRAY != vam->json_tree.type)
6731     {
6732       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6733       vat_json_init_array (&vam->json_tree);
6734     }
6735   node = vat_json_array_add (&vam->json_tree);
6736
6737   vat_json_init_object (node);
6738   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6739   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6740   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6741   vat_json_object_add_uint (node, "mode", mp->mode);
6742 }
6743
6744 static int
6745 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_sw_interface_rx_placement_dump_t *mp;
6749   vl_api_control_ping_t *mp_ping;
6750   int ret;
6751   u32 sw_if_index;
6752   u8 sw_if_index_set = 0;
6753
6754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6755     {
6756       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6757         sw_if_index_set++;
6758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6759         sw_if_index_set++;
6760       else
6761         break;
6762     }
6763
6764   print (vam->ofp,
6765          "\n%-11s %-11s %-6s %-5s %-4s",
6766          "sw_if_index", "main/worker", "thread", "queue", "mode");
6767
6768   /* Dump Interface rx placement */
6769   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6770
6771   if (sw_if_index_set)
6772     mp->sw_if_index = htonl (sw_if_index);
6773   else
6774     mp->sw_if_index = ~0;
6775
6776   S (mp);
6777
6778   /* Use a control ping for synchronization */
6779   MPING (CONTROL_PING, mp_ping);
6780   S (mp_ping);
6781
6782   W (ret);
6783   return ret;
6784 }
6785
6786 static int
6787 api_sw_interface_clear_stats (vat_main_t * vam)
6788 {
6789   unformat_input_t *i = vam->input;
6790   vl_api_sw_interface_clear_stats_t *mp;
6791   u32 sw_if_index;
6792   u8 sw_if_index_set = 0;
6793   int ret;
6794
6795   /* Parse args required to build the message */
6796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6797     {
6798       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6799         sw_if_index_set = 1;
6800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6801         sw_if_index_set = 1;
6802       else
6803         break;
6804     }
6805
6806   /* Construct the API message */
6807   M (SW_INTERFACE_CLEAR_STATS, mp);
6808
6809   if (sw_if_index_set == 1)
6810     mp->sw_if_index = ntohl (sw_if_index);
6811   else
6812     mp->sw_if_index = ~0;
6813
6814   /* send it... */
6815   S (mp);
6816
6817   /* Wait for a reply, return the good/bad news... */
6818   W (ret);
6819   return ret;
6820 }
6821
6822 static int
6823 api_sw_interface_add_del_address (vat_main_t * vam)
6824 {
6825   unformat_input_t *i = vam->input;
6826   vl_api_sw_interface_add_del_address_t *mp;
6827   u32 sw_if_index;
6828   u8 sw_if_index_set = 0;
6829   u8 is_add = 1, del_all = 0;
6830   u32 address_length = 0;
6831   u8 v4_address_set = 0;
6832   u8 v6_address_set = 0;
6833   ip4_address_t v4address;
6834   ip6_address_t v6address;
6835   int ret;
6836
6837   /* Parse args required to build the message */
6838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6839     {
6840       if (unformat (i, "del-all"))
6841         del_all = 1;
6842       else if (unformat (i, "del"))
6843         is_add = 0;
6844       else
6845         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6846         sw_if_index_set = 1;
6847       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6848         sw_if_index_set = 1;
6849       else if (unformat (i, "%U/%d",
6850                          unformat_ip4_address, &v4address, &address_length))
6851         v4_address_set = 1;
6852       else if (unformat (i, "%U/%d",
6853                          unformat_ip6_address, &v6address, &address_length))
6854         v6_address_set = 1;
6855       else
6856         break;
6857     }
6858
6859   if (sw_if_index_set == 0)
6860     {
6861       errmsg ("missing interface name or sw_if_index");
6862       return -99;
6863     }
6864   if (v4_address_set && v6_address_set)
6865     {
6866       errmsg ("both v4 and v6 addresses set");
6867       return -99;
6868     }
6869   if (!v4_address_set && !v6_address_set && !del_all)
6870     {
6871       errmsg ("no addresses set");
6872       return -99;
6873     }
6874
6875   /* Construct the API message */
6876   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6877
6878   mp->sw_if_index = ntohl (sw_if_index);
6879   mp->is_add = is_add;
6880   mp->del_all = del_all;
6881   if (v6_address_set)
6882     {
6883       mp->is_ipv6 = 1;
6884       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6885     }
6886   else
6887     {
6888       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6889     }
6890   mp->address_length = address_length;
6891
6892   /* send it... */
6893   S (mp);
6894
6895   /* Wait for a reply, return good/bad news  */
6896   W (ret);
6897   return ret;
6898 }
6899
6900 static int
6901 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6902 {
6903   unformat_input_t *i = vam->input;
6904   vl_api_sw_interface_set_mpls_enable_t *mp;
6905   u32 sw_if_index;
6906   u8 sw_if_index_set = 0;
6907   u8 enable = 1;
6908   int ret;
6909
6910   /* Parse args required to build the message */
6911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6912     {
6913       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6914         sw_if_index_set = 1;
6915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6916         sw_if_index_set = 1;
6917       else if (unformat (i, "disable"))
6918         enable = 0;
6919       else if (unformat (i, "dis"))
6920         enable = 0;
6921       else
6922         break;
6923     }
6924
6925   if (sw_if_index_set == 0)
6926     {
6927       errmsg ("missing interface name or sw_if_index");
6928       return -99;
6929     }
6930
6931   /* Construct the API message */
6932   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6933
6934   mp->sw_if_index = ntohl (sw_if_index);
6935   mp->enable = enable;
6936
6937   /* send it... */
6938   S (mp);
6939
6940   /* Wait for a reply... */
6941   W (ret);
6942   return ret;
6943 }
6944
6945 static int
6946 api_sw_interface_set_table (vat_main_t * vam)
6947 {
6948   unformat_input_t *i = vam->input;
6949   vl_api_sw_interface_set_table_t *mp;
6950   u32 sw_if_index, vrf_id = 0;
6951   u8 sw_if_index_set = 0;
6952   u8 is_ipv6 = 0;
6953   int ret;
6954
6955   /* Parse args required to build the message */
6956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6957     {
6958       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6959         sw_if_index_set = 1;
6960       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6961         sw_if_index_set = 1;
6962       else if (unformat (i, "vrf %d", &vrf_id))
6963         ;
6964       else if (unformat (i, "ipv6"))
6965         is_ipv6 = 1;
6966       else
6967         break;
6968     }
6969
6970   if (sw_if_index_set == 0)
6971     {
6972       errmsg ("missing interface name or sw_if_index");
6973       return -99;
6974     }
6975
6976   /* Construct the API message */
6977   M (SW_INTERFACE_SET_TABLE, mp);
6978
6979   mp->sw_if_index = ntohl (sw_if_index);
6980   mp->is_ipv6 = is_ipv6;
6981   mp->vrf_id = ntohl (vrf_id);
6982
6983   /* send it... */
6984   S (mp);
6985
6986   /* Wait for a reply... */
6987   W (ret);
6988   return ret;
6989 }
6990
6991 static void vl_api_sw_interface_get_table_reply_t_handler
6992   (vl_api_sw_interface_get_table_reply_t * mp)
6993 {
6994   vat_main_t *vam = &vat_main;
6995
6996   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6997
6998   vam->retval = ntohl (mp->retval);
6999   vam->result_ready = 1;
7000
7001 }
7002
7003 static void vl_api_sw_interface_get_table_reply_t_handler_json
7004   (vl_api_sw_interface_get_table_reply_t * mp)
7005 {
7006   vat_main_t *vam = &vat_main;
7007   vat_json_node_t node;
7008
7009   vat_json_init_object (&node);
7010   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
7011   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
7012
7013   vat_json_print (vam->ofp, &node);
7014   vat_json_free (&node);
7015
7016   vam->retval = ntohl (mp->retval);
7017   vam->result_ready = 1;
7018 }
7019
7020 static int
7021 api_sw_interface_get_table (vat_main_t * vam)
7022 {
7023   unformat_input_t *i = vam->input;
7024   vl_api_sw_interface_get_table_t *mp;
7025   u32 sw_if_index;
7026   u8 sw_if_index_set = 0;
7027   u8 is_ipv6 = 0;
7028   int ret;
7029
7030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7031     {
7032       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7033         sw_if_index_set = 1;
7034       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7035         sw_if_index_set = 1;
7036       else if (unformat (i, "ipv6"))
7037         is_ipv6 = 1;
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 (SW_INTERFACE_GET_TABLE, mp);
7049   mp->sw_if_index = htonl (sw_if_index);
7050   mp->is_ipv6 = is_ipv6;
7051
7052   S (mp);
7053   W (ret);
7054   return ret;
7055 }
7056
7057 static int
7058 api_sw_interface_set_vpath (vat_main_t * vam)
7059 {
7060   unformat_input_t *i = vam->input;
7061   vl_api_sw_interface_set_vpath_t *mp;
7062   u32 sw_if_index = 0;
7063   u8 sw_if_index_set = 0;
7064   u8 is_enable = 0;
7065   int ret;
7066
7067   /* Parse args required to build the message */
7068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7069     {
7070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7071         sw_if_index_set = 1;
7072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7073         sw_if_index_set = 1;
7074       else if (unformat (i, "enable"))
7075         is_enable = 1;
7076       else if (unformat (i, "disable"))
7077         is_enable = 0;
7078       else
7079         break;
7080     }
7081
7082   if (sw_if_index_set == 0)
7083     {
7084       errmsg ("missing interface name or sw_if_index");
7085       return -99;
7086     }
7087
7088   /* Construct the API message */
7089   M (SW_INTERFACE_SET_VPATH, mp);
7090
7091   mp->sw_if_index = ntohl (sw_if_index);
7092   mp->enable = is_enable;
7093
7094   /* send it... */
7095   S (mp);
7096
7097   /* Wait for a reply... */
7098   W (ret);
7099   return ret;
7100 }
7101
7102 static int
7103 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7104 {
7105   unformat_input_t *i = vam->input;
7106   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7107   u32 sw_if_index = 0;
7108   u8 sw_if_index_set = 0;
7109   u8 is_enable = 1;
7110   u8 is_ipv6 = 0;
7111   int ret;
7112
7113   /* Parse args required to build the message */
7114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7115     {
7116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7117         sw_if_index_set = 1;
7118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7119         sw_if_index_set = 1;
7120       else if (unformat (i, "enable"))
7121         is_enable = 1;
7122       else if (unformat (i, "disable"))
7123         is_enable = 0;
7124       else if (unformat (i, "ip4"))
7125         is_ipv6 = 0;
7126       else if (unformat (i, "ip6"))
7127         is_ipv6 = 1;
7128       else
7129         break;
7130     }
7131
7132   if (sw_if_index_set == 0)
7133     {
7134       errmsg ("missing interface name or sw_if_index");
7135       return -99;
7136     }
7137
7138   /* Construct the API message */
7139   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7140
7141   mp->sw_if_index = ntohl (sw_if_index);
7142   mp->enable = is_enable;
7143   mp->is_ipv6 = is_ipv6;
7144
7145   /* send it... */
7146   S (mp);
7147
7148   /* Wait for a reply... */
7149   W (ret);
7150   return ret;
7151 }
7152
7153 static int
7154 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7155 {
7156   unformat_input_t *i = vam->input;
7157   vl_api_sw_interface_set_geneve_bypass_t *mp;
7158   u32 sw_if_index = 0;
7159   u8 sw_if_index_set = 0;
7160   u8 is_enable = 1;
7161   u8 is_ipv6 = 0;
7162   int ret;
7163
7164   /* Parse args required to build the message */
7165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7166     {
7167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7168         sw_if_index_set = 1;
7169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7170         sw_if_index_set = 1;
7171       else if (unformat (i, "enable"))
7172         is_enable = 1;
7173       else if (unformat (i, "disable"))
7174         is_enable = 0;
7175       else if (unformat (i, "ip4"))
7176         is_ipv6 = 0;
7177       else if (unformat (i, "ip6"))
7178         is_ipv6 = 1;
7179       else
7180         break;
7181     }
7182
7183   if (sw_if_index_set == 0)
7184     {
7185       errmsg ("missing interface name or sw_if_index");
7186       return -99;
7187     }
7188
7189   /* Construct the API message */
7190   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7191
7192   mp->sw_if_index = ntohl (sw_if_index);
7193   mp->enable = is_enable;
7194   mp->is_ipv6 = is_ipv6;
7195
7196   /* send it... */
7197   S (mp);
7198
7199   /* Wait for a reply... */
7200   W (ret);
7201   return ret;
7202 }
7203
7204 static int
7205 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7206 {
7207   unformat_input_t *i = vam->input;
7208   vl_api_sw_interface_set_l2_xconnect_t *mp;
7209   u32 rx_sw_if_index;
7210   u8 rx_sw_if_index_set = 0;
7211   u32 tx_sw_if_index;
7212   u8 tx_sw_if_index_set = 0;
7213   u8 enable = 1;
7214   int ret;
7215
7216   /* Parse args required to build the message */
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7220         rx_sw_if_index_set = 1;
7221       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7222         tx_sw_if_index_set = 1;
7223       else if (unformat (i, "rx"))
7224         {
7225           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226             {
7227               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7228                             &rx_sw_if_index))
7229                 rx_sw_if_index_set = 1;
7230             }
7231           else
7232             break;
7233         }
7234       else if (unformat (i, "tx"))
7235         {
7236           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7237             {
7238               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7239                             &tx_sw_if_index))
7240                 tx_sw_if_index_set = 1;
7241             }
7242           else
7243             break;
7244         }
7245       else if (unformat (i, "enable"))
7246         enable = 1;
7247       else if (unformat (i, "disable"))
7248         enable = 0;
7249       else
7250         break;
7251     }
7252
7253   if (rx_sw_if_index_set == 0)
7254     {
7255       errmsg ("missing rx interface name or rx_sw_if_index");
7256       return -99;
7257     }
7258
7259   if (enable && (tx_sw_if_index_set == 0))
7260     {
7261       errmsg ("missing tx interface name or tx_sw_if_index");
7262       return -99;
7263     }
7264
7265   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7266
7267   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7268   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7269   mp->enable = enable;
7270
7271   S (mp);
7272   W (ret);
7273   return ret;
7274 }
7275
7276 static int
7277 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7278 {
7279   unformat_input_t *i = vam->input;
7280   vl_api_sw_interface_set_l2_bridge_t *mp;
7281   vl_api_l2_port_type_t port_type;
7282   u32 rx_sw_if_index;
7283   u8 rx_sw_if_index_set = 0;
7284   u32 bd_id;
7285   u8 bd_id_set = 0;
7286   u32 shg = 0;
7287   u8 enable = 1;
7288   int ret;
7289
7290   port_type = L2_API_PORT_TYPE_NORMAL;
7291
7292   /* Parse args required to build the message */
7293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7294     {
7295       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7296         rx_sw_if_index_set = 1;
7297       else if (unformat (i, "bd_id %d", &bd_id))
7298         bd_id_set = 1;
7299       else
7300         if (unformat
7301             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7302         rx_sw_if_index_set = 1;
7303       else if (unformat (i, "shg %d", &shg))
7304         ;
7305       else if (unformat (i, "bvi"))
7306         port_type = L2_API_PORT_TYPE_BVI;
7307       else if (unformat (i, "uu-fwd"))
7308         port_type = L2_API_PORT_TYPE_UU_FWD;
7309       else if (unformat (i, "enable"))
7310         enable = 1;
7311       else if (unformat (i, "disable"))
7312         enable = 0;
7313       else
7314         break;
7315     }
7316
7317   if (rx_sw_if_index_set == 0)
7318     {
7319       errmsg ("missing rx interface name or sw_if_index");
7320       return -99;
7321     }
7322
7323   if (enable && (bd_id_set == 0))
7324     {
7325       errmsg ("missing bridge domain");
7326       return -99;
7327     }
7328
7329   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7330
7331   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7332   mp->bd_id = ntohl (bd_id);
7333   mp->shg = (u8) shg;
7334   mp->port_type = ntohl (port_type);
7335   mp->enable = enable;
7336
7337   S (mp);
7338   W (ret);
7339   return ret;
7340 }
7341
7342 static int
7343 api_bridge_domain_dump (vat_main_t * vam)
7344 {
7345   unformat_input_t *i = vam->input;
7346   vl_api_bridge_domain_dump_t *mp;
7347   vl_api_control_ping_t *mp_ping;
7348   u32 bd_id = ~0;
7349   int ret;
7350
7351   /* Parse args required to build the message */
7352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7353     {
7354       if (unformat (i, "bd_id %d", &bd_id))
7355         ;
7356       else
7357         break;
7358     }
7359
7360   M (BRIDGE_DOMAIN_DUMP, mp);
7361   mp->bd_id = ntohl (bd_id);
7362   S (mp);
7363
7364   /* Use a control ping for synchronization */
7365   MPING (CONTROL_PING, mp_ping);
7366   S (mp_ping);
7367
7368   W (ret);
7369   return ret;
7370 }
7371
7372 static int
7373 api_bridge_domain_add_del (vat_main_t * vam)
7374 {
7375   unformat_input_t *i = vam->input;
7376   vl_api_bridge_domain_add_del_t *mp;
7377   u32 bd_id = ~0;
7378   u8 is_add = 1;
7379   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7380   u8 *bd_tag = NULL;
7381   u32 mac_age = 0;
7382   int ret;
7383
7384   /* Parse args required to build the message */
7385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7386     {
7387       if (unformat (i, "bd_id %d", &bd_id))
7388         ;
7389       else if (unformat (i, "flood %d", &flood))
7390         ;
7391       else if (unformat (i, "uu-flood %d", &uu_flood))
7392         ;
7393       else if (unformat (i, "forward %d", &forward))
7394         ;
7395       else if (unformat (i, "learn %d", &learn))
7396         ;
7397       else if (unformat (i, "arp-term %d", &arp_term))
7398         ;
7399       else if (unformat (i, "mac-age %d", &mac_age))
7400         ;
7401       else if (unformat (i, "bd-tag %s", &bd_tag))
7402         ;
7403       else if (unformat (i, "del"))
7404         {
7405           is_add = 0;
7406           flood = uu_flood = forward = learn = 0;
7407         }
7408       else
7409         break;
7410     }
7411
7412   if (bd_id == ~0)
7413     {
7414       errmsg ("missing bridge domain");
7415       ret = -99;
7416       goto done;
7417     }
7418
7419   if (mac_age > 255)
7420     {
7421       errmsg ("mac age must be less than 256 ");
7422       ret = -99;
7423       goto done;
7424     }
7425
7426   if ((bd_tag) && (vec_len (bd_tag) > 63))
7427     {
7428       errmsg ("bd-tag cannot be longer than 63");
7429       ret = -99;
7430       goto done;
7431     }
7432
7433   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7434
7435   mp->bd_id = ntohl (bd_id);
7436   mp->flood = flood;
7437   mp->uu_flood = uu_flood;
7438   mp->forward = forward;
7439   mp->learn = learn;
7440   mp->arp_term = arp_term;
7441   mp->is_add = is_add;
7442   mp->mac_age = (u8) mac_age;
7443   if (bd_tag)
7444     {
7445       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7446       mp->bd_tag[vec_len (bd_tag)] = 0;
7447     }
7448   S (mp);
7449   W (ret);
7450
7451 done:
7452   vec_free (bd_tag);
7453   return ret;
7454 }
7455
7456 static int
7457 api_l2fib_flush_bd (vat_main_t * vam)
7458 {
7459   unformat_input_t *i = vam->input;
7460   vl_api_l2fib_flush_bd_t *mp;
7461   u32 bd_id = ~0;
7462   int ret;
7463
7464   /* Parse args required to build the message */
7465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7466     {
7467       if (unformat (i, "bd_id %d", &bd_id));
7468       else
7469         break;
7470     }
7471
7472   if (bd_id == ~0)
7473     {
7474       errmsg ("missing bridge domain");
7475       return -99;
7476     }
7477
7478   M (L2FIB_FLUSH_BD, mp);
7479
7480   mp->bd_id = htonl (bd_id);
7481
7482   S (mp);
7483   W (ret);
7484   return ret;
7485 }
7486
7487 static int
7488 api_l2fib_flush_int (vat_main_t * vam)
7489 {
7490   unformat_input_t *i = vam->input;
7491   vl_api_l2fib_flush_int_t *mp;
7492   u32 sw_if_index = ~0;
7493   int ret;
7494
7495   /* Parse args required to build the message */
7496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7497     {
7498       if (unformat (i, "sw_if_index %d", &sw_if_index));
7499       else
7500         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7501       else
7502         break;
7503     }
7504
7505   if (sw_if_index == ~0)
7506     {
7507       errmsg ("missing interface name or sw_if_index");
7508       return -99;
7509     }
7510
7511   M (L2FIB_FLUSH_INT, mp);
7512
7513   mp->sw_if_index = ntohl (sw_if_index);
7514
7515   S (mp);
7516   W (ret);
7517   return ret;
7518 }
7519
7520 static int
7521 api_l2fib_add_del (vat_main_t * vam)
7522 {
7523   unformat_input_t *i = vam->input;
7524   vl_api_l2fib_add_del_t *mp;
7525   f64 timeout;
7526   u8 mac[6] = { 0 };
7527   u8 mac_set = 0;
7528   u32 bd_id;
7529   u8 bd_id_set = 0;
7530   u32 sw_if_index = 0;
7531   u8 sw_if_index_set = 0;
7532   u8 is_add = 1;
7533   u8 static_mac = 0;
7534   u8 filter_mac = 0;
7535   u8 bvi_mac = 0;
7536   int count = 1;
7537   f64 before = 0;
7538   int j;
7539
7540   /* Parse args required to build the message */
7541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7542     {
7543       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7544         mac_set = 1;
7545       else if (unformat (i, "bd_id %d", &bd_id))
7546         bd_id_set = 1;
7547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7548         sw_if_index_set = 1;
7549       else if (unformat (i, "sw_if"))
7550         {
7551           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7552             {
7553               if (unformat
7554                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7555                 sw_if_index_set = 1;
7556             }
7557           else
7558             break;
7559         }
7560       else if (unformat (i, "static"))
7561         static_mac = 1;
7562       else if (unformat (i, "filter"))
7563         {
7564           filter_mac = 1;
7565           static_mac = 1;
7566         }
7567       else if (unformat (i, "bvi"))
7568         {
7569           bvi_mac = 1;
7570           static_mac = 1;
7571         }
7572       else if (unformat (i, "del"))
7573         is_add = 0;
7574       else if (unformat (i, "count %d", &count))
7575         ;
7576       else
7577         break;
7578     }
7579
7580   if (mac_set == 0)
7581     {
7582       errmsg ("missing mac address");
7583       return -99;
7584     }
7585
7586   if (bd_id_set == 0)
7587     {
7588       errmsg ("missing bridge domain");
7589       return -99;
7590     }
7591
7592   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7593     {
7594       errmsg ("missing interface name or sw_if_index");
7595       return -99;
7596     }
7597
7598   if (count > 1)
7599     {
7600       /* Turn on async mode */
7601       vam->async_mode = 1;
7602       vam->async_errors = 0;
7603       before = vat_time_now (vam);
7604     }
7605
7606   for (j = 0; j < count; j++)
7607     {
7608       M (L2FIB_ADD_DEL, mp);
7609
7610       clib_memcpy (mp->mac, mac, 6);
7611       mp->bd_id = ntohl (bd_id);
7612       mp->is_add = is_add;
7613       mp->sw_if_index = ntohl (sw_if_index);
7614
7615       if (is_add)
7616         {
7617           mp->static_mac = static_mac;
7618           mp->filter_mac = filter_mac;
7619           mp->bvi_mac = bvi_mac;
7620         }
7621       increment_mac_address (mac);
7622       /* send it... */
7623       S (mp);
7624     }
7625
7626   if (count > 1)
7627     {
7628       vl_api_control_ping_t *mp_ping;
7629       f64 after;
7630
7631       /* Shut off async mode */
7632       vam->async_mode = 0;
7633
7634       MPING (CONTROL_PING, mp_ping);
7635       S (mp_ping);
7636
7637       timeout = vat_time_now (vam) + 1.0;
7638       while (vat_time_now (vam) < timeout)
7639         if (vam->result_ready == 1)
7640           goto out;
7641       vam->retval = -99;
7642
7643     out:
7644       if (vam->retval == -99)
7645         errmsg ("timeout");
7646
7647       if (vam->async_errors > 0)
7648         {
7649           errmsg ("%d asynchronous errors", vam->async_errors);
7650           vam->retval = -98;
7651         }
7652       vam->async_errors = 0;
7653       after = vat_time_now (vam);
7654
7655       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7656              count, after - before, count / (after - before));
7657     }
7658   else
7659     {
7660       int ret;
7661
7662       /* Wait for a reply... */
7663       W (ret);
7664       return ret;
7665     }
7666   /* Return the good/bad news */
7667   return (vam->retval);
7668 }
7669
7670 static int
7671 api_bridge_domain_set_mac_age (vat_main_t * vam)
7672 {
7673   unformat_input_t *i = vam->input;
7674   vl_api_bridge_domain_set_mac_age_t *mp;
7675   u32 bd_id = ~0;
7676   u32 mac_age = 0;
7677   int ret;
7678
7679   /* Parse args required to build the message */
7680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7681     {
7682       if (unformat (i, "bd_id %d", &bd_id));
7683       else if (unformat (i, "mac-age %d", &mac_age));
7684       else
7685         break;
7686     }
7687
7688   if (bd_id == ~0)
7689     {
7690       errmsg ("missing bridge domain");
7691       return -99;
7692     }
7693
7694   if (mac_age > 255)
7695     {
7696       errmsg ("mac age must be less than 256 ");
7697       return -99;
7698     }
7699
7700   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7701
7702   mp->bd_id = htonl (bd_id);
7703   mp->mac_age = (u8) mac_age;
7704
7705   S (mp);
7706   W (ret);
7707   return ret;
7708 }
7709
7710 static int
7711 api_l2_flags (vat_main_t * vam)
7712 {
7713   unformat_input_t *i = vam->input;
7714   vl_api_l2_flags_t *mp;
7715   u32 sw_if_index;
7716   u32 flags = 0;
7717   u8 sw_if_index_set = 0;
7718   u8 is_set = 0;
7719   int ret;
7720
7721   /* Parse args required to build the message */
7722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7723     {
7724       if (unformat (i, "sw_if_index %d", &sw_if_index))
7725         sw_if_index_set = 1;
7726       else if (unformat (i, "sw_if"))
7727         {
7728           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7729             {
7730               if (unformat
7731                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7732                 sw_if_index_set = 1;
7733             }
7734           else
7735             break;
7736         }
7737       else if (unformat (i, "learn"))
7738         flags |= L2_LEARN;
7739       else if (unformat (i, "forward"))
7740         flags |= L2_FWD;
7741       else if (unformat (i, "flood"))
7742         flags |= L2_FLOOD;
7743       else if (unformat (i, "uu-flood"))
7744         flags |= L2_UU_FLOOD;
7745       else if (unformat (i, "arp-term"))
7746         flags |= L2_ARP_TERM;
7747       else if (unformat (i, "off"))
7748         is_set = 0;
7749       else if (unformat (i, "disable"))
7750         is_set = 0;
7751       else
7752         break;
7753     }
7754
7755   if (sw_if_index_set == 0)
7756     {
7757       errmsg ("missing interface name or sw_if_index");
7758       return -99;
7759     }
7760
7761   M (L2_FLAGS, mp);
7762
7763   mp->sw_if_index = ntohl (sw_if_index);
7764   mp->feature_bitmap = ntohl (flags);
7765   mp->is_set = is_set;
7766
7767   S (mp);
7768   W (ret);
7769   return ret;
7770 }
7771
7772 static int
7773 api_bridge_flags (vat_main_t * vam)
7774 {
7775   unformat_input_t *i = vam->input;
7776   vl_api_bridge_flags_t *mp;
7777   u32 bd_id;
7778   u8 bd_id_set = 0;
7779   u8 is_set = 1;
7780   bd_flags_t flags = 0;
7781   int ret;
7782
7783   /* Parse args required to build the message */
7784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7785     {
7786       if (unformat (i, "bd_id %d", &bd_id))
7787         bd_id_set = 1;
7788       else if (unformat (i, "learn"))
7789         flags |= BRIDGE_API_FLAG_LEARN;
7790       else if (unformat (i, "forward"))
7791         flags |= BRIDGE_API_FLAG_FWD;
7792       else if (unformat (i, "flood"))
7793         flags |= BRIDGE_API_FLAG_FLOOD;
7794       else if (unformat (i, "uu-flood"))
7795         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7796       else if (unformat (i, "arp-term"))
7797         flags |= BRIDGE_API_FLAG_ARP_TERM;
7798       else if (unformat (i, "off"))
7799         is_set = 0;
7800       else if (unformat (i, "disable"))
7801         is_set = 0;
7802       else
7803         break;
7804     }
7805
7806   if (bd_id_set == 0)
7807     {
7808       errmsg ("missing bridge domain");
7809       return -99;
7810     }
7811
7812   M (BRIDGE_FLAGS, mp);
7813
7814   mp->bd_id = ntohl (bd_id);
7815   mp->flags = ntohl (flags);
7816   mp->is_set = is_set;
7817
7818   S (mp);
7819   W (ret);
7820   return ret;
7821 }
7822
7823 static int
7824 api_bd_ip_mac_add_del (vat_main_t * vam)
7825 {
7826   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7827   vl_api_mac_address_t mac = VL_API_ZERO_MAC_ADDRESS;
7828   unformat_input_t *i = vam->input;
7829   vl_api_bd_ip_mac_add_del_t *mp;
7830   ip46_type_t type;
7831   u32 bd_id;
7832   u8 is_ipv6 = 0;
7833   u8 is_add = 1;
7834   u8 bd_id_set = 0;
7835   u8 ip_set = 0;
7836   u8 mac_set = 0;
7837   u8 macaddr[6];
7838   int ret;
7839
7840
7841   /* Parse args required to build the message */
7842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7843     {
7844       if (unformat (i, "bd_id %d", &bd_id))
7845         {
7846           bd_id_set++;
7847         }
7848       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7849         {
7850           ip_set++;
7851         }
7852       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7853         {
7854           mac_set++;
7855         }
7856       else if (unformat (i, "del"))
7857         is_add = 0;
7858       else
7859         break;
7860     }
7861
7862   if (bd_id_set == 0)
7863     {
7864       errmsg ("missing bridge domain");
7865       return -99;
7866     }
7867   else if (ip_set == 0)
7868     {
7869       errmsg ("missing IP address");
7870       return -99;
7871     }
7872   else if (mac_set == 0)
7873     {
7874       errmsg ("missing MAC address");
7875       return -99;
7876     }
7877
7878   M (BD_IP_MAC_ADD_DEL, mp);
7879
7880   mp->bd_id = ntohl (bd_id);
7881   mp->is_add = is_add;
7882
7883   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7884   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7885
7886   S (mp);
7887   W (ret);
7888   return ret;
7889 }
7890
7891 static void vl_api_bd_ip_mac_details_t_handler
7892   (vl_api_bd_ip_mac_details_t * mp)
7893 {
7894   vat_main_t *vam = &vat_main;
7895   u8 *ip = 0;
7896
7897   if (!mp->is_ipv6)
7898     ip =
7899       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7900   else
7901     ip =
7902       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7903
7904   print (vam->ofp,
7905          "\n%-5d %-7s %-20U %-30s",
7906          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7907          format_ethernet_address, mp->mac_address, ip);
7908
7909   vec_free (ip);
7910 }
7911
7912 static void vl_api_bd_ip_mac_details_t_handler_json
7913   (vl_api_bd_ip_mac_details_t * mp)
7914 {
7915   vat_main_t *vam = &vat_main;
7916   vat_json_node_t *node = NULL;
7917
7918   if (VAT_JSON_ARRAY != vam->json_tree.type)
7919     {
7920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7921       vat_json_init_array (&vam->json_tree);
7922     }
7923   node = vat_json_array_add (&vam->json_tree);
7924
7925   vat_json_init_object (node);
7926   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7927   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7928   vat_json_object_add_string_copy (node, "mac_address",
7929                                    format (0, "%U", format_ethernet_address,
7930                                            &mp->mac_address));
7931   u8 *ip = 0;
7932
7933   if (!mp->is_ipv6)
7934     ip =
7935       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7936   else
7937     ip =
7938       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7939   vat_json_object_add_string_copy (node, "ip_address", ip);
7940   vec_free (ip);
7941 }
7942
7943 static int
7944 api_bd_ip_mac_dump (vat_main_t * vam)
7945 {
7946   unformat_input_t *i = vam->input;
7947   vl_api_bd_ip_mac_dump_t *mp;
7948   vl_api_control_ping_t *mp_ping;
7949   int ret;
7950   u32 bd_id;
7951   u8 bd_id_set = 0;
7952
7953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7954     {
7955       if (unformat (i, "bd_id %d", &bd_id))
7956         {
7957           bd_id_set++;
7958         }
7959       else
7960         break;
7961     }
7962
7963   print (vam->ofp,
7964          "\n%-5s %-7s %-20s %-30s",
7965          "bd_id", "is_ipv6", "mac_address", "ip_address");
7966
7967   /* Dump Bridge Domain Ip to Mac entries */
7968   M (BD_IP_MAC_DUMP, mp);
7969
7970   if (bd_id_set)
7971     mp->bd_id = htonl (bd_id);
7972   else
7973     mp->bd_id = ~0;
7974
7975   S (mp);
7976
7977   /* Use a control ping for synchronization */
7978   MPING (CONTROL_PING, mp_ping);
7979   S (mp_ping);
7980
7981   W (ret);
7982   return ret;
7983 }
7984
7985 static int
7986 api_tap_connect (vat_main_t * vam)
7987 {
7988   unformat_input_t *i = vam->input;
7989   vl_api_tap_connect_t *mp;
7990   u8 mac_address[6];
7991   u8 random_mac = 1;
7992   u8 name_set = 0;
7993   u8 *tap_name;
7994   u8 *tag = 0;
7995   ip4_address_t ip4_address;
7996   u32 ip4_mask_width;
7997   int ip4_address_set = 0;
7998   ip6_address_t ip6_address;
7999   u32 ip6_mask_width;
8000   int ip6_address_set = 0;
8001   int ret;
8002
8003   clib_memset (mac_address, 0, sizeof (mac_address));
8004
8005   /* Parse args required to build the message */
8006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8007     {
8008       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8009         {
8010           random_mac = 0;
8011         }
8012       else if (unformat (i, "random-mac"))
8013         random_mac = 1;
8014       else if (unformat (i, "tapname %s", &tap_name))
8015         name_set = 1;
8016       else if (unformat (i, "tag %s", &tag))
8017         ;
8018       else if (unformat (i, "address %U/%d",
8019                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
8020         ip4_address_set = 1;
8021       else if (unformat (i, "address %U/%d",
8022                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
8023         ip6_address_set = 1;
8024       else
8025         break;
8026     }
8027
8028   if (name_set == 0)
8029     {
8030       errmsg ("missing tap name");
8031       return -99;
8032     }
8033   if (vec_len (tap_name) > 63)
8034     {
8035       errmsg ("tap name too long");
8036       return -99;
8037     }
8038   vec_add1 (tap_name, 0);
8039
8040   if (vec_len (tag) > 63)
8041     {
8042       errmsg ("tag too long");
8043       return -99;
8044     }
8045
8046   /* Construct the API message */
8047   M (TAP_CONNECT, mp);
8048
8049   mp->use_random_mac = random_mac;
8050   clib_memcpy (mp->mac_address, mac_address, 6);
8051   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8052   if (tag)
8053     clib_memcpy (mp->tag, tag, vec_len (tag));
8054
8055   if (ip4_address_set)
8056     {
8057       mp->ip4_address_set = 1;
8058       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
8059       mp->ip4_mask_width = ip4_mask_width;
8060     }
8061   if (ip6_address_set)
8062     {
8063       mp->ip6_address_set = 1;
8064       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
8065       mp->ip6_mask_width = ip6_mask_width;
8066     }
8067
8068   vec_free (tap_name);
8069   vec_free (tag);
8070
8071   /* send it... */
8072   S (mp);
8073
8074   /* Wait for a reply... */
8075   W (ret);
8076   return ret;
8077 }
8078
8079 static int
8080 api_tap_modify (vat_main_t * vam)
8081 {
8082   unformat_input_t *i = vam->input;
8083   vl_api_tap_modify_t *mp;
8084   u8 mac_address[6];
8085   u8 random_mac = 1;
8086   u8 name_set = 0;
8087   u8 *tap_name;
8088   u32 sw_if_index = ~0;
8089   u8 sw_if_index_set = 0;
8090   int ret;
8091
8092   clib_memset (mac_address, 0, sizeof (mac_address));
8093
8094   /* Parse args required to build the message */
8095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8096     {
8097       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8098         sw_if_index_set = 1;
8099       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8100         sw_if_index_set = 1;
8101       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8102         {
8103           random_mac = 0;
8104         }
8105       else if (unformat (i, "random-mac"))
8106         random_mac = 1;
8107       else if (unformat (i, "tapname %s", &tap_name))
8108         name_set = 1;
8109       else
8110         break;
8111     }
8112
8113   if (sw_if_index_set == 0)
8114     {
8115       errmsg ("missing vpp interface name");
8116       return -99;
8117     }
8118   if (name_set == 0)
8119     {
8120       errmsg ("missing tap name");
8121       return -99;
8122     }
8123   if (vec_len (tap_name) > 63)
8124     {
8125       errmsg ("tap name too long");
8126     }
8127   vec_add1 (tap_name, 0);
8128
8129   /* Construct the API message */
8130   M (TAP_MODIFY, mp);
8131
8132   mp->use_random_mac = random_mac;
8133   mp->sw_if_index = ntohl (sw_if_index);
8134   clib_memcpy (mp->mac_address, mac_address, 6);
8135   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8136   vec_free (tap_name);
8137
8138   /* send it... */
8139   S (mp);
8140
8141   /* Wait for a reply... */
8142   W (ret);
8143   return ret;
8144 }
8145
8146 static int
8147 api_tap_delete (vat_main_t * vam)
8148 {
8149   unformat_input_t *i = vam->input;
8150   vl_api_tap_delete_t *mp;
8151   u32 sw_if_index = ~0;
8152   u8 sw_if_index_set = 0;
8153   int ret;
8154
8155   /* Parse args required to build the message */
8156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8157     {
8158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8159         sw_if_index_set = 1;
8160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8161         sw_if_index_set = 1;
8162       else
8163         break;
8164     }
8165
8166   if (sw_if_index_set == 0)
8167     {
8168       errmsg ("missing vpp interface name");
8169       return -99;
8170     }
8171
8172   /* Construct the API message */
8173   M (TAP_DELETE, mp);
8174
8175   mp->sw_if_index = ntohl (sw_if_index);
8176
8177   /* send it... */
8178   S (mp);
8179
8180   /* Wait for a reply... */
8181   W (ret);
8182   return ret;
8183 }
8184
8185 static int
8186 api_tap_create_v2 (vat_main_t * vam)
8187 {
8188   unformat_input_t *i = vam->input;
8189   vl_api_tap_create_v2_t *mp;
8190   u8 mac_address[6];
8191   u8 random_mac = 1;
8192   u32 id = ~0;
8193   u8 *host_if_name = 0;
8194   u8 *host_ns = 0;
8195   u8 host_mac_addr[6];
8196   u8 host_mac_addr_set = 0;
8197   u8 *host_bridge = 0;
8198   ip4_address_t host_ip4_addr;
8199   ip4_address_t host_ip4_gw;
8200   u8 host_ip4_gw_set = 0;
8201   u32 host_ip4_prefix_len = 0;
8202   ip6_address_t host_ip6_addr;
8203   ip6_address_t host_ip6_gw;
8204   u8 host_ip6_gw_set = 0;
8205   u32 host_ip6_prefix_len = 0;
8206   int ret;
8207   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8208
8209   clib_memset (mac_address, 0, sizeof (mac_address));
8210
8211   /* Parse args required to build the message */
8212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8213     {
8214       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8215         {
8216           random_mac = 0;
8217         }
8218       else if (unformat (i, "id %u", &id))
8219         ;
8220       else if (unformat (i, "host-if-name %s", &host_if_name))
8221         ;
8222       else if (unformat (i, "host-ns %s", &host_ns))
8223         ;
8224       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8225                          host_mac_addr))
8226         host_mac_addr_set = 1;
8227       else if (unformat (i, "host-bridge %s", &host_bridge))
8228         ;
8229       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8230                          &host_ip4_addr, &host_ip4_prefix_len))
8231         ;
8232       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8233                          &host_ip6_addr, &host_ip6_prefix_len))
8234         ;
8235       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8236                          &host_ip4_gw))
8237         host_ip4_gw_set = 1;
8238       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8239                          &host_ip6_gw))
8240         host_ip6_gw_set = 1;
8241       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8242         ;
8243       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8244         ;
8245       else
8246         break;
8247     }
8248
8249   if (vec_len (host_if_name) > 63)
8250     {
8251       errmsg ("tap name too long. ");
8252       return -99;
8253     }
8254   if (vec_len (host_ns) > 63)
8255     {
8256       errmsg ("host name space too long. ");
8257       return -99;
8258     }
8259   if (vec_len (host_bridge) > 63)
8260     {
8261       errmsg ("host bridge name too long. ");
8262       return -99;
8263     }
8264   if (host_ip4_prefix_len > 32)
8265     {
8266       errmsg ("host ip4 prefix length not valid. ");
8267       return -99;
8268     }
8269   if (host_ip6_prefix_len > 128)
8270     {
8271       errmsg ("host ip6 prefix length not valid. ");
8272       return -99;
8273     }
8274   if (!is_pow2 (rx_ring_sz))
8275     {
8276       errmsg ("rx ring size must be power of 2. ");
8277       return -99;
8278     }
8279   if (rx_ring_sz > 32768)
8280     {
8281       errmsg ("rx ring size must be 32768 or lower. ");
8282       return -99;
8283     }
8284   if (!is_pow2 (tx_ring_sz))
8285     {
8286       errmsg ("tx ring size must be power of 2. ");
8287       return -99;
8288     }
8289   if (tx_ring_sz > 32768)
8290     {
8291       errmsg ("tx ring size must be 32768 or lower. ");
8292       return -99;
8293     }
8294
8295   /* Construct the API message */
8296   M (TAP_CREATE_V2, mp);
8297
8298   mp->use_random_mac = random_mac;
8299
8300   mp->id = ntohl (id);
8301   mp->host_namespace_set = host_ns != 0;
8302   mp->host_bridge_set = host_bridge != 0;
8303   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8304   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8305   mp->rx_ring_sz = ntohs (rx_ring_sz);
8306   mp->tx_ring_sz = ntohs (tx_ring_sz);
8307
8308   if (random_mac == 0)
8309     clib_memcpy (mp->mac_address, mac_address, 6);
8310   if (host_mac_addr_set)
8311     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8312   if (host_if_name)
8313     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8314   if (host_ns)
8315     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8316   if (host_bridge)
8317     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8318   if (host_ip4_prefix_len)
8319     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8320   if (host_ip6_prefix_len)
8321     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8322   if (host_ip4_gw_set)
8323     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8324   if (host_ip6_gw_set)
8325     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8326
8327   vec_free (host_ns);
8328   vec_free (host_if_name);
8329   vec_free (host_bridge);
8330
8331   /* send it... */
8332   S (mp);
8333
8334   /* Wait for a reply... */
8335   W (ret);
8336   return ret;
8337 }
8338
8339 static int
8340 api_tap_delete_v2 (vat_main_t * vam)
8341 {
8342   unformat_input_t *i = vam->input;
8343   vl_api_tap_delete_v2_t *mp;
8344   u32 sw_if_index = ~0;
8345   u8 sw_if_index_set = 0;
8346   int ret;
8347
8348   /* Parse args required to build the message */
8349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8350     {
8351       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8352         sw_if_index_set = 1;
8353       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8354         sw_if_index_set = 1;
8355       else
8356         break;
8357     }
8358
8359   if (sw_if_index_set == 0)
8360     {
8361       errmsg ("missing vpp interface name. ");
8362       return -99;
8363     }
8364
8365   /* Construct the API message */
8366   M (TAP_DELETE_V2, mp);
8367
8368   mp->sw_if_index = ntohl (sw_if_index);
8369
8370   /* send it... */
8371   S (mp);
8372
8373   /* Wait for a reply... */
8374   W (ret);
8375   return ret;
8376 }
8377
8378 static int
8379 api_bond_create (vat_main_t * vam)
8380 {
8381   unformat_input_t *i = vam->input;
8382   vl_api_bond_create_t *mp;
8383   u8 mac_address[6];
8384   u8 custom_mac = 0;
8385   int ret;
8386   u8 mode;
8387   u8 lb;
8388   u8 mode_is_set = 0;
8389
8390   clib_memset (mac_address, 0, sizeof (mac_address));
8391   lb = BOND_LB_L2;
8392
8393   /* Parse args required to build the message */
8394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8395     {
8396       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8397         mode_is_set = 1;
8398       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8399                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8400         ;
8401       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8402                          mac_address))
8403         custom_mac = 1;
8404       else
8405         break;
8406     }
8407
8408   if (mode_is_set == 0)
8409     {
8410       errmsg ("Missing bond mode. ");
8411       return -99;
8412     }
8413
8414   /* Construct the API message */
8415   M (BOND_CREATE, mp);
8416
8417   mp->use_custom_mac = custom_mac;
8418
8419   mp->mode = mode;
8420   mp->lb = lb;
8421
8422   if (custom_mac)
8423     clib_memcpy (mp->mac_address, mac_address, 6);
8424
8425   /* send it... */
8426   S (mp);
8427
8428   /* Wait for a reply... */
8429   W (ret);
8430   return ret;
8431 }
8432
8433 static int
8434 api_bond_delete (vat_main_t * vam)
8435 {
8436   unformat_input_t *i = vam->input;
8437   vl_api_bond_delete_t *mp;
8438   u32 sw_if_index = ~0;
8439   u8 sw_if_index_set = 0;
8440   int ret;
8441
8442   /* Parse args required to build the message */
8443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8444     {
8445       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8446         sw_if_index_set = 1;
8447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8448         sw_if_index_set = 1;
8449       else
8450         break;
8451     }
8452
8453   if (sw_if_index_set == 0)
8454     {
8455       errmsg ("missing vpp interface name. ");
8456       return -99;
8457     }
8458
8459   /* Construct the API message */
8460   M (BOND_DELETE, mp);
8461
8462   mp->sw_if_index = ntohl (sw_if_index);
8463
8464   /* send it... */
8465   S (mp);
8466
8467   /* Wait for a reply... */
8468   W (ret);
8469   return ret;
8470 }
8471
8472 static int
8473 api_bond_enslave (vat_main_t * vam)
8474 {
8475   unformat_input_t *i = vam->input;
8476   vl_api_bond_enslave_t *mp;
8477   u32 bond_sw_if_index;
8478   int ret;
8479   u8 is_passive;
8480   u8 is_long_timeout;
8481   u32 bond_sw_if_index_is_set = 0;
8482   u32 sw_if_index;
8483   u8 sw_if_index_is_set = 0;
8484
8485   /* Parse args required to build the message */
8486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8487     {
8488       if (unformat (i, "sw_if_index %d", &sw_if_index))
8489         sw_if_index_is_set = 1;
8490       else if (unformat (i, "bond %u", &bond_sw_if_index))
8491         bond_sw_if_index_is_set = 1;
8492       else if (unformat (i, "passive %d", &is_passive))
8493         ;
8494       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8495         ;
8496       else
8497         break;
8498     }
8499
8500   if (bond_sw_if_index_is_set == 0)
8501     {
8502       errmsg ("Missing bond sw_if_index. ");
8503       return -99;
8504     }
8505   if (sw_if_index_is_set == 0)
8506     {
8507       errmsg ("Missing slave sw_if_index. ");
8508       return -99;
8509     }
8510
8511   /* Construct the API message */
8512   M (BOND_ENSLAVE, mp);
8513
8514   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8515   mp->sw_if_index = ntohl (sw_if_index);
8516   mp->is_long_timeout = is_long_timeout;
8517   mp->is_passive = is_passive;
8518
8519   /* send it... */
8520   S (mp);
8521
8522   /* Wait for a reply... */
8523   W (ret);
8524   return ret;
8525 }
8526
8527 static int
8528 api_bond_detach_slave (vat_main_t * vam)
8529 {
8530   unformat_input_t *i = vam->input;
8531   vl_api_bond_detach_slave_t *mp;
8532   u32 sw_if_index = ~0;
8533   u8 sw_if_index_set = 0;
8534   int ret;
8535
8536   /* Parse args required to build the message */
8537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8538     {
8539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8540         sw_if_index_set = 1;
8541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8542         sw_if_index_set = 1;
8543       else
8544         break;
8545     }
8546
8547   if (sw_if_index_set == 0)
8548     {
8549       errmsg ("missing vpp interface name. ");
8550       return -99;
8551     }
8552
8553   /* Construct the API message */
8554   M (BOND_DETACH_SLAVE, mp);
8555
8556   mp->sw_if_index = ntohl (sw_if_index);
8557
8558   /* send it... */
8559   S (mp);
8560
8561   /* Wait for a reply... */
8562   W (ret);
8563   return ret;
8564 }
8565
8566 static int
8567 api_ip_table_add_del (vat_main_t * vam)
8568 {
8569   unformat_input_t *i = vam->input;
8570   vl_api_ip_table_add_del_t *mp;
8571   u32 table_id = ~0;
8572   u8 is_ipv6 = 0;
8573   u8 is_add = 1;
8574   int ret = 0;
8575
8576   /* Parse args required to build the message */
8577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8578     {
8579       if (unformat (i, "ipv6"))
8580         is_ipv6 = 1;
8581       else if (unformat (i, "del"))
8582         is_add = 0;
8583       else if (unformat (i, "add"))
8584         is_add = 1;
8585       else if (unformat (i, "table %d", &table_id))
8586         ;
8587       else
8588         {
8589           clib_warning ("parse error '%U'", format_unformat_error, i);
8590           return -99;
8591         }
8592     }
8593
8594   if (~0 == table_id)
8595     {
8596       errmsg ("missing table-ID");
8597       return -99;
8598     }
8599
8600   /* Construct the API message */
8601   M (IP_TABLE_ADD_DEL, mp);
8602
8603   mp->table_id = ntohl (table_id);
8604   mp->is_ipv6 = is_ipv6;
8605   mp->is_add = is_add;
8606
8607   /* send it... */
8608   S (mp);
8609
8610   /* Wait for a reply... */
8611   W (ret);
8612
8613   return ret;
8614 }
8615
8616 static int
8617 api_ip_add_del_route (vat_main_t * vam)
8618 {
8619   unformat_input_t *i = vam->input;
8620   vl_api_ip_add_del_route_t *mp;
8621   u32 sw_if_index = ~0, vrf_id = 0;
8622   u8 is_ipv6 = 0;
8623   u8 is_local = 0, is_drop = 0;
8624   u8 is_unreach = 0, is_prohibit = 0;
8625   u8 is_add = 1;
8626   u32 next_hop_weight = 1;
8627   u8 is_multipath = 0;
8628   u8 address_set = 0;
8629   u8 address_length_set = 0;
8630   u32 next_hop_table_id = 0;
8631   u32 resolve_attempts = 0;
8632   u32 dst_address_length = 0;
8633   u8 next_hop_set = 0;
8634   ip4_address_t v4_dst_address, v4_next_hop_address;
8635   ip6_address_t v6_dst_address, v6_next_hop_address;
8636   int count = 1;
8637   int j;
8638   f64 before = 0;
8639   u32 random_add_del = 0;
8640   u32 *random_vector = 0;
8641   uword *random_hash;
8642   u32 random_seed = 0xdeaddabe;
8643   u32 classify_table_index = ~0;
8644   u8 is_classify = 0;
8645   u8 resolve_host = 0, resolve_attached = 0;
8646   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8647   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8648   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8649
8650   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8651   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8652   /* Parse args required to build the message */
8653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8654     {
8655       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8656         ;
8657       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8658         ;
8659       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8660         {
8661           address_set = 1;
8662           is_ipv6 = 0;
8663         }
8664       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8665         {
8666           address_set = 1;
8667           is_ipv6 = 1;
8668         }
8669       else if (unformat (i, "/%d", &dst_address_length))
8670         {
8671           address_length_set = 1;
8672         }
8673
8674       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8675                                          &v4_next_hop_address))
8676         {
8677           next_hop_set = 1;
8678         }
8679       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8680                                          &v6_next_hop_address))
8681         {
8682           next_hop_set = 1;
8683         }
8684       else
8685         if (unformat
8686             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8687         {
8688           next_hop_set = 1;
8689         }
8690       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8691         {
8692           next_hop_set = 1;
8693         }
8694       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8695         ;
8696       else if (unformat (i, "weight %d", &next_hop_weight))
8697         ;
8698       else if (unformat (i, "drop"))
8699         {
8700           is_drop = 1;
8701         }
8702       else if (unformat (i, "null-send-unreach"))
8703         {
8704           is_unreach = 1;
8705         }
8706       else if (unformat (i, "null-send-prohibit"))
8707         {
8708           is_prohibit = 1;
8709         }
8710       else if (unformat (i, "local"))
8711         {
8712           is_local = 1;
8713         }
8714       else if (unformat (i, "classify %d", &classify_table_index))
8715         {
8716           is_classify = 1;
8717         }
8718       else if (unformat (i, "del"))
8719         is_add = 0;
8720       else if (unformat (i, "add"))
8721         is_add = 1;
8722       else if (unformat (i, "resolve-via-host"))
8723         resolve_host = 1;
8724       else if (unformat (i, "resolve-via-attached"))
8725         resolve_attached = 1;
8726       else if (unformat (i, "multipath"))
8727         is_multipath = 1;
8728       else if (unformat (i, "vrf %d", &vrf_id))
8729         ;
8730       else if (unformat (i, "count %d", &count))
8731         ;
8732       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8733         ;
8734       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8735         ;
8736       else if (unformat (i, "out-label %d", &next_hop_out_label))
8737         {
8738           vl_api_fib_mpls_label_t fib_label = {
8739             .label = ntohl (next_hop_out_label),
8740             .ttl = 64,
8741             .exp = 0,
8742           };
8743           vec_add1 (next_hop_out_label_stack, fib_label);
8744         }
8745       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8746         ;
8747       else if (unformat (i, "random"))
8748         random_add_del = 1;
8749       else if (unformat (i, "seed %d", &random_seed))
8750         ;
8751       else
8752         {
8753           clib_warning ("parse error '%U'", format_unformat_error, i);
8754           return -99;
8755         }
8756     }
8757
8758   if (!next_hop_set && !is_drop && !is_local &&
8759       !is_classify && !is_unreach && !is_prohibit &&
8760       MPLS_LABEL_INVALID == next_hop_via_label)
8761     {
8762       errmsg
8763         ("next hop / local / drop / unreach / prohibit / classify not set");
8764       return -99;
8765     }
8766
8767   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8768     {
8769       errmsg ("next hop and next-hop via label set");
8770       return -99;
8771     }
8772   if (address_set == 0)
8773     {
8774       errmsg ("missing addresses");
8775       return -99;
8776     }
8777
8778   if (address_length_set == 0)
8779     {
8780       errmsg ("missing address length");
8781       return -99;
8782     }
8783
8784   /* Generate a pile of unique, random routes */
8785   if (random_add_del)
8786     {
8787       u32 this_random_address;
8788       random_hash = hash_create (count, sizeof (uword));
8789
8790       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8791       for (j = 0; j <= count; j++)
8792         {
8793           do
8794             {
8795               this_random_address = random_u32 (&random_seed);
8796               this_random_address =
8797                 clib_host_to_net_u32 (this_random_address);
8798             }
8799           while (hash_get (random_hash, this_random_address));
8800           vec_add1 (random_vector, this_random_address);
8801           hash_set (random_hash, this_random_address, 1);
8802         }
8803       hash_free (random_hash);
8804       v4_dst_address.as_u32 = random_vector[0];
8805     }
8806
8807   if (count > 1)
8808     {
8809       /* Turn on async mode */
8810       vam->async_mode = 1;
8811       vam->async_errors = 0;
8812       before = vat_time_now (vam);
8813     }
8814
8815   for (j = 0; j < count; j++)
8816     {
8817       /* Construct the API message */
8818       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8819           vec_len (next_hop_out_label_stack));
8820
8821       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8822       mp->table_id = ntohl (vrf_id);
8823
8824       mp->is_add = is_add;
8825       mp->is_drop = is_drop;
8826       mp->is_unreach = is_unreach;
8827       mp->is_prohibit = is_prohibit;
8828       mp->is_ipv6 = is_ipv6;
8829       mp->is_local = is_local;
8830       mp->is_classify = is_classify;
8831       mp->is_multipath = is_multipath;
8832       mp->is_resolve_host = resolve_host;
8833       mp->is_resolve_attached = resolve_attached;
8834       mp->next_hop_weight = next_hop_weight;
8835       mp->next_hop_preference = 0;
8836       mp->dst_address_length = dst_address_length;
8837       mp->next_hop_table_id = ntohl (next_hop_table_id);
8838       mp->classify_table_index = ntohl (classify_table_index);
8839       mp->next_hop_via_label = ntohl (next_hop_via_label);
8840       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8841       if (0 != mp->next_hop_n_out_labels)
8842         {
8843           memcpy (mp->next_hop_out_label_stack,
8844                   next_hop_out_label_stack,
8845                   (vec_len (next_hop_out_label_stack) *
8846                    sizeof (vl_api_fib_mpls_label_t)));
8847           vec_free (next_hop_out_label_stack);
8848         }
8849
8850       if (is_ipv6)
8851         {
8852           clib_memcpy (mp->dst_address, &v6_dst_address,
8853                        sizeof (v6_dst_address));
8854           if (next_hop_set)
8855             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8856                          sizeof (v6_next_hop_address));
8857           increment_v6_address (&v6_dst_address);
8858         }
8859       else
8860         {
8861           clib_memcpy (mp->dst_address, &v4_dst_address,
8862                        sizeof (v4_dst_address));
8863           if (next_hop_set)
8864             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8865                          sizeof (v4_next_hop_address));
8866           if (random_add_del)
8867             v4_dst_address.as_u32 = random_vector[j + 1];
8868           else
8869             increment_v4_address (&v4_dst_address);
8870         }
8871       /* send it... */
8872       S (mp);
8873       /* If we receive SIGTERM, stop now... */
8874       if (vam->do_exit)
8875         break;
8876     }
8877
8878   /* When testing multiple add/del ops, use a control-ping to sync */
8879   if (count > 1)
8880     {
8881       vl_api_control_ping_t *mp_ping;
8882       f64 after;
8883       f64 timeout;
8884
8885       /* Shut off async mode */
8886       vam->async_mode = 0;
8887
8888       MPING (CONTROL_PING, mp_ping);
8889       S (mp_ping);
8890
8891       timeout = vat_time_now (vam) + 1.0;
8892       while (vat_time_now (vam) < timeout)
8893         if (vam->result_ready == 1)
8894           goto out;
8895       vam->retval = -99;
8896
8897     out:
8898       if (vam->retval == -99)
8899         errmsg ("timeout");
8900
8901       if (vam->async_errors > 0)
8902         {
8903           errmsg ("%d asynchronous errors", vam->async_errors);
8904           vam->retval = -98;
8905         }
8906       vam->async_errors = 0;
8907       after = vat_time_now (vam);
8908
8909       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8910       if (j > 0)
8911         count = j;
8912
8913       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8914              count, after - before, count / (after - before));
8915     }
8916   else
8917     {
8918       int ret;
8919
8920       /* Wait for a reply... */
8921       W (ret);
8922       return ret;
8923     }
8924
8925   /* Return the good/bad news */
8926   return (vam->retval);
8927 }
8928
8929 static int
8930 api_ip_mroute_add_del (vat_main_t * vam)
8931 {
8932   unformat_input_t *i = vam->input;
8933   vl_api_ip_mroute_add_del_t *mp;
8934   u32 sw_if_index = ~0, vrf_id = 0;
8935   u8 is_ipv6 = 0;
8936   u8 is_local = 0;
8937   u8 is_add = 1;
8938   u8 address_set = 0;
8939   u32 grp_address_length = 0;
8940   ip4_address_t v4_grp_address, v4_src_address;
8941   ip6_address_t v6_grp_address, v6_src_address;
8942   mfib_itf_flags_t iflags = 0;
8943   mfib_entry_flags_t eflags = 0;
8944   int ret;
8945
8946   /* Parse args required to build the message */
8947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8948     {
8949       if (unformat (i, "sw_if_index %d", &sw_if_index))
8950         ;
8951       else if (unformat (i, "%U %U",
8952                          unformat_ip4_address, &v4_src_address,
8953                          unformat_ip4_address, &v4_grp_address))
8954         {
8955           grp_address_length = 64;
8956           address_set = 1;
8957           is_ipv6 = 0;
8958         }
8959       else if (unformat (i, "%U %U",
8960                          unformat_ip6_address, &v6_src_address,
8961                          unformat_ip6_address, &v6_grp_address))
8962         {
8963           grp_address_length = 256;
8964           address_set = 1;
8965           is_ipv6 = 1;
8966         }
8967       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8968         {
8969           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8970           grp_address_length = 32;
8971           address_set = 1;
8972           is_ipv6 = 0;
8973         }
8974       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8975         {
8976           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8977           grp_address_length = 128;
8978           address_set = 1;
8979           is_ipv6 = 1;
8980         }
8981       else if (unformat (i, "/%d", &grp_address_length))
8982         ;
8983       else if (unformat (i, "local"))
8984         {
8985           is_local = 1;
8986         }
8987       else if (unformat (i, "del"))
8988         is_add = 0;
8989       else if (unformat (i, "add"))
8990         is_add = 1;
8991       else if (unformat (i, "vrf %d", &vrf_id))
8992         ;
8993       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8994         ;
8995       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8996         ;
8997       else
8998         {
8999           clib_warning ("parse error '%U'", format_unformat_error, i);
9000           return -99;
9001         }
9002     }
9003
9004   if (address_set == 0)
9005     {
9006       errmsg ("missing addresses\n");
9007       return -99;
9008     }
9009
9010   /* Construct the API message */
9011   M (IP_MROUTE_ADD_DEL, mp);
9012
9013   mp->next_hop_sw_if_index = ntohl (sw_if_index);
9014   mp->table_id = ntohl (vrf_id);
9015
9016   mp->is_add = is_add;
9017   mp->is_ipv6 = is_ipv6;
9018   mp->is_local = is_local;
9019   mp->itf_flags = ntohl (iflags);
9020   mp->entry_flags = ntohl (eflags);
9021   mp->grp_address_length = grp_address_length;
9022   mp->grp_address_length = ntohs (mp->grp_address_length);
9023
9024   if (is_ipv6)
9025     {
9026       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
9027       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
9028     }
9029   else
9030     {
9031       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
9032       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
9033
9034     }
9035
9036   /* send it... */
9037   S (mp);
9038   /* Wait for a reply... */
9039   W (ret);
9040   return ret;
9041 }
9042
9043 static int
9044 api_mpls_table_add_del (vat_main_t * vam)
9045 {
9046   unformat_input_t *i = vam->input;
9047   vl_api_mpls_table_add_del_t *mp;
9048   u32 table_id = ~0;
9049   u8 is_add = 1;
9050   int ret = 0;
9051
9052   /* Parse args required to build the message */
9053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9054     {
9055       if (unformat (i, "table %d", &table_id))
9056         ;
9057       else if (unformat (i, "del"))
9058         is_add = 0;
9059       else if (unformat (i, "add"))
9060         is_add = 1;
9061       else
9062         {
9063           clib_warning ("parse error '%U'", format_unformat_error, i);
9064           return -99;
9065         }
9066     }
9067
9068   if (~0 == table_id)
9069     {
9070       errmsg ("missing table-ID");
9071       return -99;
9072     }
9073
9074   /* Construct the API message */
9075   M (MPLS_TABLE_ADD_DEL, mp);
9076
9077   mp->mt_table_id = ntohl (table_id);
9078   mp->mt_is_add = is_add;
9079
9080   /* send it... */
9081   S (mp);
9082
9083   /* Wait for a reply... */
9084   W (ret);
9085
9086   return ret;
9087 }
9088
9089 static int
9090 api_mpls_route_add_del (vat_main_t * vam)
9091 {
9092   unformat_input_t *i = vam->input;
9093   vl_api_mpls_route_add_del_t *mp;
9094   u32 sw_if_index = ~0, table_id = 0;
9095   u8 is_add = 1;
9096   u32 next_hop_weight = 1;
9097   u8 is_multipath = 0;
9098   u32 next_hop_table_id = 0;
9099   u8 next_hop_set = 0;
9100   ip4_address_t v4_next_hop_address = {
9101     .as_u32 = 0,
9102   };
9103   ip6_address_t v6_next_hop_address = { {0} };
9104   int count = 1;
9105   int j;
9106   f64 before = 0;
9107   u32 classify_table_index = ~0;
9108   u8 is_classify = 0;
9109   u8 resolve_host = 0, resolve_attached = 0;
9110   u8 is_interface_rx = 0;
9111   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9112   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9113   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9114   mpls_label_t local_label = MPLS_LABEL_INVALID;
9115   u8 is_eos = 0;
9116   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9117
9118   /* Parse args required to build the message */
9119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9120     {
9121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9122         ;
9123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9124         ;
9125       else if (unformat (i, "%d", &local_label))
9126         ;
9127       else if (unformat (i, "eos"))
9128         is_eos = 1;
9129       else if (unformat (i, "non-eos"))
9130         is_eos = 0;
9131       else if (unformat (i, "via %U", unformat_ip4_address,
9132                          &v4_next_hop_address))
9133         {
9134           next_hop_set = 1;
9135           next_hop_proto = DPO_PROTO_IP4;
9136         }
9137       else if (unformat (i, "via %U", unformat_ip6_address,
9138                          &v6_next_hop_address))
9139         {
9140           next_hop_set = 1;
9141           next_hop_proto = DPO_PROTO_IP6;
9142         }
9143       else if (unformat (i, "weight %d", &next_hop_weight))
9144         ;
9145       else if (unformat (i, "classify %d", &classify_table_index))
9146         {
9147           is_classify = 1;
9148         }
9149       else if (unformat (i, "del"))
9150         is_add = 0;
9151       else if (unformat (i, "add"))
9152         is_add = 1;
9153       else if (unformat (i, "resolve-via-host"))
9154         resolve_host = 1;
9155       else if (unformat (i, "resolve-via-attached"))
9156         resolve_attached = 1;
9157       else if (unformat (i, "multipath"))
9158         is_multipath = 1;
9159       else if (unformat (i, "count %d", &count))
9160         ;
9161       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9162         {
9163           next_hop_set = 1;
9164           next_hop_proto = DPO_PROTO_IP4;
9165         }
9166       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9167         {
9168           next_hop_set = 1;
9169           next_hop_proto = DPO_PROTO_IP6;
9170         }
9171       else
9172         if (unformat
9173             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9174              &sw_if_index))
9175         {
9176           next_hop_set = 1;
9177           next_hop_proto = DPO_PROTO_ETHERNET;
9178           is_interface_rx = 1;
9179         }
9180       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9181         {
9182           next_hop_set = 1;
9183           next_hop_proto = DPO_PROTO_ETHERNET;
9184           is_interface_rx = 1;
9185         }
9186       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9187         next_hop_set = 1;
9188       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9189         next_hop_set = 1;
9190       else if (unformat (i, "out-label %d", &next_hop_out_label))
9191         {
9192           vl_api_fib_mpls_label_t fib_label = {
9193             .label = ntohl (next_hop_out_label),
9194             .ttl = 64,
9195             .exp = 0,
9196           };
9197           vec_add1 (next_hop_out_label_stack, fib_label);
9198         }
9199       else
9200         {
9201           clib_warning ("parse error '%U'", format_unformat_error, i);
9202           return -99;
9203         }
9204     }
9205
9206   if (!next_hop_set && !is_classify)
9207     {
9208       errmsg ("next hop / classify not set");
9209       return -99;
9210     }
9211
9212   if (MPLS_LABEL_INVALID == local_label)
9213     {
9214       errmsg ("missing label");
9215       return -99;
9216     }
9217
9218   if (count > 1)
9219     {
9220       /* Turn on async mode */
9221       vam->async_mode = 1;
9222       vam->async_errors = 0;
9223       before = vat_time_now (vam);
9224     }
9225
9226   for (j = 0; j < count; j++)
9227     {
9228       /* Construct the API message */
9229       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9230           vec_len (next_hop_out_label_stack));
9231
9232       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9233       mp->mr_table_id = ntohl (table_id);
9234
9235       mp->mr_is_add = is_add;
9236       mp->mr_next_hop_proto = next_hop_proto;
9237       mp->mr_is_classify = is_classify;
9238       mp->mr_is_multipath = is_multipath;
9239       mp->mr_is_resolve_host = resolve_host;
9240       mp->mr_is_resolve_attached = resolve_attached;
9241       mp->mr_is_interface_rx = is_interface_rx;
9242       mp->mr_next_hop_weight = next_hop_weight;
9243       mp->mr_next_hop_preference = 0;
9244       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9245       mp->mr_classify_table_index = ntohl (classify_table_index);
9246       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9247       mp->mr_label = ntohl (local_label);
9248       mp->mr_eos = is_eos;
9249
9250       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9251       if (0 != mp->mr_next_hop_n_out_labels)
9252         {
9253           memcpy (mp->mr_next_hop_out_label_stack,
9254                   next_hop_out_label_stack,
9255                   vec_len (next_hop_out_label_stack) *
9256                   sizeof (vl_api_fib_mpls_label_t));
9257           vec_free (next_hop_out_label_stack);
9258         }
9259
9260       if (next_hop_set)
9261         {
9262           if (DPO_PROTO_IP4 == next_hop_proto)
9263             {
9264               clib_memcpy (mp->mr_next_hop,
9265                            &v4_next_hop_address,
9266                            sizeof (v4_next_hop_address));
9267             }
9268           else if (DPO_PROTO_IP6 == next_hop_proto)
9269
9270             {
9271               clib_memcpy (mp->mr_next_hop,
9272                            &v6_next_hop_address,
9273                            sizeof (v6_next_hop_address));
9274             }
9275         }
9276       local_label++;
9277
9278       /* send it... */
9279       S (mp);
9280       /* If we receive SIGTERM, stop now... */
9281       if (vam->do_exit)
9282         break;
9283     }
9284
9285   /* When testing multiple add/del ops, use a control-ping to sync */
9286   if (count > 1)
9287     {
9288       vl_api_control_ping_t *mp_ping;
9289       f64 after;
9290       f64 timeout;
9291
9292       /* Shut off async mode */
9293       vam->async_mode = 0;
9294
9295       MPING (CONTROL_PING, mp_ping);
9296       S (mp_ping);
9297
9298       timeout = vat_time_now (vam) + 1.0;
9299       while (vat_time_now (vam) < timeout)
9300         if (vam->result_ready == 1)
9301           goto out;
9302       vam->retval = -99;
9303
9304     out:
9305       if (vam->retval == -99)
9306         errmsg ("timeout");
9307
9308       if (vam->async_errors > 0)
9309         {
9310           errmsg ("%d asynchronous errors", vam->async_errors);
9311           vam->retval = -98;
9312         }
9313       vam->async_errors = 0;
9314       after = vat_time_now (vam);
9315
9316       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9317       if (j > 0)
9318         count = j;
9319
9320       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9321              count, after - before, count / (after - before));
9322     }
9323   else
9324     {
9325       int ret;
9326
9327       /* Wait for a reply... */
9328       W (ret);
9329       return ret;
9330     }
9331
9332   /* Return the good/bad news */
9333   return (vam->retval);
9334 }
9335
9336 static int
9337 api_mpls_ip_bind_unbind (vat_main_t * vam)
9338 {
9339   unformat_input_t *i = vam->input;
9340   vl_api_mpls_ip_bind_unbind_t *mp;
9341   u32 ip_table_id = 0;
9342   u8 is_bind = 1;
9343   u8 is_ip4 = 1;
9344   ip4_address_t v4_address;
9345   ip6_address_t v6_address;
9346   u32 address_length;
9347   u8 address_set = 0;
9348   mpls_label_t local_label = MPLS_LABEL_INVALID;
9349   int ret;
9350
9351   /* Parse args required to build the message */
9352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9353     {
9354       if (unformat (i, "%U/%d", unformat_ip4_address,
9355                     &v4_address, &address_length))
9356         {
9357           is_ip4 = 1;
9358           address_set = 1;
9359         }
9360       else if (unformat (i, "%U/%d", unformat_ip6_address,
9361                          &v6_address, &address_length))
9362         {
9363           is_ip4 = 0;
9364           address_set = 1;
9365         }
9366       else if (unformat (i, "%d", &local_label))
9367         ;
9368       else if (unformat (i, "table-id %d", &ip_table_id))
9369         ;
9370       else if (unformat (i, "unbind"))
9371         is_bind = 0;
9372       else if (unformat (i, "bind"))
9373         is_bind = 1;
9374       else
9375         {
9376           clib_warning ("parse error '%U'", format_unformat_error, i);
9377           return -99;
9378         }
9379     }
9380
9381   if (!address_set)
9382     {
9383       errmsg ("IP address not set");
9384       return -99;
9385     }
9386
9387   if (MPLS_LABEL_INVALID == local_label)
9388     {
9389       errmsg ("missing label");
9390       return -99;
9391     }
9392
9393   /* Construct the API message */
9394   M (MPLS_IP_BIND_UNBIND, mp);
9395
9396   mp->mb_is_bind = is_bind;
9397   mp->mb_is_ip4 = is_ip4;
9398   mp->mb_ip_table_id = ntohl (ip_table_id);
9399   mp->mb_mpls_table_id = 0;
9400   mp->mb_label = ntohl (local_label);
9401   mp->mb_address_length = address_length;
9402
9403   if (is_ip4)
9404     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9405   else
9406     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9407
9408   /* send it... */
9409   S (mp);
9410
9411   /* Wait for a reply... */
9412   W (ret);
9413   return ret;
9414 }
9415
9416 static int
9417 api_sr_mpls_policy_add (vat_main_t * vam)
9418 {
9419   unformat_input_t *i = vam->input;
9420   vl_api_sr_mpls_policy_add_t *mp;
9421   u32 bsid = 0;
9422   u32 weight = 1;
9423   u8 type = 0;
9424   u8 n_segments = 0;
9425   u32 sid;
9426   u32 *segments = NULL;
9427   int ret;
9428
9429   /* Parse args required to build the message */
9430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9431     {
9432       if (unformat (i, "bsid %d", &bsid))
9433         ;
9434       else if (unformat (i, "weight %d", &weight))
9435         ;
9436       else if (unformat (i, "spray"))
9437         type = 1;
9438       else if (unformat (i, "next %d", &sid))
9439         {
9440           n_segments += 1;
9441           vec_add1 (segments, htonl (sid));
9442         }
9443       else
9444         {
9445           clib_warning ("parse error '%U'", format_unformat_error, i);
9446           return -99;
9447         }
9448     }
9449
9450   if (bsid == 0)
9451     {
9452       errmsg ("bsid not set");
9453       return -99;
9454     }
9455
9456   if (n_segments == 0)
9457     {
9458       errmsg ("no sid in segment stack");
9459       return -99;
9460     }
9461
9462   /* Construct the API message */
9463   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9464
9465   mp->bsid = htonl (bsid);
9466   mp->weight = htonl (weight);
9467   mp->type = type;
9468   mp->n_segments = n_segments;
9469   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9470   vec_free (segments);
9471
9472   /* send it... */
9473   S (mp);
9474
9475   /* Wait for a reply... */
9476   W (ret);
9477   return ret;
9478 }
9479
9480 static int
9481 api_sr_mpls_policy_del (vat_main_t * vam)
9482 {
9483   unformat_input_t *i = vam->input;
9484   vl_api_sr_mpls_policy_del_t *mp;
9485   u32 bsid = 0;
9486   int ret;
9487
9488   /* Parse args required to build the message */
9489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9490     {
9491       if (unformat (i, "bsid %d", &bsid))
9492         ;
9493       else
9494         {
9495           clib_warning ("parse error '%U'", format_unformat_error, i);
9496           return -99;
9497         }
9498     }
9499
9500   if (bsid == 0)
9501     {
9502       errmsg ("bsid not set");
9503       return -99;
9504     }
9505
9506   /* Construct the API message */
9507   M (SR_MPLS_POLICY_DEL, mp);
9508
9509   mp->bsid = htonl (bsid);
9510
9511   /* send it... */
9512   S (mp);
9513
9514   /* Wait for a reply... */
9515   W (ret);
9516   return ret;
9517 }
9518
9519 static int
9520 api_bier_table_add_del (vat_main_t * vam)
9521 {
9522   unformat_input_t *i = vam->input;
9523   vl_api_bier_table_add_del_t *mp;
9524   u8 is_add = 1;
9525   u32 set = 0, sub_domain = 0, hdr_len = 3;
9526   mpls_label_t local_label = MPLS_LABEL_INVALID;
9527   int ret;
9528
9529   /* Parse args required to build the message */
9530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9531     {
9532       if (unformat (i, "sub-domain %d", &sub_domain))
9533         ;
9534       else if (unformat (i, "set %d", &set))
9535         ;
9536       else if (unformat (i, "label %d", &local_label))
9537         ;
9538       else if (unformat (i, "hdr-len %d", &hdr_len))
9539         ;
9540       else if (unformat (i, "add"))
9541         is_add = 1;
9542       else if (unformat (i, "del"))
9543         is_add = 0;
9544       else
9545         {
9546           clib_warning ("parse error '%U'", format_unformat_error, i);
9547           return -99;
9548         }
9549     }
9550
9551   if (MPLS_LABEL_INVALID == local_label)
9552     {
9553       errmsg ("missing label\n");
9554       return -99;
9555     }
9556
9557   /* Construct the API message */
9558   M (BIER_TABLE_ADD_DEL, mp);
9559
9560   mp->bt_is_add = is_add;
9561   mp->bt_label = ntohl (local_label);
9562   mp->bt_tbl_id.bt_set = set;
9563   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9564   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9565
9566   /* send it... */
9567   S (mp);
9568
9569   /* Wait for a reply... */
9570   W (ret);
9571
9572   return (ret);
9573 }
9574
9575 static int
9576 api_bier_route_add_del (vat_main_t * vam)
9577 {
9578   unformat_input_t *i = vam->input;
9579   vl_api_bier_route_add_del_t *mp;
9580   u8 is_add = 1;
9581   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9582   ip4_address_t v4_next_hop_address;
9583   ip6_address_t v6_next_hop_address;
9584   u8 next_hop_set = 0;
9585   u8 next_hop_proto_is_ip4 = 1;
9586   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9587   int ret;
9588
9589   /* Parse args required to build the message */
9590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9591     {
9592       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9593         {
9594           next_hop_proto_is_ip4 = 1;
9595           next_hop_set = 1;
9596         }
9597       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9598         {
9599           next_hop_proto_is_ip4 = 0;
9600           next_hop_set = 1;
9601         }
9602       if (unformat (i, "sub-domain %d", &sub_domain))
9603         ;
9604       else if (unformat (i, "set %d", &set))
9605         ;
9606       else if (unformat (i, "hdr-len %d", &hdr_len))
9607         ;
9608       else if (unformat (i, "bp %d", &bp))
9609         ;
9610       else if (unformat (i, "add"))
9611         is_add = 1;
9612       else if (unformat (i, "del"))
9613         is_add = 0;
9614       else if (unformat (i, "out-label %d", &next_hop_out_label))
9615         ;
9616       else
9617         {
9618           clib_warning ("parse error '%U'", format_unformat_error, i);
9619           return -99;
9620         }
9621     }
9622
9623   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9624     {
9625       errmsg ("next hop / label set\n");
9626       return -99;
9627     }
9628   if (0 == bp)
9629     {
9630       errmsg ("bit=position not set\n");
9631       return -99;
9632     }
9633
9634   /* Construct the API message */
9635   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9636
9637   mp->br_is_add = is_add;
9638   mp->br_tbl_id.bt_set = set;
9639   mp->br_tbl_id.bt_sub_domain = sub_domain;
9640   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9641   mp->br_bp = ntohs (bp);
9642   mp->br_n_paths = 1;
9643   mp->br_paths[0].n_labels = 1;
9644   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9645   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9646
9647   if (next_hop_proto_is_ip4)
9648     {
9649       clib_memcpy (mp->br_paths[0].next_hop,
9650                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9651     }
9652   else
9653     {
9654       clib_memcpy (mp->br_paths[0].next_hop,
9655                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9656     }
9657
9658   /* send it... */
9659   S (mp);
9660
9661   /* Wait for a reply... */
9662   W (ret);
9663
9664   return (ret);
9665 }
9666
9667 static int
9668 api_proxy_arp_add_del (vat_main_t * vam)
9669 {
9670   unformat_input_t *i = vam->input;
9671   vl_api_proxy_arp_add_del_t *mp;
9672   u32 vrf_id = 0;
9673   u8 is_add = 1;
9674   ip4_address_t lo, hi;
9675   u8 range_set = 0;
9676   int ret;
9677
9678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9679     {
9680       if (unformat (i, "vrf %d", &vrf_id))
9681         ;
9682       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9683                          unformat_ip4_address, &hi))
9684         range_set = 1;
9685       else if (unformat (i, "del"))
9686         is_add = 0;
9687       else
9688         {
9689           clib_warning ("parse error '%U'", format_unformat_error, i);
9690           return -99;
9691         }
9692     }
9693
9694   if (range_set == 0)
9695     {
9696       errmsg ("address range not set");
9697       return -99;
9698     }
9699
9700   M (PROXY_ARP_ADD_DEL, mp);
9701
9702   mp->proxy.vrf_id = ntohl (vrf_id);
9703   mp->is_add = is_add;
9704   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9705   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9706
9707   S (mp);
9708   W (ret);
9709   return ret;
9710 }
9711
9712 static int
9713 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9714 {
9715   unformat_input_t *i = vam->input;
9716   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9717   u32 sw_if_index;
9718   u8 enable = 1;
9719   u8 sw_if_index_set = 0;
9720   int ret;
9721
9722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9723     {
9724       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9725         sw_if_index_set = 1;
9726       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9727         sw_if_index_set = 1;
9728       else if (unformat (i, "enable"))
9729         enable = 1;
9730       else if (unformat (i, "disable"))
9731         enable = 0;
9732       else
9733         {
9734           clib_warning ("parse error '%U'", format_unformat_error, i);
9735           return -99;
9736         }
9737     }
9738
9739   if (sw_if_index_set == 0)
9740     {
9741       errmsg ("missing interface name or sw_if_index");
9742       return -99;
9743     }
9744
9745   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9746
9747   mp->sw_if_index = ntohl (sw_if_index);
9748   mp->enable_disable = enable;
9749
9750   S (mp);
9751   W (ret);
9752   return ret;
9753 }
9754
9755 static int
9756 api_mpls_tunnel_add_del (vat_main_t * vam)
9757 {
9758   unformat_input_t *i = vam->input;
9759   vl_api_mpls_tunnel_add_del_t *mp;
9760
9761   u8 is_add = 1;
9762   u8 l2_only = 0;
9763   u32 sw_if_index = ~0;
9764   u32 next_hop_sw_if_index = ~0;
9765   u32 next_hop_proto_is_ip4 = 1;
9766
9767   u32 next_hop_table_id = 0;
9768   ip4_address_t v4_next_hop_address = {
9769     .as_u32 = 0,
9770   };
9771   ip6_address_t v6_next_hop_address = { {0} };
9772   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9773   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9774   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9775   int ret;
9776
9777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9778     {
9779       if (unformat (i, "add"))
9780         is_add = 1;
9781       else
9782         if (unformat
9783             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9784         is_add = 0;
9785       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9786         is_add = 0;
9787       else if (unformat (i, "via %U",
9788                          unformat_ip4_address, &v4_next_hop_address))
9789         {
9790           next_hop_proto_is_ip4 = 1;
9791         }
9792       else if (unformat (i, "via %U",
9793                          unformat_ip6_address, &v6_next_hop_address))
9794         {
9795           next_hop_proto_is_ip4 = 0;
9796         }
9797       else if (unformat (i, "via-label %d", &next_hop_via_label))
9798         ;
9799       else
9800         if (unformat
9801             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9802         ;
9803       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9804         ;
9805       else if (unformat (i, "l2-only"))
9806         l2_only = 1;
9807       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9808         ;
9809       else if (unformat (i, "out-label %d", &next_hop_out_label))
9810         {
9811           vl_api_fib_mpls_label_t fib_label = {
9812             .label = ntohl (next_hop_out_label),
9813             .ttl = 64,
9814             .exp = 0,
9815           };
9816           vec_add1 (next_hop_out_label_stack, fib_label);
9817         }
9818       else
9819         {
9820           clib_warning ("parse error '%U'", format_unformat_error, i);
9821           return -99;
9822         }
9823     }
9824
9825   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9826       vec_len (next_hop_out_label_stack));
9827
9828   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9829   mp->mt_sw_if_index = ntohl (sw_if_index);
9830   mp->mt_is_add = is_add;
9831   mp->mt_l2_only = l2_only;
9832   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9833   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9834   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9835   mp->mt_next_hop_weight = 1;
9836   mp->mt_next_hop_preference = 0;
9837
9838   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9839
9840   if (0 != mp->mt_next_hop_n_out_labels)
9841     {
9842       clib_memcpy (mp->mt_next_hop_out_label_stack,
9843                    next_hop_out_label_stack,
9844                    (vec_len (next_hop_out_label_stack) *
9845                     sizeof (vl_api_fib_mpls_label_t)));
9846       vec_free (next_hop_out_label_stack);
9847     }
9848
9849   if (next_hop_proto_is_ip4)
9850     {
9851       clib_memcpy (mp->mt_next_hop,
9852                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9853     }
9854   else
9855     {
9856       clib_memcpy (mp->mt_next_hop,
9857                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9858     }
9859
9860   S (mp);
9861   W (ret);
9862   return ret;
9863 }
9864
9865 static int
9866 api_sw_interface_set_unnumbered (vat_main_t * vam)
9867 {
9868   unformat_input_t *i = vam->input;
9869   vl_api_sw_interface_set_unnumbered_t *mp;
9870   u32 sw_if_index;
9871   u32 unnum_sw_index = ~0;
9872   u8 is_add = 1;
9873   u8 sw_if_index_set = 0;
9874   int ret;
9875
9876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9877     {
9878       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9879         sw_if_index_set = 1;
9880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9881         sw_if_index_set = 1;
9882       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9883         ;
9884       else if (unformat (i, "del"))
9885         is_add = 0;
9886       else
9887         {
9888           clib_warning ("parse error '%U'", format_unformat_error, i);
9889           return -99;
9890         }
9891     }
9892
9893   if (sw_if_index_set == 0)
9894     {
9895       errmsg ("missing interface name or sw_if_index");
9896       return -99;
9897     }
9898
9899   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9900
9901   mp->sw_if_index = ntohl (sw_if_index);
9902   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9903   mp->is_add = is_add;
9904
9905   S (mp);
9906   W (ret);
9907   return ret;
9908 }
9909
9910 static int
9911 api_ip_neighbor_add_del (vat_main_t * vam)
9912 {
9913   unformat_input_t *i = vam->input;
9914   vl_api_ip_neighbor_add_del_t *mp;
9915   u32 sw_if_index;
9916   u8 sw_if_index_set = 0;
9917   u8 is_add = 1;
9918   u8 is_static = 0;
9919   u8 is_no_fib_entry = 0;
9920   u8 mac_address[6];
9921   u8 mac_set = 0;
9922   u8 v4_address_set = 0;
9923   u8 v6_address_set = 0;
9924   ip4_address_t v4address;
9925   ip6_address_t v6address;
9926   int ret;
9927
9928   clib_memset (mac_address, 0, sizeof (mac_address));
9929
9930   /* Parse args required to build the message */
9931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9932     {
9933       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9934         {
9935           mac_set = 1;
9936         }
9937       else if (unformat (i, "del"))
9938         is_add = 0;
9939       else
9940         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9941         sw_if_index_set = 1;
9942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9943         sw_if_index_set = 1;
9944       else if (unformat (i, "is_static"))
9945         is_static = 1;
9946       else if (unformat (i, "no-fib-entry"))
9947         is_no_fib_entry = 1;
9948       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9949         v4_address_set = 1;
9950       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9951         v6_address_set = 1;
9952       else
9953         {
9954           clib_warning ("parse error '%U'", format_unformat_error, i);
9955           return -99;
9956         }
9957     }
9958
9959   if (sw_if_index_set == 0)
9960     {
9961       errmsg ("missing interface name or sw_if_index");
9962       return -99;
9963     }
9964   if (v4_address_set && v6_address_set)
9965     {
9966       errmsg ("both v4 and v6 addresses set");
9967       return -99;
9968     }
9969   if (!v4_address_set && !v6_address_set)
9970     {
9971       errmsg ("no address set");
9972       return -99;
9973     }
9974
9975   /* Construct the API message */
9976   M (IP_NEIGHBOR_ADD_DEL, mp);
9977
9978   mp->sw_if_index = ntohl (sw_if_index);
9979   mp->is_add = is_add;
9980   mp->is_static = is_static;
9981   mp->is_no_adj_fib = is_no_fib_entry;
9982   if (mac_set)
9983     clib_memcpy (mp->mac_address, mac_address, 6);
9984   if (v6_address_set)
9985     {
9986       mp->is_ipv6 = 1;
9987       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9988     }
9989   else
9990     {
9991       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9992       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9993     }
9994
9995   /* send it... */
9996   S (mp);
9997
9998   /* Wait for a reply, return good/bad news  */
9999   W (ret);
10000   return ret;
10001 }
10002
10003 static int
10004 api_create_vlan_subif (vat_main_t * vam)
10005 {
10006   unformat_input_t *i = vam->input;
10007   vl_api_create_vlan_subif_t *mp;
10008   u32 sw_if_index;
10009   u8 sw_if_index_set = 0;
10010   u32 vlan_id;
10011   u8 vlan_id_set = 0;
10012   int ret;
10013
10014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10015     {
10016       if (unformat (i, "sw_if_index %d", &sw_if_index))
10017         sw_if_index_set = 1;
10018       else
10019         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10020         sw_if_index_set = 1;
10021       else if (unformat (i, "vlan %d", &vlan_id))
10022         vlan_id_set = 1;
10023       else
10024         {
10025           clib_warning ("parse error '%U'", format_unformat_error, i);
10026           return -99;
10027         }
10028     }
10029
10030   if (sw_if_index_set == 0)
10031     {
10032       errmsg ("missing interface name or sw_if_index");
10033       return -99;
10034     }
10035
10036   if (vlan_id_set == 0)
10037     {
10038       errmsg ("missing vlan_id");
10039       return -99;
10040     }
10041   M (CREATE_VLAN_SUBIF, mp);
10042
10043   mp->sw_if_index = ntohl (sw_if_index);
10044   mp->vlan_id = ntohl (vlan_id);
10045
10046   S (mp);
10047   W (ret);
10048   return ret;
10049 }
10050
10051 #define foreach_create_subif_bit                \
10052 _(no_tags)                                      \
10053 _(one_tag)                                      \
10054 _(two_tags)                                     \
10055 _(dot1ad)                                       \
10056 _(exact_match)                                  \
10057 _(default_sub)                                  \
10058 _(outer_vlan_id_any)                            \
10059 _(inner_vlan_id_any)
10060
10061 static int
10062 api_create_subif (vat_main_t * vam)
10063 {
10064   unformat_input_t *i = vam->input;
10065   vl_api_create_subif_t *mp;
10066   u32 sw_if_index;
10067   u8 sw_if_index_set = 0;
10068   u32 sub_id;
10069   u8 sub_id_set = 0;
10070   u32 no_tags = 0;
10071   u32 one_tag = 0;
10072   u32 two_tags = 0;
10073   u32 dot1ad = 0;
10074   u32 exact_match = 0;
10075   u32 default_sub = 0;
10076   u32 outer_vlan_id_any = 0;
10077   u32 inner_vlan_id_any = 0;
10078   u32 tmp;
10079   u16 outer_vlan_id = 0;
10080   u16 inner_vlan_id = 0;
10081   int ret;
10082
10083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10084     {
10085       if (unformat (i, "sw_if_index %d", &sw_if_index))
10086         sw_if_index_set = 1;
10087       else
10088         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10089         sw_if_index_set = 1;
10090       else if (unformat (i, "sub_id %d", &sub_id))
10091         sub_id_set = 1;
10092       else if (unformat (i, "outer_vlan_id %d", &tmp))
10093         outer_vlan_id = tmp;
10094       else if (unformat (i, "inner_vlan_id %d", &tmp))
10095         inner_vlan_id = tmp;
10096
10097 #define _(a) else if (unformat (i, #a)) a = 1 ;
10098       foreach_create_subif_bit
10099 #undef _
10100         else
10101         {
10102           clib_warning ("parse error '%U'", format_unformat_error, i);
10103           return -99;
10104         }
10105     }
10106
10107   if (sw_if_index_set == 0)
10108     {
10109       errmsg ("missing interface name or sw_if_index");
10110       return -99;
10111     }
10112
10113   if (sub_id_set == 0)
10114     {
10115       errmsg ("missing sub_id");
10116       return -99;
10117     }
10118   M (CREATE_SUBIF, mp);
10119
10120   mp->sw_if_index = ntohl (sw_if_index);
10121   mp->sub_id = ntohl (sub_id);
10122
10123 #define _(a) mp->a = a;
10124   foreach_create_subif_bit;
10125 #undef _
10126
10127   mp->outer_vlan_id = ntohs (outer_vlan_id);
10128   mp->inner_vlan_id = ntohs (inner_vlan_id);
10129
10130   S (mp);
10131   W (ret);
10132   return ret;
10133 }
10134
10135 static int
10136 api_oam_add_del (vat_main_t * vam)
10137 {
10138   unformat_input_t *i = vam->input;
10139   vl_api_oam_add_del_t *mp;
10140   u32 vrf_id = 0;
10141   u8 is_add = 1;
10142   ip4_address_t src, dst;
10143   u8 src_set = 0;
10144   u8 dst_set = 0;
10145   int ret;
10146
10147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10148     {
10149       if (unformat (i, "vrf %d", &vrf_id))
10150         ;
10151       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10152         src_set = 1;
10153       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10154         dst_set = 1;
10155       else if (unformat (i, "del"))
10156         is_add = 0;
10157       else
10158         {
10159           clib_warning ("parse error '%U'", format_unformat_error, i);
10160           return -99;
10161         }
10162     }
10163
10164   if (src_set == 0)
10165     {
10166       errmsg ("missing src addr");
10167       return -99;
10168     }
10169
10170   if (dst_set == 0)
10171     {
10172       errmsg ("missing dst addr");
10173       return -99;
10174     }
10175
10176   M (OAM_ADD_DEL, mp);
10177
10178   mp->vrf_id = ntohl (vrf_id);
10179   mp->is_add = is_add;
10180   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10181   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10182
10183   S (mp);
10184   W (ret);
10185   return ret;
10186 }
10187
10188 static int
10189 api_reset_fib (vat_main_t * vam)
10190 {
10191   unformat_input_t *i = vam->input;
10192   vl_api_reset_fib_t *mp;
10193   u32 vrf_id = 0;
10194   u8 is_ipv6 = 0;
10195   u8 vrf_id_set = 0;
10196
10197   int ret;
10198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10199     {
10200       if (unformat (i, "vrf %d", &vrf_id))
10201         vrf_id_set = 1;
10202       else if (unformat (i, "ipv6"))
10203         is_ipv6 = 1;
10204       else
10205         {
10206           clib_warning ("parse error '%U'", format_unformat_error, i);
10207           return -99;
10208         }
10209     }
10210
10211   if (vrf_id_set == 0)
10212     {
10213       errmsg ("missing vrf id");
10214       return -99;
10215     }
10216
10217   M (RESET_FIB, mp);
10218
10219   mp->vrf_id = ntohl (vrf_id);
10220   mp->is_ipv6 = is_ipv6;
10221
10222   S (mp);
10223   W (ret);
10224   return ret;
10225 }
10226
10227 static int
10228 api_dhcp_proxy_config (vat_main_t * vam)
10229 {
10230   unformat_input_t *i = vam->input;
10231   vl_api_dhcp_proxy_config_t *mp;
10232   u32 rx_vrf_id = 0;
10233   u32 server_vrf_id = 0;
10234   u8 is_add = 1;
10235   u8 v4_address_set = 0;
10236   u8 v6_address_set = 0;
10237   ip4_address_t v4address;
10238   ip6_address_t v6address;
10239   u8 v4_src_address_set = 0;
10240   u8 v6_src_address_set = 0;
10241   ip4_address_t v4srcaddress;
10242   ip6_address_t v6srcaddress;
10243   int ret;
10244
10245   /* Parse args required to build the message */
10246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10247     {
10248       if (unformat (i, "del"))
10249         is_add = 0;
10250       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10251         ;
10252       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10253         ;
10254       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10255         v4_address_set = 1;
10256       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10257         v6_address_set = 1;
10258       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10259         v4_src_address_set = 1;
10260       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10261         v6_src_address_set = 1;
10262       else
10263         break;
10264     }
10265
10266   if (v4_address_set && v6_address_set)
10267     {
10268       errmsg ("both v4 and v6 server addresses set");
10269       return -99;
10270     }
10271   if (!v4_address_set && !v6_address_set)
10272     {
10273       errmsg ("no server addresses set");
10274       return -99;
10275     }
10276
10277   if (v4_src_address_set && v6_src_address_set)
10278     {
10279       errmsg ("both v4 and v6  src addresses set");
10280       return -99;
10281     }
10282   if (!v4_src_address_set && !v6_src_address_set)
10283     {
10284       errmsg ("no src addresses set");
10285       return -99;
10286     }
10287
10288   if (!(v4_src_address_set && v4_address_set) &&
10289       !(v6_src_address_set && v6_address_set))
10290     {
10291       errmsg ("no matching server and src addresses set");
10292       return -99;
10293     }
10294
10295   /* Construct the API message */
10296   M (DHCP_PROXY_CONFIG, mp);
10297
10298   mp->is_add = is_add;
10299   mp->rx_vrf_id = ntohl (rx_vrf_id);
10300   mp->server_vrf_id = ntohl (server_vrf_id);
10301   if (v6_address_set)
10302     {
10303       mp->is_ipv6 = 1;
10304       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10305       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10306     }
10307   else
10308     {
10309       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10310       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10311     }
10312
10313   /* send it... */
10314   S (mp);
10315
10316   /* Wait for a reply, return good/bad news  */
10317   W (ret);
10318   return ret;
10319 }
10320
10321 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10322 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10323
10324 static void
10325 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10326 {
10327   vat_main_t *vam = &vat_main;
10328   u32 i, count = mp->count;
10329   vl_api_dhcp_server_t *s;
10330
10331   if (mp->is_ipv6)
10332     print (vam->ofp,
10333            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10334            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10335            ntohl (mp->rx_vrf_id),
10336            format_ip6_address, mp->dhcp_src_address,
10337            mp->vss_type, mp->vss_vpn_ascii_id,
10338            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10339   else
10340     print (vam->ofp,
10341            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10342            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10343            ntohl (mp->rx_vrf_id),
10344            format_ip4_address, mp->dhcp_src_address,
10345            mp->vss_type, mp->vss_vpn_ascii_id,
10346            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10347
10348   for (i = 0; i < count; i++)
10349     {
10350       s = &mp->servers[i];
10351
10352       if (mp->is_ipv6)
10353         print (vam->ofp,
10354                " Server Table-ID %d, Server Address %U",
10355                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10356       else
10357         print (vam->ofp,
10358                " Server Table-ID %d, Server Address %U",
10359                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10360     }
10361 }
10362
10363 static void vl_api_dhcp_proxy_details_t_handler_json
10364   (vl_api_dhcp_proxy_details_t * mp)
10365 {
10366   vat_main_t *vam = &vat_main;
10367   vat_json_node_t *node = NULL;
10368   u32 i, count = mp->count;
10369   struct in_addr ip4;
10370   struct in6_addr ip6;
10371   vl_api_dhcp_server_t *s;
10372
10373   if (VAT_JSON_ARRAY != vam->json_tree.type)
10374     {
10375       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10376       vat_json_init_array (&vam->json_tree);
10377     }
10378   node = vat_json_array_add (&vam->json_tree);
10379
10380   vat_json_init_object (node);
10381   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10382   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10383                              sizeof (mp->vss_type));
10384   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10385                                    mp->vss_vpn_ascii_id);
10386   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10387   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10388
10389   if (mp->is_ipv6)
10390     {
10391       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10392       vat_json_object_add_ip6 (node, "src_address", ip6);
10393     }
10394   else
10395     {
10396       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10397       vat_json_object_add_ip4 (node, "src_address", ip4);
10398     }
10399
10400   for (i = 0; i < count; i++)
10401     {
10402       s = &mp->servers[i];
10403
10404       vat_json_object_add_uint (node, "server-table-id",
10405                                 ntohl (s->server_vrf_id));
10406
10407       if (mp->is_ipv6)
10408         {
10409           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10410           vat_json_object_add_ip4 (node, "src_address", ip4);
10411         }
10412       else
10413         {
10414           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10415           vat_json_object_add_ip6 (node, "server_address", ip6);
10416         }
10417     }
10418 }
10419
10420 static int
10421 api_dhcp_proxy_dump (vat_main_t * vam)
10422 {
10423   unformat_input_t *i = vam->input;
10424   vl_api_control_ping_t *mp_ping;
10425   vl_api_dhcp_proxy_dump_t *mp;
10426   u8 is_ipv6 = 0;
10427   int ret;
10428
10429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10430     {
10431       if (unformat (i, "ipv6"))
10432         is_ipv6 = 1;
10433       else
10434         {
10435           clib_warning ("parse error '%U'", format_unformat_error, i);
10436           return -99;
10437         }
10438     }
10439
10440   M (DHCP_PROXY_DUMP, mp);
10441
10442   mp->is_ip6 = is_ipv6;
10443   S (mp);
10444
10445   /* Use a control ping for synchronization */
10446   MPING (CONTROL_PING, mp_ping);
10447   S (mp_ping);
10448
10449   W (ret);
10450   return ret;
10451 }
10452
10453 static int
10454 api_dhcp_proxy_set_vss (vat_main_t * vam)
10455 {
10456   unformat_input_t *i = vam->input;
10457   vl_api_dhcp_proxy_set_vss_t *mp;
10458   u8 is_ipv6 = 0;
10459   u8 is_add = 1;
10460   u32 tbl_id = ~0;
10461   u8 vss_type = VSS_TYPE_DEFAULT;
10462   u8 *vpn_ascii_id = 0;
10463   u32 oui = 0;
10464   u32 fib_id = 0;
10465   int ret;
10466
10467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10468     {
10469       if (unformat (i, "tbl_id %d", &tbl_id))
10470         ;
10471       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10472         vss_type = VSS_TYPE_ASCII;
10473       else if (unformat (i, "fib_id %d", &fib_id))
10474         vss_type = VSS_TYPE_VPN_ID;
10475       else if (unformat (i, "oui %d", &oui))
10476         vss_type = VSS_TYPE_VPN_ID;
10477       else if (unformat (i, "ipv6"))
10478         is_ipv6 = 1;
10479       else if (unformat (i, "del"))
10480         is_add = 0;
10481       else
10482         break;
10483     }
10484
10485   if (tbl_id == ~0)
10486     {
10487       errmsg ("missing tbl_id ");
10488       vec_free (vpn_ascii_id);
10489       return -99;
10490     }
10491
10492   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10493     {
10494       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10495       vec_free (vpn_ascii_id);
10496       return -99;
10497     }
10498
10499   M (DHCP_PROXY_SET_VSS, mp);
10500   mp->tbl_id = ntohl (tbl_id);
10501   mp->vss_type = vss_type;
10502   if (vpn_ascii_id)
10503     {
10504       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10505       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10506     }
10507   mp->vpn_index = ntohl (fib_id);
10508   mp->oui = ntohl (oui);
10509   mp->is_ipv6 = is_ipv6;
10510   mp->is_add = is_add;
10511
10512   S (mp);
10513   W (ret);
10514
10515   vec_free (vpn_ascii_id);
10516   return ret;
10517 }
10518
10519 static int
10520 api_dhcp_client_config (vat_main_t * vam)
10521 {
10522   unformat_input_t *i = vam->input;
10523   vl_api_dhcp_client_config_t *mp;
10524   u32 sw_if_index;
10525   u8 sw_if_index_set = 0;
10526   u8 is_add = 1;
10527   u8 *hostname = 0;
10528   u8 disable_event = 0;
10529   int ret;
10530
10531   /* Parse args required to build the message */
10532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10533     {
10534       if (unformat (i, "del"))
10535         is_add = 0;
10536       else
10537         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10538         sw_if_index_set = 1;
10539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10540         sw_if_index_set = 1;
10541       else if (unformat (i, "hostname %s", &hostname))
10542         ;
10543       else if (unformat (i, "disable_event"))
10544         disable_event = 1;
10545       else
10546         break;
10547     }
10548
10549   if (sw_if_index_set == 0)
10550     {
10551       errmsg ("missing interface name or sw_if_index");
10552       return -99;
10553     }
10554
10555   if (vec_len (hostname) > 63)
10556     {
10557       errmsg ("hostname too long");
10558     }
10559   vec_add1 (hostname, 0);
10560
10561   /* Construct the API message */
10562   M (DHCP_CLIENT_CONFIG, mp);
10563
10564   mp->is_add = is_add;
10565   mp->client.sw_if_index = htonl (sw_if_index);
10566   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10567   vec_free (hostname);
10568   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10569   mp->client.pid = htonl (getpid ());
10570
10571   /* send it... */
10572   S (mp);
10573
10574   /* Wait for a reply, return good/bad news  */
10575   W (ret);
10576   return ret;
10577 }
10578
10579 static int
10580 api_set_ip_flow_hash (vat_main_t * vam)
10581 {
10582   unformat_input_t *i = vam->input;
10583   vl_api_set_ip_flow_hash_t *mp;
10584   u32 vrf_id = 0;
10585   u8 is_ipv6 = 0;
10586   u8 vrf_id_set = 0;
10587   u8 src = 0;
10588   u8 dst = 0;
10589   u8 sport = 0;
10590   u8 dport = 0;
10591   u8 proto = 0;
10592   u8 reverse = 0;
10593   int ret;
10594
10595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (unformat (i, "vrf %d", &vrf_id))
10598         vrf_id_set = 1;
10599       else if (unformat (i, "ipv6"))
10600         is_ipv6 = 1;
10601       else if (unformat (i, "src"))
10602         src = 1;
10603       else if (unformat (i, "dst"))
10604         dst = 1;
10605       else if (unformat (i, "sport"))
10606         sport = 1;
10607       else if (unformat (i, "dport"))
10608         dport = 1;
10609       else if (unformat (i, "proto"))
10610         proto = 1;
10611       else if (unformat (i, "reverse"))
10612         reverse = 1;
10613
10614       else
10615         {
10616           clib_warning ("parse error '%U'", format_unformat_error, i);
10617           return -99;
10618         }
10619     }
10620
10621   if (vrf_id_set == 0)
10622     {
10623       errmsg ("missing vrf id");
10624       return -99;
10625     }
10626
10627   M (SET_IP_FLOW_HASH, mp);
10628   mp->src = src;
10629   mp->dst = dst;
10630   mp->sport = sport;
10631   mp->dport = dport;
10632   mp->proto = proto;
10633   mp->reverse = reverse;
10634   mp->vrf_id = ntohl (vrf_id);
10635   mp->is_ipv6 = is_ipv6;
10636
10637   S (mp);
10638   W (ret);
10639   return ret;
10640 }
10641
10642 static int
10643 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10644 {
10645   unformat_input_t *i = vam->input;
10646   vl_api_sw_interface_ip6_enable_disable_t *mp;
10647   u32 sw_if_index;
10648   u8 sw_if_index_set = 0;
10649   u8 enable = 0;
10650   int ret;
10651
10652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10653     {
10654       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10655         sw_if_index_set = 1;
10656       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10657         sw_if_index_set = 1;
10658       else if (unformat (i, "enable"))
10659         enable = 1;
10660       else if (unformat (i, "disable"))
10661         enable = 0;
10662       else
10663         {
10664           clib_warning ("parse error '%U'", format_unformat_error, i);
10665           return -99;
10666         }
10667     }
10668
10669   if (sw_if_index_set == 0)
10670     {
10671       errmsg ("missing interface name or sw_if_index");
10672       return -99;
10673     }
10674
10675   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10676
10677   mp->sw_if_index = ntohl (sw_if_index);
10678   mp->enable = enable;
10679
10680   S (mp);
10681   W (ret);
10682   return ret;
10683 }
10684
10685 static int
10686 api_ip6nd_proxy_add_del (vat_main_t * vam)
10687 {
10688   unformat_input_t *i = vam->input;
10689   vl_api_ip6nd_proxy_add_del_t *mp;
10690   u32 sw_if_index = ~0;
10691   u8 v6_address_set = 0;
10692   ip6_address_t v6address;
10693   u8 is_del = 0;
10694   int ret;
10695
10696   /* Parse args required to build the message */
10697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10698     {
10699       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10700         ;
10701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10702         ;
10703       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10704         v6_address_set = 1;
10705       if (unformat (i, "del"))
10706         is_del = 1;
10707       else
10708         {
10709           clib_warning ("parse error '%U'", format_unformat_error, i);
10710           return -99;
10711         }
10712     }
10713
10714   if (sw_if_index == ~0)
10715     {
10716       errmsg ("missing interface name or sw_if_index");
10717       return -99;
10718     }
10719   if (!v6_address_set)
10720     {
10721       errmsg ("no address set");
10722       return -99;
10723     }
10724
10725   /* Construct the API message */
10726   M (IP6ND_PROXY_ADD_DEL, mp);
10727
10728   mp->is_del = is_del;
10729   mp->sw_if_index = ntohl (sw_if_index);
10730   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10731
10732   /* send it... */
10733   S (mp);
10734
10735   /* Wait for a reply, return good/bad news  */
10736   W (ret);
10737   return ret;
10738 }
10739
10740 static int
10741 api_ip6nd_proxy_dump (vat_main_t * vam)
10742 {
10743   vl_api_ip6nd_proxy_dump_t *mp;
10744   vl_api_control_ping_t *mp_ping;
10745   int ret;
10746
10747   M (IP6ND_PROXY_DUMP, mp);
10748
10749   S (mp);
10750
10751   /* Use a control ping for synchronization */
10752   MPING (CONTROL_PING, mp_ping);
10753   S (mp_ping);
10754
10755   W (ret);
10756   return ret;
10757 }
10758
10759 static void vl_api_ip6nd_proxy_details_t_handler
10760   (vl_api_ip6nd_proxy_details_t * mp)
10761 {
10762   vat_main_t *vam = &vat_main;
10763
10764   print (vam->ofp, "host %U sw_if_index %d",
10765          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10766 }
10767
10768 static void vl_api_ip6nd_proxy_details_t_handler_json
10769   (vl_api_ip6nd_proxy_details_t * mp)
10770 {
10771   vat_main_t *vam = &vat_main;
10772   struct in6_addr ip6;
10773   vat_json_node_t *node = NULL;
10774
10775   if (VAT_JSON_ARRAY != vam->json_tree.type)
10776     {
10777       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10778       vat_json_init_array (&vam->json_tree);
10779     }
10780   node = vat_json_array_add (&vam->json_tree);
10781
10782   vat_json_init_object (node);
10783   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10784
10785   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10786   vat_json_object_add_ip6 (node, "host", ip6);
10787 }
10788
10789 static int
10790 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10791 {
10792   unformat_input_t *i = vam->input;
10793   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10794   u32 sw_if_index;
10795   u8 sw_if_index_set = 0;
10796   u32 address_length = 0;
10797   u8 v6_address_set = 0;
10798   ip6_address_t v6address;
10799   u8 use_default = 0;
10800   u8 no_advertise = 0;
10801   u8 off_link = 0;
10802   u8 no_autoconfig = 0;
10803   u8 no_onlink = 0;
10804   u8 is_no = 0;
10805   u32 val_lifetime = 0;
10806   u32 pref_lifetime = 0;
10807   int ret;
10808
10809   /* Parse args required to build the message */
10810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10811     {
10812       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10813         sw_if_index_set = 1;
10814       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10815         sw_if_index_set = 1;
10816       else if (unformat (i, "%U/%d",
10817                          unformat_ip6_address, &v6address, &address_length))
10818         v6_address_set = 1;
10819       else if (unformat (i, "val_life %d", &val_lifetime))
10820         ;
10821       else if (unformat (i, "pref_life %d", &pref_lifetime))
10822         ;
10823       else if (unformat (i, "def"))
10824         use_default = 1;
10825       else if (unformat (i, "noadv"))
10826         no_advertise = 1;
10827       else if (unformat (i, "offl"))
10828         off_link = 1;
10829       else if (unformat (i, "noauto"))
10830         no_autoconfig = 1;
10831       else if (unformat (i, "nolink"))
10832         no_onlink = 1;
10833       else if (unformat (i, "isno"))
10834         is_no = 1;
10835       else
10836         {
10837           clib_warning ("parse error '%U'", format_unformat_error, i);
10838           return -99;
10839         }
10840     }
10841
10842   if (sw_if_index_set == 0)
10843     {
10844       errmsg ("missing interface name or sw_if_index");
10845       return -99;
10846     }
10847   if (!v6_address_set)
10848     {
10849       errmsg ("no address set");
10850       return -99;
10851     }
10852
10853   /* Construct the API message */
10854   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10855
10856   mp->sw_if_index = ntohl (sw_if_index);
10857   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10858   mp->address_length = address_length;
10859   mp->use_default = use_default;
10860   mp->no_advertise = no_advertise;
10861   mp->off_link = off_link;
10862   mp->no_autoconfig = no_autoconfig;
10863   mp->no_onlink = no_onlink;
10864   mp->is_no = is_no;
10865   mp->val_lifetime = ntohl (val_lifetime);
10866   mp->pref_lifetime = ntohl (pref_lifetime);
10867
10868   /* send it... */
10869   S (mp);
10870
10871   /* Wait for a reply, return good/bad news  */
10872   W (ret);
10873   return ret;
10874 }
10875
10876 static int
10877 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10878 {
10879   unformat_input_t *i = vam->input;
10880   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10881   u32 sw_if_index;
10882   u8 sw_if_index_set = 0;
10883   u8 suppress = 0;
10884   u8 managed = 0;
10885   u8 other = 0;
10886   u8 ll_option = 0;
10887   u8 send_unicast = 0;
10888   u8 cease = 0;
10889   u8 is_no = 0;
10890   u8 default_router = 0;
10891   u32 max_interval = 0;
10892   u32 min_interval = 0;
10893   u32 lifetime = 0;
10894   u32 initial_count = 0;
10895   u32 initial_interval = 0;
10896   int ret;
10897
10898
10899   /* Parse args required to build the message */
10900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10901     {
10902       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10903         sw_if_index_set = 1;
10904       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10905         sw_if_index_set = 1;
10906       else if (unformat (i, "maxint %d", &max_interval))
10907         ;
10908       else if (unformat (i, "minint %d", &min_interval))
10909         ;
10910       else if (unformat (i, "life %d", &lifetime))
10911         ;
10912       else if (unformat (i, "count %d", &initial_count))
10913         ;
10914       else if (unformat (i, "interval %d", &initial_interval))
10915         ;
10916       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10917         suppress = 1;
10918       else if (unformat (i, "managed"))
10919         managed = 1;
10920       else if (unformat (i, "other"))
10921         other = 1;
10922       else if (unformat (i, "ll"))
10923         ll_option = 1;
10924       else if (unformat (i, "send"))
10925         send_unicast = 1;
10926       else if (unformat (i, "cease"))
10927         cease = 1;
10928       else if (unformat (i, "isno"))
10929         is_no = 1;
10930       else if (unformat (i, "def"))
10931         default_router = 1;
10932       else
10933         {
10934           clib_warning ("parse error '%U'", format_unformat_error, i);
10935           return -99;
10936         }
10937     }
10938
10939   if (sw_if_index_set == 0)
10940     {
10941       errmsg ("missing interface name or sw_if_index");
10942       return -99;
10943     }
10944
10945   /* Construct the API message */
10946   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10947
10948   mp->sw_if_index = ntohl (sw_if_index);
10949   mp->max_interval = ntohl (max_interval);
10950   mp->min_interval = ntohl (min_interval);
10951   mp->lifetime = ntohl (lifetime);
10952   mp->initial_count = ntohl (initial_count);
10953   mp->initial_interval = ntohl (initial_interval);
10954   mp->suppress = suppress;
10955   mp->managed = managed;
10956   mp->other = other;
10957   mp->ll_option = ll_option;
10958   mp->send_unicast = send_unicast;
10959   mp->cease = cease;
10960   mp->is_no = is_no;
10961   mp->default_router = default_router;
10962
10963   /* send it... */
10964   S (mp);
10965
10966   /* Wait for a reply, return good/bad news  */
10967   W (ret);
10968   return ret;
10969 }
10970
10971 static int
10972 api_set_arp_neighbor_limit (vat_main_t * vam)
10973 {
10974   unformat_input_t *i = vam->input;
10975   vl_api_set_arp_neighbor_limit_t *mp;
10976   u32 arp_nbr_limit;
10977   u8 limit_set = 0;
10978   u8 is_ipv6 = 0;
10979   int ret;
10980
10981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10982     {
10983       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10984         limit_set = 1;
10985       else if (unformat (i, "ipv6"))
10986         is_ipv6 = 1;
10987       else
10988         {
10989           clib_warning ("parse error '%U'", format_unformat_error, i);
10990           return -99;
10991         }
10992     }
10993
10994   if (limit_set == 0)
10995     {
10996       errmsg ("missing limit value");
10997       return -99;
10998     }
10999
11000   M (SET_ARP_NEIGHBOR_LIMIT, mp);
11001
11002   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
11003   mp->is_ipv6 = is_ipv6;
11004
11005   S (mp);
11006   W (ret);
11007   return ret;
11008 }
11009
11010 static int
11011 api_l2_patch_add_del (vat_main_t * vam)
11012 {
11013   unformat_input_t *i = vam->input;
11014   vl_api_l2_patch_add_del_t *mp;
11015   u32 rx_sw_if_index;
11016   u8 rx_sw_if_index_set = 0;
11017   u32 tx_sw_if_index;
11018   u8 tx_sw_if_index_set = 0;
11019   u8 is_add = 1;
11020   int ret;
11021
11022   /* Parse args required to build the message */
11023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11024     {
11025       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
11026         rx_sw_if_index_set = 1;
11027       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
11028         tx_sw_if_index_set = 1;
11029       else if (unformat (i, "rx"))
11030         {
11031           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11032             {
11033               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11034                             &rx_sw_if_index))
11035                 rx_sw_if_index_set = 1;
11036             }
11037           else
11038             break;
11039         }
11040       else if (unformat (i, "tx"))
11041         {
11042           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11043             {
11044               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11045                             &tx_sw_if_index))
11046                 tx_sw_if_index_set = 1;
11047             }
11048           else
11049             break;
11050         }
11051       else if (unformat (i, "del"))
11052         is_add = 0;
11053       else
11054         break;
11055     }
11056
11057   if (rx_sw_if_index_set == 0)
11058     {
11059       errmsg ("missing rx interface name or rx_sw_if_index");
11060       return -99;
11061     }
11062
11063   if (tx_sw_if_index_set == 0)
11064     {
11065       errmsg ("missing tx interface name or tx_sw_if_index");
11066       return -99;
11067     }
11068
11069   M (L2_PATCH_ADD_DEL, mp);
11070
11071   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11072   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11073   mp->is_add = is_add;
11074
11075   S (mp);
11076   W (ret);
11077   return ret;
11078 }
11079
11080 u8 is_del;
11081 u8 localsid_addr[16];
11082 u8 end_psp;
11083 u8 behavior;
11084 u32 sw_if_index;
11085 u32 vlan_index;
11086 u32 fib_table;
11087 u8 nh_addr[16];
11088
11089 static int
11090 api_sr_localsid_add_del (vat_main_t * vam)
11091 {
11092   unformat_input_t *i = vam->input;
11093   vl_api_sr_localsid_add_del_t *mp;
11094
11095   u8 is_del;
11096   ip6_address_t localsid;
11097   u8 end_psp = 0;
11098   u8 behavior = ~0;
11099   u32 sw_if_index;
11100   u32 fib_table = ~(u32) 0;
11101   ip6_address_t nh_addr6;
11102   ip4_address_t nh_addr4;
11103   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
11104   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
11105
11106   bool nexthop_set = 0;
11107
11108   int ret;
11109
11110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11111     {
11112       if (unformat (i, "del"))
11113         is_del = 1;
11114       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11115       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11116         nexthop_set = 1;
11117       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11118         nexthop_set = 1;
11119       else if (unformat (i, "behavior %u", &behavior));
11120       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11121       else if (unformat (i, "fib-table %u", &fib_table));
11122       else if (unformat (i, "end.psp %u", &behavior));
11123       else
11124         break;
11125     }
11126
11127   M (SR_LOCALSID_ADD_DEL, mp);
11128
11129   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11130   if (nexthop_set)
11131     {
11132       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11133       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11134     }
11135   mp->behavior = behavior;
11136   mp->sw_if_index = ntohl (sw_if_index);
11137   mp->fib_table = ntohl (fib_table);
11138   mp->end_psp = end_psp;
11139   mp->is_del = is_del;
11140
11141   S (mp);
11142   W (ret);
11143   return ret;
11144 }
11145
11146 static int
11147 api_ioam_enable (vat_main_t * vam)
11148 {
11149   unformat_input_t *input = vam->input;
11150   vl_api_ioam_enable_t *mp;
11151   u32 id = 0;
11152   int has_trace_option = 0;
11153   int has_pot_option = 0;
11154   int has_seqno_option = 0;
11155   int has_analyse_option = 0;
11156   int ret;
11157
11158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11159     {
11160       if (unformat (input, "trace"))
11161         has_trace_option = 1;
11162       else if (unformat (input, "pot"))
11163         has_pot_option = 1;
11164       else if (unformat (input, "seqno"))
11165         has_seqno_option = 1;
11166       else if (unformat (input, "analyse"))
11167         has_analyse_option = 1;
11168       else
11169         break;
11170     }
11171   M (IOAM_ENABLE, mp);
11172   mp->id = htons (id);
11173   mp->seqno = has_seqno_option;
11174   mp->analyse = has_analyse_option;
11175   mp->pot_enable = has_pot_option;
11176   mp->trace_enable = has_trace_option;
11177
11178   S (mp);
11179   W (ret);
11180   return ret;
11181 }
11182
11183
11184 static int
11185 api_ioam_disable (vat_main_t * vam)
11186 {
11187   vl_api_ioam_disable_t *mp;
11188   int ret;
11189
11190   M (IOAM_DISABLE, mp);
11191   S (mp);
11192   W (ret);
11193   return ret;
11194 }
11195
11196 #define foreach_tcp_proto_field                 \
11197 _(src_port)                                     \
11198 _(dst_port)
11199
11200 #define foreach_udp_proto_field                 \
11201 _(src_port)                                     \
11202 _(dst_port)
11203
11204 #define foreach_ip4_proto_field                 \
11205 _(src_address)                                  \
11206 _(dst_address)                                  \
11207 _(tos)                                          \
11208 _(length)                                       \
11209 _(fragment_id)                                  \
11210 _(ttl)                                          \
11211 _(protocol)                                     \
11212 _(checksum)
11213
11214 typedef struct
11215 {
11216   u16 src_port, dst_port;
11217 } tcpudp_header_t;
11218
11219 #if VPP_API_TEST_BUILTIN == 0
11220 uword
11221 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11222 {
11223   u8 **maskp = va_arg (*args, u8 **);
11224   u8 *mask = 0;
11225   u8 found_something = 0;
11226   tcp_header_t *tcp;
11227
11228 #define _(a) u8 a=0;
11229   foreach_tcp_proto_field;
11230 #undef _
11231
11232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11233     {
11234       if (0);
11235 #define _(a) else if (unformat (input, #a)) a=1;
11236       foreach_tcp_proto_field
11237 #undef _
11238         else
11239         break;
11240     }
11241
11242 #define _(a) found_something += a;
11243   foreach_tcp_proto_field;
11244 #undef _
11245
11246   if (found_something == 0)
11247     return 0;
11248
11249   vec_validate (mask, sizeof (*tcp) - 1);
11250
11251   tcp = (tcp_header_t *) mask;
11252
11253 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
11254   foreach_tcp_proto_field;
11255 #undef _
11256
11257   *maskp = mask;
11258   return 1;
11259 }
11260
11261 uword
11262 unformat_udp_mask (unformat_input_t * input, va_list * args)
11263 {
11264   u8 **maskp = va_arg (*args, u8 **);
11265   u8 *mask = 0;
11266   u8 found_something = 0;
11267   udp_header_t *udp;
11268
11269 #define _(a) u8 a=0;
11270   foreach_udp_proto_field;
11271 #undef _
11272
11273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11274     {
11275       if (0);
11276 #define _(a) else if (unformat (input, #a)) a=1;
11277       foreach_udp_proto_field
11278 #undef _
11279         else
11280         break;
11281     }
11282
11283 #define _(a) found_something += a;
11284   foreach_udp_proto_field;
11285 #undef _
11286
11287   if (found_something == 0)
11288     return 0;
11289
11290   vec_validate (mask, sizeof (*udp) - 1);
11291
11292   udp = (udp_header_t *) mask;
11293
11294 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
11295   foreach_udp_proto_field;
11296 #undef _
11297
11298   *maskp = mask;
11299   return 1;
11300 }
11301
11302 uword
11303 unformat_l4_mask (unformat_input_t * input, va_list * args)
11304 {
11305   u8 **maskp = va_arg (*args, u8 **);
11306   u16 src_port = 0, dst_port = 0;
11307   tcpudp_header_t *tcpudp;
11308
11309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11310     {
11311       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11312         return 1;
11313       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11314         return 1;
11315       else if (unformat (input, "src_port"))
11316         src_port = 0xFFFF;
11317       else if (unformat (input, "dst_port"))
11318         dst_port = 0xFFFF;
11319       else
11320         return 0;
11321     }
11322
11323   if (!src_port && !dst_port)
11324     return 0;
11325
11326   u8 *mask = 0;
11327   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11328
11329   tcpudp = (tcpudp_header_t *) mask;
11330   tcpudp->src_port = src_port;
11331   tcpudp->dst_port = dst_port;
11332
11333   *maskp = mask;
11334
11335   return 1;
11336 }
11337
11338 uword
11339 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11340 {
11341   u8 **maskp = va_arg (*args, u8 **);
11342   u8 *mask = 0;
11343   u8 found_something = 0;
11344   ip4_header_t *ip;
11345
11346 #define _(a) u8 a=0;
11347   foreach_ip4_proto_field;
11348 #undef _
11349   u8 version = 0;
11350   u8 hdr_length = 0;
11351
11352
11353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11354     {
11355       if (unformat (input, "version"))
11356         version = 1;
11357       else if (unformat (input, "hdr_length"))
11358         hdr_length = 1;
11359       else if (unformat (input, "src"))
11360         src_address = 1;
11361       else if (unformat (input, "dst"))
11362         dst_address = 1;
11363       else if (unformat (input, "proto"))
11364         protocol = 1;
11365
11366 #define _(a) else if (unformat (input, #a)) a=1;
11367       foreach_ip4_proto_field
11368 #undef _
11369         else
11370         break;
11371     }
11372
11373 #define _(a) found_something += a;
11374   foreach_ip4_proto_field;
11375 #undef _
11376
11377   if (found_something == 0)
11378     return 0;
11379
11380   vec_validate (mask, sizeof (*ip) - 1);
11381
11382   ip = (ip4_header_t *) mask;
11383
11384 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11385   foreach_ip4_proto_field;
11386 #undef _
11387
11388   ip->ip_version_and_header_length = 0;
11389
11390   if (version)
11391     ip->ip_version_and_header_length |= 0xF0;
11392
11393   if (hdr_length)
11394     ip->ip_version_and_header_length |= 0x0F;
11395
11396   *maskp = mask;
11397   return 1;
11398 }
11399
11400 #define foreach_ip6_proto_field                 \
11401 _(src_address)                                  \
11402 _(dst_address)                                  \
11403 _(payload_length)                               \
11404 _(hop_limit)                                    \
11405 _(protocol)
11406
11407 uword
11408 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11409 {
11410   u8 **maskp = va_arg (*args, u8 **);
11411   u8 *mask = 0;
11412   u8 found_something = 0;
11413   ip6_header_t *ip;
11414   u32 ip_version_traffic_class_and_flow_label;
11415
11416 #define _(a) u8 a=0;
11417   foreach_ip6_proto_field;
11418 #undef _
11419   u8 version = 0;
11420   u8 traffic_class = 0;
11421   u8 flow_label = 0;
11422
11423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11424     {
11425       if (unformat (input, "version"))
11426         version = 1;
11427       else if (unformat (input, "traffic-class"))
11428         traffic_class = 1;
11429       else if (unformat (input, "flow-label"))
11430         flow_label = 1;
11431       else if (unformat (input, "src"))
11432         src_address = 1;
11433       else if (unformat (input, "dst"))
11434         dst_address = 1;
11435       else if (unformat (input, "proto"))
11436         protocol = 1;
11437
11438 #define _(a) else if (unformat (input, #a)) a=1;
11439       foreach_ip6_proto_field
11440 #undef _
11441         else
11442         break;
11443     }
11444
11445 #define _(a) found_something += a;
11446   foreach_ip6_proto_field;
11447 #undef _
11448
11449   if (found_something == 0)
11450     return 0;
11451
11452   vec_validate (mask, sizeof (*ip) - 1);
11453
11454   ip = (ip6_header_t *) mask;
11455
11456 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11457   foreach_ip6_proto_field;
11458 #undef _
11459
11460   ip_version_traffic_class_and_flow_label = 0;
11461
11462   if (version)
11463     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11464
11465   if (traffic_class)
11466     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11467
11468   if (flow_label)
11469     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11470
11471   ip->ip_version_traffic_class_and_flow_label =
11472     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11473
11474   *maskp = mask;
11475   return 1;
11476 }
11477
11478 uword
11479 unformat_l3_mask (unformat_input_t * input, va_list * args)
11480 {
11481   u8 **maskp = va_arg (*args, u8 **);
11482
11483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11486         return 1;
11487       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11488         return 1;
11489       else
11490         break;
11491     }
11492   return 0;
11493 }
11494
11495 uword
11496 unformat_l2_mask (unformat_input_t * input, va_list * args)
11497 {
11498   u8 **maskp = va_arg (*args, u8 **);
11499   u8 *mask = 0;
11500   u8 src = 0;
11501   u8 dst = 0;
11502   u8 proto = 0;
11503   u8 tag1 = 0;
11504   u8 tag2 = 0;
11505   u8 ignore_tag1 = 0;
11506   u8 ignore_tag2 = 0;
11507   u8 cos1 = 0;
11508   u8 cos2 = 0;
11509   u8 dot1q = 0;
11510   u8 dot1ad = 0;
11511   int len = 14;
11512
11513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11514     {
11515       if (unformat (input, "src"))
11516         src = 1;
11517       else if (unformat (input, "dst"))
11518         dst = 1;
11519       else if (unformat (input, "proto"))
11520         proto = 1;
11521       else if (unformat (input, "tag1"))
11522         tag1 = 1;
11523       else if (unformat (input, "tag2"))
11524         tag2 = 1;
11525       else if (unformat (input, "ignore-tag1"))
11526         ignore_tag1 = 1;
11527       else if (unformat (input, "ignore-tag2"))
11528         ignore_tag2 = 1;
11529       else if (unformat (input, "cos1"))
11530         cos1 = 1;
11531       else if (unformat (input, "cos2"))
11532         cos2 = 1;
11533       else if (unformat (input, "dot1q"))
11534         dot1q = 1;
11535       else if (unformat (input, "dot1ad"))
11536         dot1ad = 1;
11537       else
11538         break;
11539     }
11540   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11541        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11542     return 0;
11543
11544   if (tag1 || ignore_tag1 || cos1 || dot1q)
11545     len = 18;
11546   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11547     len = 22;
11548
11549   vec_validate (mask, len - 1);
11550
11551   if (dst)
11552     clib_memset (mask, 0xff, 6);
11553
11554   if (src)
11555     clib_memset (mask + 6, 0xff, 6);
11556
11557   if (tag2 || dot1ad)
11558     {
11559       /* inner vlan tag */
11560       if (tag2)
11561         {
11562           mask[19] = 0xff;
11563           mask[18] = 0x0f;
11564         }
11565       if (cos2)
11566         mask[18] |= 0xe0;
11567       if (proto)
11568         mask[21] = mask[20] = 0xff;
11569       if (tag1)
11570         {
11571           mask[15] = 0xff;
11572           mask[14] = 0x0f;
11573         }
11574       if (cos1)
11575         mask[14] |= 0xe0;
11576       *maskp = mask;
11577       return 1;
11578     }
11579   if (tag1 | dot1q)
11580     {
11581       if (tag1)
11582         {
11583           mask[15] = 0xff;
11584           mask[14] = 0x0f;
11585         }
11586       if (cos1)
11587         mask[14] |= 0xe0;
11588       if (proto)
11589         mask[16] = mask[17] = 0xff;
11590
11591       *maskp = mask;
11592       return 1;
11593     }
11594   if (cos2)
11595     mask[18] |= 0xe0;
11596   if (cos1)
11597     mask[14] |= 0xe0;
11598   if (proto)
11599     mask[12] = mask[13] = 0xff;
11600
11601   *maskp = mask;
11602   return 1;
11603 }
11604
11605 uword
11606 unformat_classify_mask (unformat_input_t * input, va_list * args)
11607 {
11608   u8 **maskp = va_arg (*args, u8 **);
11609   u32 *skipp = va_arg (*args, u32 *);
11610   u32 *matchp = va_arg (*args, u32 *);
11611   u32 match;
11612   u8 *mask = 0;
11613   u8 *l2 = 0;
11614   u8 *l3 = 0;
11615   u8 *l4 = 0;
11616   int i;
11617
11618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11619     {
11620       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11621         ;
11622       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11623         ;
11624       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11625         ;
11626       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11627         ;
11628       else
11629         break;
11630     }
11631
11632   if (l4 && !l3)
11633     {
11634       vec_free (mask);
11635       vec_free (l2);
11636       vec_free (l4);
11637       return 0;
11638     }
11639
11640   if (mask || l2 || l3 || l4)
11641     {
11642       if (l2 || l3 || l4)
11643         {
11644           /* "With a free Ethernet header in every package" */
11645           if (l2 == 0)
11646             vec_validate (l2, 13);
11647           mask = l2;
11648           if (vec_len (l3))
11649             {
11650               vec_append (mask, l3);
11651               vec_free (l3);
11652             }
11653           if (vec_len (l4))
11654             {
11655               vec_append (mask, l4);
11656               vec_free (l4);
11657             }
11658         }
11659
11660       /* Scan forward looking for the first significant mask octet */
11661       for (i = 0; i < vec_len (mask); i++)
11662         if (mask[i])
11663           break;
11664
11665       /* compute (skip, match) params */
11666       *skipp = i / sizeof (u32x4);
11667       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11668
11669       /* Pad mask to an even multiple of the vector size */
11670       while (vec_len (mask) % sizeof (u32x4))
11671         vec_add1 (mask, 0);
11672
11673       match = vec_len (mask) / sizeof (u32x4);
11674
11675       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11676         {
11677           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11678           if (*tmp || *(tmp + 1))
11679             break;
11680           match--;
11681         }
11682       if (match == 0)
11683         clib_warning ("BUG: match 0");
11684
11685       _vec_len (mask) = match * sizeof (u32x4);
11686
11687       *matchp = match;
11688       *maskp = mask;
11689
11690       return 1;
11691     }
11692
11693   return 0;
11694 }
11695 #endif /* VPP_API_TEST_BUILTIN */
11696
11697 #define foreach_l2_next                         \
11698 _(drop, DROP)                                   \
11699 _(ethernet, ETHERNET_INPUT)                     \
11700 _(ip4, IP4_INPUT)                               \
11701 _(ip6, IP6_INPUT)
11702
11703 uword
11704 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11705 {
11706   u32 *miss_next_indexp = va_arg (*args, u32 *);
11707   u32 next_index = 0;
11708   u32 tmp;
11709
11710 #define _(n,N) \
11711   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11712   foreach_l2_next;
11713 #undef _
11714
11715   if (unformat (input, "%d", &tmp))
11716     {
11717       next_index = tmp;
11718       goto out;
11719     }
11720
11721   return 0;
11722
11723 out:
11724   *miss_next_indexp = next_index;
11725   return 1;
11726 }
11727
11728 #define foreach_ip_next                         \
11729 _(drop, DROP)                                   \
11730 _(local, LOCAL)                                 \
11731 _(rewrite, REWRITE)
11732
11733 uword
11734 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11735 {
11736   u32 *miss_next_indexp = va_arg (*args, u32 *);
11737   u32 next_index = 0;
11738   u32 tmp;
11739
11740 #define _(n,N) \
11741   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11742   foreach_ip_next;
11743 #undef _
11744
11745   if (unformat (input, "%d", &tmp))
11746     {
11747       next_index = tmp;
11748       goto out;
11749     }
11750
11751   return 0;
11752
11753 out:
11754   *miss_next_indexp = next_index;
11755   return 1;
11756 }
11757
11758 #define foreach_acl_next                        \
11759 _(deny, DENY)
11760
11761 uword
11762 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11763 {
11764   u32 *miss_next_indexp = va_arg (*args, u32 *);
11765   u32 next_index = 0;
11766   u32 tmp;
11767
11768 #define _(n,N) \
11769   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11770   foreach_acl_next;
11771 #undef _
11772
11773   if (unformat (input, "permit"))
11774     {
11775       next_index = ~0;
11776       goto out;
11777     }
11778   else if (unformat (input, "%d", &tmp))
11779     {
11780       next_index = tmp;
11781       goto out;
11782     }
11783
11784   return 0;
11785
11786 out:
11787   *miss_next_indexp = next_index;
11788   return 1;
11789 }
11790
11791 uword
11792 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11793 {
11794   u32 *r = va_arg (*args, u32 *);
11795
11796   if (unformat (input, "conform-color"))
11797     *r = POLICE_CONFORM;
11798   else if (unformat (input, "exceed-color"))
11799     *r = POLICE_EXCEED;
11800   else
11801     return 0;
11802
11803   return 1;
11804 }
11805
11806 static int
11807 api_classify_add_del_table (vat_main_t * vam)
11808 {
11809   unformat_input_t *i = vam->input;
11810   vl_api_classify_add_del_table_t *mp;
11811
11812   u32 nbuckets = 2;
11813   u32 skip = ~0;
11814   u32 match = ~0;
11815   int is_add = 1;
11816   int del_chain = 0;
11817   u32 table_index = ~0;
11818   u32 next_table_index = ~0;
11819   u32 miss_next_index = ~0;
11820   u32 memory_size = 32 << 20;
11821   u8 *mask = 0;
11822   u32 current_data_flag = 0;
11823   int current_data_offset = 0;
11824   int ret;
11825
11826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11827     {
11828       if (unformat (i, "del"))
11829         is_add = 0;
11830       else if (unformat (i, "del-chain"))
11831         {
11832           is_add = 0;
11833           del_chain = 1;
11834         }
11835       else if (unformat (i, "buckets %d", &nbuckets))
11836         ;
11837       else if (unformat (i, "memory_size %d", &memory_size))
11838         ;
11839       else if (unformat (i, "skip %d", &skip))
11840         ;
11841       else if (unformat (i, "match %d", &match))
11842         ;
11843       else if (unformat (i, "table %d", &table_index))
11844         ;
11845       else if (unformat (i, "mask %U", unformat_classify_mask,
11846                          &mask, &skip, &match))
11847         ;
11848       else if (unformat (i, "next-table %d", &next_table_index))
11849         ;
11850       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11851                          &miss_next_index))
11852         ;
11853       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11854                          &miss_next_index))
11855         ;
11856       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11857                          &miss_next_index))
11858         ;
11859       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11860         ;
11861       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11862         ;
11863       else
11864         break;
11865     }
11866
11867   if (is_add && mask == 0)
11868     {
11869       errmsg ("Mask required");
11870       return -99;
11871     }
11872
11873   if (is_add && skip == ~0)
11874     {
11875       errmsg ("skip count required");
11876       return -99;
11877     }
11878
11879   if (is_add && match == ~0)
11880     {
11881       errmsg ("match count required");
11882       return -99;
11883     }
11884
11885   if (!is_add && table_index == ~0)
11886     {
11887       errmsg ("table index required for delete");
11888       return -99;
11889     }
11890
11891   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11892
11893   mp->is_add = is_add;
11894   mp->del_chain = del_chain;
11895   mp->table_index = ntohl (table_index);
11896   mp->nbuckets = ntohl (nbuckets);
11897   mp->memory_size = ntohl (memory_size);
11898   mp->skip_n_vectors = ntohl (skip);
11899   mp->match_n_vectors = ntohl (match);
11900   mp->next_table_index = ntohl (next_table_index);
11901   mp->miss_next_index = ntohl (miss_next_index);
11902   mp->current_data_flag = ntohl (current_data_flag);
11903   mp->current_data_offset = ntohl (current_data_offset);
11904   mp->mask_len = ntohl (vec_len (mask));
11905   clib_memcpy (mp->mask, mask, vec_len (mask));
11906
11907   vec_free (mask);
11908
11909   S (mp);
11910   W (ret);
11911   return ret;
11912 }
11913
11914 #if VPP_API_TEST_BUILTIN == 0
11915 uword
11916 unformat_l4_match (unformat_input_t * input, va_list * args)
11917 {
11918   u8 **matchp = va_arg (*args, u8 **);
11919
11920   u8 *proto_header = 0;
11921   int src_port = 0;
11922   int dst_port = 0;
11923
11924   tcpudp_header_t h;
11925
11926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11927     {
11928       if (unformat (input, "src_port %d", &src_port))
11929         ;
11930       else if (unformat (input, "dst_port %d", &dst_port))
11931         ;
11932       else
11933         return 0;
11934     }
11935
11936   h.src_port = clib_host_to_net_u16 (src_port);
11937   h.dst_port = clib_host_to_net_u16 (dst_port);
11938   vec_validate (proto_header, sizeof (h) - 1);
11939   memcpy (proto_header, &h, sizeof (h));
11940
11941   *matchp = proto_header;
11942
11943   return 1;
11944 }
11945
11946 uword
11947 unformat_ip4_match (unformat_input_t * input, va_list * args)
11948 {
11949   u8 **matchp = va_arg (*args, u8 **);
11950   u8 *match = 0;
11951   ip4_header_t *ip;
11952   int version = 0;
11953   u32 version_val;
11954   int hdr_length = 0;
11955   u32 hdr_length_val;
11956   int src = 0, dst = 0;
11957   ip4_address_t src_val, dst_val;
11958   int proto = 0;
11959   u32 proto_val;
11960   int tos = 0;
11961   u32 tos_val;
11962   int length = 0;
11963   u32 length_val;
11964   int fragment_id = 0;
11965   u32 fragment_id_val;
11966   int ttl = 0;
11967   int ttl_val;
11968   int checksum = 0;
11969   u32 checksum_val;
11970
11971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11972     {
11973       if (unformat (input, "version %d", &version_val))
11974         version = 1;
11975       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11976         hdr_length = 1;
11977       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11978         src = 1;
11979       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11980         dst = 1;
11981       else if (unformat (input, "proto %d", &proto_val))
11982         proto = 1;
11983       else if (unformat (input, "tos %d", &tos_val))
11984         tos = 1;
11985       else if (unformat (input, "length %d", &length_val))
11986         length = 1;
11987       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11988         fragment_id = 1;
11989       else if (unformat (input, "ttl %d", &ttl_val))
11990         ttl = 1;
11991       else if (unformat (input, "checksum %d", &checksum_val))
11992         checksum = 1;
11993       else
11994         break;
11995     }
11996
11997   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11998       + ttl + checksum == 0)
11999     return 0;
12000
12001   /*
12002    * Aligned because we use the real comparison functions
12003    */
12004   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12005
12006   ip = (ip4_header_t *) match;
12007
12008   /* These are realistically matched in practice */
12009   if (src)
12010     ip->src_address.as_u32 = src_val.as_u32;
12011
12012   if (dst)
12013     ip->dst_address.as_u32 = dst_val.as_u32;
12014
12015   if (proto)
12016     ip->protocol = proto_val;
12017
12018
12019   /* These are not, but they're included for completeness */
12020   if (version)
12021     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
12022
12023   if (hdr_length)
12024     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
12025
12026   if (tos)
12027     ip->tos = tos_val;
12028
12029   if (length)
12030     ip->length = clib_host_to_net_u16 (length_val);
12031
12032   if (ttl)
12033     ip->ttl = ttl_val;
12034
12035   if (checksum)
12036     ip->checksum = clib_host_to_net_u16 (checksum_val);
12037
12038   *matchp = match;
12039   return 1;
12040 }
12041
12042 uword
12043 unformat_ip6_match (unformat_input_t * input, va_list * args)
12044 {
12045   u8 **matchp = va_arg (*args, u8 **);
12046   u8 *match = 0;
12047   ip6_header_t *ip;
12048   int version = 0;
12049   u32 version_val;
12050   u8 traffic_class = 0;
12051   u32 traffic_class_val = 0;
12052   u8 flow_label = 0;
12053   u8 flow_label_val;
12054   int src = 0, dst = 0;
12055   ip6_address_t src_val, dst_val;
12056   int proto = 0;
12057   u32 proto_val;
12058   int payload_length = 0;
12059   u32 payload_length_val;
12060   int hop_limit = 0;
12061   int hop_limit_val;
12062   u32 ip_version_traffic_class_and_flow_label;
12063
12064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12065     {
12066       if (unformat (input, "version %d", &version_val))
12067         version = 1;
12068       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12069         traffic_class = 1;
12070       else if (unformat (input, "flow_label %d", &flow_label_val))
12071         flow_label = 1;
12072       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12073         src = 1;
12074       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12075         dst = 1;
12076       else if (unformat (input, "proto %d", &proto_val))
12077         proto = 1;
12078       else if (unformat (input, "payload_length %d", &payload_length_val))
12079         payload_length = 1;
12080       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12081         hop_limit = 1;
12082       else
12083         break;
12084     }
12085
12086   if (version + traffic_class + flow_label + src + dst + proto +
12087       payload_length + hop_limit == 0)
12088     return 0;
12089
12090   /*
12091    * Aligned because we use the real comparison functions
12092    */
12093   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12094
12095   ip = (ip6_header_t *) match;
12096
12097   if (src)
12098     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12099
12100   if (dst)
12101     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12102
12103   if (proto)
12104     ip->protocol = proto_val;
12105
12106   ip_version_traffic_class_and_flow_label = 0;
12107
12108   if (version)
12109     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12110
12111   if (traffic_class)
12112     ip_version_traffic_class_and_flow_label |=
12113       (traffic_class_val & 0xFF) << 20;
12114
12115   if (flow_label)
12116     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12117
12118   ip->ip_version_traffic_class_and_flow_label =
12119     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12120
12121   if (payload_length)
12122     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12123
12124   if (hop_limit)
12125     ip->hop_limit = hop_limit_val;
12126
12127   *matchp = match;
12128   return 1;
12129 }
12130
12131 uword
12132 unformat_l3_match (unformat_input_t * input, va_list * args)
12133 {
12134   u8 **matchp = va_arg (*args, u8 **);
12135
12136   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12137     {
12138       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12139         return 1;
12140       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12141         return 1;
12142       else
12143         break;
12144     }
12145   return 0;
12146 }
12147
12148 uword
12149 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12150 {
12151   u8 *tagp = va_arg (*args, u8 *);
12152   u32 tag;
12153
12154   if (unformat (input, "%d", &tag))
12155     {
12156       tagp[0] = (tag >> 8) & 0x0F;
12157       tagp[1] = tag & 0xFF;
12158       return 1;
12159     }
12160
12161   return 0;
12162 }
12163
12164 uword
12165 unformat_l2_match (unformat_input_t * input, va_list * args)
12166 {
12167   u8 **matchp = va_arg (*args, u8 **);
12168   u8 *match = 0;
12169   u8 src = 0;
12170   u8 src_val[6];
12171   u8 dst = 0;
12172   u8 dst_val[6];
12173   u8 proto = 0;
12174   u16 proto_val;
12175   u8 tag1 = 0;
12176   u8 tag1_val[2];
12177   u8 tag2 = 0;
12178   u8 tag2_val[2];
12179   int len = 14;
12180   u8 ignore_tag1 = 0;
12181   u8 ignore_tag2 = 0;
12182   u8 cos1 = 0;
12183   u8 cos2 = 0;
12184   u32 cos1_val = 0;
12185   u32 cos2_val = 0;
12186
12187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12188     {
12189       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12190         src = 1;
12191       else
12192         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12193         dst = 1;
12194       else if (unformat (input, "proto %U",
12195                          unformat_ethernet_type_host_byte_order, &proto_val))
12196         proto = 1;
12197       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12198         tag1 = 1;
12199       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12200         tag2 = 1;
12201       else if (unformat (input, "ignore-tag1"))
12202         ignore_tag1 = 1;
12203       else if (unformat (input, "ignore-tag2"))
12204         ignore_tag2 = 1;
12205       else if (unformat (input, "cos1 %d", &cos1_val))
12206         cos1 = 1;
12207       else if (unformat (input, "cos2 %d", &cos2_val))
12208         cos2 = 1;
12209       else
12210         break;
12211     }
12212   if ((src + dst + proto + tag1 + tag2 +
12213        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12214     return 0;
12215
12216   if (tag1 || ignore_tag1 || cos1)
12217     len = 18;
12218   if (tag2 || ignore_tag2 || cos2)
12219     len = 22;
12220
12221   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12222
12223   if (dst)
12224     clib_memcpy (match, dst_val, 6);
12225
12226   if (src)
12227     clib_memcpy (match + 6, src_val, 6);
12228
12229   if (tag2)
12230     {
12231       /* inner vlan tag */
12232       match[19] = tag2_val[1];
12233       match[18] = tag2_val[0];
12234       if (cos2)
12235         match[18] |= (cos2_val & 0x7) << 5;
12236       if (proto)
12237         {
12238           match[21] = proto_val & 0xff;
12239           match[20] = proto_val >> 8;
12240         }
12241       if (tag1)
12242         {
12243           match[15] = tag1_val[1];
12244           match[14] = tag1_val[0];
12245         }
12246       if (cos1)
12247         match[14] |= (cos1_val & 0x7) << 5;
12248       *matchp = match;
12249       return 1;
12250     }
12251   if (tag1)
12252     {
12253       match[15] = tag1_val[1];
12254       match[14] = tag1_val[0];
12255       if (proto)
12256         {
12257           match[17] = proto_val & 0xff;
12258           match[16] = proto_val >> 8;
12259         }
12260       if (cos1)
12261         match[14] |= (cos1_val & 0x7) << 5;
12262
12263       *matchp = match;
12264       return 1;
12265     }
12266   if (cos2)
12267     match[18] |= (cos2_val & 0x7) << 5;
12268   if (cos1)
12269     match[14] |= (cos1_val & 0x7) << 5;
12270   if (proto)
12271     {
12272       match[13] = proto_val & 0xff;
12273       match[12] = proto_val >> 8;
12274     }
12275
12276   *matchp = match;
12277   return 1;
12278 }
12279
12280 uword
12281 unformat_qos_source (unformat_input_t * input, va_list * args)
12282 {
12283   int *qs = va_arg (*args, int *);
12284
12285   if (unformat (input, "ip"))
12286     *qs = QOS_SOURCE_IP;
12287   else if (unformat (input, "mpls"))
12288     *qs = QOS_SOURCE_MPLS;
12289   else if (unformat (input, "ext"))
12290     *qs = QOS_SOURCE_EXT;
12291   else if (unformat (input, "vlan"))
12292     *qs = QOS_SOURCE_VLAN;
12293   else
12294     return 0;
12295
12296   return 1;
12297 }
12298 #endif
12299
12300 uword
12301 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12302 {
12303   u8 **matchp = va_arg (*args, u8 **);
12304   u32 skip_n_vectors = va_arg (*args, u32);
12305   u32 match_n_vectors = va_arg (*args, u32);
12306
12307   u8 *match = 0;
12308   u8 *l2 = 0;
12309   u8 *l3 = 0;
12310   u8 *l4 = 0;
12311
12312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12313     {
12314       if (unformat (input, "hex %U", unformat_hex_string, &match))
12315         ;
12316       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12317         ;
12318       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12319         ;
12320       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12321         ;
12322       else
12323         break;
12324     }
12325
12326   if (l4 && !l3)
12327     {
12328       vec_free (match);
12329       vec_free (l2);
12330       vec_free (l4);
12331       return 0;
12332     }
12333
12334   if (match || l2 || l3 || l4)
12335     {
12336       if (l2 || l3 || l4)
12337         {
12338           /* "Win a free Ethernet header in every packet" */
12339           if (l2 == 0)
12340             vec_validate_aligned (l2, 13, sizeof (u32x4));
12341           match = l2;
12342           if (vec_len (l3))
12343             {
12344               vec_append_aligned (match, l3, sizeof (u32x4));
12345               vec_free (l3);
12346             }
12347           if (vec_len (l4))
12348             {
12349               vec_append_aligned (match, l4, sizeof (u32x4));
12350               vec_free (l4);
12351             }
12352         }
12353
12354       /* Make sure the vector is big enough even if key is all 0's */
12355       vec_validate_aligned
12356         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12357          sizeof (u32x4));
12358
12359       /* Set size, include skipped vectors */
12360       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12361
12362       *matchp = match;
12363
12364       return 1;
12365     }
12366
12367   return 0;
12368 }
12369
12370 static int
12371 api_classify_add_del_session (vat_main_t * vam)
12372 {
12373   unformat_input_t *i = vam->input;
12374   vl_api_classify_add_del_session_t *mp;
12375   int is_add = 1;
12376   u32 table_index = ~0;
12377   u32 hit_next_index = ~0;
12378   u32 opaque_index = ~0;
12379   u8 *match = 0;
12380   i32 advance = 0;
12381   u32 skip_n_vectors = 0;
12382   u32 match_n_vectors = 0;
12383   u32 action = 0;
12384   u32 metadata = 0;
12385   int ret;
12386
12387   /*
12388    * Warning: you have to supply skip_n and match_n
12389    * because the API client cant simply look at the classify
12390    * table object.
12391    */
12392
12393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12394     {
12395       if (unformat (i, "del"))
12396         is_add = 0;
12397       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12398                          &hit_next_index))
12399         ;
12400       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12401                          &hit_next_index))
12402         ;
12403       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12404                          &hit_next_index))
12405         ;
12406       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12407         ;
12408       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12409         ;
12410       else if (unformat (i, "opaque-index %d", &opaque_index))
12411         ;
12412       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12413         ;
12414       else if (unformat (i, "match_n %d", &match_n_vectors))
12415         ;
12416       else if (unformat (i, "match %U", api_unformat_classify_match,
12417                          &match, skip_n_vectors, match_n_vectors))
12418         ;
12419       else if (unformat (i, "advance %d", &advance))
12420         ;
12421       else if (unformat (i, "table-index %d", &table_index))
12422         ;
12423       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12424         action = 1;
12425       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12426         action = 2;
12427       else if (unformat (i, "action %d", &action))
12428         ;
12429       else if (unformat (i, "metadata %d", &metadata))
12430         ;
12431       else
12432         break;
12433     }
12434
12435   if (table_index == ~0)
12436     {
12437       errmsg ("Table index required");
12438       return -99;
12439     }
12440
12441   if (is_add && match == 0)
12442     {
12443       errmsg ("Match value required");
12444       return -99;
12445     }
12446
12447   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12448
12449   mp->is_add = is_add;
12450   mp->table_index = ntohl (table_index);
12451   mp->hit_next_index = ntohl (hit_next_index);
12452   mp->opaque_index = ntohl (opaque_index);
12453   mp->advance = ntohl (advance);
12454   mp->action = action;
12455   mp->metadata = ntohl (metadata);
12456   mp->match_len = ntohl (vec_len (match));
12457   clib_memcpy (mp->match, match, vec_len (match));
12458   vec_free (match);
12459
12460   S (mp);
12461   W (ret);
12462   return ret;
12463 }
12464
12465 static int
12466 api_classify_set_interface_ip_table (vat_main_t * vam)
12467 {
12468   unformat_input_t *i = vam->input;
12469   vl_api_classify_set_interface_ip_table_t *mp;
12470   u32 sw_if_index;
12471   int sw_if_index_set;
12472   u32 table_index = ~0;
12473   u8 is_ipv6 = 0;
12474   int ret;
12475
12476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12477     {
12478       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12479         sw_if_index_set = 1;
12480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12481         sw_if_index_set = 1;
12482       else if (unformat (i, "table %d", &table_index))
12483         ;
12484       else
12485         {
12486           clib_warning ("parse error '%U'", format_unformat_error, i);
12487           return -99;
12488         }
12489     }
12490
12491   if (sw_if_index_set == 0)
12492     {
12493       errmsg ("missing interface name or sw_if_index");
12494       return -99;
12495     }
12496
12497
12498   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12499
12500   mp->sw_if_index = ntohl (sw_if_index);
12501   mp->table_index = ntohl (table_index);
12502   mp->is_ipv6 = is_ipv6;
12503
12504   S (mp);
12505   W (ret);
12506   return ret;
12507 }
12508
12509 static int
12510 api_classify_set_interface_l2_tables (vat_main_t * vam)
12511 {
12512   unformat_input_t *i = vam->input;
12513   vl_api_classify_set_interface_l2_tables_t *mp;
12514   u32 sw_if_index;
12515   int sw_if_index_set;
12516   u32 ip4_table_index = ~0;
12517   u32 ip6_table_index = ~0;
12518   u32 other_table_index = ~0;
12519   u32 is_input = 1;
12520   int ret;
12521
12522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12523     {
12524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12525         sw_if_index_set = 1;
12526       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12527         sw_if_index_set = 1;
12528       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12529         ;
12530       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12531         ;
12532       else if (unformat (i, "other-table %d", &other_table_index))
12533         ;
12534       else if (unformat (i, "is-input %d", &is_input))
12535         ;
12536       else
12537         {
12538           clib_warning ("parse error '%U'", format_unformat_error, i);
12539           return -99;
12540         }
12541     }
12542
12543   if (sw_if_index_set == 0)
12544     {
12545       errmsg ("missing interface name or sw_if_index");
12546       return -99;
12547     }
12548
12549
12550   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12551
12552   mp->sw_if_index = ntohl (sw_if_index);
12553   mp->ip4_table_index = ntohl (ip4_table_index);
12554   mp->ip6_table_index = ntohl (ip6_table_index);
12555   mp->other_table_index = ntohl (other_table_index);
12556   mp->is_input = (u8) is_input;
12557
12558   S (mp);
12559   W (ret);
12560   return ret;
12561 }
12562
12563 static int
12564 api_set_ipfix_exporter (vat_main_t * vam)
12565 {
12566   unformat_input_t *i = vam->input;
12567   vl_api_set_ipfix_exporter_t *mp;
12568   ip4_address_t collector_address;
12569   u8 collector_address_set = 0;
12570   u32 collector_port = ~0;
12571   ip4_address_t src_address;
12572   u8 src_address_set = 0;
12573   u32 vrf_id = ~0;
12574   u32 path_mtu = ~0;
12575   u32 template_interval = ~0;
12576   u8 udp_checksum = 0;
12577   int ret;
12578
12579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12580     {
12581       if (unformat (i, "collector_address %U", unformat_ip4_address,
12582                     &collector_address))
12583         collector_address_set = 1;
12584       else if (unformat (i, "collector_port %d", &collector_port))
12585         ;
12586       else if (unformat (i, "src_address %U", unformat_ip4_address,
12587                          &src_address))
12588         src_address_set = 1;
12589       else if (unformat (i, "vrf_id %d", &vrf_id))
12590         ;
12591       else if (unformat (i, "path_mtu %d", &path_mtu))
12592         ;
12593       else if (unformat (i, "template_interval %d", &template_interval))
12594         ;
12595       else if (unformat (i, "udp_checksum"))
12596         udp_checksum = 1;
12597       else
12598         break;
12599     }
12600
12601   if (collector_address_set == 0)
12602     {
12603       errmsg ("collector_address required");
12604       return -99;
12605     }
12606
12607   if (src_address_set == 0)
12608     {
12609       errmsg ("src_address required");
12610       return -99;
12611     }
12612
12613   M (SET_IPFIX_EXPORTER, mp);
12614
12615   memcpy (mp->collector_address, collector_address.data,
12616           sizeof (collector_address.data));
12617   mp->collector_port = htons ((u16) collector_port);
12618   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12619   mp->vrf_id = htonl (vrf_id);
12620   mp->path_mtu = htonl (path_mtu);
12621   mp->template_interval = htonl (template_interval);
12622   mp->udp_checksum = udp_checksum;
12623
12624   S (mp);
12625   W (ret);
12626   return ret;
12627 }
12628
12629 static int
12630 api_set_ipfix_classify_stream (vat_main_t * vam)
12631 {
12632   unformat_input_t *i = vam->input;
12633   vl_api_set_ipfix_classify_stream_t *mp;
12634   u32 domain_id = 0;
12635   u32 src_port = UDP_DST_PORT_ipfix;
12636   int ret;
12637
12638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12639     {
12640       if (unformat (i, "domain %d", &domain_id))
12641         ;
12642       else if (unformat (i, "src_port %d", &src_port))
12643         ;
12644       else
12645         {
12646           errmsg ("unknown input `%U'", format_unformat_error, i);
12647           return -99;
12648         }
12649     }
12650
12651   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12652
12653   mp->domain_id = htonl (domain_id);
12654   mp->src_port = htons ((u16) src_port);
12655
12656   S (mp);
12657   W (ret);
12658   return ret;
12659 }
12660
12661 static int
12662 api_ipfix_classify_table_add_del (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_ipfix_classify_table_add_del_t *mp;
12666   int is_add = -1;
12667   u32 classify_table_index = ~0;
12668   u8 ip_version = 0;
12669   u8 transport_protocol = 255;
12670   int ret;
12671
12672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12673     {
12674       if (unformat (i, "add"))
12675         is_add = 1;
12676       else if (unformat (i, "del"))
12677         is_add = 0;
12678       else if (unformat (i, "table %d", &classify_table_index))
12679         ;
12680       else if (unformat (i, "ip4"))
12681         ip_version = 4;
12682       else if (unformat (i, "ip6"))
12683         ip_version = 6;
12684       else if (unformat (i, "tcp"))
12685         transport_protocol = 6;
12686       else if (unformat (i, "udp"))
12687         transport_protocol = 17;
12688       else
12689         {
12690           errmsg ("unknown input `%U'", format_unformat_error, i);
12691           return -99;
12692         }
12693     }
12694
12695   if (is_add == -1)
12696     {
12697       errmsg ("expecting: add|del");
12698       return -99;
12699     }
12700   if (classify_table_index == ~0)
12701     {
12702       errmsg ("classifier table not specified");
12703       return -99;
12704     }
12705   if (ip_version == 0)
12706     {
12707       errmsg ("IP version not specified");
12708       return -99;
12709     }
12710
12711   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12712
12713   mp->is_add = is_add;
12714   mp->table_id = htonl (classify_table_index);
12715   mp->ip_version = ip_version;
12716   mp->transport_protocol = transport_protocol;
12717
12718   S (mp);
12719   W (ret);
12720   return ret;
12721 }
12722
12723 static int
12724 api_get_node_index (vat_main_t * vam)
12725 {
12726   unformat_input_t *i = vam->input;
12727   vl_api_get_node_index_t *mp;
12728   u8 *name = 0;
12729   int ret;
12730
12731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12732     {
12733       if (unformat (i, "node %s", &name))
12734         ;
12735       else
12736         break;
12737     }
12738   if (name == 0)
12739     {
12740       errmsg ("node name required");
12741       return -99;
12742     }
12743   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12744     {
12745       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12746       return -99;
12747     }
12748
12749   M (GET_NODE_INDEX, mp);
12750   clib_memcpy (mp->node_name, name, vec_len (name));
12751   vec_free (name);
12752
12753   S (mp);
12754   W (ret);
12755   return ret;
12756 }
12757
12758 static int
12759 api_get_next_index (vat_main_t * vam)
12760 {
12761   unformat_input_t *i = vam->input;
12762   vl_api_get_next_index_t *mp;
12763   u8 *node_name = 0, *next_node_name = 0;
12764   int ret;
12765
12766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12767     {
12768       if (unformat (i, "node-name %s", &node_name))
12769         ;
12770       else if (unformat (i, "next-node-name %s", &next_node_name))
12771         break;
12772     }
12773
12774   if (node_name == 0)
12775     {
12776       errmsg ("node name required");
12777       return -99;
12778     }
12779   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12780     {
12781       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12782       return -99;
12783     }
12784
12785   if (next_node_name == 0)
12786     {
12787       errmsg ("next node name required");
12788       return -99;
12789     }
12790   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12791     {
12792       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12793       return -99;
12794     }
12795
12796   M (GET_NEXT_INDEX, mp);
12797   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12798   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12799   vec_free (node_name);
12800   vec_free (next_node_name);
12801
12802   S (mp);
12803   W (ret);
12804   return ret;
12805 }
12806
12807 static int
12808 api_add_node_next (vat_main_t * vam)
12809 {
12810   unformat_input_t *i = vam->input;
12811   vl_api_add_node_next_t *mp;
12812   u8 *name = 0;
12813   u8 *next = 0;
12814   int ret;
12815
12816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12817     {
12818       if (unformat (i, "node %s", &name))
12819         ;
12820       else if (unformat (i, "next %s", &next))
12821         ;
12822       else
12823         break;
12824     }
12825   if (name == 0)
12826     {
12827       errmsg ("node name required");
12828       return -99;
12829     }
12830   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12831     {
12832       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12833       return -99;
12834     }
12835   if (next == 0)
12836     {
12837       errmsg ("next node required");
12838       return -99;
12839     }
12840   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12841     {
12842       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12843       return -99;
12844     }
12845
12846   M (ADD_NODE_NEXT, mp);
12847   clib_memcpy (mp->node_name, name, vec_len (name));
12848   clib_memcpy (mp->next_name, next, vec_len (next));
12849   vec_free (name);
12850   vec_free (next);
12851
12852   S (mp);
12853   W (ret);
12854   return ret;
12855 }
12856
12857 static int
12858 api_l2tpv3_create_tunnel (vat_main_t * vam)
12859 {
12860   unformat_input_t *i = vam->input;
12861   ip6_address_t client_address, our_address;
12862   int client_address_set = 0;
12863   int our_address_set = 0;
12864   u32 local_session_id = 0;
12865   u32 remote_session_id = 0;
12866   u64 local_cookie = 0;
12867   u64 remote_cookie = 0;
12868   u8 l2_sublayer_present = 0;
12869   vl_api_l2tpv3_create_tunnel_t *mp;
12870   int ret;
12871
12872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12873     {
12874       if (unformat (i, "client_address %U", unformat_ip6_address,
12875                     &client_address))
12876         client_address_set = 1;
12877       else if (unformat (i, "our_address %U", unformat_ip6_address,
12878                          &our_address))
12879         our_address_set = 1;
12880       else if (unformat (i, "local_session_id %d", &local_session_id))
12881         ;
12882       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12883         ;
12884       else if (unformat (i, "local_cookie %lld", &local_cookie))
12885         ;
12886       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12887         ;
12888       else if (unformat (i, "l2-sublayer-present"))
12889         l2_sublayer_present = 1;
12890       else
12891         break;
12892     }
12893
12894   if (client_address_set == 0)
12895     {
12896       errmsg ("client_address required");
12897       return -99;
12898     }
12899
12900   if (our_address_set == 0)
12901     {
12902       errmsg ("our_address required");
12903       return -99;
12904     }
12905
12906   M (L2TPV3_CREATE_TUNNEL, mp);
12907
12908   clib_memcpy (mp->client_address, client_address.as_u8,
12909                sizeof (mp->client_address));
12910
12911   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12912
12913   mp->local_session_id = ntohl (local_session_id);
12914   mp->remote_session_id = ntohl (remote_session_id);
12915   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12916   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12917   mp->l2_sublayer_present = l2_sublayer_present;
12918   mp->is_ipv6 = 1;
12919
12920   S (mp);
12921   W (ret);
12922   return ret;
12923 }
12924
12925 static int
12926 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12927 {
12928   unformat_input_t *i = vam->input;
12929   u32 sw_if_index;
12930   u8 sw_if_index_set = 0;
12931   u64 new_local_cookie = 0;
12932   u64 new_remote_cookie = 0;
12933   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12934   int ret;
12935
12936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12937     {
12938       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12939         sw_if_index_set = 1;
12940       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12941         sw_if_index_set = 1;
12942       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12943         ;
12944       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12945         ;
12946       else
12947         break;
12948     }
12949
12950   if (sw_if_index_set == 0)
12951     {
12952       errmsg ("missing interface name or sw_if_index");
12953       return -99;
12954     }
12955
12956   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12957
12958   mp->sw_if_index = ntohl (sw_if_index);
12959   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12960   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12961
12962   S (mp);
12963   W (ret);
12964   return ret;
12965 }
12966
12967 static int
12968 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12969 {
12970   unformat_input_t *i = vam->input;
12971   vl_api_l2tpv3_interface_enable_disable_t *mp;
12972   u32 sw_if_index;
12973   u8 sw_if_index_set = 0;
12974   u8 enable_disable = 1;
12975   int ret;
12976
12977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12978     {
12979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12980         sw_if_index_set = 1;
12981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12982         sw_if_index_set = 1;
12983       else if (unformat (i, "enable"))
12984         enable_disable = 1;
12985       else if (unformat (i, "disable"))
12986         enable_disable = 0;
12987       else
12988         break;
12989     }
12990
12991   if (sw_if_index_set == 0)
12992     {
12993       errmsg ("missing interface name or sw_if_index");
12994       return -99;
12995     }
12996
12997   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12998
12999   mp->sw_if_index = ntohl (sw_if_index);
13000   mp->enable_disable = enable_disable;
13001
13002   S (mp);
13003   W (ret);
13004   return ret;
13005 }
13006
13007 static int
13008 api_l2tpv3_set_lookup_key (vat_main_t * vam)
13009 {
13010   unformat_input_t *i = vam->input;
13011   vl_api_l2tpv3_set_lookup_key_t *mp;
13012   u8 key = ~0;
13013   int ret;
13014
13015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13016     {
13017       if (unformat (i, "lookup_v6_src"))
13018         key = L2T_LOOKUP_SRC_ADDRESS;
13019       else if (unformat (i, "lookup_v6_dst"))
13020         key = L2T_LOOKUP_DST_ADDRESS;
13021       else if (unformat (i, "lookup_session_id"))
13022         key = L2T_LOOKUP_SESSION_ID;
13023       else
13024         break;
13025     }
13026
13027   if (key == (u8) ~ 0)
13028     {
13029       errmsg ("l2tp session lookup key unset");
13030       return -99;
13031     }
13032
13033   M (L2TPV3_SET_LOOKUP_KEY, mp);
13034
13035   mp->key = key;
13036
13037   S (mp);
13038   W (ret);
13039   return ret;
13040 }
13041
13042 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
13043   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13044 {
13045   vat_main_t *vam = &vat_main;
13046
13047   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
13048          format_ip6_address, mp->our_address,
13049          format_ip6_address, mp->client_address,
13050          clib_net_to_host_u32 (mp->sw_if_index));
13051
13052   print (vam->ofp,
13053          "   local cookies %016llx %016llx remote cookie %016llx",
13054          clib_net_to_host_u64 (mp->local_cookie[0]),
13055          clib_net_to_host_u64 (mp->local_cookie[1]),
13056          clib_net_to_host_u64 (mp->remote_cookie));
13057
13058   print (vam->ofp, "   local session-id %d remote session-id %d",
13059          clib_net_to_host_u32 (mp->local_session_id),
13060          clib_net_to_host_u32 (mp->remote_session_id));
13061
13062   print (vam->ofp, "   l2 specific sublayer %s\n",
13063          mp->l2_sublayer_present ? "preset" : "absent");
13064
13065 }
13066
13067 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13068   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13069 {
13070   vat_main_t *vam = &vat_main;
13071   vat_json_node_t *node = NULL;
13072   struct in6_addr addr;
13073
13074   if (VAT_JSON_ARRAY != vam->json_tree.type)
13075     {
13076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13077       vat_json_init_array (&vam->json_tree);
13078     }
13079   node = vat_json_array_add (&vam->json_tree);
13080
13081   vat_json_init_object (node);
13082
13083   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13084   vat_json_object_add_ip6 (node, "our_address", addr);
13085   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13086   vat_json_object_add_ip6 (node, "client_address", addr);
13087
13088   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13089   vat_json_init_array (lc);
13090   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13091   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13092   vat_json_object_add_uint (node, "remote_cookie",
13093                             clib_net_to_host_u64 (mp->remote_cookie));
13094
13095   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13096   vat_json_object_add_uint (node, "local_session_id",
13097                             clib_net_to_host_u32 (mp->local_session_id));
13098   vat_json_object_add_uint (node, "remote_session_id",
13099                             clib_net_to_host_u32 (mp->remote_session_id));
13100   vat_json_object_add_string_copy (node, "l2_sublayer",
13101                                    mp->l2_sublayer_present ? (u8 *) "present"
13102                                    : (u8 *) "absent");
13103 }
13104
13105 static int
13106 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13107 {
13108   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13109   vl_api_control_ping_t *mp_ping;
13110   int ret;
13111
13112   /* Get list of l2tpv3-tunnel interfaces */
13113   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13114   S (mp);
13115
13116   /* Use a control ping for synchronization */
13117   MPING (CONTROL_PING, mp_ping);
13118   S (mp_ping);
13119
13120   W (ret);
13121   return ret;
13122 }
13123
13124
13125 static void vl_api_sw_interface_tap_details_t_handler
13126   (vl_api_sw_interface_tap_details_t * mp)
13127 {
13128   vat_main_t *vam = &vat_main;
13129
13130   print (vam->ofp, "%-16s %d",
13131          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13132 }
13133
13134 static void vl_api_sw_interface_tap_details_t_handler_json
13135   (vl_api_sw_interface_tap_details_t * mp)
13136 {
13137   vat_main_t *vam = &vat_main;
13138   vat_json_node_t *node = NULL;
13139
13140   if (VAT_JSON_ARRAY != vam->json_tree.type)
13141     {
13142       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13143       vat_json_init_array (&vam->json_tree);
13144     }
13145   node = vat_json_array_add (&vam->json_tree);
13146
13147   vat_json_init_object (node);
13148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13149   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13150 }
13151
13152 static int
13153 api_sw_interface_tap_dump (vat_main_t * vam)
13154 {
13155   vl_api_sw_interface_tap_dump_t *mp;
13156   vl_api_control_ping_t *mp_ping;
13157   int ret;
13158
13159   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13160   /* Get list of tap interfaces */
13161   M (SW_INTERFACE_TAP_DUMP, mp);
13162   S (mp);
13163
13164   /* Use a control ping for synchronization */
13165   MPING (CONTROL_PING, mp_ping);
13166   S (mp_ping);
13167
13168   W (ret);
13169   return ret;
13170 }
13171
13172 static void vl_api_sw_interface_tap_v2_details_t_handler
13173   (vl_api_sw_interface_tap_v2_details_t * mp)
13174 {
13175   vat_main_t *vam = &vat_main;
13176
13177   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13178                     mp->host_ip4_prefix_len);
13179   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13180                     mp->host_ip6_prefix_len);
13181
13182   print (vam->ofp,
13183          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13184          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13185          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13186          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13187          mp->host_bridge, ip4, ip6);
13188
13189   vec_free (ip4);
13190   vec_free (ip6);
13191 }
13192
13193 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13194   (vl_api_sw_interface_tap_v2_details_t * mp)
13195 {
13196   vat_main_t *vam = &vat_main;
13197   vat_json_node_t *node = NULL;
13198
13199   if (VAT_JSON_ARRAY != vam->json_tree.type)
13200     {
13201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13202       vat_json_init_array (&vam->json_tree);
13203     }
13204   node = vat_json_array_add (&vam->json_tree);
13205
13206   vat_json_init_object (node);
13207   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13208   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13209   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13210   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13211   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13212   vat_json_object_add_string_copy (node, "host_mac_addr",
13213                                    format (0, "%U", format_ethernet_address,
13214                                            &mp->host_mac_addr));
13215   vat_json_object_add_string_copy (node, "host_namespace",
13216                                    mp->host_namespace);
13217   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13218   vat_json_object_add_string_copy (node, "host_ip4_addr",
13219                                    format (0, "%U/%d", format_ip4_address,
13220                                            mp->host_ip4_addr,
13221                                            mp->host_ip4_prefix_len));
13222   vat_json_object_add_string_copy (node, "host_ip6_addr",
13223                                    format (0, "%U/%d", format_ip6_address,
13224                                            mp->host_ip6_addr,
13225                                            mp->host_ip6_prefix_len));
13226
13227 }
13228
13229 static int
13230 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13231 {
13232   vl_api_sw_interface_tap_v2_dump_t *mp;
13233   vl_api_control_ping_t *mp_ping;
13234   int ret;
13235
13236   print (vam->ofp,
13237          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13238          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13239          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13240          "host_ip6_addr");
13241
13242   /* Get list of tap interfaces */
13243   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13244   S (mp);
13245
13246   /* Use a control ping for synchronization */
13247   MPING (CONTROL_PING, mp_ping);
13248   S (mp_ping);
13249
13250   W (ret);
13251   return ret;
13252 }
13253
13254 static int
13255 api_vxlan_offload_rx (vat_main_t * vam)
13256 {
13257   unformat_input_t *line_input = vam->input;
13258   vl_api_vxlan_offload_rx_t *mp;
13259   u32 hw_if_index = ~0, rx_if_index = ~0;
13260   u8 is_add = 1;
13261   int ret;
13262
13263   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13264     {
13265       if (unformat (line_input, "del"))
13266         is_add = 0;
13267       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13268                          &hw_if_index))
13269         ;
13270       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13271         ;
13272       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13273                          &rx_if_index))
13274         ;
13275       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13276         ;
13277       else
13278         {
13279           errmsg ("parse error '%U'", format_unformat_error, line_input);
13280           return -99;
13281         }
13282     }
13283
13284   if (hw_if_index == ~0)
13285     {
13286       errmsg ("no hw interface");
13287       return -99;
13288     }
13289
13290   if (rx_if_index == ~0)
13291     {
13292       errmsg ("no rx tunnel");
13293       return -99;
13294     }
13295
13296   M (VXLAN_OFFLOAD_RX, mp);
13297
13298   mp->hw_if_index = ntohl (hw_if_index);
13299   mp->sw_if_index = ntohl (rx_if_index);
13300   mp->enable = is_add;
13301
13302   S (mp);
13303   W (ret);
13304   return ret;
13305 }
13306
13307 static uword unformat_vxlan_decap_next
13308   (unformat_input_t * input, va_list * args)
13309 {
13310   u32 *result = va_arg (*args, u32 *);
13311   u32 tmp;
13312
13313   if (unformat (input, "l2"))
13314     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13315   else if (unformat (input, "%d", &tmp))
13316     *result = tmp;
13317   else
13318     return 0;
13319   return 1;
13320 }
13321
13322 static int
13323 api_vxlan_add_del_tunnel (vat_main_t * vam)
13324 {
13325   unformat_input_t *line_input = vam->input;
13326   vl_api_vxlan_add_del_tunnel_t *mp;
13327   ip46_address_t src, dst;
13328   u8 is_add = 1;
13329   u8 ipv4_set = 0, ipv6_set = 0;
13330   u8 src_set = 0;
13331   u8 dst_set = 0;
13332   u8 grp_set = 0;
13333   u32 instance = ~0;
13334   u32 mcast_sw_if_index = ~0;
13335   u32 encap_vrf_id = 0;
13336   u32 decap_next_index = ~0;
13337   u32 vni = 0;
13338   int ret;
13339
13340   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13341   clib_memset (&src, 0, sizeof src);
13342   clib_memset (&dst, 0, sizeof dst);
13343
13344   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13345     {
13346       if (unformat (line_input, "del"))
13347         is_add = 0;
13348       else if (unformat (line_input, "instance %d", &instance))
13349         ;
13350       else
13351         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13352         {
13353           ipv4_set = 1;
13354           src_set = 1;
13355         }
13356       else
13357         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13358         {
13359           ipv4_set = 1;
13360           dst_set = 1;
13361         }
13362       else
13363         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13364         {
13365           ipv6_set = 1;
13366           src_set = 1;
13367         }
13368       else
13369         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13370         {
13371           ipv6_set = 1;
13372           dst_set = 1;
13373         }
13374       else if (unformat (line_input, "group %U %U",
13375                          unformat_ip4_address, &dst.ip4,
13376                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13377         {
13378           grp_set = dst_set = 1;
13379           ipv4_set = 1;
13380         }
13381       else if (unformat (line_input, "group %U",
13382                          unformat_ip4_address, &dst.ip4))
13383         {
13384           grp_set = dst_set = 1;
13385           ipv4_set = 1;
13386         }
13387       else if (unformat (line_input, "group %U %U",
13388                          unformat_ip6_address, &dst.ip6,
13389                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13390         {
13391           grp_set = dst_set = 1;
13392           ipv6_set = 1;
13393         }
13394       else if (unformat (line_input, "group %U",
13395                          unformat_ip6_address, &dst.ip6))
13396         {
13397           grp_set = dst_set = 1;
13398           ipv6_set = 1;
13399         }
13400       else
13401         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13402         ;
13403       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13404         ;
13405       else if (unformat (line_input, "decap-next %U",
13406                          unformat_vxlan_decap_next, &decap_next_index))
13407         ;
13408       else if (unformat (line_input, "vni %d", &vni))
13409         ;
13410       else
13411         {
13412           errmsg ("parse error '%U'", format_unformat_error, line_input);
13413           return -99;
13414         }
13415     }
13416
13417   if (src_set == 0)
13418     {
13419       errmsg ("tunnel src address not specified");
13420       return -99;
13421     }
13422   if (dst_set == 0)
13423     {
13424       errmsg ("tunnel dst address not specified");
13425       return -99;
13426     }
13427
13428   if (grp_set && !ip46_address_is_multicast (&dst))
13429     {
13430       errmsg ("tunnel group address not multicast");
13431       return -99;
13432     }
13433   if (grp_set && mcast_sw_if_index == ~0)
13434     {
13435       errmsg ("tunnel nonexistent multicast device");
13436       return -99;
13437     }
13438   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13439     {
13440       errmsg ("tunnel dst address must be unicast");
13441       return -99;
13442     }
13443
13444
13445   if (ipv4_set && ipv6_set)
13446     {
13447       errmsg ("both IPv4 and IPv6 addresses specified");
13448       return -99;
13449     }
13450
13451   if ((vni == 0) || (vni >> 24))
13452     {
13453       errmsg ("vni not specified or out of range");
13454       return -99;
13455     }
13456
13457   M (VXLAN_ADD_DEL_TUNNEL, mp);
13458
13459   if (ipv6_set)
13460     {
13461       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13462       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13463     }
13464   else
13465     {
13466       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13467       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13468     }
13469
13470   mp->instance = htonl (instance);
13471   mp->encap_vrf_id = ntohl (encap_vrf_id);
13472   mp->decap_next_index = ntohl (decap_next_index);
13473   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13474   mp->vni = ntohl (vni);
13475   mp->is_add = is_add;
13476   mp->is_ipv6 = ipv6_set;
13477
13478   S (mp);
13479   W (ret);
13480   return ret;
13481 }
13482
13483 static void vl_api_vxlan_tunnel_details_t_handler
13484   (vl_api_vxlan_tunnel_details_t * mp)
13485 {
13486   vat_main_t *vam = &vat_main;
13487   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13488   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13489
13490   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13491          ntohl (mp->sw_if_index),
13492          ntohl (mp->instance),
13493          format_ip46_address, &src, IP46_TYPE_ANY,
13494          format_ip46_address, &dst, IP46_TYPE_ANY,
13495          ntohl (mp->encap_vrf_id),
13496          ntohl (mp->decap_next_index), ntohl (mp->vni),
13497          ntohl (mp->mcast_sw_if_index));
13498 }
13499
13500 static void vl_api_vxlan_tunnel_details_t_handler_json
13501   (vl_api_vxlan_tunnel_details_t * mp)
13502 {
13503   vat_main_t *vam = &vat_main;
13504   vat_json_node_t *node = NULL;
13505
13506   if (VAT_JSON_ARRAY != vam->json_tree.type)
13507     {
13508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13509       vat_json_init_array (&vam->json_tree);
13510     }
13511   node = vat_json_array_add (&vam->json_tree);
13512
13513   vat_json_init_object (node);
13514   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13515
13516   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13517
13518   if (mp->is_ipv6)
13519     {
13520       struct in6_addr ip6;
13521
13522       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13523       vat_json_object_add_ip6 (node, "src_address", ip6);
13524       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13525       vat_json_object_add_ip6 (node, "dst_address", ip6);
13526     }
13527   else
13528     {
13529       struct in_addr ip4;
13530
13531       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13532       vat_json_object_add_ip4 (node, "src_address", ip4);
13533       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13534       vat_json_object_add_ip4 (node, "dst_address", ip4);
13535     }
13536   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13537   vat_json_object_add_uint (node, "decap_next_index",
13538                             ntohl (mp->decap_next_index));
13539   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13540   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13541   vat_json_object_add_uint (node, "mcast_sw_if_index",
13542                             ntohl (mp->mcast_sw_if_index));
13543 }
13544
13545 static int
13546 api_vxlan_tunnel_dump (vat_main_t * vam)
13547 {
13548   unformat_input_t *i = vam->input;
13549   vl_api_vxlan_tunnel_dump_t *mp;
13550   vl_api_control_ping_t *mp_ping;
13551   u32 sw_if_index;
13552   u8 sw_if_index_set = 0;
13553   int ret;
13554
13555   /* Parse args required to build the message */
13556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13557     {
13558       if (unformat (i, "sw_if_index %d", &sw_if_index))
13559         sw_if_index_set = 1;
13560       else
13561         break;
13562     }
13563
13564   if (sw_if_index_set == 0)
13565     {
13566       sw_if_index = ~0;
13567     }
13568
13569   if (!vam->json_output)
13570     {
13571       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13572              "sw_if_index", "instance", "src_address", "dst_address",
13573              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13574     }
13575
13576   /* Get list of vxlan-tunnel interfaces */
13577   M (VXLAN_TUNNEL_DUMP, mp);
13578
13579   mp->sw_if_index = htonl (sw_if_index);
13580
13581   S (mp);
13582
13583   /* Use a control ping for synchronization */
13584   MPING (CONTROL_PING, mp_ping);
13585   S (mp_ping);
13586
13587   W (ret);
13588   return ret;
13589 }
13590
13591 static uword unformat_geneve_decap_next
13592   (unformat_input_t * input, va_list * args)
13593 {
13594   u32 *result = va_arg (*args, u32 *);
13595   u32 tmp;
13596
13597   if (unformat (input, "l2"))
13598     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13599   else if (unformat (input, "%d", &tmp))
13600     *result = tmp;
13601   else
13602     return 0;
13603   return 1;
13604 }
13605
13606 static int
13607 api_geneve_add_del_tunnel (vat_main_t * vam)
13608 {
13609   unformat_input_t *line_input = vam->input;
13610   vl_api_geneve_add_del_tunnel_t *mp;
13611   ip46_address_t src, dst;
13612   u8 is_add = 1;
13613   u8 ipv4_set = 0, ipv6_set = 0;
13614   u8 src_set = 0;
13615   u8 dst_set = 0;
13616   u8 grp_set = 0;
13617   u32 mcast_sw_if_index = ~0;
13618   u32 encap_vrf_id = 0;
13619   u32 decap_next_index = ~0;
13620   u32 vni = 0;
13621   int ret;
13622
13623   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13624   clib_memset (&src, 0, sizeof src);
13625   clib_memset (&dst, 0, sizeof dst);
13626
13627   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13628     {
13629       if (unformat (line_input, "del"))
13630         is_add = 0;
13631       else
13632         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13633         {
13634           ipv4_set = 1;
13635           src_set = 1;
13636         }
13637       else
13638         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13639         {
13640           ipv4_set = 1;
13641           dst_set = 1;
13642         }
13643       else
13644         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13645         {
13646           ipv6_set = 1;
13647           src_set = 1;
13648         }
13649       else
13650         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13651         {
13652           ipv6_set = 1;
13653           dst_set = 1;
13654         }
13655       else if (unformat (line_input, "group %U %U",
13656                          unformat_ip4_address, &dst.ip4,
13657                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13658         {
13659           grp_set = dst_set = 1;
13660           ipv4_set = 1;
13661         }
13662       else if (unformat (line_input, "group %U",
13663                          unformat_ip4_address, &dst.ip4))
13664         {
13665           grp_set = dst_set = 1;
13666           ipv4_set = 1;
13667         }
13668       else if (unformat (line_input, "group %U %U",
13669                          unformat_ip6_address, &dst.ip6,
13670                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13671         {
13672           grp_set = dst_set = 1;
13673           ipv6_set = 1;
13674         }
13675       else if (unformat (line_input, "group %U",
13676                          unformat_ip6_address, &dst.ip6))
13677         {
13678           grp_set = dst_set = 1;
13679           ipv6_set = 1;
13680         }
13681       else
13682         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13683         ;
13684       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13685         ;
13686       else if (unformat (line_input, "decap-next %U",
13687                          unformat_geneve_decap_next, &decap_next_index))
13688         ;
13689       else if (unformat (line_input, "vni %d", &vni))
13690         ;
13691       else
13692         {
13693           errmsg ("parse error '%U'", format_unformat_error, line_input);
13694           return -99;
13695         }
13696     }
13697
13698   if (src_set == 0)
13699     {
13700       errmsg ("tunnel src address not specified");
13701       return -99;
13702     }
13703   if (dst_set == 0)
13704     {
13705       errmsg ("tunnel dst address not specified");
13706       return -99;
13707     }
13708
13709   if (grp_set && !ip46_address_is_multicast (&dst))
13710     {
13711       errmsg ("tunnel group address not multicast");
13712       return -99;
13713     }
13714   if (grp_set && mcast_sw_if_index == ~0)
13715     {
13716       errmsg ("tunnel nonexistent multicast device");
13717       return -99;
13718     }
13719   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13720     {
13721       errmsg ("tunnel dst address must be unicast");
13722       return -99;
13723     }
13724
13725
13726   if (ipv4_set && ipv6_set)
13727     {
13728       errmsg ("both IPv4 and IPv6 addresses specified");
13729       return -99;
13730     }
13731
13732   if ((vni == 0) || (vni >> 24))
13733     {
13734       errmsg ("vni not specified or out of range");
13735       return -99;
13736     }
13737
13738   M (GENEVE_ADD_DEL_TUNNEL, mp);
13739
13740   if (ipv6_set)
13741     {
13742       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13743       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13744     }
13745   else
13746     {
13747       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13748       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13749     }
13750   mp->encap_vrf_id = ntohl (encap_vrf_id);
13751   mp->decap_next_index = ntohl (decap_next_index);
13752   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13753   mp->vni = ntohl (vni);
13754   mp->is_add = is_add;
13755   mp->is_ipv6 = ipv6_set;
13756
13757   S (mp);
13758   W (ret);
13759   return ret;
13760 }
13761
13762 static void vl_api_geneve_tunnel_details_t_handler
13763   (vl_api_geneve_tunnel_details_t * mp)
13764 {
13765   vat_main_t *vam = &vat_main;
13766   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13767   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13768
13769   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13770          ntohl (mp->sw_if_index),
13771          format_ip46_address, &src, IP46_TYPE_ANY,
13772          format_ip46_address, &dst, IP46_TYPE_ANY,
13773          ntohl (mp->encap_vrf_id),
13774          ntohl (mp->decap_next_index), ntohl (mp->vni),
13775          ntohl (mp->mcast_sw_if_index));
13776 }
13777
13778 static void vl_api_geneve_tunnel_details_t_handler_json
13779   (vl_api_geneve_tunnel_details_t * mp)
13780 {
13781   vat_main_t *vam = &vat_main;
13782   vat_json_node_t *node = NULL;
13783
13784   if (VAT_JSON_ARRAY != vam->json_tree.type)
13785     {
13786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13787       vat_json_init_array (&vam->json_tree);
13788     }
13789   node = vat_json_array_add (&vam->json_tree);
13790
13791   vat_json_init_object (node);
13792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13793   if (mp->is_ipv6)
13794     {
13795       struct in6_addr ip6;
13796
13797       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13798       vat_json_object_add_ip6 (node, "src_address", ip6);
13799       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13800       vat_json_object_add_ip6 (node, "dst_address", ip6);
13801     }
13802   else
13803     {
13804       struct in_addr ip4;
13805
13806       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13807       vat_json_object_add_ip4 (node, "src_address", ip4);
13808       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13809       vat_json_object_add_ip4 (node, "dst_address", ip4);
13810     }
13811   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13812   vat_json_object_add_uint (node, "decap_next_index",
13813                             ntohl (mp->decap_next_index));
13814   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13815   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13816   vat_json_object_add_uint (node, "mcast_sw_if_index",
13817                             ntohl (mp->mcast_sw_if_index));
13818 }
13819
13820 static int
13821 api_geneve_tunnel_dump (vat_main_t * vam)
13822 {
13823   unformat_input_t *i = vam->input;
13824   vl_api_geneve_tunnel_dump_t *mp;
13825   vl_api_control_ping_t *mp_ping;
13826   u32 sw_if_index;
13827   u8 sw_if_index_set = 0;
13828   int ret;
13829
13830   /* Parse args required to build the message */
13831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13832     {
13833       if (unformat (i, "sw_if_index %d", &sw_if_index))
13834         sw_if_index_set = 1;
13835       else
13836         break;
13837     }
13838
13839   if (sw_if_index_set == 0)
13840     {
13841       sw_if_index = ~0;
13842     }
13843
13844   if (!vam->json_output)
13845     {
13846       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13847              "sw_if_index", "local_address", "remote_address",
13848              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13849     }
13850
13851   /* Get list of geneve-tunnel interfaces */
13852   M (GENEVE_TUNNEL_DUMP, mp);
13853
13854   mp->sw_if_index = htonl (sw_if_index);
13855
13856   S (mp);
13857
13858   /* Use a control ping for synchronization */
13859   M (CONTROL_PING, mp_ping);
13860   S (mp_ping);
13861
13862   W (ret);
13863   return ret;
13864 }
13865
13866 static int
13867 api_gre_add_del_tunnel (vat_main_t * vam)
13868 {
13869   unformat_input_t *line_input = vam->input;
13870   vl_api_gre_add_del_tunnel_t *mp;
13871   ip4_address_t src4, dst4;
13872   ip6_address_t src6, dst6;
13873   u8 is_add = 1;
13874   u8 ipv4_set = 0;
13875   u8 ipv6_set = 0;
13876   u8 t_type = GRE_TUNNEL_TYPE_L3;
13877   u8 src_set = 0;
13878   u8 dst_set = 0;
13879   u32 outer_fib_id = 0;
13880   u32 session_id = 0;
13881   u32 instance = ~0;
13882   int ret;
13883
13884   clib_memset (&src4, 0, sizeof src4);
13885   clib_memset (&dst4, 0, sizeof dst4);
13886   clib_memset (&src6, 0, sizeof src6);
13887   clib_memset (&dst6, 0, sizeof dst6);
13888
13889   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13890     {
13891       if (unformat (line_input, "del"))
13892         is_add = 0;
13893       else if (unformat (line_input, "instance %d", &instance))
13894         ;
13895       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13896         {
13897           src_set = 1;
13898           ipv4_set = 1;
13899         }
13900       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13901         {
13902           dst_set = 1;
13903           ipv4_set = 1;
13904         }
13905       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13906         {
13907           src_set = 1;
13908           ipv6_set = 1;
13909         }
13910       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13911         {
13912           dst_set = 1;
13913           ipv6_set = 1;
13914         }
13915       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13916         ;
13917       else if (unformat (line_input, "teb"))
13918         t_type = GRE_TUNNEL_TYPE_TEB;
13919       else if (unformat (line_input, "erspan %d", &session_id))
13920         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13921       else
13922         {
13923           errmsg ("parse error '%U'", format_unformat_error, line_input);
13924           return -99;
13925         }
13926     }
13927
13928   if (src_set == 0)
13929     {
13930       errmsg ("tunnel src address not specified");
13931       return -99;
13932     }
13933   if (dst_set == 0)
13934     {
13935       errmsg ("tunnel dst address not specified");
13936       return -99;
13937     }
13938   if (ipv4_set && ipv6_set)
13939     {
13940       errmsg ("both IPv4 and IPv6 addresses specified");
13941       return -99;
13942     }
13943
13944
13945   M (GRE_ADD_DEL_TUNNEL, mp);
13946
13947   if (ipv4_set)
13948     {
13949       clib_memcpy (&mp->src_address, &src4, 4);
13950       clib_memcpy (&mp->dst_address, &dst4, 4);
13951     }
13952   else
13953     {
13954       clib_memcpy (&mp->src_address, &src6, 16);
13955       clib_memcpy (&mp->dst_address, &dst6, 16);
13956     }
13957   mp->instance = htonl (instance);
13958   mp->outer_fib_id = htonl (outer_fib_id);
13959   mp->is_add = is_add;
13960   mp->session_id = htons ((u16) session_id);
13961   mp->tunnel_type = t_type;
13962   mp->is_ipv6 = ipv6_set;
13963
13964   S (mp);
13965   W (ret);
13966   return ret;
13967 }
13968
13969 static void vl_api_gre_tunnel_details_t_handler
13970   (vl_api_gre_tunnel_details_t * mp)
13971 {
13972   vat_main_t *vam = &vat_main;
13973   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13974   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13975
13976   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13977          ntohl (mp->sw_if_index),
13978          ntohl (mp->instance),
13979          format_ip46_address, &src, IP46_TYPE_ANY,
13980          format_ip46_address, &dst, IP46_TYPE_ANY,
13981          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13982 }
13983
13984 static void vl_api_gre_tunnel_details_t_handler_json
13985   (vl_api_gre_tunnel_details_t * mp)
13986 {
13987   vat_main_t *vam = &vat_main;
13988   vat_json_node_t *node = NULL;
13989   struct in_addr ip4;
13990   struct in6_addr ip6;
13991
13992   if (VAT_JSON_ARRAY != vam->json_tree.type)
13993     {
13994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13995       vat_json_init_array (&vam->json_tree);
13996     }
13997   node = vat_json_array_add (&vam->json_tree);
13998
13999   vat_json_init_object (node);
14000   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14001   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
14002   if (!mp->is_ipv6)
14003     {
14004       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14005       vat_json_object_add_ip4 (node, "src_address", ip4);
14006       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14007       vat_json_object_add_ip4 (node, "dst_address", ip4);
14008     }
14009   else
14010     {
14011       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
14012       vat_json_object_add_ip6 (node, "src_address", ip6);
14013       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
14014       vat_json_object_add_ip6 (node, "dst_address", ip6);
14015     }
14016   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
14017   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
14018   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
14019   vat_json_object_add_uint (node, "session_id", mp->session_id);
14020 }
14021
14022 static int
14023 api_gre_tunnel_dump (vat_main_t * vam)
14024 {
14025   unformat_input_t *i = vam->input;
14026   vl_api_gre_tunnel_dump_t *mp;
14027   vl_api_control_ping_t *mp_ping;
14028   u32 sw_if_index;
14029   u8 sw_if_index_set = 0;
14030   int ret;
14031
14032   /* Parse args required to build the message */
14033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14034     {
14035       if (unformat (i, "sw_if_index %d", &sw_if_index))
14036         sw_if_index_set = 1;
14037       else
14038         break;
14039     }
14040
14041   if (sw_if_index_set == 0)
14042     {
14043       sw_if_index = ~0;
14044     }
14045
14046   if (!vam->json_output)
14047     {
14048       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
14049              "sw_if_index", "instance", "src_address", "dst_address",
14050              "tunnel_type", "outer_fib_id", "session_id");
14051     }
14052
14053   /* Get list of gre-tunnel interfaces */
14054   M (GRE_TUNNEL_DUMP, mp);
14055
14056   mp->sw_if_index = htonl (sw_if_index);
14057
14058   S (mp);
14059
14060   /* Use a control ping for synchronization */
14061   MPING (CONTROL_PING, mp_ping);
14062   S (mp_ping);
14063
14064   W (ret);
14065   return ret;
14066 }
14067
14068 static int
14069 api_l2_fib_clear_table (vat_main_t * vam)
14070 {
14071 //  unformat_input_t * i = vam->input;
14072   vl_api_l2_fib_clear_table_t *mp;
14073   int ret;
14074
14075   M (L2_FIB_CLEAR_TABLE, mp);
14076
14077   S (mp);
14078   W (ret);
14079   return ret;
14080 }
14081
14082 static int
14083 api_l2_interface_efp_filter (vat_main_t * vam)
14084 {
14085   unformat_input_t *i = vam->input;
14086   vl_api_l2_interface_efp_filter_t *mp;
14087   u32 sw_if_index;
14088   u8 enable = 1;
14089   u8 sw_if_index_set = 0;
14090   int ret;
14091
14092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14093     {
14094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14095         sw_if_index_set = 1;
14096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14097         sw_if_index_set = 1;
14098       else if (unformat (i, "enable"))
14099         enable = 1;
14100       else if (unformat (i, "disable"))
14101         enable = 0;
14102       else
14103         {
14104           clib_warning ("parse error '%U'", format_unformat_error, i);
14105           return -99;
14106         }
14107     }
14108
14109   if (sw_if_index_set == 0)
14110     {
14111       errmsg ("missing sw_if_index");
14112       return -99;
14113     }
14114
14115   M (L2_INTERFACE_EFP_FILTER, mp);
14116
14117   mp->sw_if_index = ntohl (sw_if_index);
14118   mp->enable_disable = enable;
14119
14120   S (mp);
14121   W (ret);
14122   return ret;
14123 }
14124
14125 #define foreach_vtr_op                          \
14126 _("disable",  L2_VTR_DISABLED)                  \
14127 _("push-1",  L2_VTR_PUSH_1)                     \
14128 _("push-2",  L2_VTR_PUSH_2)                     \
14129 _("pop-1",  L2_VTR_POP_1)                       \
14130 _("pop-2",  L2_VTR_POP_2)                       \
14131 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14132 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14133 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14134 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14135
14136 static int
14137 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14138 {
14139   unformat_input_t *i = vam->input;
14140   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14141   u32 sw_if_index;
14142   u8 sw_if_index_set = 0;
14143   u8 vtr_op_set = 0;
14144   u32 vtr_op = 0;
14145   u32 push_dot1q = 1;
14146   u32 tag1 = ~0;
14147   u32 tag2 = ~0;
14148   int ret;
14149
14150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14151     {
14152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14153         sw_if_index_set = 1;
14154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14155         sw_if_index_set = 1;
14156       else if (unformat (i, "vtr_op %d", &vtr_op))
14157         vtr_op_set = 1;
14158 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14159       foreach_vtr_op
14160 #undef _
14161         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14162         ;
14163       else if (unformat (i, "tag1 %d", &tag1))
14164         ;
14165       else if (unformat (i, "tag2 %d", &tag2))
14166         ;
14167       else
14168         {
14169           clib_warning ("parse error '%U'", format_unformat_error, i);
14170           return -99;
14171         }
14172     }
14173
14174   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14175     {
14176       errmsg ("missing vtr operation or sw_if_index");
14177       return -99;
14178     }
14179
14180   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14181   mp->sw_if_index = ntohl (sw_if_index);
14182   mp->vtr_op = ntohl (vtr_op);
14183   mp->push_dot1q = ntohl (push_dot1q);
14184   mp->tag1 = ntohl (tag1);
14185   mp->tag2 = ntohl (tag2);
14186
14187   S (mp);
14188   W (ret);
14189   return ret;
14190 }
14191
14192 static int
14193 api_create_vhost_user_if (vat_main_t * vam)
14194 {
14195   unformat_input_t *i = vam->input;
14196   vl_api_create_vhost_user_if_t *mp;
14197   u8 *file_name;
14198   u8 is_server = 0;
14199   u8 file_name_set = 0;
14200   u32 custom_dev_instance = ~0;
14201   u8 hwaddr[6];
14202   u8 use_custom_mac = 0;
14203   u8 disable_mrg_rxbuf = 0;
14204   u8 disable_indirect_desc = 0;
14205   u8 *tag = 0;
14206   int ret;
14207
14208   /* Shut up coverity */
14209   clib_memset (hwaddr, 0, sizeof (hwaddr));
14210
14211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14212     {
14213       if (unformat (i, "socket %s", &file_name))
14214         {
14215           file_name_set = 1;
14216         }
14217       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14218         ;
14219       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14220         use_custom_mac = 1;
14221       else if (unformat (i, "server"))
14222         is_server = 1;
14223       else if (unformat (i, "disable_mrg_rxbuf"))
14224         disable_mrg_rxbuf = 1;
14225       else if (unformat (i, "disable_indirect_desc"))
14226         disable_indirect_desc = 1;
14227       else if (unformat (i, "tag %s", &tag))
14228         ;
14229       else
14230         break;
14231     }
14232
14233   if (file_name_set == 0)
14234     {
14235       errmsg ("missing socket file name");
14236       return -99;
14237     }
14238
14239   if (vec_len (file_name) > 255)
14240     {
14241       errmsg ("socket file name too long");
14242       return -99;
14243     }
14244   vec_add1 (file_name, 0);
14245
14246   M (CREATE_VHOST_USER_IF, mp);
14247
14248   mp->is_server = is_server;
14249   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14250   mp->disable_indirect_desc = disable_indirect_desc;
14251   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14252   vec_free (file_name);
14253   if (custom_dev_instance != ~0)
14254     {
14255       mp->renumber = 1;
14256       mp->custom_dev_instance = ntohl (custom_dev_instance);
14257     }
14258
14259   mp->use_custom_mac = use_custom_mac;
14260   clib_memcpy (mp->mac_address, hwaddr, 6);
14261   if (tag)
14262     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14263   vec_free (tag);
14264
14265   S (mp);
14266   W (ret);
14267   return ret;
14268 }
14269
14270 static int
14271 api_modify_vhost_user_if (vat_main_t * vam)
14272 {
14273   unformat_input_t *i = vam->input;
14274   vl_api_modify_vhost_user_if_t *mp;
14275   u8 *file_name;
14276   u8 is_server = 0;
14277   u8 file_name_set = 0;
14278   u32 custom_dev_instance = ~0;
14279   u8 sw_if_index_set = 0;
14280   u32 sw_if_index = (u32) ~ 0;
14281   int ret;
14282
14283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14284     {
14285       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14286         sw_if_index_set = 1;
14287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14288         sw_if_index_set = 1;
14289       else if (unformat (i, "socket %s", &file_name))
14290         {
14291           file_name_set = 1;
14292         }
14293       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14294         ;
14295       else if (unformat (i, "server"))
14296         is_server = 1;
14297       else
14298         break;
14299     }
14300
14301   if (sw_if_index_set == 0)
14302     {
14303       errmsg ("missing sw_if_index or interface name");
14304       return -99;
14305     }
14306
14307   if (file_name_set == 0)
14308     {
14309       errmsg ("missing socket file name");
14310       return -99;
14311     }
14312
14313   if (vec_len (file_name) > 255)
14314     {
14315       errmsg ("socket file name too long");
14316       return -99;
14317     }
14318   vec_add1 (file_name, 0);
14319
14320   M (MODIFY_VHOST_USER_IF, mp);
14321
14322   mp->sw_if_index = ntohl (sw_if_index);
14323   mp->is_server = is_server;
14324   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14325   vec_free (file_name);
14326   if (custom_dev_instance != ~0)
14327     {
14328       mp->renumber = 1;
14329       mp->custom_dev_instance = ntohl (custom_dev_instance);
14330     }
14331
14332   S (mp);
14333   W (ret);
14334   return ret;
14335 }
14336
14337 static int
14338 api_delete_vhost_user_if (vat_main_t * vam)
14339 {
14340   unformat_input_t *i = vam->input;
14341   vl_api_delete_vhost_user_if_t *mp;
14342   u32 sw_if_index = ~0;
14343   u8 sw_if_index_set = 0;
14344   int ret;
14345
14346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14347     {
14348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14349         sw_if_index_set = 1;
14350       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14351         sw_if_index_set = 1;
14352       else
14353         break;
14354     }
14355
14356   if (sw_if_index_set == 0)
14357     {
14358       errmsg ("missing sw_if_index or interface name");
14359       return -99;
14360     }
14361
14362
14363   M (DELETE_VHOST_USER_IF, mp);
14364
14365   mp->sw_if_index = ntohl (sw_if_index);
14366
14367   S (mp);
14368   W (ret);
14369   return ret;
14370 }
14371
14372 static void vl_api_sw_interface_vhost_user_details_t_handler
14373   (vl_api_sw_interface_vhost_user_details_t * mp)
14374 {
14375   vat_main_t *vam = &vat_main;
14376
14377   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14378          (char *) mp->interface_name,
14379          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14380          clib_net_to_host_u64 (mp->features), mp->is_server,
14381          ntohl (mp->num_regions), (char *) mp->sock_filename);
14382   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14383 }
14384
14385 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14386   (vl_api_sw_interface_vhost_user_details_t * mp)
14387 {
14388   vat_main_t *vam = &vat_main;
14389   vat_json_node_t *node = NULL;
14390
14391   if (VAT_JSON_ARRAY != vam->json_tree.type)
14392     {
14393       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14394       vat_json_init_array (&vam->json_tree);
14395     }
14396   node = vat_json_array_add (&vam->json_tree);
14397
14398   vat_json_init_object (node);
14399   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14400   vat_json_object_add_string_copy (node, "interface_name",
14401                                    mp->interface_name);
14402   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14403                             ntohl (mp->virtio_net_hdr_sz));
14404   vat_json_object_add_uint (node, "features",
14405                             clib_net_to_host_u64 (mp->features));
14406   vat_json_object_add_uint (node, "is_server", mp->is_server);
14407   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14408   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14409   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14410 }
14411
14412 static int
14413 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14414 {
14415   vl_api_sw_interface_vhost_user_dump_t *mp;
14416   vl_api_control_ping_t *mp_ping;
14417   int ret;
14418   print (vam->ofp,
14419          "Interface name            idx hdr_sz features server regions filename");
14420
14421   /* Get list of vhost-user interfaces */
14422   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14423   S (mp);
14424
14425   /* Use a control ping for synchronization */
14426   MPING (CONTROL_PING, mp_ping);
14427   S (mp_ping);
14428
14429   W (ret);
14430   return ret;
14431 }
14432
14433 static int
14434 api_show_version (vat_main_t * vam)
14435 {
14436   vl_api_show_version_t *mp;
14437   int ret;
14438
14439   M (SHOW_VERSION, mp);
14440
14441   S (mp);
14442   W (ret);
14443   return ret;
14444 }
14445
14446
14447 static int
14448 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14449 {
14450   unformat_input_t *line_input = vam->input;
14451   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14452   ip4_address_t local4, remote4;
14453   ip6_address_t local6, remote6;
14454   u8 is_add = 1;
14455   u8 ipv4_set = 0, ipv6_set = 0;
14456   u8 local_set = 0;
14457   u8 remote_set = 0;
14458   u8 grp_set = 0;
14459   u32 mcast_sw_if_index = ~0;
14460   u32 encap_vrf_id = 0;
14461   u32 decap_vrf_id = 0;
14462   u8 protocol = ~0;
14463   u32 vni;
14464   u8 vni_set = 0;
14465   int ret;
14466
14467   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14468   clib_memset (&local4, 0, sizeof local4);
14469   clib_memset (&remote4, 0, sizeof remote4);
14470   clib_memset (&local6, 0, sizeof local6);
14471   clib_memset (&remote6, 0, sizeof remote6);
14472
14473   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14474     {
14475       if (unformat (line_input, "del"))
14476         is_add = 0;
14477       else if (unformat (line_input, "local %U",
14478                          unformat_ip4_address, &local4))
14479         {
14480           local_set = 1;
14481           ipv4_set = 1;
14482         }
14483       else if (unformat (line_input, "remote %U",
14484                          unformat_ip4_address, &remote4))
14485         {
14486           remote_set = 1;
14487           ipv4_set = 1;
14488         }
14489       else if (unformat (line_input, "local %U",
14490                          unformat_ip6_address, &local6))
14491         {
14492           local_set = 1;
14493           ipv6_set = 1;
14494         }
14495       else if (unformat (line_input, "remote %U",
14496                          unformat_ip6_address, &remote6))
14497         {
14498           remote_set = 1;
14499           ipv6_set = 1;
14500         }
14501       else if (unformat (line_input, "group %U %U",
14502                          unformat_ip4_address, &remote4,
14503                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14504         {
14505           grp_set = remote_set = 1;
14506           ipv4_set = 1;
14507         }
14508       else if (unformat (line_input, "group %U",
14509                          unformat_ip4_address, &remote4))
14510         {
14511           grp_set = remote_set = 1;
14512           ipv4_set = 1;
14513         }
14514       else if (unformat (line_input, "group %U %U",
14515                          unformat_ip6_address, &remote6,
14516                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14517         {
14518           grp_set = remote_set = 1;
14519           ipv6_set = 1;
14520         }
14521       else if (unformat (line_input, "group %U",
14522                          unformat_ip6_address, &remote6))
14523         {
14524           grp_set = remote_set = 1;
14525           ipv6_set = 1;
14526         }
14527       else
14528         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14529         ;
14530       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14531         ;
14532       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14533         ;
14534       else if (unformat (line_input, "vni %d", &vni))
14535         vni_set = 1;
14536       else if (unformat (line_input, "next-ip4"))
14537         protocol = 1;
14538       else if (unformat (line_input, "next-ip6"))
14539         protocol = 2;
14540       else if (unformat (line_input, "next-ethernet"))
14541         protocol = 3;
14542       else if (unformat (line_input, "next-nsh"))
14543         protocol = 4;
14544       else
14545         {
14546           errmsg ("parse error '%U'", format_unformat_error, line_input);
14547           return -99;
14548         }
14549     }
14550
14551   if (local_set == 0)
14552     {
14553       errmsg ("tunnel local address not specified");
14554       return -99;
14555     }
14556   if (remote_set == 0)
14557     {
14558       errmsg ("tunnel remote address not specified");
14559       return -99;
14560     }
14561   if (grp_set && mcast_sw_if_index == ~0)
14562     {
14563       errmsg ("tunnel nonexistent multicast device");
14564       return -99;
14565     }
14566   if (ipv4_set && ipv6_set)
14567     {
14568       errmsg ("both IPv4 and IPv6 addresses specified");
14569       return -99;
14570     }
14571
14572   if (vni_set == 0)
14573     {
14574       errmsg ("vni not specified");
14575       return -99;
14576     }
14577
14578   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14579
14580
14581   if (ipv6_set)
14582     {
14583       clib_memcpy (&mp->local, &local6, sizeof (local6));
14584       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14585     }
14586   else
14587     {
14588       clib_memcpy (&mp->local, &local4, sizeof (local4));
14589       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14590     }
14591
14592   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14593   mp->encap_vrf_id = ntohl (encap_vrf_id);
14594   mp->decap_vrf_id = ntohl (decap_vrf_id);
14595   mp->protocol = protocol;
14596   mp->vni = ntohl (vni);
14597   mp->is_add = is_add;
14598   mp->is_ipv6 = ipv6_set;
14599
14600   S (mp);
14601   W (ret);
14602   return ret;
14603 }
14604
14605 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14606   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14607 {
14608   vat_main_t *vam = &vat_main;
14609   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14610   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14611
14612   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14613          ntohl (mp->sw_if_index),
14614          format_ip46_address, &local, IP46_TYPE_ANY,
14615          format_ip46_address, &remote, IP46_TYPE_ANY,
14616          ntohl (mp->vni), mp->protocol,
14617          ntohl (mp->mcast_sw_if_index),
14618          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14619 }
14620
14621
14622 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14623   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14624 {
14625   vat_main_t *vam = &vat_main;
14626   vat_json_node_t *node = NULL;
14627   struct in_addr ip4;
14628   struct in6_addr ip6;
14629
14630   if (VAT_JSON_ARRAY != vam->json_tree.type)
14631     {
14632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14633       vat_json_init_array (&vam->json_tree);
14634     }
14635   node = vat_json_array_add (&vam->json_tree);
14636
14637   vat_json_init_object (node);
14638   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14639   if (mp->is_ipv6)
14640     {
14641       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14642       vat_json_object_add_ip6 (node, "local", ip6);
14643       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14644       vat_json_object_add_ip6 (node, "remote", ip6);
14645     }
14646   else
14647     {
14648       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14649       vat_json_object_add_ip4 (node, "local", ip4);
14650       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14651       vat_json_object_add_ip4 (node, "remote", ip4);
14652     }
14653   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14654   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14655   vat_json_object_add_uint (node, "mcast_sw_if_index",
14656                             ntohl (mp->mcast_sw_if_index));
14657   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14658   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14659   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14660 }
14661
14662 static int
14663 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14664 {
14665   unformat_input_t *i = vam->input;
14666   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14667   vl_api_control_ping_t *mp_ping;
14668   u32 sw_if_index;
14669   u8 sw_if_index_set = 0;
14670   int ret;
14671
14672   /* Parse args required to build the message */
14673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14674     {
14675       if (unformat (i, "sw_if_index %d", &sw_if_index))
14676         sw_if_index_set = 1;
14677       else
14678         break;
14679     }
14680
14681   if (sw_if_index_set == 0)
14682     {
14683       sw_if_index = ~0;
14684     }
14685
14686   if (!vam->json_output)
14687     {
14688       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14689              "sw_if_index", "local", "remote", "vni",
14690              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14691     }
14692
14693   /* Get list of vxlan-tunnel interfaces */
14694   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14695
14696   mp->sw_if_index = htonl (sw_if_index);
14697
14698   S (mp);
14699
14700   /* Use a control ping for synchronization */
14701   MPING (CONTROL_PING, mp_ping);
14702   S (mp_ping);
14703
14704   W (ret);
14705   return ret;
14706 }
14707
14708 static void vl_api_l2_fib_table_details_t_handler
14709   (vl_api_l2_fib_table_details_t * mp)
14710 {
14711   vat_main_t *vam = &vat_main;
14712
14713   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14714          "       %d       %d     %d",
14715          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14716          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14717          mp->bvi_mac);
14718 }
14719
14720 static void vl_api_l2_fib_table_details_t_handler_json
14721   (vl_api_l2_fib_table_details_t * mp)
14722 {
14723   vat_main_t *vam = &vat_main;
14724   vat_json_node_t *node = NULL;
14725
14726   if (VAT_JSON_ARRAY != vam->json_tree.type)
14727     {
14728       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14729       vat_json_init_array (&vam->json_tree);
14730     }
14731   node = vat_json_array_add (&vam->json_tree);
14732
14733   vat_json_init_object (node);
14734   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14735   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14736   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14737   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14738   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14739   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14740 }
14741
14742 static int
14743 api_l2_fib_table_dump (vat_main_t * vam)
14744 {
14745   unformat_input_t *i = vam->input;
14746   vl_api_l2_fib_table_dump_t *mp;
14747   vl_api_control_ping_t *mp_ping;
14748   u32 bd_id;
14749   u8 bd_id_set = 0;
14750   int ret;
14751
14752   /* Parse args required to build the message */
14753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14754     {
14755       if (unformat (i, "bd_id %d", &bd_id))
14756         bd_id_set = 1;
14757       else
14758         break;
14759     }
14760
14761   if (bd_id_set == 0)
14762     {
14763       errmsg ("missing bridge domain");
14764       return -99;
14765     }
14766
14767   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14768
14769   /* Get list of l2 fib entries */
14770   M (L2_FIB_TABLE_DUMP, mp);
14771
14772   mp->bd_id = ntohl (bd_id);
14773   S (mp);
14774
14775   /* Use a control ping for synchronization */
14776   MPING (CONTROL_PING, mp_ping);
14777   S (mp_ping);
14778
14779   W (ret);
14780   return ret;
14781 }
14782
14783
14784 static int
14785 api_interface_name_renumber (vat_main_t * vam)
14786 {
14787   unformat_input_t *line_input = vam->input;
14788   vl_api_interface_name_renumber_t *mp;
14789   u32 sw_if_index = ~0;
14790   u32 new_show_dev_instance = ~0;
14791   int ret;
14792
14793   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14794     {
14795       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14796                     &sw_if_index))
14797         ;
14798       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14799         ;
14800       else if (unformat (line_input, "new_show_dev_instance %d",
14801                          &new_show_dev_instance))
14802         ;
14803       else
14804         break;
14805     }
14806
14807   if (sw_if_index == ~0)
14808     {
14809       errmsg ("missing interface name or sw_if_index");
14810       return -99;
14811     }
14812
14813   if (new_show_dev_instance == ~0)
14814     {
14815       errmsg ("missing new_show_dev_instance");
14816       return -99;
14817     }
14818
14819   M (INTERFACE_NAME_RENUMBER, mp);
14820
14821   mp->sw_if_index = ntohl (sw_if_index);
14822   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14823
14824   S (mp);
14825   W (ret);
14826   return ret;
14827 }
14828
14829 static int
14830 api_ip_probe_neighbor (vat_main_t * vam)
14831 {
14832   unformat_input_t *i = vam->input;
14833   vl_api_ip_probe_neighbor_t *mp;
14834   u8 int_set = 0;
14835   u8 adr_set = 0;
14836   u8 is_ipv6 = 0;
14837   u8 dst_adr[16];
14838   u32 sw_if_index;
14839   int ret;
14840
14841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14842     {
14843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14844         int_set = 1;
14845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14846         int_set = 1;
14847       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14848         adr_set = 1;
14849       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14850         {
14851           adr_set = 1;
14852           is_ipv6 = 1;
14853         }
14854       else
14855         break;
14856     }
14857
14858   if (int_set == 0)
14859     {
14860       errmsg ("missing interface");
14861       return -99;
14862     }
14863
14864   if (adr_set == 0)
14865     {
14866       errmsg ("missing addresses");
14867       return -99;
14868     }
14869
14870   M (IP_PROBE_NEIGHBOR, mp);
14871
14872   mp->sw_if_index = ntohl (sw_if_index);
14873   mp->is_ipv6 = is_ipv6;
14874   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14875
14876   S (mp);
14877   W (ret);
14878   return ret;
14879 }
14880
14881 static int
14882 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14883 {
14884   unformat_input_t *i = vam->input;
14885   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14886   u8 mode = IP_SCAN_V46_NEIGHBORS;
14887   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14888   int ret;
14889
14890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14891     {
14892       if (unformat (i, "ip4"))
14893         mode = IP_SCAN_V4_NEIGHBORS;
14894       else if (unformat (i, "ip6"))
14895         mode = IP_SCAN_V6_NEIGHBORS;
14896       if (unformat (i, "both"))
14897         mode = IP_SCAN_V46_NEIGHBORS;
14898       else if (unformat (i, "disable"))
14899         mode = IP_SCAN_DISABLED;
14900       else if (unformat (i, "interval %d", &interval))
14901         ;
14902       else if (unformat (i, "max-time %d", &time))
14903         ;
14904       else if (unformat (i, "max-update %d", &update))
14905         ;
14906       else if (unformat (i, "delay %d", &delay))
14907         ;
14908       else if (unformat (i, "stale %d", &stale))
14909         ;
14910       else
14911         break;
14912     }
14913
14914   if (interval > 255)
14915     {
14916       errmsg ("interval cannot exceed 255 minutes.");
14917       return -99;
14918     }
14919   if (time > 255)
14920     {
14921       errmsg ("max-time cannot exceed 255 usec.");
14922       return -99;
14923     }
14924   if (update > 255)
14925     {
14926       errmsg ("max-update cannot exceed 255.");
14927       return -99;
14928     }
14929   if (delay > 255)
14930     {
14931       errmsg ("delay cannot exceed 255 msec.");
14932       return -99;
14933     }
14934   if (stale > 255)
14935     {
14936       errmsg ("stale cannot exceed 255 minutes.");
14937       return -99;
14938     }
14939
14940   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14941   mp->mode = mode;
14942   mp->scan_interval = interval;
14943   mp->max_proc_time = time;
14944   mp->max_update = update;
14945   mp->scan_int_delay = delay;
14946   mp->stale_threshold = stale;
14947
14948   S (mp);
14949   W (ret);
14950   return ret;
14951 }
14952
14953 static int
14954 api_want_ip4_arp_events (vat_main_t * vam)
14955 {
14956   unformat_input_t *line_input = vam->input;
14957   vl_api_want_ip4_arp_events_t *mp;
14958   ip4_address_t address;
14959   int address_set = 0;
14960   u32 enable_disable = 1;
14961   int ret;
14962
14963   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14964     {
14965       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14966         address_set = 1;
14967       else if (unformat (line_input, "del"))
14968         enable_disable = 0;
14969       else
14970         break;
14971     }
14972
14973   if (address_set == 0)
14974     {
14975       errmsg ("missing addresses");
14976       return -99;
14977     }
14978
14979   M (WANT_IP4_ARP_EVENTS, mp);
14980   mp->enable_disable = enable_disable;
14981   mp->pid = htonl (getpid ());
14982   mp->address = address.as_u32;
14983
14984   S (mp);
14985   W (ret);
14986   return ret;
14987 }
14988
14989 static int
14990 api_want_ip6_nd_events (vat_main_t * vam)
14991 {
14992   unformat_input_t *line_input = vam->input;
14993   vl_api_want_ip6_nd_events_t *mp;
14994   ip6_address_t address;
14995   int address_set = 0;
14996   u32 enable_disable = 1;
14997   int ret;
14998
14999   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15000     {
15001       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
15002         address_set = 1;
15003       else if (unformat (line_input, "del"))
15004         enable_disable = 0;
15005       else
15006         break;
15007     }
15008
15009   if (address_set == 0)
15010     {
15011       errmsg ("missing addresses");
15012       return -99;
15013     }
15014
15015   M (WANT_IP6_ND_EVENTS, mp);
15016   mp->enable_disable = enable_disable;
15017   mp->pid = htonl (getpid ());
15018   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
15019
15020   S (mp);
15021   W (ret);
15022   return ret;
15023 }
15024
15025 static int
15026 api_want_l2_macs_events (vat_main_t * vam)
15027 {
15028   unformat_input_t *line_input = vam->input;
15029   vl_api_want_l2_macs_events_t *mp;
15030   u8 enable_disable = 1;
15031   u32 scan_delay = 0;
15032   u32 max_macs_in_event = 0;
15033   u32 learn_limit = 0;
15034   int ret;
15035
15036   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15037     {
15038       if (unformat (line_input, "learn-limit %d", &learn_limit))
15039         ;
15040       else if (unformat (line_input, "scan-delay %d", &scan_delay))
15041         ;
15042       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
15043         ;
15044       else if (unformat (line_input, "disable"))
15045         enable_disable = 0;
15046       else
15047         break;
15048     }
15049
15050   M (WANT_L2_MACS_EVENTS, mp);
15051   mp->enable_disable = enable_disable;
15052   mp->pid = htonl (getpid ());
15053   mp->learn_limit = htonl (learn_limit);
15054   mp->scan_delay = (u8) scan_delay;
15055   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15056   S (mp);
15057   W (ret);
15058   return ret;
15059 }
15060
15061 static int
15062 api_input_acl_set_interface (vat_main_t * vam)
15063 {
15064   unformat_input_t *i = vam->input;
15065   vl_api_input_acl_set_interface_t *mp;
15066   u32 sw_if_index;
15067   int sw_if_index_set;
15068   u32 ip4_table_index = ~0;
15069   u32 ip6_table_index = ~0;
15070   u32 l2_table_index = ~0;
15071   u8 is_add = 1;
15072   int ret;
15073
15074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15075     {
15076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15077         sw_if_index_set = 1;
15078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15079         sw_if_index_set = 1;
15080       else if (unformat (i, "del"))
15081         is_add = 0;
15082       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15083         ;
15084       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15085         ;
15086       else if (unformat (i, "l2-table %d", &l2_table_index))
15087         ;
15088       else
15089         {
15090           clib_warning ("parse error '%U'", format_unformat_error, i);
15091           return -99;
15092         }
15093     }
15094
15095   if (sw_if_index_set == 0)
15096     {
15097       errmsg ("missing interface name or sw_if_index");
15098       return -99;
15099     }
15100
15101   M (INPUT_ACL_SET_INTERFACE, mp);
15102
15103   mp->sw_if_index = ntohl (sw_if_index);
15104   mp->ip4_table_index = ntohl (ip4_table_index);
15105   mp->ip6_table_index = ntohl (ip6_table_index);
15106   mp->l2_table_index = ntohl (l2_table_index);
15107   mp->is_add = is_add;
15108
15109   S (mp);
15110   W (ret);
15111   return ret;
15112 }
15113
15114 static int
15115 api_output_acl_set_interface (vat_main_t * vam)
15116 {
15117   unformat_input_t *i = vam->input;
15118   vl_api_output_acl_set_interface_t *mp;
15119   u32 sw_if_index;
15120   int sw_if_index_set;
15121   u32 ip4_table_index = ~0;
15122   u32 ip6_table_index = ~0;
15123   u32 l2_table_index = ~0;
15124   u8 is_add = 1;
15125   int ret;
15126
15127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15128     {
15129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15130         sw_if_index_set = 1;
15131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15132         sw_if_index_set = 1;
15133       else if (unformat (i, "del"))
15134         is_add = 0;
15135       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15136         ;
15137       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15138         ;
15139       else if (unformat (i, "l2-table %d", &l2_table_index))
15140         ;
15141       else
15142         {
15143           clib_warning ("parse error '%U'", format_unformat_error, i);
15144           return -99;
15145         }
15146     }
15147
15148   if (sw_if_index_set == 0)
15149     {
15150       errmsg ("missing interface name or sw_if_index");
15151       return -99;
15152     }
15153
15154   M (OUTPUT_ACL_SET_INTERFACE, mp);
15155
15156   mp->sw_if_index = ntohl (sw_if_index);
15157   mp->ip4_table_index = ntohl (ip4_table_index);
15158   mp->ip6_table_index = ntohl (ip6_table_index);
15159   mp->l2_table_index = ntohl (l2_table_index);
15160   mp->is_add = is_add;
15161
15162   S (mp);
15163   W (ret);
15164   return ret;
15165 }
15166
15167 static int
15168 api_ip_address_dump (vat_main_t * vam)
15169 {
15170   unformat_input_t *i = vam->input;
15171   vl_api_ip_address_dump_t *mp;
15172   vl_api_control_ping_t *mp_ping;
15173   u32 sw_if_index = ~0;
15174   u8 sw_if_index_set = 0;
15175   u8 ipv4_set = 0;
15176   u8 ipv6_set = 0;
15177   int ret;
15178
15179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15180     {
15181       if (unformat (i, "sw_if_index %d", &sw_if_index))
15182         sw_if_index_set = 1;
15183       else
15184         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15185         sw_if_index_set = 1;
15186       else if (unformat (i, "ipv4"))
15187         ipv4_set = 1;
15188       else if (unformat (i, "ipv6"))
15189         ipv6_set = 1;
15190       else
15191         break;
15192     }
15193
15194   if (ipv4_set && ipv6_set)
15195     {
15196       errmsg ("ipv4 and ipv6 flags cannot be both set");
15197       return -99;
15198     }
15199
15200   if ((!ipv4_set) && (!ipv6_set))
15201     {
15202       errmsg ("no ipv4 nor ipv6 flag set");
15203       return -99;
15204     }
15205
15206   if (sw_if_index_set == 0)
15207     {
15208       errmsg ("missing interface name or sw_if_index");
15209       return -99;
15210     }
15211
15212   vam->current_sw_if_index = sw_if_index;
15213   vam->is_ipv6 = ipv6_set;
15214
15215   M (IP_ADDRESS_DUMP, mp);
15216   mp->sw_if_index = ntohl (sw_if_index);
15217   mp->is_ipv6 = ipv6_set;
15218   S (mp);
15219
15220   /* Use a control ping for synchronization */
15221   MPING (CONTROL_PING, mp_ping);
15222   S (mp_ping);
15223
15224   W (ret);
15225   return ret;
15226 }
15227
15228 static int
15229 api_ip_dump (vat_main_t * vam)
15230 {
15231   vl_api_ip_dump_t *mp;
15232   vl_api_control_ping_t *mp_ping;
15233   unformat_input_t *in = vam->input;
15234   int ipv4_set = 0;
15235   int ipv6_set = 0;
15236   int is_ipv6;
15237   int i;
15238   int ret;
15239
15240   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15241     {
15242       if (unformat (in, "ipv4"))
15243         ipv4_set = 1;
15244       else if (unformat (in, "ipv6"))
15245         ipv6_set = 1;
15246       else
15247         break;
15248     }
15249
15250   if (ipv4_set && ipv6_set)
15251     {
15252       errmsg ("ipv4 and ipv6 flags cannot be both set");
15253       return -99;
15254     }
15255
15256   if ((!ipv4_set) && (!ipv6_set))
15257     {
15258       errmsg ("no ipv4 nor ipv6 flag set");
15259       return -99;
15260     }
15261
15262   is_ipv6 = ipv6_set;
15263   vam->is_ipv6 = is_ipv6;
15264
15265   /* free old data */
15266   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15267     {
15268       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15269     }
15270   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15271
15272   M (IP_DUMP, mp);
15273   mp->is_ipv6 = ipv6_set;
15274   S (mp);
15275
15276   /* Use a control ping for synchronization */
15277   MPING (CONTROL_PING, mp_ping);
15278   S (mp_ping);
15279
15280   W (ret);
15281   return ret;
15282 }
15283
15284 static int
15285 api_ipsec_spd_add_del (vat_main_t * vam)
15286 {
15287   unformat_input_t *i = vam->input;
15288   vl_api_ipsec_spd_add_del_t *mp;
15289   u32 spd_id = ~0;
15290   u8 is_add = 1;
15291   int ret;
15292
15293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15294     {
15295       if (unformat (i, "spd_id %d", &spd_id))
15296         ;
15297       else if (unformat (i, "del"))
15298         is_add = 0;
15299       else
15300         {
15301           clib_warning ("parse error '%U'", format_unformat_error, i);
15302           return -99;
15303         }
15304     }
15305   if (spd_id == ~0)
15306     {
15307       errmsg ("spd_id must be set");
15308       return -99;
15309     }
15310
15311   M (IPSEC_SPD_ADD_DEL, mp);
15312
15313   mp->spd_id = ntohl (spd_id);
15314   mp->is_add = is_add;
15315
15316   S (mp);
15317   W (ret);
15318   return ret;
15319 }
15320
15321 static int
15322 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15323 {
15324   unformat_input_t *i = vam->input;
15325   vl_api_ipsec_interface_add_del_spd_t *mp;
15326   u32 sw_if_index;
15327   u8 sw_if_index_set = 0;
15328   u32 spd_id = (u32) ~ 0;
15329   u8 is_add = 1;
15330   int ret;
15331
15332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15333     {
15334       if (unformat (i, "del"))
15335         is_add = 0;
15336       else if (unformat (i, "spd_id %d", &spd_id))
15337         ;
15338       else
15339         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15340         sw_if_index_set = 1;
15341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15342         sw_if_index_set = 1;
15343       else
15344         {
15345           clib_warning ("parse error '%U'", format_unformat_error, i);
15346           return -99;
15347         }
15348
15349     }
15350
15351   if (spd_id == (u32) ~ 0)
15352     {
15353       errmsg ("spd_id must be set");
15354       return -99;
15355     }
15356
15357   if (sw_if_index_set == 0)
15358     {
15359       errmsg ("missing interface name or sw_if_index");
15360       return -99;
15361     }
15362
15363   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15364
15365   mp->spd_id = ntohl (spd_id);
15366   mp->sw_if_index = ntohl (sw_if_index);
15367   mp->is_add = is_add;
15368
15369   S (mp);
15370   W (ret);
15371   return ret;
15372 }
15373
15374 static int
15375 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15376 {
15377   unformat_input_t *i = vam->input;
15378   vl_api_ipsec_spd_add_del_entry_t *mp;
15379   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15380   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15381   i32 priority = 0;
15382   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15383   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15384   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15385   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15386   int ret;
15387
15388   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15389   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15390   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15391   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15392   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15393   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15394
15395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15396     {
15397       if (unformat (i, "del"))
15398         is_add = 0;
15399       if (unformat (i, "outbound"))
15400         is_outbound = 1;
15401       if (unformat (i, "inbound"))
15402         is_outbound = 0;
15403       else if (unformat (i, "spd_id %d", &spd_id))
15404         ;
15405       else if (unformat (i, "sa_id %d", &sa_id))
15406         ;
15407       else if (unformat (i, "priority %d", &priority))
15408         ;
15409       else if (unformat (i, "protocol %d", &protocol))
15410         ;
15411       else if (unformat (i, "lport_start %d", &lport_start))
15412         ;
15413       else if (unformat (i, "lport_stop %d", &lport_stop))
15414         ;
15415       else if (unformat (i, "rport_start %d", &rport_start))
15416         ;
15417       else if (unformat (i, "rport_stop %d", &rport_stop))
15418         ;
15419       else
15420         if (unformat
15421             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15422         {
15423           is_ipv6 = 0;
15424           is_ip_any = 0;
15425         }
15426       else
15427         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15428         {
15429           is_ipv6 = 0;
15430           is_ip_any = 0;
15431         }
15432       else
15433         if (unformat
15434             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15435         {
15436           is_ipv6 = 0;
15437           is_ip_any = 0;
15438         }
15439       else
15440         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15441         {
15442           is_ipv6 = 0;
15443           is_ip_any = 0;
15444         }
15445       else
15446         if (unformat
15447             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15448         {
15449           is_ipv6 = 1;
15450           is_ip_any = 0;
15451         }
15452       else
15453         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15454         {
15455           is_ipv6 = 1;
15456           is_ip_any = 0;
15457         }
15458       else
15459         if (unformat
15460             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15461         {
15462           is_ipv6 = 1;
15463           is_ip_any = 0;
15464         }
15465       else
15466         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15467         {
15468           is_ipv6 = 1;
15469           is_ip_any = 0;
15470         }
15471       else
15472         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15473         {
15474           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15475             {
15476               clib_warning ("unsupported action: 'resolve'");
15477               return -99;
15478             }
15479         }
15480       else
15481         {
15482           clib_warning ("parse error '%U'", format_unformat_error, i);
15483           return -99;
15484         }
15485
15486     }
15487
15488   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15489
15490   mp->spd_id = ntohl (spd_id);
15491   mp->priority = ntohl (priority);
15492   mp->is_outbound = is_outbound;
15493
15494   mp->is_ipv6 = is_ipv6;
15495   if (is_ipv6 || is_ip_any)
15496     {
15497       clib_memcpy (mp->remote_address_start, &raddr6_start,
15498                    sizeof (ip6_address_t));
15499       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15500                    sizeof (ip6_address_t));
15501       clib_memcpy (mp->local_address_start, &laddr6_start,
15502                    sizeof (ip6_address_t));
15503       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15504                    sizeof (ip6_address_t));
15505     }
15506   else
15507     {
15508       clib_memcpy (mp->remote_address_start, &raddr4_start,
15509                    sizeof (ip4_address_t));
15510       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15511                    sizeof (ip4_address_t));
15512       clib_memcpy (mp->local_address_start, &laddr4_start,
15513                    sizeof (ip4_address_t));
15514       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15515                    sizeof (ip4_address_t));
15516     }
15517   mp->protocol = (u8) protocol;
15518   mp->local_port_start = ntohs ((u16) lport_start);
15519   mp->local_port_stop = ntohs ((u16) lport_stop);
15520   mp->remote_port_start = ntohs ((u16) rport_start);
15521   mp->remote_port_stop = ntohs ((u16) rport_stop);
15522   mp->policy = (u8) policy;
15523   mp->sa_id = ntohl (sa_id);
15524   mp->is_add = is_add;
15525   mp->is_ip_any = is_ip_any;
15526   S (mp);
15527   W (ret);
15528   return ret;
15529 }
15530
15531 static int
15532 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15533 {
15534   unformat_input_t *i = vam->input;
15535   vl_api_ipsec_sad_add_del_entry_t *mp;
15536   u32 sad_id = 0, spi = 0;
15537   u8 *ck = 0, *ik = 0;
15538   u8 is_add = 1;
15539
15540   u8 protocol = IPSEC_PROTOCOL_AH;
15541   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15542   u32 crypto_alg = 0, integ_alg = 0;
15543   ip4_address_t tun_src4;
15544   ip4_address_t tun_dst4;
15545   ip6_address_t tun_src6;
15546   ip6_address_t tun_dst6;
15547   int ret;
15548
15549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15550     {
15551       if (unformat (i, "del"))
15552         is_add = 0;
15553       else if (unformat (i, "sad_id %d", &sad_id))
15554         ;
15555       else if (unformat (i, "spi %d", &spi))
15556         ;
15557       else if (unformat (i, "esp"))
15558         protocol = IPSEC_PROTOCOL_ESP;
15559       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15560         {
15561           is_tunnel = 1;
15562           is_tunnel_ipv6 = 0;
15563         }
15564       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15565         {
15566           is_tunnel = 1;
15567           is_tunnel_ipv6 = 0;
15568         }
15569       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15570         {
15571           is_tunnel = 1;
15572           is_tunnel_ipv6 = 1;
15573         }
15574       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15575         {
15576           is_tunnel = 1;
15577           is_tunnel_ipv6 = 1;
15578         }
15579       else
15580         if (unformat
15581             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15582         {
15583           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15584             {
15585               clib_warning ("unsupported crypto-alg: '%U'",
15586                             format_ipsec_crypto_alg, crypto_alg);
15587               return -99;
15588             }
15589         }
15590       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15591         ;
15592       else
15593         if (unformat
15594             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15595         {
15596           if (integ_alg >= IPSEC_INTEG_N_ALG)
15597             {
15598               clib_warning ("unsupported integ-alg: '%U'",
15599                             format_ipsec_integ_alg, integ_alg);
15600               return -99;
15601             }
15602         }
15603       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15604         ;
15605       else
15606         {
15607           clib_warning ("parse error '%U'", format_unformat_error, i);
15608           return -99;
15609         }
15610
15611     }
15612
15613   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15614
15615   mp->sad_id = ntohl (sad_id);
15616   mp->is_add = is_add;
15617   mp->protocol = protocol;
15618   mp->spi = ntohl (spi);
15619   mp->is_tunnel = is_tunnel;
15620   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15621   mp->crypto_algorithm = crypto_alg;
15622   mp->integrity_algorithm = integ_alg;
15623   mp->crypto_key_length = vec_len (ck);
15624   mp->integrity_key_length = vec_len (ik);
15625
15626   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15627     mp->crypto_key_length = sizeof (mp->crypto_key);
15628
15629   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15630     mp->integrity_key_length = sizeof (mp->integrity_key);
15631
15632   if (ck)
15633     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15634   if (ik)
15635     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15636
15637   if (is_tunnel)
15638     {
15639       if (is_tunnel_ipv6)
15640         {
15641           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15642                        sizeof (ip6_address_t));
15643           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15644                        sizeof (ip6_address_t));
15645         }
15646       else
15647         {
15648           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15649                        sizeof (ip4_address_t));
15650           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15651                        sizeof (ip4_address_t));
15652         }
15653     }
15654
15655   S (mp);
15656   W (ret);
15657   return ret;
15658 }
15659
15660 static int
15661 api_ipsec_sa_set_key (vat_main_t * vam)
15662 {
15663   unformat_input_t *i = vam->input;
15664   vl_api_ipsec_sa_set_key_t *mp;
15665   u32 sa_id;
15666   u8 *ck = 0, *ik = 0;
15667   int ret;
15668
15669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (i, "sa_id %d", &sa_id))
15672         ;
15673       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15674         ;
15675       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15676         ;
15677       else
15678         {
15679           clib_warning ("parse error '%U'", format_unformat_error, i);
15680           return -99;
15681         }
15682     }
15683
15684   M (IPSEC_SA_SET_KEY, mp);
15685
15686   mp->sa_id = ntohl (sa_id);
15687   mp->crypto_key_length = vec_len (ck);
15688   mp->integrity_key_length = vec_len (ik);
15689
15690   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15691     mp->crypto_key_length = sizeof (mp->crypto_key);
15692
15693   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15694     mp->integrity_key_length = sizeof (mp->integrity_key);
15695
15696   if (ck)
15697     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15698   if (ik)
15699     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15700
15701   S (mp);
15702   W (ret);
15703   return ret;
15704 }
15705
15706 static int
15707 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15708 {
15709   unformat_input_t *i = vam->input;
15710   vl_api_ipsec_tunnel_if_add_del_t *mp;
15711   u32 local_spi = 0, remote_spi = 0;
15712   u32 crypto_alg = 0, integ_alg = 0;
15713   u8 *lck = NULL, *rck = NULL;
15714   u8 *lik = NULL, *rik = NULL;
15715   ip4_address_t local_ip = { {0} };
15716   ip4_address_t remote_ip = { {0} };
15717   u8 is_add = 1;
15718   u8 esn = 0;
15719   u8 anti_replay = 0;
15720   u8 renumber = 0;
15721   u32 instance = ~0;
15722   int ret;
15723
15724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15725     {
15726       if (unformat (i, "del"))
15727         is_add = 0;
15728       else if (unformat (i, "esn"))
15729         esn = 1;
15730       else if (unformat (i, "anti_replay"))
15731         anti_replay = 1;
15732       else if (unformat (i, "local_spi %d", &local_spi))
15733         ;
15734       else if (unformat (i, "remote_spi %d", &remote_spi))
15735         ;
15736       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15737         ;
15738       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15739         ;
15740       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15741         ;
15742       else
15743         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15744         ;
15745       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15746         ;
15747       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15748         ;
15749       else
15750         if (unformat
15751             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15752         {
15753           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15754             {
15755               errmsg ("unsupported crypto-alg: '%U'\n",
15756                       format_ipsec_crypto_alg, crypto_alg);
15757               return -99;
15758             }
15759         }
15760       else
15761         if (unformat
15762             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15763         {
15764           if (integ_alg >= IPSEC_INTEG_N_ALG)
15765             {
15766               errmsg ("unsupported integ-alg: '%U'\n",
15767                       format_ipsec_integ_alg, integ_alg);
15768               return -99;
15769             }
15770         }
15771       else if (unformat (i, "instance %u", &instance))
15772         renumber = 1;
15773       else
15774         {
15775           errmsg ("parse error '%U'\n", format_unformat_error, i);
15776           return -99;
15777         }
15778     }
15779
15780   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15781
15782   mp->is_add = is_add;
15783   mp->esn = esn;
15784   mp->anti_replay = anti_replay;
15785
15786   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15787   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15788
15789   mp->local_spi = htonl (local_spi);
15790   mp->remote_spi = htonl (remote_spi);
15791   mp->crypto_alg = (u8) crypto_alg;
15792
15793   mp->local_crypto_key_len = 0;
15794   if (lck)
15795     {
15796       mp->local_crypto_key_len = vec_len (lck);
15797       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15798         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15799       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15800     }
15801
15802   mp->remote_crypto_key_len = 0;
15803   if (rck)
15804     {
15805       mp->remote_crypto_key_len = vec_len (rck);
15806       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15807         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15808       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15809     }
15810
15811   mp->integ_alg = (u8) integ_alg;
15812
15813   mp->local_integ_key_len = 0;
15814   if (lik)
15815     {
15816       mp->local_integ_key_len = vec_len (lik);
15817       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15818         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15819       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15820     }
15821
15822   mp->remote_integ_key_len = 0;
15823   if (rik)
15824     {
15825       mp->remote_integ_key_len = vec_len (rik);
15826       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15827         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15828       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15829     }
15830
15831   if (renumber)
15832     {
15833       mp->renumber = renumber;
15834       mp->show_instance = ntohl (instance);
15835     }
15836
15837   S (mp);
15838   W (ret);
15839   return ret;
15840 }
15841
15842 static void
15843 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15844 {
15845   vat_main_t *vam = &vat_main;
15846
15847   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15848          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15849          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15850          "tunnel_src_addr %U tunnel_dst_addr %U "
15851          "salt %u seq_outbound %lu last_seq_inbound %lu "
15852          "replay_window %lu total_data_size %lu\n",
15853          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15854          mp->protocol,
15855          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15856          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15857          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15858          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15859          mp->tunnel_src_addr,
15860          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15861          mp->tunnel_dst_addr,
15862          ntohl (mp->salt),
15863          clib_net_to_host_u64 (mp->seq_outbound),
15864          clib_net_to_host_u64 (mp->last_seq_inbound),
15865          clib_net_to_host_u64 (mp->replay_window),
15866          clib_net_to_host_u64 (mp->total_data_size));
15867 }
15868
15869 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15870 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15871
15872 static void vl_api_ipsec_sa_details_t_handler_json
15873   (vl_api_ipsec_sa_details_t * mp)
15874 {
15875   vat_main_t *vam = &vat_main;
15876   vat_json_node_t *node = NULL;
15877   struct in_addr src_ip4, dst_ip4;
15878   struct in6_addr src_ip6, dst_ip6;
15879
15880   if (VAT_JSON_ARRAY != vam->json_tree.type)
15881     {
15882       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15883       vat_json_init_array (&vam->json_tree);
15884     }
15885   node = vat_json_array_add (&vam->json_tree);
15886
15887   vat_json_init_object (node);
15888   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15889   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15890   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15891   vat_json_object_add_uint (node, "proto", mp->protocol);
15892   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15893   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15894   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15895   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15896   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15897   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15898   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15899                              mp->crypto_key_len);
15900   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15901                              mp->integ_key_len);
15902   if (mp->is_tunnel_ip6)
15903     {
15904       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15905       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15906       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15907       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15908     }
15909   else
15910     {
15911       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15912       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15913       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15914       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15915     }
15916   vat_json_object_add_uint (node, "replay_window",
15917                             clib_net_to_host_u64 (mp->replay_window));
15918   vat_json_object_add_uint (node, "total_data_size",
15919                             clib_net_to_host_u64 (mp->total_data_size));
15920
15921 }
15922
15923 static int
15924 api_ipsec_sa_dump (vat_main_t * vam)
15925 {
15926   unformat_input_t *i = vam->input;
15927   vl_api_ipsec_sa_dump_t *mp;
15928   vl_api_control_ping_t *mp_ping;
15929   u32 sa_id = ~0;
15930   int ret;
15931
15932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15933     {
15934       if (unformat (i, "sa_id %d", &sa_id))
15935         ;
15936       else
15937         {
15938           clib_warning ("parse error '%U'", format_unformat_error, i);
15939           return -99;
15940         }
15941     }
15942
15943   M (IPSEC_SA_DUMP, mp);
15944
15945   mp->sa_id = ntohl (sa_id);
15946
15947   S (mp);
15948
15949   /* Use a control ping for synchronization */
15950   M (CONTROL_PING, mp_ping);
15951   S (mp_ping);
15952
15953   W (ret);
15954   return ret;
15955 }
15956
15957 static int
15958 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15959 {
15960   unformat_input_t *i = vam->input;
15961   vl_api_ipsec_tunnel_if_set_key_t *mp;
15962   u32 sw_if_index = ~0;
15963   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15964   u8 *key = 0;
15965   u32 alg = ~0;
15966   int ret;
15967
15968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15969     {
15970       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15971         ;
15972       else
15973         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15974         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15975       else
15976         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15977         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15978       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15979         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15980       else
15981         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15982         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15983       else if (unformat (i, "%U", unformat_hex_string, &key))
15984         ;
15985       else
15986         {
15987           clib_warning ("parse error '%U'", format_unformat_error, i);
15988           return -99;
15989         }
15990     }
15991
15992   if (sw_if_index == ~0)
15993     {
15994       errmsg ("interface must be specified");
15995       return -99;
15996     }
15997
15998   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15999     {
16000       errmsg ("key type must be specified");
16001       return -99;
16002     }
16003
16004   if (alg == ~0)
16005     {
16006       errmsg ("algorithm must be specified");
16007       return -99;
16008     }
16009
16010   if (vec_len (key) == 0)
16011     {
16012       errmsg ("key must be specified");
16013       return -99;
16014     }
16015
16016   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
16017
16018   mp->sw_if_index = htonl (sw_if_index);
16019   mp->alg = alg;
16020   mp->key_type = key_type;
16021   mp->key_len = vec_len (key);
16022   clib_memcpy (mp->key, key, vec_len (key));
16023
16024   S (mp);
16025   W (ret);
16026
16027   return ret;
16028 }
16029
16030 static int
16031 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
16032 {
16033   unformat_input_t *i = vam->input;
16034   vl_api_ipsec_tunnel_if_set_sa_t *mp;
16035   u32 sw_if_index = ~0;
16036   u32 sa_id = ~0;
16037   u8 is_outbound = (u8) ~ 0;
16038   int ret;
16039
16040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16041     {
16042       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16043         ;
16044       else if (unformat (i, "sa_id %d", &sa_id))
16045         ;
16046       else if (unformat (i, "outbound"))
16047         is_outbound = 1;
16048       else if (unformat (i, "inbound"))
16049         is_outbound = 0;
16050       else
16051         {
16052           clib_warning ("parse error '%U'", format_unformat_error, i);
16053           return -99;
16054         }
16055     }
16056
16057   if (sw_if_index == ~0)
16058     {
16059       errmsg ("interface must be specified");
16060       return -99;
16061     }
16062
16063   if (sa_id == ~0)
16064     {
16065       errmsg ("SA ID must be specified");
16066       return -99;
16067     }
16068
16069   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16070
16071   mp->sw_if_index = htonl (sw_if_index);
16072   mp->sa_id = htonl (sa_id);
16073   mp->is_outbound = is_outbound;
16074
16075   S (mp);
16076   W (ret);
16077
16078   return ret;
16079 }
16080
16081 static int
16082 api_ikev2_profile_add_del (vat_main_t * vam)
16083 {
16084   unformat_input_t *i = vam->input;
16085   vl_api_ikev2_profile_add_del_t *mp;
16086   u8 is_add = 1;
16087   u8 *name = 0;
16088   int ret;
16089
16090   const char *valid_chars = "a-zA-Z0-9_";
16091
16092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16093     {
16094       if (unformat (i, "del"))
16095         is_add = 0;
16096       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16097         vec_add1 (name, 0);
16098       else
16099         {
16100           errmsg ("parse error '%U'", format_unformat_error, i);
16101           return -99;
16102         }
16103     }
16104
16105   if (!vec_len (name))
16106     {
16107       errmsg ("profile name must be specified");
16108       return -99;
16109     }
16110
16111   if (vec_len (name) > 64)
16112     {
16113       errmsg ("profile name too long");
16114       return -99;
16115     }
16116
16117   M (IKEV2_PROFILE_ADD_DEL, mp);
16118
16119   clib_memcpy (mp->name, name, vec_len (name));
16120   mp->is_add = is_add;
16121   vec_free (name);
16122
16123   S (mp);
16124   W (ret);
16125   return ret;
16126 }
16127
16128 static int
16129 api_ikev2_profile_set_auth (vat_main_t * vam)
16130 {
16131   unformat_input_t *i = vam->input;
16132   vl_api_ikev2_profile_set_auth_t *mp;
16133   u8 *name = 0;
16134   u8 *data = 0;
16135   u32 auth_method = 0;
16136   u8 is_hex = 0;
16137   int ret;
16138
16139   const char *valid_chars = "a-zA-Z0-9_";
16140
16141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16142     {
16143       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16144         vec_add1 (name, 0);
16145       else if (unformat (i, "auth_method %U",
16146                          unformat_ikev2_auth_method, &auth_method))
16147         ;
16148       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16149         is_hex = 1;
16150       else if (unformat (i, "auth_data %v", &data))
16151         ;
16152       else
16153         {
16154           errmsg ("parse error '%U'", format_unformat_error, i);
16155           return -99;
16156         }
16157     }
16158
16159   if (!vec_len (name))
16160     {
16161       errmsg ("profile name must be specified");
16162       return -99;
16163     }
16164
16165   if (vec_len (name) > 64)
16166     {
16167       errmsg ("profile name too long");
16168       return -99;
16169     }
16170
16171   if (!vec_len (data))
16172     {
16173       errmsg ("auth_data must be specified");
16174       return -99;
16175     }
16176
16177   if (!auth_method)
16178     {
16179       errmsg ("auth_method must be specified");
16180       return -99;
16181     }
16182
16183   M (IKEV2_PROFILE_SET_AUTH, mp);
16184
16185   mp->is_hex = is_hex;
16186   mp->auth_method = (u8) auth_method;
16187   mp->data_len = vec_len (data);
16188   clib_memcpy (mp->name, name, vec_len (name));
16189   clib_memcpy (mp->data, data, vec_len (data));
16190   vec_free (name);
16191   vec_free (data);
16192
16193   S (mp);
16194   W (ret);
16195   return ret;
16196 }
16197
16198 static int
16199 api_ikev2_profile_set_id (vat_main_t * vam)
16200 {
16201   unformat_input_t *i = vam->input;
16202   vl_api_ikev2_profile_set_id_t *mp;
16203   u8 *name = 0;
16204   u8 *data = 0;
16205   u8 is_local = 0;
16206   u32 id_type = 0;
16207   ip4_address_t ip4;
16208   int ret;
16209
16210   const char *valid_chars = "a-zA-Z0-9_";
16211
16212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16213     {
16214       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16215         vec_add1 (name, 0);
16216       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16217         ;
16218       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16219         {
16220           data = vec_new (u8, 4);
16221           clib_memcpy (data, ip4.as_u8, 4);
16222         }
16223       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16224         ;
16225       else if (unformat (i, "id_data %v", &data))
16226         ;
16227       else if (unformat (i, "local"))
16228         is_local = 1;
16229       else if (unformat (i, "remote"))
16230         is_local = 0;
16231       else
16232         {
16233           errmsg ("parse error '%U'", format_unformat_error, i);
16234           return -99;
16235         }
16236     }
16237
16238   if (!vec_len (name))
16239     {
16240       errmsg ("profile name must be specified");
16241       return -99;
16242     }
16243
16244   if (vec_len (name) > 64)
16245     {
16246       errmsg ("profile name too long");
16247       return -99;
16248     }
16249
16250   if (!vec_len (data))
16251     {
16252       errmsg ("id_data must be specified");
16253       return -99;
16254     }
16255
16256   if (!id_type)
16257     {
16258       errmsg ("id_type must be specified");
16259       return -99;
16260     }
16261
16262   M (IKEV2_PROFILE_SET_ID, mp);
16263
16264   mp->is_local = is_local;
16265   mp->id_type = (u8) id_type;
16266   mp->data_len = vec_len (data);
16267   clib_memcpy (mp->name, name, vec_len (name));
16268   clib_memcpy (mp->data, data, vec_len (data));
16269   vec_free (name);
16270   vec_free (data);
16271
16272   S (mp);
16273   W (ret);
16274   return ret;
16275 }
16276
16277 static int
16278 api_ikev2_profile_set_ts (vat_main_t * vam)
16279 {
16280   unformat_input_t *i = vam->input;
16281   vl_api_ikev2_profile_set_ts_t *mp;
16282   u8 *name = 0;
16283   u8 is_local = 0;
16284   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16285   ip4_address_t start_addr, end_addr;
16286
16287   const char *valid_chars = "a-zA-Z0-9_";
16288   int ret;
16289
16290   start_addr.as_u32 = 0;
16291   end_addr.as_u32 = (u32) ~ 0;
16292
16293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16294     {
16295       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16296         vec_add1 (name, 0);
16297       else if (unformat (i, "protocol %d", &proto))
16298         ;
16299       else if (unformat (i, "start_port %d", &start_port))
16300         ;
16301       else if (unformat (i, "end_port %d", &end_port))
16302         ;
16303       else
16304         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16305         ;
16306       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16307         ;
16308       else if (unformat (i, "local"))
16309         is_local = 1;
16310       else if (unformat (i, "remote"))
16311         is_local = 0;
16312       else
16313         {
16314           errmsg ("parse error '%U'", format_unformat_error, i);
16315           return -99;
16316         }
16317     }
16318
16319   if (!vec_len (name))
16320     {
16321       errmsg ("profile name must be specified");
16322       return -99;
16323     }
16324
16325   if (vec_len (name) > 64)
16326     {
16327       errmsg ("profile name too long");
16328       return -99;
16329     }
16330
16331   M (IKEV2_PROFILE_SET_TS, mp);
16332
16333   mp->is_local = is_local;
16334   mp->proto = (u8) proto;
16335   mp->start_port = (u16) start_port;
16336   mp->end_port = (u16) end_port;
16337   mp->start_addr = start_addr.as_u32;
16338   mp->end_addr = end_addr.as_u32;
16339   clib_memcpy (mp->name, name, vec_len (name));
16340   vec_free (name);
16341
16342   S (mp);
16343   W (ret);
16344   return ret;
16345 }
16346
16347 static int
16348 api_ikev2_set_local_key (vat_main_t * vam)
16349 {
16350   unformat_input_t *i = vam->input;
16351   vl_api_ikev2_set_local_key_t *mp;
16352   u8 *file = 0;
16353   int ret;
16354
16355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16356     {
16357       if (unformat (i, "file %v", &file))
16358         vec_add1 (file, 0);
16359       else
16360         {
16361           errmsg ("parse error '%U'", format_unformat_error, i);
16362           return -99;
16363         }
16364     }
16365
16366   if (!vec_len (file))
16367     {
16368       errmsg ("RSA key file must be specified");
16369       return -99;
16370     }
16371
16372   if (vec_len (file) > 256)
16373     {
16374       errmsg ("file name too long");
16375       return -99;
16376     }
16377
16378   M (IKEV2_SET_LOCAL_KEY, mp);
16379
16380   clib_memcpy (mp->key_file, file, vec_len (file));
16381   vec_free (file);
16382
16383   S (mp);
16384   W (ret);
16385   return ret;
16386 }
16387
16388 static int
16389 api_ikev2_set_responder (vat_main_t * vam)
16390 {
16391   unformat_input_t *i = vam->input;
16392   vl_api_ikev2_set_responder_t *mp;
16393   int ret;
16394   u8 *name = 0;
16395   u32 sw_if_index = ~0;
16396   ip4_address_t address;
16397
16398   const char *valid_chars = "a-zA-Z0-9_";
16399
16400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16401     {
16402       if (unformat
16403           (i, "%U interface %d address %U", unformat_token, valid_chars,
16404            &name, &sw_if_index, unformat_ip4_address, &address))
16405         vec_add1 (name, 0);
16406       else
16407         {
16408           errmsg ("parse error '%U'", format_unformat_error, i);
16409           return -99;
16410         }
16411     }
16412
16413   if (!vec_len (name))
16414     {
16415       errmsg ("profile name must be specified");
16416       return -99;
16417     }
16418
16419   if (vec_len (name) > 64)
16420     {
16421       errmsg ("profile name too long");
16422       return -99;
16423     }
16424
16425   M (IKEV2_SET_RESPONDER, mp);
16426
16427   clib_memcpy (mp->name, name, vec_len (name));
16428   vec_free (name);
16429
16430   mp->sw_if_index = sw_if_index;
16431   clib_memcpy (mp->address, &address, sizeof (address));
16432
16433   S (mp);
16434   W (ret);
16435   return ret;
16436 }
16437
16438 static int
16439 api_ikev2_set_ike_transforms (vat_main_t * vam)
16440 {
16441   unformat_input_t *i = vam->input;
16442   vl_api_ikev2_set_ike_transforms_t *mp;
16443   int ret;
16444   u8 *name = 0;
16445   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16446
16447   const char *valid_chars = "a-zA-Z0-9_";
16448
16449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16450     {
16451       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16452                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16453         vec_add1 (name, 0);
16454       else
16455         {
16456           errmsg ("parse error '%U'", format_unformat_error, i);
16457           return -99;
16458         }
16459     }
16460
16461   if (!vec_len (name))
16462     {
16463       errmsg ("profile name must be specified");
16464       return -99;
16465     }
16466
16467   if (vec_len (name) > 64)
16468     {
16469       errmsg ("profile name too long");
16470       return -99;
16471     }
16472
16473   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16474
16475   clib_memcpy (mp->name, name, vec_len (name));
16476   vec_free (name);
16477   mp->crypto_alg = crypto_alg;
16478   mp->crypto_key_size = crypto_key_size;
16479   mp->integ_alg = integ_alg;
16480   mp->dh_group = dh_group;
16481
16482   S (mp);
16483   W (ret);
16484   return ret;
16485 }
16486
16487
16488 static int
16489 api_ikev2_set_esp_transforms (vat_main_t * vam)
16490 {
16491   unformat_input_t *i = vam->input;
16492   vl_api_ikev2_set_esp_transforms_t *mp;
16493   int ret;
16494   u8 *name = 0;
16495   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16496
16497   const char *valid_chars = "a-zA-Z0-9_";
16498
16499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16500     {
16501       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16502                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16503         vec_add1 (name, 0);
16504       else
16505         {
16506           errmsg ("parse error '%U'", format_unformat_error, i);
16507           return -99;
16508         }
16509     }
16510
16511   if (!vec_len (name))
16512     {
16513       errmsg ("profile name must be specified");
16514       return -99;
16515     }
16516
16517   if (vec_len (name) > 64)
16518     {
16519       errmsg ("profile name too long");
16520       return -99;
16521     }
16522
16523   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16524
16525   clib_memcpy (mp->name, name, vec_len (name));
16526   vec_free (name);
16527   mp->crypto_alg = crypto_alg;
16528   mp->crypto_key_size = crypto_key_size;
16529   mp->integ_alg = integ_alg;
16530   mp->dh_group = dh_group;
16531
16532   S (mp);
16533   W (ret);
16534   return ret;
16535 }
16536
16537 static int
16538 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16539 {
16540   unformat_input_t *i = vam->input;
16541   vl_api_ikev2_set_sa_lifetime_t *mp;
16542   int ret;
16543   u8 *name = 0;
16544   u64 lifetime, lifetime_maxdata;
16545   u32 lifetime_jitter, handover;
16546
16547   const char *valid_chars = "a-zA-Z0-9_";
16548
16549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16550     {
16551       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16552                     &lifetime, &lifetime_jitter, &handover,
16553                     &lifetime_maxdata))
16554         vec_add1 (name, 0);
16555       else
16556         {
16557           errmsg ("parse error '%U'", format_unformat_error, i);
16558           return -99;
16559         }
16560     }
16561
16562   if (!vec_len (name))
16563     {
16564       errmsg ("profile name must be specified");
16565       return -99;
16566     }
16567
16568   if (vec_len (name) > 64)
16569     {
16570       errmsg ("profile name too long");
16571       return -99;
16572     }
16573
16574   M (IKEV2_SET_SA_LIFETIME, mp);
16575
16576   clib_memcpy (mp->name, name, vec_len (name));
16577   vec_free (name);
16578   mp->lifetime = lifetime;
16579   mp->lifetime_jitter = lifetime_jitter;
16580   mp->handover = handover;
16581   mp->lifetime_maxdata = lifetime_maxdata;
16582
16583   S (mp);
16584   W (ret);
16585   return ret;
16586 }
16587
16588 static int
16589 api_ikev2_initiate_sa_init (vat_main_t * vam)
16590 {
16591   unformat_input_t *i = vam->input;
16592   vl_api_ikev2_initiate_sa_init_t *mp;
16593   int ret;
16594   u8 *name = 0;
16595
16596   const char *valid_chars = "a-zA-Z0-9_";
16597
16598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16599     {
16600       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16601         vec_add1 (name, 0);
16602       else
16603         {
16604           errmsg ("parse error '%U'", format_unformat_error, i);
16605           return -99;
16606         }
16607     }
16608
16609   if (!vec_len (name))
16610     {
16611       errmsg ("profile name must be specified");
16612       return -99;
16613     }
16614
16615   if (vec_len (name) > 64)
16616     {
16617       errmsg ("profile name too long");
16618       return -99;
16619     }
16620
16621   M (IKEV2_INITIATE_SA_INIT, mp);
16622
16623   clib_memcpy (mp->name, name, vec_len (name));
16624   vec_free (name);
16625
16626   S (mp);
16627   W (ret);
16628   return ret;
16629 }
16630
16631 static int
16632 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16633 {
16634   unformat_input_t *i = vam->input;
16635   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16636   int ret;
16637   u64 ispi;
16638
16639
16640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16641     {
16642       if (unformat (i, "%lx", &ispi))
16643         ;
16644       else
16645         {
16646           errmsg ("parse error '%U'", format_unformat_error, i);
16647           return -99;
16648         }
16649     }
16650
16651   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16652
16653   mp->ispi = ispi;
16654
16655   S (mp);
16656   W (ret);
16657   return ret;
16658 }
16659
16660 static int
16661 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16662 {
16663   unformat_input_t *i = vam->input;
16664   vl_api_ikev2_initiate_del_child_sa_t *mp;
16665   int ret;
16666   u32 ispi;
16667
16668
16669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16670     {
16671       if (unformat (i, "%x", &ispi))
16672         ;
16673       else
16674         {
16675           errmsg ("parse error '%U'", format_unformat_error, i);
16676           return -99;
16677         }
16678     }
16679
16680   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16681
16682   mp->ispi = ispi;
16683
16684   S (mp);
16685   W (ret);
16686   return ret;
16687 }
16688
16689 static int
16690 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16691 {
16692   unformat_input_t *i = vam->input;
16693   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16694   int ret;
16695   u32 ispi;
16696
16697
16698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16699     {
16700       if (unformat (i, "%x", &ispi))
16701         ;
16702       else
16703         {
16704           errmsg ("parse error '%U'", format_unformat_error, i);
16705           return -99;
16706         }
16707     }
16708
16709   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16710
16711   mp->ispi = ispi;
16712
16713   S (mp);
16714   W (ret);
16715   return ret;
16716 }
16717
16718 static int
16719 api_get_first_msg_id (vat_main_t * vam)
16720 {
16721   vl_api_get_first_msg_id_t *mp;
16722   unformat_input_t *i = vam->input;
16723   u8 *name;
16724   u8 name_set = 0;
16725   int ret;
16726
16727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16728     {
16729       if (unformat (i, "client %s", &name))
16730         name_set = 1;
16731       else
16732         break;
16733     }
16734
16735   if (name_set == 0)
16736     {
16737       errmsg ("missing client name");
16738       return -99;
16739     }
16740   vec_add1 (name, 0);
16741
16742   if (vec_len (name) > 63)
16743     {
16744       errmsg ("client name too long");
16745       return -99;
16746     }
16747
16748   M (GET_FIRST_MSG_ID, mp);
16749   clib_memcpy (mp->name, name, vec_len (name));
16750   S (mp);
16751   W (ret);
16752   return ret;
16753 }
16754
16755 static int
16756 api_cop_interface_enable_disable (vat_main_t * vam)
16757 {
16758   unformat_input_t *line_input = vam->input;
16759   vl_api_cop_interface_enable_disable_t *mp;
16760   u32 sw_if_index = ~0;
16761   u8 enable_disable = 1;
16762   int ret;
16763
16764   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16765     {
16766       if (unformat (line_input, "disable"))
16767         enable_disable = 0;
16768       if (unformat (line_input, "enable"))
16769         enable_disable = 1;
16770       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16771                          vam, &sw_if_index))
16772         ;
16773       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16774         ;
16775       else
16776         break;
16777     }
16778
16779   if (sw_if_index == ~0)
16780     {
16781       errmsg ("missing interface name or sw_if_index");
16782       return -99;
16783     }
16784
16785   /* Construct the API message */
16786   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16787   mp->sw_if_index = ntohl (sw_if_index);
16788   mp->enable_disable = enable_disable;
16789
16790   /* send it... */
16791   S (mp);
16792   /* Wait for the reply */
16793   W (ret);
16794   return ret;
16795 }
16796
16797 static int
16798 api_cop_whitelist_enable_disable (vat_main_t * vam)
16799 {
16800   unformat_input_t *line_input = vam->input;
16801   vl_api_cop_whitelist_enable_disable_t *mp;
16802   u32 sw_if_index = ~0;
16803   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16804   u32 fib_id = 0;
16805   int ret;
16806
16807   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16808     {
16809       if (unformat (line_input, "ip4"))
16810         ip4 = 1;
16811       else if (unformat (line_input, "ip6"))
16812         ip6 = 1;
16813       else if (unformat (line_input, "default"))
16814         default_cop = 1;
16815       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16816                          vam, &sw_if_index))
16817         ;
16818       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16819         ;
16820       else if (unformat (line_input, "fib-id %d", &fib_id))
16821         ;
16822       else
16823         break;
16824     }
16825
16826   if (sw_if_index == ~0)
16827     {
16828       errmsg ("missing interface name or sw_if_index");
16829       return -99;
16830     }
16831
16832   /* Construct the API message */
16833   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16834   mp->sw_if_index = ntohl (sw_if_index);
16835   mp->fib_id = ntohl (fib_id);
16836   mp->ip4 = ip4;
16837   mp->ip6 = ip6;
16838   mp->default_cop = default_cop;
16839
16840   /* send it... */
16841   S (mp);
16842   /* Wait for the reply */
16843   W (ret);
16844   return ret;
16845 }
16846
16847 static int
16848 api_get_node_graph (vat_main_t * vam)
16849 {
16850   vl_api_get_node_graph_t *mp;
16851   int ret;
16852
16853   M (GET_NODE_GRAPH, mp);
16854
16855   /* send it... */
16856   S (mp);
16857   /* Wait for the reply */
16858   W (ret);
16859   return ret;
16860 }
16861
16862 /* *INDENT-OFF* */
16863 /** Used for parsing LISP eids */
16864 typedef CLIB_PACKED(struct{
16865   u8 addr[16];   /**< eid address */
16866   u32 len;       /**< prefix length if IP */
16867   u8 type;      /**< type of eid */
16868 }) lisp_eid_vat_t;
16869 /* *INDENT-ON* */
16870
16871 static uword
16872 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16873 {
16874   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16875
16876   clib_memset (a, 0, sizeof (a[0]));
16877
16878   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16879     {
16880       a->type = 0;              /* ipv4 type */
16881     }
16882   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16883     {
16884       a->type = 1;              /* ipv6 type */
16885     }
16886   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16887     {
16888       a->type = 2;              /* mac type */
16889     }
16890   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16891     {
16892       a->type = 3;              /* NSH type */
16893       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16894       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16895     }
16896   else
16897     {
16898       return 0;
16899     }
16900
16901   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16902     {
16903       return 0;
16904     }
16905
16906   return 1;
16907 }
16908
16909 static int
16910 lisp_eid_size_vat (u8 type)
16911 {
16912   switch (type)
16913     {
16914     case 0:
16915       return 4;
16916     case 1:
16917       return 16;
16918     case 2:
16919       return 6;
16920     case 3:
16921       return 5;
16922     }
16923   return 0;
16924 }
16925
16926 static void
16927 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16928 {
16929   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16930 }
16931
16932 static int
16933 api_one_add_del_locator_set (vat_main_t * vam)
16934 {
16935   unformat_input_t *input = vam->input;
16936   vl_api_one_add_del_locator_set_t *mp;
16937   u8 is_add = 1;
16938   u8 *locator_set_name = NULL;
16939   u8 locator_set_name_set = 0;
16940   vl_api_local_locator_t locator, *locators = 0;
16941   u32 sw_if_index, priority, weight;
16942   u32 data_len = 0;
16943
16944   int ret;
16945   /* Parse args required to build the message */
16946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16947     {
16948       if (unformat (input, "del"))
16949         {
16950           is_add = 0;
16951         }
16952       else if (unformat (input, "locator-set %s", &locator_set_name))
16953         {
16954           locator_set_name_set = 1;
16955         }
16956       else if (unformat (input, "sw_if_index %u p %u w %u",
16957                          &sw_if_index, &priority, &weight))
16958         {
16959           locator.sw_if_index = htonl (sw_if_index);
16960           locator.priority = priority;
16961           locator.weight = weight;
16962           vec_add1 (locators, locator);
16963         }
16964       else
16965         if (unformat
16966             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16967              &sw_if_index, &priority, &weight))
16968         {
16969           locator.sw_if_index = htonl (sw_if_index);
16970           locator.priority = priority;
16971           locator.weight = weight;
16972           vec_add1 (locators, locator);
16973         }
16974       else
16975         break;
16976     }
16977
16978   if (locator_set_name_set == 0)
16979     {
16980       errmsg ("missing locator-set name");
16981       vec_free (locators);
16982       return -99;
16983     }
16984
16985   if (vec_len (locator_set_name) > 64)
16986     {
16987       errmsg ("locator-set name too long");
16988       vec_free (locator_set_name);
16989       vec_free (locators);
16990       return -99;
16991     }
16992   vec_add1 (locator_set_name, 0);
16993
16994   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16995
16996   /* Construct the API message */
16997   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16998
16999   mp->is_add = is_add;
17000   clib_memcpy (mp->locator_set_name, locator_set_name,
17001                vec_len (locator_set_name));
17002   vec_free (locator_set_name);
17003
17004   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
17005   if (locators)
17006     clib_memcpy (mp->locators, locators, data_len);
17007   vec_free (locators);
17008
17009   /* send it... */
17010   S (mp);
17011
17012   /* Wait for a reply... */
17013   W (ret);
17014   return ret;
17015 }
17016
17017 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
17018
17019 static int
17020 api_one_add_del_locator (vat_main_t * vam)
17021 {
17022   unformat_input_t *input = vam->input;
17023   vl_api_one_add_del_locator_t *mp;
17024   u32 tmp_if_index = ~0;
17025   u32 sw_if_index = ~0;
17026   u8 sw_if_index_set = 0;
17027   u8 sw_if_index_if_name_set = 0;
17028   u32 priority = ~0;
17029   u8 priority_set = 0;
17030   u32 weight = ~0;
17031   u8 weight_set = 0;
17032   u8 is_add = 1;
17033   u8 *locator_set_name = NULL;
17034   u8 locator_set_name_set = 0;
17035   int ret;
17036
17037   /* Parse args required to build the message */
17038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17039     {
17040       if (unformat (input, "del"))
17041         {
17042           is_add = 0;
17043         }
17044       else if (unformat (input, "locator-set %s", &locator_set_name))
17045         {
17046           locator_set_name_set = 1;
17047         }
17048       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
17049                          &tmp_if_index))
17050         {
17051           sw_if_index_if_name_set = 1;
17052           sw_if_index = tmp_if_index;
17053         }
17054       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17055         {
17056           sw_if_index_set = 1;
17057           sw_if_index = tmp_if_index;
17058         }
17059       else if (unformat (input, "p %d", &priority))
17060         {
17061           priority_set = 1;
17062         }
17063       else if (unformat (input, "w %d", &weight))
17064         {
17065           weight_set = 1;
17066         }
17067       else
17068         break;
17069     }
17070
17071   if (locator_set_name_set == 0)
17072     {
17073       errmsg ("missing locator-set name");
17074       return -99;
17075     }
17076
17077   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17078     {
17079       errmsg ("missing sw_if_index");
17080       vec_free (locator_set_name);
17081       return -99;
17082     }
17083
17084   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17085     {
17086       errmsg ("cannot use both params interface name and sw_if_index");
17087       vec_free (locator_set_name);
17088       return -99;
17089     }
17090
17091   if (priority_set == 0)
17092     {
17093       errmsg ("missing locator-set priority");
17094       vec_free (locator_set_name);
17095       return -99;
17096     }
17097
17098   if (weight_set == 0)
17099     {
17100       errmsg ("missing locator-set weight");
17101       vec_free (locator_set_name);
17102       return -99;
17103     }
17104
17105   if (vec_len (locator_set_name) > 64)
17106     {
17107       errmsg ("locator-set name too long");
17108       vec_free (locator_set_name);
17109       return -99;
17110     }
17111   vec_add1 (locator_set_name, 0);
17112
17113   /* Construct the API message */
17114   M (ONE_ADD_DEL_LOCATOR, mp);
17115
17116   mp->is_add = is_add;
17117   mp->sw_if_index = ntohl (sw_if_index);
17118   mp->priority = priority;
17119   mp->weight = weight;
17120   clib_memcpy (mp->locator_set_name, locator_set_name,
17121                vec_len (locator_set_name));
17122   vec_free (locator_set_name);
17123
17124   /* send it... */
17125   S (mp);
17126
17127   /* Wait for a reply... */
17128   W (ret);
17129   return ret;
17130 }
17131
17132 #define api_lisp_add_del_locator api_one_add_del_locator
17133
17134 uword
17135 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17136 {
17137   u32 *key_id = va_arg (*args, u32 *);
17138   u8 *s = 0;
17139
17140   if (unformat (input, "%s", &s))
17141     {
17142       if (!strcmp ((char *) s, "sha1"))
17143         key_id[0] = HMAC_SHA_1_96;
17144       else if (!strcmp ((char *) s, "sha256"))
17145         key_id[0] = HMAC_SHA_256_128;
17146       else
17147         {
17148           clib_warning ("invalid key_id: '%s'", s);
17149           key_id[0] = HMAC_NO_KEY;
17150         }
17151     }
17152   else
17153     return 0;
17154
17155   vec_free (s);
17156   return 1;
17157 }
17158
17159 static int
17160 api_one_add_del_local_eid (vat_main_t * vam)
17161 {
17162   unformat_input_t *input = vam->input;
17163   vl_api_one_add_del_local_eid_t *mp;
17164   u8 is_add = 1;
17165   u8 eid_set = 0;
17166   lisp_eid_vat_t _eid, *eid = &_eid;
17167   u8 *locator_set_name = 0;
17168   u8 locator_set_name_set = 0;
17169   u32 vni = 0;
17170   u16 key_id = 0;
17171   u8 *key = 0;
17172   int ret;
17173
17174   /* Parse args required to build the message */
17175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17176     {
17177       if (unformat (input, "del"))
17178         {
17179           is_add = 0;
17180         }
17181       else if (unformat (input, "vni %d", &vni))
17182         {
17183           ;
17184         }
17185       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17186         {
17187           eid_set = 1;
17188         }
17189       else if (unformat (input, "locator-set %s", &locator_set_name))
17190         {
17191           locator_set_name_set = 1;
17192         }
17193       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17194         ;
17195       else if (unformat (input, "secret-key %_%v%_", &key))
17196         ;
17197       else
17198         break;
17199     }
17200
17201   if (locator_set_name_set == 0)
17202     {
17203       errmsg ("missing locator-set name");
17204       return -99;
17205     }
17206
17207   if (0 == eid_set)
17208     {
17209       errmsg ("EID address not set!");
17210       vec_free (locator_set_name);
17211       return -99;
17212     }
17213
17214   if (key && (0 == key_id))
17215     {
17216       errmsg ("invalid key_id!");
17217       return -99;
17218     }
17219
17220   if (vec_len (key) > 64)
17221     {
17222       errmsg ("key too long");
17223       vec_free (key);
17224       return -99;
17225     }
17226
17227   if (vec_len (locator_set_name) > 64)
17228     {
17229       errmsg ("locator-set name too long");
17230       vec_free (locator_set_name);
17231       return -99;
17232     }
17233   vec_add1 (locator_set_name, 0);
17234
17235   /* Construct the API message */
17236   M (ONE_ADD_DEL_LOCAL_EID, mp);
17237
17238   mp->is_add = is_add;
17239   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17240   mp->eid_type = eid->type;
17241   mp->prefix_len = eid->len;
17242   mp->vni = clib_host_to_net_u32 (vni);
17243   mp->key_id = clib_host_to_net_u16 (key_id);
17244   clib_memcpy (mp->locator_set_name, locator_set_name,
17245                vec_len (locator_set_name));
17246   clib_memcpy (mp->key, key, vec_len (key));
17247
17248   vec_free (locator_set_name);
17249   vec_free (key);
17250
17251   /* send it... */
17252   S (mp);
17253
17254   /* Wait for a reply... */
17255   W (ret);
17256   return ret;
17257 }
17258
17259 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17260
17261 static int
17262 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17263 {
17264   u32 dp_table = 0, vni = 0;;
17265   unformat_input_t *input = vam->input;
17266   vl_api_gpe_add_del_fwd_entry_t *mp;
17267   u8 is_add = 1;
17268   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17269   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17270   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17271   u32 action = ~0, w;
17272   ip4_address_t rmt_rloc4, lcl_rloc4;
17273   ip6_address_t rmt_rloc6, lcl_rloc6;
17274   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17275   int ret;
17276
17277   clib_memset (&rloc, 0, sizeof (rloc));
17278
17279   /* Parse args required to build the message */
17280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17281     {
17282       if (unformat (input, "del"))
17283         is_add = 0;
17284       else if (unformat (input, "add"))
17285         is_add = 1;
17286       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17287         {
17288           rmt_eid_set = 1;
17289         }
17290       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17291         {
17292           lcl_eid_set = 1;
17293         }
17294       else if (unformat (input, "vrf %d", &dp_table))
17295         ;
17296       else if (unformat (input, "bd %d", &dp_table))
17297         ;
17298       else if (unformat (input, "vni %d", &vni))
17299         ;
17300       else if (unformat (input, "w %d", &w))
17301         {
17302           if (!curr_rloc)
17303             {
17304               errmsg ("No RLOC configured for setting priority/weight!");
17305               return -99;
17306             }
17307           curr_rloc->weight = w;
17308         }
17309       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17310                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17311         {
17312           rloc.is_ip4 = 1;
17313
17314           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17315           rloc.weight = 0;
17316           vec_add1 (lcl_locs, rloc);
17317
17318           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17319           vec_add1 (rmt_locs, rloc);
17320           /* weight saved in rmt loc */
17321           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17322         }
17323       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17324                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17325         {
17326           rloc.is_ip4 = 0;
17327           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17328           rloc.weight = 0;
17329           vec_add1 (lcl_locs, rloc);
17330
17331           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17332           vec_add1 (rmt_locs, rloc);
17333           /* weight saved in rmt loc */
17334           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17335         }
17336       else if (unformat (input, "action %d", &action))
17337         {
17338           ;
17339         }
17340       else
17341         {
17342           clib_warning ("parse error '%U'", format_unformat_error, input);
17343           return -99;
17344         }
17345     }
17346
17347   if (!rmt_eid_set)
17348     {
17349       errmsg ("remote eid addresses not set");
17350       return -99;
17351     }
17352
17353   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17354     {
17355       errmsg ("eid types don't match");
17356       return -99;
17357     }
17358
17359   if (0 == rmt_locs && (u32) ~ 0 == action)
17360     {
17361       errmsg ("action not set for negative mapping");
17362       return -99;
17363     }
17364
17365   /* Construct the API message */
17366   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17367       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17368
17369   mp->is_add = is_add;
17370   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17371   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17372   mp->eid_type = rmt_eid->type;
17373   mp->dp_table = clib_host_to_net_u32 (dp_table);
17374   mp->vni = clib_host_to_net_u32 (vni);
17375   mp->rmt_len = rmt_eid->len;
17376   mp->lcl_len = lcl_eid->len;
17377   mp->action = action;
17378
17379   if (0 != rmt_locs && 0 != lcl_locs)
17380     {
17381       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17382       clib_memcpy (mp->locs, lcl_locs,
17383                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17384
17385       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17386       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17387                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17388     }
17389   vec_free (lcl_locs);
17390   vec_free (rmt_locs);
17391
17392   /* send it... */
17393   S (mp);
17394
17395   /* Wait for a reply... */
17396   W (ret);
17397   return ret;
17398 }
17399
17400 static int
17401 api_one_add_del_map_server (vat_main_t * vam)
17402 {
17403   unformat_input_t *input = vam->input;
17404   vl_api_one_add_del_map_server_t *mp;
17405   u8 is_add = 1;
17406   u8 ipv4_set = 0;
17407   u8 ipv6_set = 0;
17408   ip4_address_t ipv4;
17409   ip6_address_t ipv6;
17410   int ret;
17411
17412   /* Parse args required to build the message */
17413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17414     {
17415       if (unformat (input, "del"))
17416         {
17417           is_add = 0;
17418         }
17419       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17420         {
17421           ipv4_set = 1;
17422         }
17423       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17424         {
17425           ipv6_set = 1;
17426         }
17427       else
17428         break;
17429     }
17430
17431   if (ipv4_set && ipv6_set)
17432     {
17433       errmsg ("both eid v4 and v6 addresses set");
17434       return -99;
17435     }
17436
17437   if (!ipv4_set && !ipv6_set)
17438     {
17439       errmsg ("eid addresses not set");
17440       return -99;
17441     }
17442
17443   /* Construct the API message */
17444   M (ONE_ADD_DEL_MAP_SERVER, mp);
17445
17446   mp->is_add = is_add;
17447   if (ipv6_set)
17448     {
17449       mp->is_ipv6 = 1;
17450       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17451     }
17452   else
17453     {
17454       mp->is_ipv6 = 0;
17455       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17456     }
17457
17458   /* send it... */
17459   S (mp);
17460
17461   /* Wait for a reply... */
17462   W (ret);
17463   return ret;
17464 }
17465
17466 #define api_lisp_add_del_map_server api_one_add_del_map_server
17467
17468 static int
17469 api_one_add_del_map_resolver (vat_main_t * vam)
17470 {
17471   unformat_input_t *input = vam->input;
17472   vl_api_one_add_del_map_resolver_t *mp;
17473   u8 is_add = 1;
17474   u8 ipv4_set = 0;
17475   u8 ipv6_set = 0;
17476   ip4_address_t ipv4;
17477   ip6_address_t ipv6;
17478   int ret;
17479
17480   /* Parse args required to build the message */
17481   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17482     {
17483       if (unformat (input, "del"))
17484         {
17485           is_add = 0;
17486         }
17487       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17488         {
17489           ipv4_set = 1;
17490         }
17491       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17492         {
17493           ipv6_set = 1;
17494         }
17495       else
17496         break;
17497     }
17498
17499   if (ipv4_set && ipv6_set)
17500     {
17501       errmsg ("both eid v4 and v6 addresses set");
17502       return -99;
17503     }
17504
17505   if (!ipv4_set && !ipv6_set)
17506     {
17507       errmsg ("eid addresses not set");
17508       return -99;
17509     }
17510
17511   /* Construct the API message */
17512   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17513
17514   mp->is_add = is_add;
17515   if (ipv6_set)
17516     {
17517       mp->is_ipv6 = 1;
17518       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17519     }
17520   else
17521     {
17522       mp->is_ipv6 = 0;
17523       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17524     }
17525
17526   /* send it... */
17527   S (mp);
17528
17529   /* Wait for a reply... */
17530   W (ret);
17531   return ret;
17532 }
17533
17534 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17535
17536 static int
17537 api_lisp_gpe_enable_disable (vat_main_t * vam)
17538 {
17539   unformat_input_t *input = vam->input;
17540   vl_api_gpe_enable_disable_t *mp;
17541   u8 is_set = 0;
17542   u8 is_en = 1;
17543   int ret;
17544
17545   /* Parse args required to build the message */
17546   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17547     {
17548       if (unformat (input, "enable"))
17549         {
17550           is_set = 1;
17551           is_en = 1;
17552         }
17553       else if (unformat (input, "disable"))
17554         {
17555           is_set = 1;
17556           is_en = 0;
17557         }
17558       else
17559         break;
17560     }
17561
17562   if (is_set == 0)
17563     {
17564       errmsg ("Value not set");
17565       return -99;
17566     }
17567
17568   /* Construct the API message */
17569   M (GPE_ENABLE_DISABLE, mp);
17570
17571   mp->is_en = is_en;
17572
17573   /* send it... */
17574   S (mp);
17575
17576   /* Wait for a reply... */
17577   W (ret);
17578   return ret;
17579 }
17580
17581 static int
17582 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17583 {
17584   unformat_input_t *input = vam->input;
17585   vl_api_one_rloc_probe_enable_disable_t *mp;
17586   u8 is_set = 0;
17587   u8 is_en = 0;
17588   int ret;
17589
17590   /* Parse args required to build the message */
17591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17592     {
17593       if (unformat (input, "enable"))
17594         {
17595           is_set = 1;
17596           is_en = 1;
17597         }
17598       else if (unformat (input, "disable"))
17599         is_set = 1;
17600       else
17601         break;
17602     }
17603
17604   if (!is_set)
17605     {
17606       errmsg ("Value not set");
17607       return -99;
17608     }
17609
17610   /* Construct the API message */
17611   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17612
17613   mp->is_enabled = is_en;
17614
17615   /* send it... */
17616   S (mp);
17617
17618   /* Wait for a reply... */
17619   W (ret);
17620   return ret;
17621 }
17622
17623 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17624
17625 static int
17626 api_one_map_register_enable_disable (vat_main_t * vam)
17627 {
17628   unformat_input_t *input = vam->input;
17629   vl_api_one_map_register_enable_disable_t *mp;
17630   u8 is_set = 0;
17631   u8 is_en = 0;
17632   int ret;
17633
17634   /* Parse args required to build the message */
17635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17636     {
17637       if (unformat (input, "enable"))
17638         {
17639           is_set = 1;
17640           is_en = 1;
17641         }
17642       else if (unformat (input, "disable"))
17643         is_set = 1;
17644       else
17645         break;
17646     }
17647
17648   if (!is_set)
17649     {
17650       errmsg ("Value not set");
17651       return -99;
17652     }
17653
17654   /* Construct the API message */
17655   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17656
17657   mp->is_enabled = is_en;
17658
17659   /* send it... */
17660   S (mp);
17661
17662   /* Wait for a reply... */
17663   W (ret);
17664   return ret;
17665 }
17666
17667 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17668
17669 static int
17670 api_one_enable_disable (vat_main_t * vam)
17671 {
17672   unformat_input_t *input = vam->input;
17673   vl_api_one_enable_disable_t *mp;
17674   u8 is_set = 0;
17675   u8 is_en = 0;
17676   int ret;
17677
17678   /* Parse args required to build the message */
17679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17680     {
17681       if (unformat (input, "enable"))
17682         {
17683           is_set = 1;
17684           is_en = 1;
17685         }
17686       else if (unformat (input, "disable"))
17687         {
17688           is_set = 1;
17689         }
17690       else
17691         break;
17692     }
17693
17694   if (!is_set)
17695     {
17696       errmsg ("Value not set");
17697       return -99;
17698     }
17699
17700   /* Construct the API message */
17701   M (ONE_ENABLE_DISABLE, mp);
17702
17703   mp->is_en = is_en;
17704
17705   /* send it... */
17706   S (mp);
17707
17708   /* Wait for a reply... */
17709   W (ret);
17710   return ret;
17711 }
17712
17713 #define api_lisp_enable_disable api_one_enable_disable
17714
17715 static int
17716 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17717 {
17718   unformat_input_t *input = vam->input;
17719   vl_api_one_enable_disable_xtr_mode_t *mp;
17720   u8 is_set = 0;
17721   u8 is_en = 0;
17722   int ret;
17723
17724   /* Parse args required to build the message */
17725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17726     {
17727       if (unformat (input, "enable"))
17728         {
17729           is_set = 1;
17730           is_en = 1;
17731         }
17732       else if (unformat (input, "disable"))
17733         {
17734           is_set = 1;
17735         }
17736       else
17737         break;
17738     }
17739
17740   if (!is_set)
17741     {
17742       errmsg ("Value not set");
17743       return -99;
17744     }
17745
17746   /* Construct the API message */
17747   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17748
17749   mp->is_en = is_en;
17750
17751   /* send it... */
17752   S (mp);
17753
17754   /* Wait for a reply... */
17755   W (ret);
17756   return ret;
17757 }
17758
17759 static int
17760 api_one_show_xtr_mode (vat_main_t * vam)
17761 {
17762   vl_api_one_show_xtr_mode_t *mp;
17763   int ret;
17764
17765   /* Construct the API message */
17766   M (ONE_SHOW_XTR_MODE, mp);
17767
17768   /* send it... */
17769   S (mp);
17770
17771   /* Wait for a reply... */
17772   W (ret);
17773   return ret;
17774 }
17775
17776 static int
17777 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17778 {
17779   unformat_input_t *input = vam->input;
17780   vl_api_one_enable_disable_pitr_mode_t *mp;
17781   u8 is_set = 0;
17782   u8 is_en = 0;
17783   int ret;
17784
17785   /* Parse args required to build the message */
17786   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17787     {
17788       if (unformat (input, "enable"))
17789         {
17790           is_set = 1;
17791           is_en = 1;
17792         }
17793       else if (unformat (input, "disable"))
17794         {
17795           is_set = 1;
17796         }
17797       else
17798         break;
17799     }
17800
17801   if (!is_set)
17802     {
17803       errmsg ("Value not set");
17804       return -99;
17805     }
17806
17807   /* Construct the API message */
17808   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17809
17810   mp->is_en = is_en;
17811
17812   /* send it... */
17813   S (mp);
17814
17815   /* Wait for a reply... */
17816   W (ret);
17817   return ret;
17818 }
17819
17820 static int
17821 api_one_show_pitr_mode (vat_main_t * vam)
17822 {
17823   vl_api_one_show_pitr_mode_t *mp;
17824   int ret;
17825
17826   /* Construct the API message */
17827   M (ONE_SHOW_PITR_MODE, mp);
17828
17829   /* send it... */
17830   S (mp);
17831
17832   /* Wait for a reply... */
17833   W (ret);
17834   return ret;
17835 }
17836
17837 static int
17838 api_one_enable_disable_petr_mode (vat_main_t * vam)
17839 {
17840   unformat_input_t *input = vam->input;
17841   vl_api_one_enable_disable_petr_mode_t *mp;
17842   u8 is_set = 0;
17843   u8 is_en = 0;
17844   int ret;
17845
17846   /* Parse args required to build the message */
17847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17848     {
17849       if (unformat (input, "enable"))
17850         {
17851           is_set = 1;
17852           is_en = 1;
17853         }
17854       else if (unformat (input, "disable"))
17855         {
17856           is_set = 1;
17857         }
17858       else
17859         break;
17860     }
17861
17862   if (!is_set)
17863     {
17864       errmsg ("Value not set");
17865       return -99;
17866     }
17867
17868   /* Construct the API message */
17869   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17870
17871   mp->is_en = is_en;
17872
17873   /* send it... */
17874   S (mp);
17875
17876   /* Wait for a reply... */
17877   W (ret);
17878   return ret;
17879 }
17880
17881 static int
17882 api_one_show_petr_mode (vat_main_t * vam)
17883 {
17884   vl_api_one_show_petr_mode_t *mp;
17885   int ret;
17886
17887   /* Construct the API message */
17888   M (ONE_SHOW_PETR_MODE, mp);
17889
17890   /* send it... */
17891   S (mp);
17892
17893   /* Wait for a reply... */
17894   W (ret);
17895   return ret;
17896 }
17897
17898 static int
17899 api_show_one_map_register_state (vat_main_t * vam)
17900 {
17901   vl_api_show_one_map_register_state_t *mp;
17902   int ret;
17903
17904   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17905
17906   /* send */
17907   S (mp);
17908
17909   /* wait for reply */
17910   W (ret);
17911   return ret;
17912 }
17913
17914 #define api_show_lisp_map_register_state api_show_one_map_register_state
17915
17916 static int
17917 api_show_one_rloc_probe_state (vat_main_t * vam)
17918 {
17919   vl_api_show_one_rloc_probe_state_t *mp;
17920   int ret;
17921
17922   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17923
17924   /* send */
17925   S (mp);
17926
17927   /* wait for reply */
17928   W (ret);
17929   return ret;
17930 }
17931
17932 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17933
17934 static int
17935 api_one_add_del_ndp_entry (vat_main_t * vam)
17936 {
17937   vl_api_one_add_del_ndp_entry_t *mp;
17938   unformat_input_t *input = vam->input;
17939   u8 is_add = 1;
17940   u8 mac_set = 0;
17941   u8 bd_set = 0;
17942   u8 ip_set = 0;
17943   u8 mac[6] = { 0, };
17944   u8 ip6[16] = { 0, };
17945   u32 bd = ~0;
17946   int ret;
17947
17948   /* Parse args required to build the message */
17949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17950     {
17951       if (unformat (input, "del"))
17952         is_add = 0;
17953       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17954         mac_set = 1;
17955       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17956         ip_set = 1;
17957       else if (unformat (input, "bd %d", &bd))
17958         bd_set = 1;
17959       else
17960         {
17961           errmsg ("parse error '%U'", format_unformat_error, input);
17962           return -99;
17963         }
17964     }
17965
17966   if (!bd_set || !ip_set || (!mac_set && is_add))
17967     {
17968       errmsg ("Missing BD, IP or MAC!");
17969       return -99;
17970     }
17971
17972   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17973   mp->is_add = is_add;
17974   clib_memcpy (mp->mac, mac, 6);
17975   mp->bd = clib_host_to_net_u32 (bd);
17976   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17977
17978   /* send */
17979   S (mp);
17980
17981   /* wait for reply */
17982   W (ret);
17983   return ret;
17984 }
17985
17986 static int
17987 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17988 {
17989   vl_api_one_add_del_l2_arp_entry_t *mp;
17990   unformat_input_t *input = vam->input;
17991   u8 is_add = 1;
17992   u8 mac_set = 0;
17993   u8 bd_set = 0;
17994   u8 ip_set = 0;
17995   u8 mac[6] = { 0, };
17996   u32 ip4 = 0, bd = ~0;
17997   int ret;
17998
17999   /* Parse args required to build the message */
18000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18001     {
18002       if (unformat (input, "del"))
18003         is_add = 0;
18004       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18005         mac_set = 1;
18006       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
18007         ip_set = 1;
18008       else if (unformat (input, "bd %d", &bd))
18009         bd_set = 1;
18010       else
18011         {
18012           errmsg ("parse error '%U'", format_unformat_error, input);
18013           return -99;
18014         }
18015     }
18016
18017   if (!bd_set || !ip_set || (!mac_set && is_add))
18018     {
18019       errmsg ("Missing BD, IP or MAC!");
18020       return -99;
18021     }
18022
18023   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
18024   mp->is_add = is_add;
18025   clib_memcpy (mp->mac, mac, 6);
18026   mp->bd = clib_host_to_net_u32 (bd);
18027   mp->ip4 = ip4;
18028
18029   /* send */
18030   S (mp);
18031
18032   /* wait for reply */
18033   W (ret);
18034   return ret;
18035 }
18036
18037 static int
18038 api_one_ndp_bd_get (vat_main_t * vam)
18039 {
18040   vl_api_one_ndp_bd_get_t *mp;
18041   int ret;
18042
18043   M (ONE_NDP_BD_GET, mp);
18044
18045   /* send */
18046   S (mp);
18047
18048   /* wait for reply */
18049   W (ret);
18050   return ret;
18051 }
18052
18053 static int
18054 api_one_ndp_entries_get (vat_main_t * vam)
18055 {
18056   vl_api_one_ndp_entries_get_t *mp;
18057   unformat_input_t *input = vam->input;
18058   u8 bd_set = 0;
18059   u32 bd = ~0;
18060   int ret;
18061
18062   /* Parse args required to build the message */
18063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18064     {
18065       if (unformat (input, "bd %d", &bd))
18066         bd_set = 1;
18067       else
18068         {
18069           errmsg ("parse error '%U'", format_unformat_error, input);
18070           return -99;
18071         }
18072     }
18073
18074   if (!bd_set)
18075     {
18076       errmsg ("Expected bridge domain!");
18077       return -99;
18078     }
18079
18080   M (ONE_NDP_ENTRIES_GET, mp);
18081   mp->bd = clib_host_to_net_u32 (bd);
18082
18083   /* send */
18084   S (mp);
18085
18086   /* wait for reply */
18087   W (ret);
18088   return ret;
18089 }
18090
18091 static int
18092 api_one_l2_arp_bd_get (vat_main_t * vam)
18093 {
18094   vl_api_one_l2_arp_bd_get_t *mp;
18095   int ret;
18096
18097   M (ONE_L2_ARP_BD_GET, mp);
18098
18099   /* send */
18100   S (mp);
18101
18102   /* wait for reply */
18103   W (ret);
18104   return ret;
18105 }
18106
18107 static int
18108 api_one_l2_arp_entries_get (vat_main_t * vam)
18109 {
18110   vl_api_one_l2_arp_entries_get_t *mp;
18111   unformat_input_t *input = vam->input;
18112   u8 bd_set = 0;
18113   u32 bd = ~0;
18114   int ret;
18115
18116   /* Parse args required to build the message */
18117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18118     {
18119       if (unformat (input, "bd %d", &bd))
18120         bd_set = 1;
18121       else
18122         {
18123           errmsg ("parse error '%U'", format_unformat_error, input);
18124           return -99;
18125         }
18126     }
18127
18128   if (!bd_set)
18129     {
18130       errmsg ("Expected bridge domain!");
18131       return -99;
18132     }
18133
18134   M (ONE_L2_ARP_ENTRIES_GET, mp);
18135   mp->bd = clib_host_to_net_u32 (bd);
18136
18137   /* send */
18138   S (mp);
18139
18140   /* wait for reply */
18141   W (ret);
18142   return ret;
18143 }
18144
18145 static int
18146 api_one_stats_enable_disable (vat_main_t * vam)
18147 {
18148   vl_api_one_stats_enable_disable_t *mp;
18149   unformat_input_t *input = vam->input;
18150   u8 is_set = 0;
18151   u8 is_en = 0;
18152   int ret;
18153
18154   /* Parse args required to build the message */
18155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18156     {
18157       if (unformat (input, "enable"))
18158         {
18159           is_set = 1;
18160           is_en = 1;
18161         }
18162       else if (unformat (input, "disable"))
18163         {
18164           is_set = 1;
18165         }
18166       else
18167         break;
18168     }
18169
18170   if (!is_set)
18171     {
18172       errmsg ("Value not set");
18173       return -99;
18174     }
18175
18176   M (ONE_STATS_ENABLE_DISABLE, mp);
18177   mp->is_en = is_en;
18178
18179   /* send */
18180   S (mp);
18181
18182   /* wait for reply */
18183   W (ret);
18184   return ret;
18185 }
18186
18187 static int
18188 api_show_one_stats_enable_disable (vat_main_t * vam)
18189 {
18190   vl_api_show_one_stats_enable_disable_t *mp;
18191   int ret;
18192
18193   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18194
18195   /* send */
18196   S (mp);
18197
18198   /* wait for reply */
18199   W (ret);
18200   return ret;
18201 }
18202
18203 static int
18204 api_show_one_map_request_mode (vat_main_t * vam)
18205 {
18206   vl_api_show_one_map_request_mode_t *mp;
18207   int ret;
18208
18209   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18210
18211   /* send */
18212   S (mp);
18213
18214   /* wait for reply */
18215   W (ret);
18216   return ret;
18217 }
18218
18219 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18220
18221 static int
18222 api_one_map_request_mode (vat_main_t * vam)
18223 {
18224   unformat_input_t *input = vam->input;
18225   vl_api_one_map_request_mode_t *mp;
18226   u8 mode = 0;
18227   int ret;
18228
18229   /* Parse args required to build the message */
18230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18231     {
18232       if (unformat (input, "dst-only"))
18233         mode = 0;
18234       else if (unformat (input, "src-dst"))
18235         mode = 1;
18236       else
18237         {
18238           errmsg ("parse error '%U'", format_unformat_error, input);
18239           return -99;
18240         }
18241     }
18242
18243   M (ONE_MAP_REQUEST_MODE, mp);
18244
18245   mp->mode = mode;
18246
18247   /* send */
18248   S (mp);
18249
18250   /* wait for reply */
18251   W (ret);
18252   return ret;
18253 }
18254
18255 #define api_lisp_map_request_mode api_one_map_request_mode
18256
18257 /**
18258  * Enable/disable ONE proxy ITR.
18259  *
18260  * @param vam vpp API test context
18261  * @return return code
18262  */
18263 static int
18264 api_one_pitr_set_locator_set (vat_main_t * vam)
18265 {
18266   u8 ls_name_set = 0;
18267   unformat_input_t *input = vam->input;
18268   vl_api_one_pitr_set_locator_set_t *mp;
18269   u8 is_add = 1;
18270   u8 *ls_name = 0;
18271   int ret;
18272
18273   /* Parse args required to build the message */
18274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18275     {
18276       if (unformat (input, "del"))
18277         is_add = 0;
18278       else if (unformat (input, "locator-set %s", &ls_name))
18279         ls_name_set = 1;
18280       else
18281         {
18282           errmsg ("parse error '%U'", format_unformat_error, input);
18283           return -99;
18284         }
18285     }
18286
18287   if (!ls_name_set)
18288     {
18289       errmsg ("locator-set name not set!");
18290       return -99;
18291     }
18292
18293   M (ONE_PITR_SET_LOCATOR_SET, mp);
18294
18295   mp->is_add = is_add;
18296   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18297   vec_free (ls_name);
18298
18299   /* send */
18300   S (mp);
18301
18302   /* wait for reply */
18303   W (ret);
18304   return ret;
18305 }
18306
18307 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18308
18309 static int
18310 api_one_nsh_set_locator_set (vat_main_t * vam)
18311 {
18312   u8 ls_name_set = 0;
18313   unformat_input_t *input = vam->input;
18314   vl_api_one_nsh_set_locator_set_t *mp;
18315   u8 is_add = 1;
18316   u8 *ls_name = 0;
18317   int ret;
18318
18319   /* Parse args required to build the message */
18320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18321     {
18322       if (unformat (input, "del"))
18323         is_add = 0;
18324       else if (unformat (input, "ls %s", &ls_name))
18325         ls_name_set = 1;
18326       else
18327         {
18328           errmsg ("parse error '%U'", format_unformat_error, input);
18329           return -99;
18330         }
18331     }
18332
18333   if (!ls_name_set && is_add)
18334     {
18335       errmsg ("locator-set name not set!");
18336       return -99;
18337     }
18338
18339   M (ONE_NSH_SET_LOCATOR_SET, mp);
18340
18341   mp->is_add = is_add;
18342   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18343   vec_free (ls_name);
18344
18345   /* send */
18346   S (mp);
18347
18348   /* wait for reply */
18349   W (ret);
18350   return ret;
18351 }
18352
18353 static int
18354 api_show_one_pitr (vat_main_t * vam)
18355 {
18356   vl_api_show_one_pitr_t *mp;
18357   int ret;
18358
18359   if (!vam->json_output)
18360     {
18361       print (vam->ofp, "%=20s", "lisp status:");
18362     }
18363
18364   M (SHOW_ONE_PITR, mp);
18365   /* send it... */
18366   S (mp);
18367
18368   /* Wait for a reply... */
18369   W (ret);
18370   return ret;
18371 }
18372
18373 #define api_show_lisp_pitr api_show_one_pitr
18374
18375 static int
18376 api_one_use_petr (vat_main_t * vam)
18377 {
18378   unformat_input_t *input = vam->input;
18379   vl_api_one_use_petr_t *mp;
18380   u8 is_add = 0;
18381   ip_address_t ip;
18382   int ret;
18383
18384   clib_memset (&ip, 0, sizeof (ip));
18385
18386   /* Parse args required to build the message */
18387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18388     {
18389       if (unformat (input, "disable"))
18390         is_add = 0;
18391       else
18392         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18393         {
18394           is_add = 1;
18395           ip_addr_version (&ip) = IP4;
18396         }
18397       else
18398         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18399         {
18400           is_add = 1;
18401           ip_addr_version (&ip) = IP6;
18402         }
18403       else
18404         {
18405           errmsg ("parse error '%U'", format_unformat_error, input);
18406           return -99;
18407         }
18408     }
18409
18410   M (ONE_USE_PETR, mp);
18411
18412   mp->is_add = is_add;
18413   if (is_add)
18414     {
18415       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18416       if (mp->is_ip4)
18417         clib_memcpy (mp->address, &ip, 4);
18418       else
18419         clib_memcpy (mp->address, &ip, 16);
18420     }
18421
18422   /* send */
18423   S (mp);
18424
18425   /* wait for reply */
18426   W (ret);
18427   return ret;
18428 }
18429
18430 #define api_lisp_use_petr api_one_use_petr
18431
18432 static int
18433 api_show_one_nsh_mapping (vat_main_t * vam)
18434 {
18435   vl_api_show_one_use_petr_t *mp;
18436   int ret;
18437
18438   if (!vam->json_output)
18439     {
18440       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18441     }
18442
18443   M (SHOW_ONE_NSH_MAPPING, mp);
18444   /* send it... */
18445   S (mp);
18446
18447   /* Wait for a reply... */
18448   W (ret);
18449   return ret;
18450 }
18451
18452 static int
18453 api_show_one_use_petr (vat_main_t * vam)
18454 {
18455   vl_api_show_one_use_petr_t *mp;
18456   int ret;
18457
18458   if (!vam->json_output)
18459     {
18460       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18461     }
18462
18463   M (SHOW_ONE_USE_PETR, mp);
18464   /* send it... */
18465   S (mp);
18466
18467   /* Wait for a reply... */
18468   W (ret);
18469   return ret;
18470 }
18471
18472 #define api_show_lisp_use_petr api_show_one_use_petr
18473
18474 /**
18475  * Add/delete mapping between vni and vrf
18476  */
18477 static int
18478 api_one_eid_table_add_del_map (vat_main_t * vam)
18479 {
18480   unformat_input_t *input = vam->input;
18481   vl_api_one_eid_table_add_del_map_t *mp;
18482   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18483   u32 vni, vrf, bd_index;
18484   int ret;
18485
18486   /* Parse args required to build the message */
18487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18488     {
18489       if (unformat (input, "del"))
18490         is_add = 0;
18491       else if (unformat (input, "vrf %d", &vrf))
18492         vrf_set = 1;
18493       else if (unformat (input, "bd_index %d", &bd_index))
18494         bd_index_set = 1;
18495       else if (unformat (input, "vni %d", &vni))
18496         vni_set = 1;
18497       else
18498         break;
18499     }
18500
18501   if (!vni_set || (!vrf_set && !bd_index_set))
18502     {
18503       errmsg ("missing arguments!");
18504       return -99;
18505     }
18506
18507   if (vrf_set && bd_index_set)
18508     {
18509       errmsg ("error: both vrf and bd entered!");
18510       return -99;
18511     }
18512
18513   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18514
18515   mp->is_add = is_add;
18516   mp->vni = htonl (vni);
18517   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18518   mp->is_l2 = bd_index_set;
18519
18520   /* send */
18521   S (mp);
18522
18523   /* wait for reply */
18524   W (ret);
18525   return ret;
18526 }
18527
18528 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18529
18530 uword
18531 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18532 {
18533   u32 *action = va_arg (*args, u32 *);
18534   u8 *s = 0;
18535
18536   if (unformat (input, "%s", &s))
18537     {
18538       if (!strcmp ((char *) s, "no-action"))
18539         action[0] = 0;
18540       else if (!strcmp ((char *) s, "natively-forward"))
18541         action[0] = 1;
18542       else if (!strcmp ((char *) s, "send-map-request"))
18543         action[0] = 2;
18544       else if (!strcmp ((char *) s, "drop"))
18545         action[0] = 3;
18546       else
18547         {
18548           clib_warning ("invalid action: '%s'", s);
18549           action[0] = 3;
18550         }
18551     }
18552   else
18553     return 0;
18554
18555   vec_free (s);
18556   return 1;
18557 }
18558
18559 /**
18560  * Add/del remote mapping to/from ONE control plane
18561  *
18562  * @param vam vpp API test context
18563  * @return return code
18564  */
18565 static int
18566 api_one_add_del_remote_mapping (vat_main_t * vam)
18567 {
18568   unformat_input_t *input = vam->input;
18569   vl_api_one_add_del_remote_mapping_t *mp;
18570   u32 vni = 0;
18571   lisp_eid_vat_t _eid, *eid = &_eid;
18572   lisp_eid_vat_t _seid, *seid = &_seid;
18573   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18574   u32 action = ~0, p, w, data_len;
18575   ip4_address_t rloc4;
18576   ip6_address_t rloc6;
18577   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18578   int ret;
18579
18580   clib_memset (&rloc, 0, sizeof (rloc));
18581
18582   /* Parse args required to build the message */
18583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18584     {
18585       if (unformat (input, "del-all"))
18586         {
18587           del_all = 1;
18588         }
18589       else if (unformat (input, "del"))
18590         {
18591           is_add = 0;
18592         }
18593       else if (unformat (input, "add"))
18594         {
18595           is_add = 1;
18596         }
18597       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18598         {
18599           eid_set = 1;
18600         }
18601       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18602         {
18603           seid_set = 1;
18604         }
18605       else if (unformat (input, "vni %d", &vni))
18606         {
18607           ;
18608         }
18609       else if (unformat (input, "p %d w %d", &p, &w))
18610         {
18611           if (!curr_rloc)
18612             {
18613               errmsg ("No RLOC configured for setting priority/weight!");
18614               return -99;
18615             }
18616           curr_rloc->priority = p;
18617           curr_rloc->weight = w;
18618         }
18619       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18620         {
18621           rloc.is_ip4 = 1;
18622           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18623           vec_add1 (rlocs, rloc);
18624           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18625         }
18626       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18627         {
18628           rloc.is_ip4 = 0;
18629           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18630           vec_add1 (rlocs, rloc);
18631           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18632         }
18633       else if (unformat (input, "action %U",
18634                          unformat_negative_mapping_action, &action))
18635         {
18636           ;
18637         }
18638       else
18639         {
18640           clib_warning ("parse error '%U'", format_unformat_error, input);
18641           return -99;
18642         }
18643     }
18644
18645   if (0 == eid_set)
18646     {
18647       errmsg ("missing params!");
18648       return -99;
18649     }
18650
18651   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18652     {
18653       errmsg ("no action set for negative map-reply!");
18654       return -99;
18655     }
18656
18657   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18658
18659   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18660   mp->is_add = is_add;
18661   mp->vni = htonl (vni);
18662   mp->action = (u8) action;
18663   mp->is_src_dst = seid_set;
18664   mp->eid_len = eid->len;
18665   mp->seid_len = seid->len;
18666   mp->del_all = del_all;
18667   mp->eid_type = eid->type;
18668   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18669   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18670
18671   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18672   clib_memcpy (mp->rlocs, rlocs, data_len);
18673   vec_free (rlocs);
18674
18675   /* send it... */
18676   S (mp);
18677
18678   /* Wait for a reply... */
18679   W (ret);
18680   return ret;
18681 }
18682
18683 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18684
18685 /**
18686  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18687  * forwarding entries in data-plane accordingly.
18688  *
18689  * @param vam vpp API test context
18690  * @return return code
18691  */
18692 static int
18693 api_one_add_del_adjacency (vat_main_t * vam)
18694 {
18695   unformat_input_t *input = vam->input;
18696   vl_api_one_add_del_adjacency_t *mp;
18697   u32 vni = 0;
18698   ip4_address_t leid4, reid4;
18699   ip6_address_t leid6, reid6;
18700   u8 reid_mac[6] = { 0 };
18701   u8 leid_mac[6] = { 0 };
18702   u8 reid_type, leid_type;
18703   u32 leid_len = 0, reid_len = 0, len;
18704   u8 is_add = 1;
18705   int ret;
18706
18707   leid_type = reid_type = (u8) ~ 0;
18708
18709   /* Parse args required to build the message */
18710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18711     {
18712       if (unformat (input, "del"))
18713         {
18714           is_add = 0;
18715         }
18716       else if (unformat (input, "add"))
18717         {
18718           is_add = 1;
18719         }
18720       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18721                          &reid4, &len))
18722         {
18723           reid_type = 0;        /* ipv4 */
18724           reid_len = len;
18725         }
18726       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18727                          &reid6, &len))
18728         {
18729           reid_type = 1;        /* ipv6 */
18730           reid_len = len;
18731         }
18732       else if (unformat (input, "reid %U", unformat_ethernet_address,
18733                          reid_mac))
18734         {
18735           reid_type = 2;        /* mac */
18736         }
18737       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18738                          &leid4, &len))
18739         {
18740           leid_type = 0;        /* ipv4 */
18741           leid_len = len;
18742         }
18743       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18744                          &leid6, &len))
18745         {
18746           leid_type = 1;        /* ipv6 */
18747           leid_len = len;
18748         }
18749       else if (unformat (input, "leid %U", unformat_ethernet_address,
18750                          leid_mac))
18751         {
18752           leid_type = 2;        /* mac */
18753         }
18754       else if (unformat (input, "vni %d", &vni))
18755         {
18756           ;
18757         }
18758       else
18759         {
18760           errmsg ("parse error '%U'", format_unformat_error, input);
18761           return -99;
18762         }
18763     }
18764
18765   if ((u8) ~ 0 == reid_type)
18766     {
18767       errmsg ("missing params!");
18768       return -99;
18769     }
18770
18771   if (leid_type != reid_type)
18772     {
18773       errmsg ("remote and local EIDs are of different types!");
18774       return -99;
18775     }
18776
18777   M (ONE_ADD_DEL_ADJACENCY, mp);
18778   mp->is_add = is_add;
18779   mp->vni = htonl (vni);
18780   mp->leid_len = leid_len;
18781   mp->reid_len = reid_len;
18782   mp->eid_type = reid_type;
18783
18784   switch (mp->eid_type)
18785     {
18786     case 0:
18787       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18788       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18789       break;
18790     case 1:
18791       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18792       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18793       break;
18794     case 2:
18795       clib_memcpy (mp->leid, leid_mac, 6);
18796       clib_memcpy (mp->reid, reid_mac, 6);
18797       break;
18798     default:
18799       errmsg ("unknown EID type %d!", mp->eid_type);
18800       return 0;
18801     }
18802
18803   /* send it... */
18804   S (mp);
18805
18806   /* Wait for a reply... */
18807   W (ret);
18808   return ret;
18809 }
18810
18811 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18812
18813 uword
18814 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18815 {
18816   u32 *mode = va_arg (*args, u32 *);
18817
18818   if (unformat (input, "lisp"))
18819     *mode = 0;
18820   else if (unformat (input, "vxlan"))
18821     *mode = 1;
18822   else
18823     return 0;
18824
18825   return 1;
18826 }
18827
18828 static int
18829 api_gpe_get_encap_mode (vat_main_t * vam)
18830 {
18831   vl_api_gpe_get_encap_mode_t *mp;
18832   int ret;
18833
18834   /* Construct the API message */
18835   M (GPE_GET_ENCAP_MODE, mp);
18836
18837   /* send it... */
18838   S (mp);
18839
18840   /* Wait for a reply... */
18841   W (ret);
18842   return ret;
18843 }
18844
18845 static int
18846 api_gpe_set_encap_mode (vat_main_t * vam)
18847 {
18848   unformat_input_t *input = vam->input;
18849   vl_api_gpe_set_encap_mode_t *mp;
18850   int ret;
18851   u32 mode = 0;
18852
18853   /* Parse args required to build the message */
18854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18855     {
18856       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18857         ;
18858       else
18859         break;
18860     }
18861
18862   /* Construct the API message */
18863   M (GPE_SET_ENCAP_MODE, mp);
18864
18865   mp->mode = mode;
18866
18867   /* send it... */
18868   S (mp);
18869
18870   /* Wait for a reply... */
18871   W (ret);
18872   return ret;
18873 }
18874
18875 static int
18876 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18877 {
18878   unformat_input_t *input = vam->input;
18879   vl_api_gpe_add_del_iface_t *mp;
18880   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18881   u32 dp_table = 0, vni = 0;
18882   int ret;
18883
18884   /* Parse args required to build the message */
18885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18886     {
18887       if (unformat (input, "up"))
18888         {
18889           action_set = 1;
18890           is_add = 1;
18891         }
18892       else if (unformat (input, "down"))
18893         {
18894           action_set = 1;
18895           is_add = 0;
18896         }
18897       else if (unformat (input, "table_id %d", &dp_table))
18898         {
18899           dp_table_set = 1;
18900         }
18901       else if (unformat (input, "bd_id %d", &dp_table))
18902         {
18903           dp_table_set = 1;
18904           is_l2 = 1;
18905         }
18906       else if (unformat (input, "vni %d", &vni))
18907         {
18908           vni_set = 1;
18909         }
18910       else
18911         break;
18912     }
18913
18914   if (action_set == 0)
18915     {
18916       errmsg ("Action not set");
18917       return -99;
18918     }
18919   if (dp_table_set == 0 || vni_set == 0)
18920     {
18921       errmsg ("vni and dp_table must be set");
18922       return -99;
18923     }
18924
18925   /* Construct the API message */
18926   M (GPE_ADD_DEL_IFACE, mp);
18927
18928   mp->is_add = is_add;
18929   mp->dp_table = clib_host_to_net_u32 (dp_table);
18930   mp->is_l2 = is_l2;
18931   mp->vni = clib_host_to_net_u32 (vni);
18932
18933   /* send it... */
18934   S (mp);
18935
18936   /* Wait for a reply... */
18937   W (ret);
18938   return ret;
18939 }
18940
18941 static int
18942 api_one_map_register_fallback_threshold (vat_main_t * vam)
18943 {
18944   unformat_input_t *input = vam->input;
18945   vl_api_one_map_register_fallback_threshold_t *mp;
18946   u32 value = 0;
18947   u8 is_set = 0;
18948   int ret;
18949
18950   /* Parse args required to build the message */
18951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18952     {
18953       if (unformat (input, "%u", &value))
18954         is_set = 1;
18955       else
18956         {
18957           clib_warning ("parse error '%U'", format_unformat_error, input);
18958           return -99;
18959         }
18960     }
18961
18962   if (!is_set)
18963     {
18964       errmsg ("fallback threshold value is missing!");
18965       return -99;
18966     }
18967
18968   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18969   mp->value = clib_host_to_net_u32 (value);
18970
18971   /* send it... */
18972   S (mp);
18973
18974   /* Wait for a reply... */
18975   W (ret);
18976   return ret;
18977 }
18978
18979 static int
18980 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18981 {
18982   vl_api_show_one_map_register_fallback_threshold_t *mp;
18983   int ret;
18984
18985   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18986
18987   /* send it... */
18988   S (mp);
18989
18990   /* Wait for a reply... */
18991   W (ret);
18992   return ret;
18993 }
18994
18995 uword
18996 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18997 {
18998   u32 *proto = va_arg (*args, u32 *);
18999
19000   if (unformat (input, "udp"))
19001     *proto = 1;
19002   else if (unformat (input, "api"))
19003     *proto = 2;
19004   else
19005     return 0;
19006
19007   return 1;
19008 }
19009
19010 static int
19011 api_one_set_transport_protocol (vat_main_t * vam)
19012 {
19013   unformat_input_t *input = vam->input;
19014   vl_api_one_set_transport_protocol_t *mp;
19015   u8 is_set = 0;
19016   u32 protocol = 0;
19017   int ret;
19018
19019   /* Parse args required to build the message */
19020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19021     {
19022       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
19023         is_set = 1;
19024       else
19025         {
19026           clib_warning ("parse error '%U'", format_unformat_error, input);
19027           return -99;
19028         }
19029     }
19030
19031   if (!is_set)
19032     {
19033       errmsg ("Transport protocol missing!");
19034       return -99;
19035     }
19036
19037   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
19038   mp->protocol = (u8) protocol;
19039
19040   /* send it... */
19041   S (mp);
19042
19043   /* Wait for a reply... */
19044   W (ret);
19045   return ret;
19046 }
19047
19048 static int
19049 api_one_get_transport_protocol (vat_main_t * vam)
19050 {
19051   vl_api_one_get_transport_protocol_t *mp;
19052   int ret;
19053
19054   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19055
19056   /* send it... */
19057   S (mp);
19058
19059   /* Wait for a reply... */
19060   W (ret);
19061   return ret;
19062 }
19063
19064 static int
19065 api_one_map_register_set_ttl (vat_main_t * vam)
19066 {
19067   unformat_input_t *input = vam->input;
19068   vl_api_one_map_register_set_ttl_t *mp;
19069   u32 ttl = 0;
19070   u8 is_set = 0;
19071   int ret;
19072
19073   /* Parse args required to build the message */
19074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19075     {
19076       if (unformat (input, "%u", &ttl))
19077         is_set = 1;
19078       else
19079         {
19080           clib_warning ("parse error '%U'", format_unformat_error, input);
19081           return -99;
19082         }
19083     }
19084
19085   if (!is_set)
19086     {
19087       errmsg ("TTL value missing!");
19088       return -99;
19089     }
19090
19091   M (ONE_MAP_REGISTER_SET_TTL, mp);
19092   mp->ttl = clib_host_to_net_u32 (ttl);
19093
19094   /* send it... */
19095   S (mp);
19096
19097   /* Wait for a reply... */
19098   W (ret);
19099   return ret;
19100 }
19101
19102 static int
19103 api_show_one_map_register_ttl (vat_main_t * vam)
19104 {
19105   vl_api_show_one_map_register_ttl_t *mp;
19106   int ret;
19107
19108   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19109
19110   /* send it... */
19111   S (mp);
19112
19113   /* Wait for a reply... */
19114   W (ret);
19115   return ret;
19116 }
19117
19118 /**
19119  * Add/del map request itr rlocs from ONE control plane and updates
19120  *
19121  * @param vam vpp API test context
19122  * @return return code
19123  */
19124 static int
19125 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19126 {
19127   unformat_input_t *input = vam->input;
19128   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19129   u8 *locator_set_name = 0;
19130   u8 locator_set_name_set = 0;
19131   u8 is_add = 1;
19132   int ret;
19133
19134   /* Parse args required to build the message */
19135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19136     {
19137       if (unformat (input, "del"))
19138         {
19139           is_add = 0;
19140         }
19141       else if (unformat (input, "%_%v%_", &locator_set_name))
19142         {
19143           locator_set_name_set = 1;
19144         }
19145       else
19146         {
19147           clib_warning ("parse error '%U'", format_unformat_error, input);
19148           return -99;
19149         }
19150     }
19151
19152   if (is_add && !locator_set_name_set)
19153     {
19154       errmsg ("itr-rloc is not set!");
19155       return -99;
19156     }
19157
19158   if (is_add && vec_len (locator_set_name) > 64)
19159     {
19160       errmsg ("itr-rloc locator-set name too long");
19161       vec_free (locator_set_name);
19162       return -99;
19163     }
19164
19165   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19166   mp->is_add = is_add;
19167   if (is_add)
19168     {
19169       clib_memcpy (mp->locator_set_name, locator_set_name,
19170                    vec_len (locator_set_name));
19171     }
19172   else
19173     {
19174       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19175     }
19176   vec_free (locator_set_name);
19177
19178   /* send it... */
19179   S (mp);
19180
19181   /* Wait for a reply... */
19182   W (ret);
19183   return ret;
19184 }
19185
19186 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19187
19188 static int
19189 api_one_locator_dump (vat_main_t * vam)
19190 {
19191   unformat_input_t *input = vam->input;
19192   vl_api_one_locator_dump_t *mp;
19193   vl_api_control_ping_t *mp_ping;
19194   u8 is_index_set = 0, is_name_set = 0;
19195   u8 *ls_name = 0;
19196   u32 ls_index = ~0;
19197   int ret;
19198
19199   /* Parse args required to build the message */
19200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19201     {
19202       if (unformat (input, "ls_name %_%v%_", &ls_name))
19203         {
19204           is_name_set = 1;
19205         }
19206       else if (unformat (input, "ls_index %d", &ls_index))
19207         {
19208           is_index_set = 1;
19209         }
19210       else
19211         {
19212           errmsg ("parse error '%U'", format_unformat_error, input);
19213           return -99;
19214         }
19215     }
19216
19217   if (!is_index_set && !is_name_set)
19218     {
19219       errmsg ("error: expected one of index or name!");
19220       return -99;
19221     }
19222
19223   if (is_index_set && is_name_set)
19224     {
19225       errmsg ("error: only one param expected!");
19226       return -99;
19227     }
19228
19229   if (vec_len (ls_name) > 62)
19230     {
19231       errmsg ("error: locator set name too long!");
19232       return -99;
19233     }
19234
19235   if (!vam->json_output)
19236     {
19237       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19238     }
19239
19240   M (ONE_LOCATOR_DUMP, mp);
19241   mp->is_index_set = is_index_set;
19242
19243   if (is_index_set)
19244     mp->ls_index = clib_host_to_net_u32 (ls_index);
19245   else
19246     {
19247       vec_add1 (ls_name, 0);
19248       strncpy ((char *) mp->ls_name, (char *) ls_name,
19249                sizeof (mp->ls_name) - 1);
19250     }
19251
19252   /* send it... */
19253   S (mp);
19254
19255   /* Use a control ping for synchronization */
19256   MPING (CONTROL_PING, mp_ping);
19257   S (mp_ping);
19258
19259   /* Wait for a reply... */
19260   W (ret);
19261   return ret;
19262 }
19263
19264 #define api_lisp_locator_dump api_one_locator_dump
19265
19266 static int
19267 api_one_locator_set_dump (vat_main_t * vam)
19268 {
19269   vl_api_one_locator_set_dump_t *mp;
19270   vl_api_control_ping_t *mp_ping;
19271   unformat_input_t *input = vam->input;
19272   u8 filter = 0;
19273   int ret;
19274
19275   /* Parse args required to build the message */
19276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19277     {
19278       if (unformat (input, "local"))
19279         {
19280           filter = 1;
19281         }
19282       else if (unformat (input, "remote"))
19283         {
19284           filter = 2;
19285         }
19286       else
19287         {
19288           errmsg ("parse error '%U'", format_unformat_error, input);
19289           return -99;
19290         }
19291     }
19292
19293   if (!vam->json_output)
19294     {
19295       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19296     }
19297
19298   M (ONE_LOCATOR_SET_DUMP, mp);
19299
19300   mp->filter = filter;
19301
19302   /* send it... */
19303   S (mp);
19304
19305   /* Use a control ping for synchronization */
19306   MPING (CONTROL_PING, mp_ping);
19307   S (mp_ping);
19308
19309   /* Wait for a reply... */
19310   W (ret);
19311   return ret;
19312 }
19313
19314 #define api_lisp_locator_set_dump api_one_locator_set_dump
19315
19316 static int
19317 api_one_eid_table_map_dump (vat_main_t * vam)
19318 {
19319   u8 is_l2 = 0;
19320   u8 mode_set = 0;
19321   unformat_input_t *input = vam->input;
19322   vl_api_one_eid_table_map_dump_t *mp;
19323   vl_api_control_ping_t *mp_ping;
19324   int ret;
19325
19326   /* Parse args required to build the message */
19327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19328     {
19329       if (unformat (input, "l2"))
19330         {
19331           is_l2 = 1;
19332           mode_set = 1;
19333         }
19334       else if (unformat (input, "l3"))
19335         {
19336           is_l2 = 0;
19337           mode_set = 1;
19338         }
19339       else
19340         {
19341           errmsg ("parse error '%U'", format_unformat_error, input);
19342           return -99;
19343         }
19344     }
19345
19346   if (!mode_set)
19347     {
19348       errmsg ("expected one of 'l2' or 'l3' parameter!");
19349       return -99;
19350     }
19351
19352   if (!vam->json_output)
19353     {
19354       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19355     }
19356
19357   M (ONE_EID_TABLE_MAP_DUMP, mp);
19358   mp->is_l2 = is_l2;
19359
19360   /* send it... */
19361   S (mp);
19362
19363   /* Use a control ping for synchronization */
19364   MPING (CONTROL_PING, mp_ping);
19365   S (mp_ping);
19366
19367   /* Wait for a reply... */
19368   W (ret);
19369   return ret;
19370 }
19371
19372 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19373
19374 static int
19375 api_one_eid_table_vni_dump (vat_main_t * vam)
19376 {
19377   vl_api_one_eid_table_vni_dump_t *mp;
19378   vl_api_control_ping_t *mp_ping;
19379   int ret;
19380
19381   if (!vam->json_output)
19382     {
19383       print (vam->ofp, "VNI");
19384     }
19385
19386   M (ONE_EID_TABLE_VNI_DUMP, mp);
19387
19388   /* send it... */
19389   S (mp);
19390
19391   /* Use a control ping for synchronization */
19392   MPING (CONTROL_PING, mp_ping);
19393   S (mp_ping);
19394
19395   /* Wait for a reply... */
19396   W (ret);
19397   return ret;
19398 }
19399
19400 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19401
19402 static int
19403 api_one_eid_table_dump (vat_main_t * vam)
19404 {
19405   unformat_input_t *i = vam->input;
19406   vl_api_one_eid_table_dump_t *mp;
19407   vl_api_control_ping_t *mp_ping;
19408   struct in_addr ip4;
19409   struct in6_addr ip6;
19410   u8 mac[6];
19411   u8 eid_type = ~0, eid_set = 0;
19412   u32 prefix_length = ~0, t, vni = 0;
19413   u8 filter = 0;
19414   int ret;
19415   lisp_nsh_api_t nsh;
19416
19417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19418     {
19419       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19420         {
19421           eid_set = 1;
19422           eid_type = 0;
19423           prefix_length = t;
19424         }
19425       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19426         {
19427           eid_set = 1;
19428           eid_type = 1;
19429           prefix_length = t;
19430         }
19431       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19432         {
19433           eid_set = 1;
19434           eid_type = 2;
19435         }
19436       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19437         {
19438           eid_set = 1;
19439           eid_type = 3;
19440         }
19441       else if (unformat (i, "vni %d", &t))
19442         {
19443           vni = t;
19444         }
19445       else if (unformat (i, "local"))
19446         {
19447           filter = 1;
19448         }
19449       else if (unformat (i, "remote"))
19450         {
19451           filter = 2;
19452         }
19453       else
19454         {
19455           errmsg ("parse error '%U'", format_unformat_error, i);
19456           return -99;
19457         }
19458     }
19459
19460   if (!vam->json_output)
19461     {
19462       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19463              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19464     }
19465
19466   M (ONE_EID_TABLE_DUMP, mp);
19467
19468   mp->filter = filter;
19469   if (eid_set)
19470     {
19471       mp->eid_set = 1;
19472       mp->vni = htonl (vni);
19473       mp->eid_type = eid_type;
19474       switch (eid_type)
19475         {
19476         case 0:
19477           mp->prefix_length = prefix_length;
19478           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19479           break;
19480         case 1:
19481           mp->prefix_length = prefix_length;
19482           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19483           break;
19484         case 2:
19485           clib_memcpy (mp->eid, mac, sizeof (mac));
19486           break;
19487         case 3:
19488           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19489           break;
19490         default:
19491           errmsg ("unknown EID type %d!", eid_type);
19492           return -99;
19493         }
19494     }
19495
19496   /* send it... */
19497   S (mp);
19498
19499   /* Use a control ping for synchronization */
19500   MPING (CONTROL_PING, mp_ping);
19501   S (mp_ping);
19502
19503   /* Wait for a reply... */
19504   W (ret);
19505   return ret;
19506 }
19507
19508 #define api_lisp_eid_table_dump api_one_eid_table_dump
19509
19510 static int
19511 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19512 {
19513   unformat_input_t *i = vam->input;
19514   vl_api_gpe_fwd_entries_get_t *mp;
19515   u8 vni_set = 0;
19516   u32 vni = ~0;
19517   int ret;
19518
19519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19520     {
19521       if (unformat (i, "vni %d", &vni))
19522         {
19523           vni_set = 1;
19524         }
19525       else
19526         {
19527           errmsg ("parse error '%U'", format_unformat_error, i);
19528           return -99;
19529         }
19530     }
19531
19532   if (!vni_set)
19533     {
19534       errmsg ("vni not set!");
19535       return -99;
19536     }
19537
19538   if (!vam->json_output)
19539     {
19540       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19541              "leid", "reid");
19542     }
19543
19544   M (GPE_FWD_ENTRIES_GET, mp);
19545   mp->vni = clib_host_to_net_u32 (vni);
19546
19547   /* send it... */
19548   S (mp);
19549
19550   /* Wait for a reply... */
19551   W (ret);
19552   return ret;
19553 }
19554
19555 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19556 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19557 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19558 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19559 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19560 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19561 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19562 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19563
19564 static int
19565 api_one_adjacencies_get (vat_main_t * vam)
19566 {
19567   unformat_input_t *i = vam->input;
19568   vl_api_one_adjacencies_get_t *mp;
19569   u8 vni_set = 0;
19570   u32 vni = ~0;
19571   int ret;
19572
19573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19574     {
19575       if (unformat (i, "vni %d", &vni))
19576         {
19577           vni_set = 1;
19578         }
19579       else
19580         {
19581           errmsg ("parse error '%U'", format_unformat_error, i);
19582           return -99;
19583         }
19584     }
19585
19586   if (!vni_set)
19587     {
19588       errmsg ("vni not set!");
19589       return -99;
19590     }
19591
19592   if (!vam->json_output)
19593     {
19594       print (vam->ofp, "%s %40s", "leid", "reid");
19595     }
19596
19597   M (ONE_ADJACENCIES_GET, mp);
19598   mp->vni = clib_host_to_net_u32 (vni);
19599
19600   /* send it... */
19601   S (mp);
19602
19603   /* Wait for a reply... */
19604   W (ret);
19605   return ret;
19606 }
19607
19608 #define api_lisp_adjacencies_get api_one_adjacencies_get
19609
19610 static int
19611 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19612 {
19613   unformat_input_t *i = vam->input;
19614   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19615   int ret;
19616   u8 ip_family_set = 0, is_ip4 = 1;
19617
19618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19619     {
19620       if (unformat (i, "ip4"))
19621         {
19622           ip_family_set = 1;
19623           is_ip4 = 1;
19624         }
19625       else if (unformat (i, "ip6"))
19626         {
19627           ip_family_set = 1;
19628           is_ip4 = 0;
19629         }
19630       else
19631         {
19632           errmsg ("parse error '%U'", format_unformat_error, i);
19633           return -99;
19634         }
19635     }
19636
19637   if (!ip_family_set)
19638     {
19639       errmsg ("ip family not set!");
19640       return -99;
19641     }
19642
19643   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19644   mp->is_ip4 = is_ip4;
19645
19646   /* send it... */
19647   S (mp);
19648
19649   /* Wait for a reply... */
19650   W (ret);
19651   return ret;
19652 }
19653
19654 static int
19655 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19656 {
19657   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19658   int ret;
19659
19660   if (!vam->json_output)
19661     {
19662       print (vam->ofp, "VNIs");
19663     }
19664
19665   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19666
19667   /* send it... */
19668   S (mp);
19669
19670   /* Wait for a reply... */
19671   W (ret);
19672   return ret;
19673 }
19674
19675 static int
19676 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19677 {
19678   unformat_input_t *i = vam->input;
19679   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19680   int ret = 0;
19681   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19682   struct in_addr ip4;
19683   struct in6_addr ip6;
19684   u32 table_id = 0, nh_sw_if_index = ~0;
19685
19686   clib_memset (&ip4, 0, sizeof (ip4));
19687   clib_memset (&ip6, 0, sizeof (ip6));
19688
19689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19690     {
19691       if (unformat (i, "del"))
19692         is_add = 0;
19693       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19694                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19695         {
19696           ip_set = 1;
19697           is_ip4 = 1;
19698         }
19699       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19700                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19701         {
19702           ip_set = 1;
19703           is_ip4 = 0;
19704         }
19705       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19706         {
19707           ip_set = 1;
19708           is_ip4 = 1;
19709           nh_sw_if_index = ~0;
19710         }
19711       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19712         {
19713           ip_set = 1;
19714           is_ip4 = 0;
19715           nh_sw_if_index = ~0;
19716         }
19717       else if (unformat (i, "table %d", &table_id))
19718         ;
19719       else
19720         {
19721           errmsg ("parse error '%U'", format_unformat_error, i);
19722           return -99;
19723         }
19724     }
19725
19726   if (!ip_set)
19727     {
19728       errmsg ("nh addr not set!");
19729       return -99;
19730     }
19731
19732   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19733   mp->is_add = is_add;
19734   mp->table_id = clib_host_to_net_u32 (table_id);
19735   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19736   mp->is_ip4 = is_ip4;
19737   if (is_ip4)
19738     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19739   else
19740     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19741
19742   /* send it... */
19743   S (mp);
19744
19745   /* Wait for a reply... */
19746   W (ret);
19747   return ret;
19748 }
19749
19750 static int
19751 api_one_map_server_dump (vat_main_t * vam)
19752 {
19753   vl_api_one_map_server_dump_t *mp;
19754   vl_api_control_ping_t *mp_ping;
19755   int ret;
19756
19757   if (!vam->json_output)
19758     {
19759       print (vam->ofp, "%=20s", "Map server");
19760     }
19761
19762   M (ONE_MAP_SERVER_DUMP, mp);
19763   /* send it... */
19764   S (mp);
19765
19766   /* Use a control ping for synchronization */
19767   MPING (CONTROL_PING, mp_ping);
19768   S (mp_ping);
19769
19770   /* Wait for a reply... */
19771   W (ret);
19772   return ret;
19773 }
19774
19775 #define api_lisp_map_server_dump api_one_map_server_dump
19776
19777 static int
19778 api_one_map_resolver_dump (vat_main_t * vam)
19779 {
19780   vl_api_one_map_resolver_dump_t *mp;
19781   vl_api_control_ping_t *mp_ping;
19782   int ret;
19783
19784   if (!vam->json_output)
19785     {
19786       print (vam->ofp, "%=20s", "Map resolver");
19787     }
19788
19789   M (ONE_MAP_RESOLVER_DUMP, mp);
19790   /* send it... */
19791   S (mp);
19792
19793   /* Use a control ping for synchronization */
19794   MPING (CONTROL_PING, mp_ping);
19795   S (mp_ping);
19796
19797   /* Wait for a reply... */
19798   W (ret);
19799   return ret;
19800 }
19801
19802 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19803
19804 static int
19805 api_one_stats_flush (vat_main_t * vam)
19806 {
19807   vl_api_one_stats_flush_t *mp;
19808   int ret = 0;
19809
19810   M (ONE_STATS_FLUSH, mp);
19811   S (mp);
19812   W (ret);
19813   return ret;
19814 }
19815
19816 static int
19817 api_one_stats_dump (vat_main_t * vam)
19818 {
19819   vl_api_one_stats_dump_t *mp;
19820   vl_api_control_ping_t *mp_ping;
19821   int ret;
19822
19823   M (ONE_STATS_DUMP, mp);
19824   /* send it... */
19825   S (mp);
19826
19827   /* Use a control ping for synchronization */
19828   MPING (CONTROL_PING, mp_ping);
19829   S (mp_ping);
19830
19831   /* Wait for a reply... */
19832   W (ret);
19833   return ret;
19834 }
19835
19836 static int
19837 api_show_one_status (vat_main_t * vam)
19838 {
19839   vl_api_show_one_status_t *mp;
19840   int ret;
19841
19842   if (!vam->json_output)
19843     {
19844       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19845     }
19846
19847   M (SHOW_ONE_STATUS, mp);
19848   /* send it... */
19849   S (mp);
19850   /* Wait for a reply... */
19851   W (ret);
19852   return ret;
19853 }
19854
19855 #define api_show_lisp_status api_show_one_status
19856
19857 static int
19858 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19859 {
19860   vl_api_gpe_fwd_entry_path_dump_t *mp;
19861   vl_api_control_ping_t *mp_ping;
19862   unformat_input_t *i = vam->input;
19863   u32 fwd_entry_index = ~0;
19864   int ret;
19865
19866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19867     {
19868       if (unformat (i, "index %d", &fwd_entry_index))
19869         ;
19870       else
19871         break;
19872     }
19873
19874   if (~0 == fwd_entry_index)
19875     {
19876       errmsg ("no index specified!");
19877       return -99;
19878     }
19879
19880   if (!vam->json_output)
19881     {
19882       print (vam->ofp, "first line");
19883     }
19884
19885   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19886
19887   /* send it... */
19888   S (mp);
19889   /* Use a control ping for synchronization */
19890   MPING (CONTROL_PING, mp_ping);
19891   S (mp_ping);
19892
19893   /* Wait for a reply... */
19894   W (ret);
19895   return ret;
19896 }
19897
19898 static int
19899 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19900 {
19901   vl_api_one_get_map_request_itr_rlocs_t *mp;
19902   int ret;
19903
19904   if (!vam->json_output)
19905     {
19906       print (vam->ofp, "%=20s", "itr-rlocs:");
19907     }
19908
19909   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19910   /* send it... */
19911   S (mp);
19912   /* Wait for a reply... */
19913   W (ret);
19914   return ret;
19915 }
19916
19917 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19918
19919 static int
19920 api_af_packet_create (vat_main_t * vam)
19921 {
19922   unformat_input_t *i = vam->input;
19923   vl_api_af_packet_create_t *mp;
19924   u8 *host_if_name = 0;
19925   u8 hw_addr[6];
19926   u8 random_hw_addr = 1;
19927   int ret;
19928
19929   clib_memset (hw_addr, 0, sizeof (hw_addr));
19930
19931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19932     {
19933       if (unformat (i, "name %s", &host_if_name))
19934         vec_add1 (host_if_name, 0);
19935       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19936         random_hw_addr = 0;
19937       else
19938         break;
19939     }
19940
19941   if (!vec_len (host_if_name))
19942     {
19943       errmsg ("host-interface name must be specified");
19944       return -99;
19945     }
19946
19947   if (vec_len (host_if_name) > 64)
19948     {
19949       errmsg ("host-interface name too long");
19950       return -99;
19951     }
19952
19953   M (AF_PACKET_CREATE, mp);
19954
19955   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19956   clib_memcpy (mp->hw_addr, hw_addr, 6);
19957   mp->use_random_hw_addr = random_hw_addr;
19958   vec_free (host_if_name);
19959
19960   S (mp);
19961
19962   /* *INDENT-OFF* */
19963   W2 (ret,
19964       ({
19965         if (ret == 0)
19966           fprintf (vam->ofp ? vam->ofp : stderr,
19967                    " new sw_if_index = %d\n", vam->sw_if_index);
19968       }));
19969   /* *INDENT-ON* */
19970   return ret;
19971 }
19972
19973 static int
19974 api_af_packet_delete (vat_main_t * vam)
19975 {
19976   unformat_input_t *i = vam->input;
19977   vl_api_af_packet_delete_t *mp;
19978   u8 *host_if_name = 0;
19979   int ret;
19980
19981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19982     {
19983       if (unformat (i, "name %s", &host_if_name))
19984         vec_add1 (host_if_name, 0);
19985       else
19986         break;
19987     }
19988
19989   if (!vec_len (host_if_name))
19990     {
19991       errmsg ("host-interface name must be specified");
19992       return -99;
19993     }
19994
19995   if (vec_len (host_if_name) > 64)
19996     {
19997       errmsg ("host-interface name too long");
19998       return -99;
19999     }
20000
20001   M (AF_PACKET_DELETE, mp);
20002
20003   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20004   vec_free (host_if_name);
20005
20006   S (mp);
20007   W (ret);
20008   return ret;
20009 }
20010
20011 static void vl_api_af_packet_details_t_handler
20012   (vl_api_af_packet_details_t * mp)
20013 {
20014   vat_main_t *vam = &vat_main;
20015
20016   print (vam->ofp, "%-16s %d",
20017          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
20018 }
20019
20020 static void vl_api_af_packet_details_t_handler_json
20021   (vl_api_af_packet_details_t * mp)
20022 {
20023   vat_main_t *vam = &vat_main;
20024   vat_json_node_t *node = NULL;
20025
20026   if (VAT_JSON_ARRAY != vam->json_tree.type)
20027     {
20028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20029       vat_json_init_array (&vam->json_tree);
20030     }
20031   node = vat_json_array_add (&vam->json_tree);
20032
20033   vat_json_init_object (node);
20034   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20035   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
20036 }
20037
20038 static int
20039 api_af_packet_dump (vat_main_t * vam)
20040 {
20041   vl_api_af_packet_dump_t *mp;
20042   vl_api_control_ping_t *mp_ping;
20043   int ret;
20044
20045   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
20046   /* Get list of tap interfaces */
20047   M (AF_PACKET_DUMP, mp);
20048   S (mp);
20049
20050   /* Use a control ping for synchronization */
20051   MPING (CONTROL_PING, mp_ping);
20052   S (mp_ping);
20053
20054   W (ret);
20055   return ret;
20056 }
20057
20058 static int
20059 api_policer_add_del (vat_main_t * vam)
20060 {
20061   unformat_input_t *i = vam->input;
20062   vl_api_policer_add_del_t *mp;
20063   u8 is_add = 1;
20064   u8 *name = 0;
20065   u32 cir = 0;
20066   u32 eir = 0;
20067   u64 cb = 0;
20068   u64 eb = 0;
20069   u8 rate_type = 0;
20070   u8 round_type = 0;
20071   u8 type = 0;
20072   u8 color_aware = 0;
20073   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20074   int ret;
20075
20076   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20077   conform_action.dscp = 0;
20078   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20079   exceed_action.dscp = 0;
20080   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20081   violate_action.dscp = 0;
20082
20083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20084     {
20085       if (unformat (i, "del"))
20086         is_add = 0;
20087       else if (unformat (i, "name %s", &name))
20088         vec_add1 (name, 0);
20089       else if (unformat (i, "cir %u", &cir))
20090         ;
20091       else if (unformat (i, "eir %u", &eir))
20092         ;
20093       else if (unformat (i, "cb %u", &cb))
20094         ;
20095       else if (unformat (i, "eb %u", &eb))
20096         ;
20097       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20098                          &rate_type))
20099         ;
20100       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20101                          &round_type))
20102         ;
20103       else if (unformat (i, "type %U", unformat_policer_type, &type))
20104         ;
20105       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20106                          &conform_action))
20107         ;
20108       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20109                          &exceed_action))
20110         ;
20111       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20112                          &violate_action))
20113         ;
20114       else if (unformat (i, "color-aware"))
20115         color_aware = 1;
20116       else
20117         break;
20118     }
20119
20120   if (!vec_len (name))
20121     {
20122       errmsg ("policer name must be specified");
20123       return -99;
20124     }
20125
20126   if (vec_len (name) > 64)
20127     {
20128       errmsg ("policer name too long");
20129       return -99;
20130     }
20131
20132   M (POLICER_ADD_DEL, mp);
20133
20134   clib_memcpy (mp->name, name, vec_len (name));
20135   vec_free (name);
20136   mp->is_add = is_add;
20137   mp->cir = ntohl (cir);
20138   mp->eir = ntohl (eir);
20139   mp->cb = clib_net_to_host_u64 (cb);
20140   mp->eb = clib_net_to_host_u64 (eb);
20141   mp->rate_type = rate_type;
20142   mp->round_type = round_type;
20143   mp->type = type;
20144   mp->conform_action_type = conform_action.action_type;
20145   mp->conform_dscp = conform_action.dscp;
20146   mp->exceed_action_type = exceed_action.action_type;
20147   mp->exceed_dscp = exceed_action.dscp;
20148   mp->violate_action_type = violate_action.action_type;
20149   mp->violate_dscp = violate_action.dscp;
20150   mp->color_aware = color_aware;
20151
20152   S (mp);
20153   W (ret);
20154   return ret;
20155 }
20156
20157 static int
20158 api_policer_dump (vat_main_t * vam)
20159 {
20160   unformat_input_t *i = vam->input;
20161   vl_api_policer_dump_t *mp;
20162   vl_api_control_ping_t *mp_ping;
20163   u8 *match_name = 0;
20164   u8 match_name_valid = 0;
20165   int ret;
20166
20167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20168     {
20169       if (unformat (i, "name %s", &match_name))
20170         {
20171           vec_add1 (match_name, 0);
20172           match_name_valid = 1;
20173         }
20174       else
20175         break;
20176     }
20177
20178   M (POLICER_DUMP, mp);
20179   mp->match_name_valid = match_name_valid;
20180   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20181   vec_free (match_name);
20182   /* send it... */
20183   S (mp);
20184
20185   /* Use a control ping for synchronization */
20186   MPING (CONTROL_PING, mp_ping);
20187   S (mp_ping);
20188
20189   /* Wait for a reply... */
20190   W (ret);
20191   return ret;
20192 }
20193
20194 static int
20195 api_policer_classify_set_interface (vat_main_t * vam)
20196 {
20197   unformat_input_t *i = vam->input;
20198   vl_api_policer_classify_set_interface_t *mp;
20199   u32 sw_if_index;
20200   int sw_if_index_set;
20201   u32 ip4_table_index = ~0;
20202   u32 ip6_table_index = ~0;
20203   u32 l2_table_index = ~0;
20204   u8 is_add = 1;
20205   int ret;
20206
20207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20208     {
20209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20210         sw_if_index_set = 1;
20211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20212         sw_if_index_set = 1;
20213       else if (unformat (i, "del"))
20214         is_add = 0;
20215       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20216         ;
20217       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20218         ;
20219       else if (unformat (i, "l2-table %d", &l2_table_index))
20220         ;
20221       else
20222         {
20223           clib_warning ("parse error '%U'", format_unformat_error, i);
20224           return -99;
20225         }
20226     }
20227
20228   if (sw_if_index_set == 0)
20229     {
20230       errmsg ("missing interface name or sw_if_index");
20231       return -99;
20232     }
20233
20234   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20235
20236   mp->sw_if_index = ntohl (sw_if_index);
20237   mp->ip4_table_index = ntohl (ip4_table_index);
20238   mp->ip6_table_index = ntohl (ip6_table_index);
20239   mp->l2_table_index = ntohl (l2_table_index);
20240   mp->is_add = is_add;
20241
20242   S (mp);
20243   W (ret);
20244   return ret;
20245 }
20246
20247 static int
20248 api_policer_classify_dump (vat_main_t * vam)
20249 {
20250   unformat_input_t *i = vam->input;
20251   vl_api_policer_classify_dump_t *mp;
20252   vl_api_control_ping_t *mp_ping;
20253   u8 type = POLICER_CLASSIFY_N_TABLES;
20254   int ret;
20255
20256   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20257     ;
20258   else
20259     {
20260       errmsg ("classify table type must be specified");
20261       return -99;
20262     }
20263
20264   if (!vam->json_output)
20265     {
20266       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20267     }
20268
20269   M (POLICER_CLASSIFY_DUMP, mp);
20270   mp->type = type;
20271   /* send it... */
20272   S (mp);
20273
20274   /* Use a control ping for synchronization */
20275   MPING (CONTROL_PING, mp_ping);
20276   S (mp_ping);
20277
20278   /* Wait for a reply... */
20279   W (ret);
20280   return ret;
20281 }
20282
20283 static int
20284 api_netmap_create (vat_main_t * vam)
20285 {
20286   unformat_input_t *i = vam->input;
20287   vl_api_netmap_create_t *mp;
20288   u8 *if_name = 0;
20289   u8 hw_addr[6];
20290   u8 random_hw_addr = 1;
20291   u8 is_pipe = 0;
20292   u8 is_master = 0;
20293   int ret;
20294
20295   clib_memset (hw_addr, 0, sizeof (hw_addr));
20296
20297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20298     {
20299       if (unformat (i, "name %s", &if_name))
20300         vec_add1 (if_name, 0);
20301       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20302         random_hw_addr = 0;
20303       else if (unformat (i, "pipe"))
20304         is_pipe = 1;
20305       else if (unformat (i, "master"))
20306         is_master = 1;
20307       else if (unformat (i, "slave"))
20308         is_master = 0;
20309       else
20310         break;
20311     }
20312
20313   if (!vec_len (if_name))
20314     {
20315       errmsg ("interface name must be specified");
20316       return -99;
20317     }
20318
20319   if (vec_len (if_name) > 64)
20320     {
20321       errmsg ("interface name too long");
20322       return -99;
20323     }
20324
20325   M (NETMAP_CREATE, mp);
20326
20327   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20328   clib_memcpy (mp->hw_addr, hw_addr, 6);
20329   mp->use_random_hw_addr = random_hw_addr;
20330   mp->is_pipe = is_pipe;
20331   mp->is_master = is_master;
20332   vec_free (if_name);
20333
20334   S (mp);
20335   W (ret);
20336   return ret;
20337 }
20338
20339 static int
20340 api_netmap_delete (vat_main_t * vam)
20341 {
20342   unformat_input_t *i = vam->input;
20343   vl_api_netmap_delete_t *mp;
20344   u8 *if_name = 0;
20345   int ret;
20346
20347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20348     {
20349       if (unformat (i, "name %s", &if_name))
20350         vec_add1 (if_name, 0);
20351       else
20352         break;
20353     }
20354
20355   if (!vec_len (if_name))
20356     {
20357       errmsg ("interface name must be specified");
20358       return -99;
20359     }
20360
20361   if (vec_len (if_name) > 64)
20362     {
20363       errmsg ("interface name too long");
20364       return -99;
20365     }
20366
20367   M (NETMAP_DELETE, mp);
20368
20369   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20370   vec_free (if_name);
20371
20372   S (mp);
20373   W (ret);
20374   return ret;
20375 }
20376
20377 static void
20378 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20379 {
20380   if (fp->afi == IP46_TYPE_IP6)
20381     print (vam->ofp,
20382            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20383            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20384            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
20385            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20386            format_ip6_address, fp->next_hop);
20387   else if (fp->afi == IP46_TYPE_IP4)
20388     print (vam->ofp,
20389            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20390            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20391            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
20392            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20393            format_ip4_address, fp->next_hop);
20394 }
20395
20396 static void
20397 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20398                                  vl_api_fib_path_t * fp)
20399 {
20400   struct in_addr ip4;
20401   struct in6_addr ip6;
20402
20403   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20404   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20405   vat_json_object_add_uint (node, "is_local", fp->is_local);
20406   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20407   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20408   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20409   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20410   if (fp->afi == IP46_TYPE_IP4)
20411     {
20412       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20413       vat_json_object_add_ip4 (node, "next_hop", ip4);
20414     }
20415   else if (fp->afi == IP46_TYPE_IP6)
20416     {
20417       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20418       vat_json_object_add_ip6 (node, "next_hop", ip6);
20419     }
20420 }
20421
20422 static void
20423 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20424 {
20425   vat_main_t *vam = &vat_main;
20426   int count = ntohl (mp->mt_count);
20427   vl_api_fib_path_t *fp;
20428   i32 i;
20429
20430   print (vam->ofp, "[%d]: sw_if_index %d via:",
20431          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20432   fp = mp->mt_paths;
20433   for (i = 0; i < count; i++)
20434     {
20435       vl_api_mpls_fib_path_print (vam, fp);
20436       fp++;
20437     }
20438
20439   print (vam->ofp, "");
20440 }
20441
20442 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20443 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20444
20445 static void
20446 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20447 {
20448   vat_main_t *vam = &vat_main;
20449   vat_json_node_t *node = NULL;
20450   int count = ntohl (mp->mt_count);
20451   vl_api_fib_path_t *fp;
20452   i32 i;
20453
20454   if (VAT_JSON_ARRAY != vam->json_tree.type)
20455     {
20456       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20457       vat_json_init_array (&vam->json_tree);
20458     }
20459   node = vat_json_array_add (&vam->json_tree);
20460
20461   vat_json_init_object (node);
20462   vat_json_object_add_uint (node, "tunnel_index",
20463                             ntohl (mp->mt_tunnel_index));
20464   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20465
20466   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20467
20468   fp = mp->mt_paths;
20469   for (i = 0; i < count; i++)
20470     {
20471       vl_api_mpls_fib_path_json_print (node, fp);
20472       fp++;
20473     }
20474 }
20475
20476 static int
20477 api_mpls_tunnel_dump (vat_main_t * vam)
20478 {
20479   vl_api_mpls_tunnel_dump_t *mp;
20480   vl_api_control_ping_t *mp_ping;
20481   u32 sw_if_index = ~0;
20482   int ret;
20483
20484   /* Parse args required to build the message */
20485   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20486     {
20487       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20488         ;
20489     }
20490
20491   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20492
20493   M (MPLS_TUNNEL_DUMP, mp);
20494   mp->sw_if_index = htonl (sw_if_index);
20495   S (mp);
20496
20497   /* Use a control ping for synchronization */
20498   MPING (CONTROL_PING, mp_ping);
20499   S (mp_ping);
20500
20501   W (ret);
20502   return ret;
20503 }
20504
20505 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20506 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20507
20508
20509 static void
20510 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20511 {
20512   vat_main_t *vam = &vat_main;
20513   int count = ntohl (mp->count);
20514   vl_api_fib_path_t *fp;
20515   int i;
20516
20517   print (vam->ofp,
20518          "table-id %d, label %u, ess_bit %u",
20519          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20520   fp = mp->path;
20521   for (i = 0; i < count; i++)
20522     {
20523       vl_api_mpls_fib_path_print (vam, fp);
20524       fp++;
20525     }
20526 }
20527
20528 static void vl_api_mpls_fib_details_t_handler_json
20529   (vl_api_mpls_fib_details_t * mp)
20530 {
20531   vat_main_t *vam = &vat_main;
20532   int count = ntohl (mp->count);
20533   vat_json_node_t *node = NULL;
20534   vl_api_fib_path_t *fp;
20535   int i;
20536
20537   if (VAT_JSON_ARRAY != vam->json_tree.type)
20538     {
20539       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20540       vat_json_init_array (&vam->json_tree);
20541     }
20542   node = vat_json_array_add (&vam->json_tree);
20543
20544   vat_json_init_object (node);
20545   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20546   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20547   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20548   vat_json_object_add_uint (node, "path_count", count);
20549   fp = mp->path;
20550   for (i = 0; i < count; i++)
20551     {
20552       vl_api_mpls_fib_path_json_print (node, fp);
20553       fp++;
20554     }
20555 }
20556
20557 static int
20558 api_mpls_fib_dump (vat_main_t * vam)
20559 {
20560   vl_api_mpls_fib_dump_t *mp;
20561   vl_api_control_ping_t *mp_ping;
20562   int ret;
20563
20564   M (MPLS_FIB_DUMP, mp);
20565   S (mp);
20566
20567   /* Use a control ping for synchronization */
20568   MPING (CONTROL_PING, mp_ping);
20569   S (mp_ping);
20570
20571   W (ret);
20572   return ret;
20573 }
20574
20575 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20576 #define vl_api_ip_fib_details_t_print vl_noop_handler
20577
20578 static void
20579 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20580 {
20581   vat_main_t *vam = &vat_main;
20582   int count = ntohl (mp->count);
20583   vl_api_fib_path_t *fp;
20584   int i;
20585
20586   print (vam->ofp,
20587          "table-id %d, prefix %U/%d stats-index %d",
20588          ntohl (mp->table_id), format_ip4_address, mp->address,
20589          mp->address_length, ntohl (mp->stats_index));
20590   fp = mp->path;
20591   for (i = 0; i < count; i++)
20592     {
20593       if (fp->afi == IP46_TYPE_IP6)
20594         print (vam->ofp,
20595                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20596                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20597                "next_hop_table %d",
20598                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20599                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20600                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20601       else if (fp->afi == IP46_TYPE_IP4)
20602         print (vam->ofp,
20603                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20604                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20605                "next_hop_table %d",
20606                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20607                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20608                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20609       fp++;
20610     }
20611 }
20612
20613 static void vl_api_ip_fib_details_t_handler_json
20614   (vl_api_ip_fib_details_t * mp)
20615 {
20616   vat_main_t *vam = &vat_main;
20617   int count = ntohl (mp->count);
20618   vat_json_node_t *node = NULL;
20619   struct in_addr ip4;
20620   struct in6_addr ip6;
20621   vl_api_fib_path_t *fp;
20622   int i;
20623
20624   if (VAT_JSON_ARRAY != vam->json_tree.type)
20625     {
20626       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20627       vat_json_init_array (&vam->json_tree);
20628     }
20629   node = vat_json_array_add (&vam->json_tree);
20630
20631   vat_json_init_object (node);
20632   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20633   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20634   vat_json_object_add_ip4 (node, "prefix", ip4);
20635   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20636   vat_json_object_add_uint (node, "path_count", count);
20637   fp = mp->path;
20638   for (i = 0; i < count; i++)
20639     {
20640       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20641       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20642       vat_json_object_add_uint (node, "is_local", fp->is_local);
20643       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20644       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20645       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20646       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20647       if (fp->afi == IP46_TYPE_IP4)
20648         {
20649           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20650           vat_json_object_add_ip4 (node, "next_hop", ip4);
20651         }
20652       else if (fp->afi == IP46_TYPE_IP6)
20653         {
20654           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20655           vat_json_object_add_ip6 (node, "next_hop", ip6);
20656         }
20657     }
20658 }
20659
20660 static int
20661 api_ip_fib_dump (vat_main_t * vam)
20662 {
20663   vl_api_ip_fib_dump_t *mp;
20664   vl_api_control_ping_t *mp_ping;
20665   int ret;
20666
20667   M (IP_FIB_DUMP, mp);
20668   S (mp);
20669
20670   /* Use a control ping for synchronization */
20671   MPING (CONTROL_PING, mp_ping);
20672   S (mp_ping);
20673
20674   W (ret);
20675   return ret;
20676 }
20677
20678 static int
20679 api_ip_mfib_dump (vat_main_t * vam)
20680 {
20681   vl_api_ip_mfib_dump_t *mp;
20682   vl_api_control_ping_t *mp_ping;
20683   int ret;
20684
20685   M (IP_MFIB_DUMP, mp);
20686   S (mp);
20687
20688   /* Use a control ping for synchronization */
20689   MPING (CONTROL_PING, mp_ping);
20690   S (mp_ping);
20691
20692   W (ret);
20693   return ret;
20694 }
20695
20696 static void vl_api_ip_neighbor_details_t_handler
20697   (vl_api_ip_neighbor_details_t * mp)
20698 {
20699   vat_main_t *vam = &vat_main;
20700
20701   print (vam->ofp, "%c %U %U",
20702          (mp->is_static) ? 'S' : 'D',
20703          format_ethernet_address, &mp->mac_address,
20704          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20705          &mp->ip_address);
20706 }
20707
20708 static void vl_api_ip_neighbor_details_t_handler_json
20709   (vl_api_ip_neighbor_details_t * mp)
20710 {
20711
20712   vat_main_t *vam = &vat_main;
20713   vat_json_node_t *node;
20714   struct in_addr ip4;
20715   struct in6_addr ip6;
20716
20717   if (VAT_JSON_ARRAY != vam->json_tree.type)
20718     {
20719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20720       vat_json_init_array (&vam->json_tree);
20721     }
20722   node = vat_json_array_add (&vam->json_tree);
20723
20724   vat_json_init_object (node);
20725   vat_json_object_add_string_copy (node, "flag",
20726                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20727                                    "dynamic");
20728
20729   vat_json_object_add_string_copy (node, "link_layer",
20730                                    format (0, "%U", format_ethernet_address,
20731                                            &mp->mac_address));
20732
20733   if (mp->is_ipv6)
20734     {
20735       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20736       vat_json_object_add_ip6 (node, "ip_address", ip6);
20737     }
20738   else
20739     {
20740       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20741       vat_json_object_add_ip4 (node, "ip_address", ip4);
20742     }
20743 }
20744
20745 static int
20746 api_ip_neighbor_dump (vat_main_t * vam)
20747 {
20748   unformat_input_t *i = vam->input;
20749   vl_api_ip_neighbor_dump_t *mp;
20750   vl_api_control_ping_t *mp_ping;
20751   u8 is_ipv6 = 0;
20752   u32 sw_if_index = ~0;
20753   int ret;
20754
20755   /* Parse args required to build the message */
20756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20757     {
20758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20759         ;
20760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20761         ;
20762       else if (unformat (i, "ip6"))
20763         is_ipv6 = 1;
20764       else
20765         break;
20766     }
20767
20768   if (sw_if_index == ~0)
20769     {
20770       errmsg ("missing interface name or sw_if_index");
20771       return -99;
20772     }
20773
20774   M (IP_NEIGHBOR_DUMP, mp);
20775   mp->is_ipv6 = (u8) is_ipv6;
20776   mp->sw_if_index = ntohl (sw_if_index);
20777   S (mp);
20778
20779   /* Use a control ping for synchronization */
20780   MPING (CONTROL_PING, mp_ping);
20781   S (mp_ping);
20782
20783   W (ret);
20784   return ret;
20785 }
20786
20787 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20788 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20789
20790 static void
20791 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20792 {
20793   vat_main_t *vam = &vat_main;
20794   int count = ntohl (mp->count);
20795   vl_api_fib_path_t *fp;
20796   int i;
20797
20798   print (vam->ofp,
20799          "table-id %d, prefix %U/%d stats-index %d",
20800          ntohl (mp->table_id), format_ip6_address, mp->address,
20801          mp->address_length, ntohl (mp->stats_index));
20802   fp = mp->path;
20803   for (i = 0; i < count; i++)
20804     {
20805       if (fp->afi == IP46_TYPE_IP6)
20806         print (vam->ofp,
20807                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20808                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20809                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20810                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20811                format_ip6_address, fp->next_hop);
20812       else if (fp->afi == IP46_TYPE_IP4)
20813         print (vam->ofp,
20814                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20815                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20816                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20817                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20818                format_ip4_address, fp->next_hop);
20819       fp++;
20820     }
20821 }
20822
20823 static void vl_api_ip6_fib_details_t_handler_json
20824   (vl_api_ip6_fib_details_t * mp)
20825 {
20826   vat_main_t *vam = &vat_main;
20827   int count = ntohl (mp->count);
20828   vat_json_node_t *node = NULL;
20829   struct in_addr ip4;
20830   struct in6_addr ip6;
20831   vl_api_fib_path_t *fp;
20832   int i;
20833
20834   if (VAT_JSON_ARRAY != vam->json_tree.type)
20835     {
20836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20837       vat_json_init_array (&vam->json_tree);
20838     }
20839   node = vat_json_array_add (&vam->json_tree);
20840
20841   vat_json_init_object (node);
20842   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20843   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20844   vat_json_object_add_ip6 (node, "prefix", ip6);
20845   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20846   vat_json_object_add_uint (node, "path_count", count);
20847   fp = mp->path;
20848   for (i = 0; i < count; i++)
20849     {
20850       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20851       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20852       vat_json_object_add_uint (node, "is_local", fp->is_local);
20853       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20854       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20855       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20856       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20857       if (fp->afi == IP46_TYPE_IP4)
20858         {
20859           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20860           vat_json_object_add_ip4 (node, "next_hop", ip4);
20861         }
20862       else if (fp->afi == IP46_TYPE_IP6)
20863         {
20864           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20865           vat_json_object_add_ip6 (node, "next_hop", ip6);
20866         }
20867     }
20868 }
20869
20870 static int
20871 api_ip6_fib_dump (vat_main_t * vam)
20872 {
20873   vl_api_ip6_fib_dump_t *mp;
20874   vl_api_control_ping_t *mp_ping;
20875   int ret;
20876
20877   M (IP6_FIB_DUMP, mp);
20878   S (mp);
20879
20880   /* Use a control ping for synchronization */
20881   MPING (CONTROL_PING, mp_ping);
20882   S (mp_ping);
20883
20884   W (ret);
20885   return ret;
20886 }
20887
20888 static int
20889 api_ip6_mfib_dump (vat_main_t * vam)
20890 {
20891   vl_api_ip6_mfib_dump_t *mp;
20892   vl_api_control_ping_t *mp_ping;
20893   int ret;
20894
20895   M (IP6_MFIB_DUMP, mp);
20896   S (mp);
20897
20898   /* Use a control ping for synchronization */
20899   MPING (CONTROL_PING, mp_ping);
20900   S (mp_ping);
20901
20902   W (ret);
20903   return ret;
20904 }
20905
20906 int
20907 api_classify_table_ids (vat_main_t * vam)
20908 {
20909   vl_api_classify_table_ids_t *mp;
20910   int ret;
20911
20912   /* Construct the API message */
20913   M (CLASSIFY_TABLE_IDS, mp);
20914   mp->context = 0;
20915
20916   S (mp);
20917   W (ret);
20918   return ret;
20919 }
20920
20921 int
20922 api_classify_table_by_interface (vat_main_t * vam)
20923 {
20924   unformat_input_t *input = vam->input;
20925   vl_api_classify_table_by_interface_t *mp;
20926
20927   u32 sw_if_index = ~0;
20928   int ret;
20929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20930     {
20931       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20932         ;
20933       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20934         ;
20935       else
20936         break;
20937     }
20938   if (sw_if_index == ~0)
20939     {
20940       errmsg ("missing interface name or sw_if_index");
20941       return -99;
20942     }
20943
20944   /* Construct the API message */
20945   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20946   mp->context = 0;
20947   mp->sw_if_index = ntohl (sw_if_index);
20948
20949   S (mp);
20950   W (ret);
20951   return ret;
20952 }
20953
20954 int
20955 api_classify_table_info (vat_main_t * vam)
20956 {
20957   unformat_input_t *input = vam->input;
20958   vl_api_classify_table_info_t *mp;
20959
20960   u32 table_id = ~0;
20961   int ret;
20962   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20963     {
20964       if (unformat (input, "table_id %d", &table_id))
20965         ;
20966       else
20967         break;
20968     }
20969   if (table_id == ~0)
20970     {
20971       errmsg ("missing table id");
20972       return -99;
20973     }
20974
20975   /* Construct the API message */
20976   M (CLASSIFY_TABLE_INFO, mp);
20977   mp->context = 0;
20978   mp->table_id = ntohl (table_id);
20979
20980   S (mp);
20981   W (ret);
20982   return ret;
20983 }
20984
20985 int
20986 api_classify_session_dump (vat_main_t * vam)
20987 {
20988   unformat_input_t *input = vam->input;
20989   vl_api_classify_session_dump_t *mp;
20990   vl_api_control_ping_t *mp_ping;
20991
20992   u32 table_id = ~0;
20993   int ret;
20994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20995     {
20996       if (unformat (input, "table_id %d", &table_id))
20997         ;
20998       else
20999         break;
21000     }
21001   if (table_id == ~0)
21002     {
21003       errmsg ("missing table id");
21004       return -99;
21005     }
21006
21007   /* Construct the API message */
21008   M (CLASSIFY_SESSION_DUMP, mp);
21009   mp->context = 0;
21010   mp->table_id = ntohl (table_id);
21011   S (mp);
21012
21013   /* Use a control ping for synchronization */
21014   MPING (CONTROL_PING, mp_ping);
21015   S (mp_ping);
21016
21017   W (ret);
21018   return ret;
21019 }
21020
21021 static void
21022 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
21023 {
21024   vat_main_t *vam = &vat_main;
21025
21026   print (vam->ofp, "collector_address %U, collector_port %d, "
21027          "src_address %U, vrf_id %d, path_mtu %u, "
21028          "template_interval %u, udp_checksum %d",
21029          format_ip4_address, mp->collector_address,
21030          ntohs (mp->collector_port),
21031          format_ip4_address, mp->src_address,
21032          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
21033          ntohl (mp->template_interval), mp->udp_checksum);
21034
21035   vam->retval = 0;
21036   vam->result_ready = 1;
21037 }
21038
21039 static void
21040   vl_api_ipfix_exporter_details_t_handler_json
21041   (vl_api_ipfix_exporter_details_t * mp)
21042 {
21043   vat_main_t *vam = &vat_main;
21044   vat_json_node_t node;
21045   struct in_addr collector_address;
21046   struct in_addr src_address;
21047
21048   vat_json_init_object (&node);
21049   clib_memcpy (&collector_address, &mp->collector_address,
21050                sizeof (collector_address));
21051   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
21052   vat_json_object_add_uint (&node, "collector_port",
21053                             ntohs (mp->collector_port));
21054   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21055   vat_json_object_add_ip4 (&node, "src_address", src_address);
21056   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21057   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21058   vat_json_object_add_uint (&node, "template_interval",
21059                             ntohl (mp->template_interval));
21060   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21061
21062   vat_json_print (vam->ofp, &node);
21063   vat_json_free (&node);
21064   vam->retval = 0;
21065   vam->result_ready = 1;
21066 }
21067
21068 int
21069 api_ipfix_exporter_dump (vat_main_t * vam)
21070 {
21071   vl_api_ipfix_exporter_dump_t *mp;
21072   int ret;
21073
21074   /* Construct the API message */
21075   M (IPFIX_EXPORTER_DUMP, mp);
21076   mp->context = 0;
21077
21078   S (mp);
21079   W (ret);
21080   return ret;
21081 }
21082
21083 static int
21084 api_ipfix_classify_stream_dump (vat_main_t * vam)
21085 {
21086   vl_api_ipfix_classify_stream_dump_t *mp;
21087   int ret;
21088
21089   /* Construct the API message */
21090   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21091   mp->context = 0;
21092
21093   S (mp);
21094   W (ret);
21095   return ret;
21096   /* NOTREACHED */
21097   return 0;
21098 }
21099
21100 static void
21101   vl_api_ipfix_classify_stream_details_t_handler
21102   (vl_api_ipfix_classify_stream_details_t * mp)
21103 {
21104   vat_main_t *vam = &vat_main;
21105   print (vam->ofp, "domain_id %d, src_port %d",
21106          ntohl (mp->domain_id), ntohs (mp->src_port));
21107   vam->retval = 0;
21108   vam->result_ready = 1;
21109 }
21110
21111 static void
21112   vl_api_ipfix_classify_stream_details_t_handler_json
21113   (vl_api_ipfix_classify_stream_details_t * mp)
21114 {
21115   vat_main_t *vam = &vat_main;
21116   vat_json_node_t node;
21117
21118   vat_json_init_object (&node);
21119   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21120   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21121
21122   vat_json_print (vam->ofp, &node);
21123   vat_json_free (&node);
21124   vam->retval = 0;
21125   vam->result_ready = 1;
21126 }
21127
21128 static int
21129 api_ipfix_classify_table_dump (vat_main_t * vam)
21130 {
21131   vl_api_ipfix_classify_table_dump_t *mp;
21132   vl_api_control_ping_t *mp_ping;
21133   int ret;
21134
21135   if (!vam->json_output)
21136     {
21137       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21138              "transport_protocol");
21139     }
21140
21141   /* Construct the API message */
21142   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21143
21144   /* send it... */
21145   S (mp);
21146
21147   /* Use a control ping for synchronization */
21148   MPING (CONTROL_PING, mp_ping);
21149   S (mp_ping);
21150
21151   W (ret);
21152   return ret;
21153 }
21154
21155 static void
21156   vl_api_ipfix_classify_table_details_t_handler
21157   (vl_api_ipfix_classify_table_details_t * mp)
21158 {
21159   vat_main_t *vam = &vat_main;
21160   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21161          mp->transport_protocol);
21162 }
21163
21164 static void
21165   vl_api_ipfix_classify_table_details_t_handler_json
21166   (vl_api_ipfix_classify_table_details_t * mp)
21167 {
21168   vat_json_node_t *node = NULL;
21169   vat_main_t *vam = &vat_main;
21170
21171   if (VAT_JSON_ARRAY != vam->json_tree.type)
21172     {
21173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21174       vat_json_init_array (&vam->json_tree);
21175     }
21176
21177   node = vat_json_array_add (&vam->json_tree);
21178   vat_json_init_object (node);
21179
21180   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21181   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21182   vat_json_object_add_uint (node, "transport_protocol",
21183                             mp->transport_protocol);
21184 }
21185
21186 static int
21187 api_sw_interface_span_enable_disable (vat_main_t * vam)
21188 {
21189   unformat_input_t *i = vam->input;
21190   vl_api_sw_interface_span_enable_disable_t *mp;
21191   u32 src_sw_if_index = ~0;
21192   u32 dst_sw_if_index = ~0;
21193   u8 state = 3;
21194   int ret;
21195   u8 is_l2 = 0;
21196
21197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21198     {
21199       if (unformat
21200           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21201         ;
21202       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21203         ;
21204       else
21205         if (unformat
21206             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21207         ;
21208       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21209         ;
21210       else if (unformat (i, "disable"))
21211         state = 0;
21212       else if (unformat (i, "rx"))
21213         state = 1;
21214       else if (unformat (i, "tx"))
21215         state = 2;
21216       else if (unformat (i, "both"))
21217         state = 3;
21218       else if (unformat (i, "l2"))
21219         is_l2 = 1;
21220       else
21221         break;
21222     }
21223
21224   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21225
21226   mp->sw_if_index_from = htonl (src_sw_if_index);
21227   mp->sw_if_index_to = htonl (dst_sw_if_index);
21228   mp->state = state;
21229   mp->is_l2 = is_l2;
21230
21231   S (mp);
21232   W (ret);
21233   return ret;
21234 }
21235
21236 static void
21237 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21238                                             * mp)
21239 {
21240   vat_main_t *vam = &vat_main;
21241   u8 *sw_if_from_name = 0;
21242   u8 *sw_if_to_name = 0;
21243   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21244   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21245   char *states[] = { "none", "rx", "tx", "both" };
21246   hash_pair_t *p;
21247
21248   /* *INDENT-OFF* */
21249   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21250   ({
21251     if ((u32) p->value[0] == sw_if_index_from)
21252       {
21253         sw_if_from_name = (u8 *)(p->key);
21254         if (sw_if_to_name)
21255           break;
21256       }
21257     if ((u32) p->value[0] == sw_if_index_to)
21258       {
21259         sw_if_to_name = (u8 *)(p->key);
21260         if (sw_if_from_name)
21261           break;
21262       }
21263   }));
21264   /* *INDENT-ON* */
21265   print (vam->ofp, "%20s => %20s (%s) %s",
21266          sw_if_from_name, sw_if_to_name, states[mp->state],
21267          mp->is_l2 ? "l2" : "device");
21268 }
21269
21270 static void
21271   vl_api_sw_interface_span_details_t_handler_json
21272   (vl_api_sw_interface_span_details_t * mp)
21273 {
21274   vat_main_t *vam = &vat_main;
21275   vat_json_node_t *node = NULL;
21276   u8 *sw_if_from_name = 0;
21277   u8 *sw_if_to_name = 0;
21278   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21279   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21280   hash_pair_t *p;
21281
21282   /* *INDENT-OFF* */
21283   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21284   ({
21285     if ((u32) p->value[0] == sw_if_index_from)
21286       {
21287         sw_if_from_name = (u8 *)(p->key);
21288         if (sw_if_to_name)
21289           break;
21290       }
21291     if ((u32) p->value[0] == sw_if_index_to)
21292       {
21293         sw_if_to_name = (u8 *)(p->key);
21294         if (sw_if_from_name)
21295           break;
21296       }
21297   }));
21298   /* *INDENT-ON* */
21299
21300   if (VAT_JSON_ARRAY != vam->json_tree.type)
21301     {
21302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21303       vat_json_init_array (&vam->json_tree);
21304     }
21305   node = vat_json_array_add (&vam->json_tree);
21306
21307   vat_json_init_object (node);
21308   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21309   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21310   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21311   if (0 != sw_if_to_name)
21312     {
21313       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21314     }
21315   vat_json_object_add_uint (node, "state", mp->state);
21316   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21317 }
21318
21319 static int
21320 api_sw_interface_span_dump (vat_main_t * vam)
21321 {
21322   unformat_input_t *input = vam->input;
21323   vl_api_sw_interface_span_dump_t *mp;
21324   vl_api_control_ping_t *mp_ping;
21325   u8 is_l2 = 0;
21326   int ret;
21327
21328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21329     {
21330       if (unformat (input, "l2"))
21331         is_l2 = 1;
21332       else
21333         break;
21334     }
21335
21336   M (SW_INTERFACE_SPAN_DUMP, mp);
21337   mp->is_l2 = is_l2;
21338   S (mp);
21339
21340   /* Use a control ping for synchronization */
21341   MPING (CONTROL_PING, mp_ping);
21342   S (mp_ping);
21343
21344   W (ret);
21345   return ret;
21346 }
21347
21348 int
21349 api_pg_create_interface (vat_main_t * vam)
21350 {
21351   unformat_input_t *input = vam->input;
21352   vl_api_pg_create_interface_t *mp;
21353
21354   u32 if_id = ~0;
21355   int ret;
21356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21357     {
21358       if (unformat (input, "if_id %d", &if_id))
21359         ;
21360       else
21361         break;
21362     }
21363   if (if_id == ~0)
21364     {
21365       errmsg ("missing pg interface index");
21366       return -99;
21367     }
21368
21369   /* Construct the API message */
21370   M (PG_CREATE_INTERFACE, mp);
21371   mp->context = 0;
21372   mp->interface_id = ntohl (if_id);
21373
21374   S (mp);
21375   W (ret);
21376   return ret;
21377 }
21378
21379 int
21380 api_pg_capture (vat_main_t * vam)
21381 {
21382   unformat_input_t *input = vam->input;
21383   vl_api_pg_capture_t *mp;
21384
21385   u32 if_id = ~0;
21386   u8 enable = 1;
21387   u32 count = 1;
21388   u8 pcap_file_set = 0;
21389   u8 *pcap_file = 0;
21390   int ret;
21391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21392     {
21393       if (unformat (input, "if_id %d", &if_id))
21394         ;
21395       else if (unformat (input, "pcap %s", &pcap_file))
21396         pcap_file_set = 1;
21397       else if (unformat (input, "count %d", &count))
21398         ;
21399       else if (unformat (input, "disable"))
21400         enable = 0;
21401       else
21402         break;
21403     }
21404   if (if_id == ~0)
21405     {
21406       errmsg ("missing pg interface index");
21407       return -99;
21408     }
21409   if (pcap_file_set > 0)
21410     {
21411       if (vec_len (pcap_file) > 255)
21412         {
21413           errmsg ("pcap file name is too long");
21414           return -99;
21415         }
21416     }
21417
21418   u32 name_len = vec_len (pcap_file);
21419   /* Construct the API message */
21420   M (PG_CAPTURE, mp);
21421   mp->context = 0;
21422   mp->interface_id = ntohl (if_id);
21423   mp->is_enabled = enable;
21424   mp->count = ntohl (count);
21425   mp->pcap_name_length = ntohl (name_len);
21426   if (pcap_file_set != 0)
21427     {
21428       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21429     }
21430   vec_free (pcap_file);
21431
21432   S (mp);
21433   W (ret);
21434   return ret;
21435 }
21436
21437 int
21438 api_pg_enable_disable (vat_main_t * vam)
21439 {
21440   unformat_input_t *input = vam->input;
21441   vl_api_pg_enable_disable_t *mp;
21442
21443   u8 enable = 1;
21444   u8 stream_name_set = 0;
21445   u8 *stream_name = 0;
21446   int ret;
21447   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21448     {
21449       if (unformat (input, "stream %s", &stream_name))
21450         stream_name_set = 1;
21451       else if (unformat (input, "disable"))
21452         enable = 0;
21453       else
21454         break;
21455     }
21456
21457   if (stream_name_set > 0)
21458     {
21459       if (vec_len (stream_name) > 255)
21460         {
21461           errmsg ("stream name too long");
21462           return -99;
21463         }
21464     }
21465
21466   u32 name_len = vec_len (stream_name);
21467   /* Construct the API message */
21468   M (PG_ENABLE_DISABLE, mp);
21469   mp->context = 0;
21470   mp->is_enabled = enable;
21471   if (stream_name_set != 0)
21472     {
21473       mp->stream_name_length = ntohl (name_len);
21474       clib_memcpy (mp->stream_name, stream_name, name_len);
21475     }
21476   vec_free (stream_name);
21477
21478   S (mp);
21479   W (ret);
21480   return ret;
21481 }
21482
21483 int
21484 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21485 {
21486   unformat_input_t *input = vam->input;
21487   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21488
21489   u16 *low_ports = 0;
21490   u16 *high_ports = 0;
21491   u16 this_low;
21492   u16 this_hi;
21493   ip4_address_t ip4_addr;
21494   ip6_address_t ip6_addr;
21495   u32 length;
21496   u32 tmp, tmp2;
21497   u8 prefix_set = 0;
21498   u32 vrf_id = ~0;
21499   u8 is_add = 1;
21500   u8 is_ipv6 = 0;
21501   int ret;
21502
21503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21504     {
21505       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21506         {
21507           prefix_set = 1;
21508         }
21509       else
21510         if (unformat
21511             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21512         {
21513           prefix_set = 1;
21514           is_ipv6 = 1;
21515         }
21516       else if (unformat (input, "vrf %d", &vrf_id))
21517         ;
21518       else if (unformat (input, "del"))
21519         is_add = 0;
21520       else if (unformat (input, "port %d", &tmp))
21521         {
21522           if (tmp == 0 || tmp > 65535)
21523             {
21524               errmsg ("port %d out of range", tmp);
21525               return -99;
21526             }
21527           this_low = tmp;
21528           this_hi = this_low + 1;
21529           vec_add1 (low_ports, this_low);
21530           vec_add1 (high_ports, this_hi);
21531         }
21532       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21533         {
21534           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21535             {
21536               errmsg ("incorrect range parameters");
21537               return -99;
21538             }
21539           this_low = tmp;
21540           /* Note: in debug CLI +1 is added to high before
21541              passing to real fn that does "the work"
21542              (ip_source_and_port_range_check_add_del).
21543              This fn is a wrapper around the binary API fn a
21544              control plane will call, which expects this increment
21545              to have occurred. Hence letting the binary API control
21546              plane fn do the increment for consistency between VAT
21547              and other control planes.
21548            */
21549           this_hi = tmp2;
21550           vec_add1 (low_ports, this_low);
21551           vec_add1 (high_ports, this_hi);
21552         }
21553       else
21554         break;
21555     }
21556
21557   if (prefix_set == 0)
21558     {
21559       errmsg ("<address>/<mask> not specified");
21560       return -99;
21561     }
21562
21563   if (vrf_id == ~0)
21564     {
21565       errmsg ("VRF ID required, not specified");
21566       return -99;
21567     }
21568
21569   if (vrf_id == 0)
21570     {
21571       errmsg
21572         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21573       return -99;
21574     }
21575
21576   if (vec_len (low_ports) == 0)
21577     {
21578       errmsg ("At least one port or port range required");
21579       return -99;
21580     }
21581
21582   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21583
21584   mp->is_add = is_add;
21585
21586   if (is_ipv6)
21587     {
21588       mp->is_ipv6 = 1;
21589       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21590     }
21591   else
21592     {
21593       mp->is_ipv6 = 0;
21594       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21595     }
21596
21597   mp->mask_length = length;
21598   mp->number_of_ranges = vec_len (low_ports);
21599
21600   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21601   vec_free (low_ports);
21602
21603   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21604   vec_free (high_ports);
21605
21606   mp->vrf_id = ntohl (vrf_id);
21607
21608   S (mp);
21609   W (ret);
21610   return ret;
21611 }
21612
21613 int
21614 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21615 {
21616   unformat_input_t *input = vam->input;
21617   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21618   u32 sw_if_index = ~0;
21619   int vrf_set = 0;
21620   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21621   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21622   u8 is_add = 1;
21623   int ret;
21624
21625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21626     {
21627       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21628         ;
21629       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21630         ;
21631       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21632         vrf_set = 1;
21633       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21634         vrf_set = 1;
21635       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21636         vrf_set = 1;
21637       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21638         vrf_set = 1;
21639       else if (unformat (input, "del"))
21640         is_add = 0;
21641       else
21642         break;
21643     }
21644
21645   if (sw_if_index == ~0)
21646     {
21647       errmsg ("Interface required but not specified");
21648       return -99;
21649     }
21650
21651   if (vrf_set == 0)
21652     {
21653       errmsg ("VRF ID required but not specified");
21654       return -99;
21655     }
21656
21657   if (tcp_out_vrf_id == 0
21658       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21659     {
21660       errmsg
21661         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21662       return -99;
21663     }
21664
21665   /* Construct the API message */
21666   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21667
21668   mp->sw_if_index = ntohl (sw_if_index);
21669   mp->is_add = is_add;
21670   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21671   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21672   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21673   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21674
21675   /* send it... */
21676   S (mp);
21677
21678   /* Wait for a reply... */
21679   W (ret);
21680   return ret;
21681 }
21682
21683 static int
21684 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21685 {
21686   unformat_input_t *i = vam->input;
21687   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21688   u32 local_sa_id = 0;
21689   u32 remote_sa_id = 0;
21690   ip4_address_t src_address;
21691   ip4_address_t dst_address;
21692   u8 is_add = 1;
21693   int ret;
21694
21695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21696     {
21697       if (unformat (i, "local_sa %d", &local_sa_id))
21698         ;
21699       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21700         ;
21701       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21702         ;
21703       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21704         ;
21705       else if (unformat (i, "del"))
21706         is_add = 0;
21707       else
21708         {
21709           clib_warning ("parse error '%U'", format_unformat_error, i);
21710           return -99;
21711         }
21712     }
21713
21714   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21715
21716   mp->local_sa_id = ntohl (local_sa_id);
21717   mp->remote_sa_id = ntohl (remote_sa_id);
21718   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21719   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21720   mp->is_add = is_add;
21721
21722   S (mp);
21723   W (ret);
21724   return ret;
21725 }
21726
21727 static int
21728 api_set_punt (vat_main_t * vam)
21729 {
21730   unformat_input_t *i = vam->input;
21731   vl_api_set_punt_t *mp;
21732   u32 ipv = ~0;
21733   u32 protocol = ~0;
21734   u32 port = ~0;
21735   int is_add = 1;
21736   int ret;
21737
21738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21739     {
21740       if (unformat (i, "ip %d", &ipv))
21741         ;
21742       else if (unformat (i, "protocol %d", &protocol))
21743         ;
21744       else if (unformat (i, "port %d", &port))
21745         ;
21746       else if (unformat (i, "del"))
21747         is_add = 0;
21748       else
21749         {
21750           clib_warning ("parse error '%U'", format_unformat_error, i);
21751           return -99;
21752         }
21753     }
21754
21755   M (SET_PUNT, mp);
21756
21757   mp->is_add = (u8) is_add;
21758   mp->punt.ipv = (u8) ipv;
21759   mp->punt.l4_protocol = (u8) protocol;
21760   mp->punt.l4_port = htons ((u16) port);
21761
21762   S (mp);
21763   W (ret);
21764   return ret;
21765 }
21766
21767 static void vl_api_ipsec_gre_tunnel_details_t_handler
21768   (vl_api_ipsec_gre_tunnel_details_t * mp)
21769 {
21770   vat_main_t *vam = &vat_main;
21771
21772   print (vam->ofp, "%11d%15U%15U%14d%14d",
21773          ntohl (mp->sw_if_index),
21774          format_ip4_address, &mp->src_address,
21775          format_ip4_address, &mp->dst_address,
21776          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21777 }
21778
21779 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21780   (vl_api_ipsec_gre_tunnel_details_t * mp)
21781 {
21782   vat_main_t *vam = &vat_main;
21783   vat_json_node_t *node = NULL;
21784   struct in_addr ip4;
21785
21786   if (VAT_JSON_ARRAY != vam->json_tree.type)
21787     {
21788       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21789       vat_json_init_array (&vam->json_tree);
21790     }
21791   node = vat_json_array_add (&vam->json_tree);
21792
21793   vat_json_init_object (node);
21794   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21795   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21796   vat_json_object_add_ip4 (node, "src_address", ip4);
21797   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21798   vat_json_object_add_ip4 (node, "dst_address", ip4);
21799   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21800   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21801 }
21802
21803 static int
21804 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21805 {
21806   unformat_input_t *i = vam->input;
21807   vl_api_ipsec_gre_tunnel_dump_t *mp;
21808   vl_api_control_ping_t *mp_ping;
21809   u32 sw_if_index;
21810   u8 sw_if_index_set = 0;
21811   int ret;
21812
21813   /* Parse args required to build the message */
21814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21815     {
21816       if (unformat (i, "sw_if_index %d", &sw_if_index))
21817         sw_if_index_set = 1;
21818       else
21819         break;
21820     }
21821
21822   if (sw_if_index_set == 0)
21823     {
21824       sw_if_index = ~0;
21825     }
21826
21827   if (!vam->json_output)
21828     {
21829       print (vam->ofp, "%11s%15s%15s%14s%14s",
21830              "sw_if_index", "src_address", "dst_address",
21831              "local_sa_id", "remote_sa_id");
21832     }
21833
21834   /* Get list of gre-tunnel interfaces */
21835   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21836
21837   mp->sw_if_index = htonl (sw_if_index);
21838
21839   S (mp);
21840
21841   /* Use a control ping for synchronization */
21842   MPING (CONTROL_PING, mp_ping);
21843   S (mp_ping);
21844
21845   W (ret);
21846   return ret;
21847 }
21848
21849 static int
21850 api_delete_subif (vat_main_t * vam)
21851 {
21852   unformat_input_t *i = vam->input;
21853   vl_api_delete_subif_t *mp;
21854   u32 sw_if_index = ~0;
21855   int ret;
21856
21857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21858     {
21859       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21860         ;
21861       if (unformat (i, "sw_if_index %d", &sw_if_index))
21862         ;
21863       else
21864         break;
21865     }
21866
21867   if (sw_if_index == ~0)
21868     {
21869       errmsg ("missing sw_if_index");
21870       return -99;
21871     }
21872
21873   /* Construct the API message */
21874   M (DELETE_SUBIF, mp);
21875   mp->sw_if_index = ntohl (sw_if_index);
21876
21877   S (mp);
21878   W (ret);
21879   return ret;
21880 }
21881
21882 #define foreach_pbb_vtr_op      \
21883 _("disable",  L2_VTR_DISABLED)  \
21884 _("pop",  L2_VTR_POP_2)         \
21885 _("push",  L2_VTR_PUSH_2)
21886
21887 static int
21888 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21889 {
21890   unformat_input_t *i = vam->input;
21891   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21892   u32 sw_if_index = ~0, vtr_op = ~0;
21893   u16 outer_tag = ~0;
21894   u8 dmac[6], smac[6];
21895   u8 dmac_set = 0, smac_set = 0;
21896   u16 vlanid = 0;
21897   u32 sid = ~0;
21898   u32 tmp;
21899   int ret;
21900
21901   /* Shut up coverity */
21902   clib_memset (dmac, 0, sizeof (dmac));
21903   clib_memset (smac, 0, sizeof (smac));
21904
21905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21906     {
21907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21908         ;
21909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21910         ;
21911       else if (unformat (i, "vtr_op %d", &vtr_op))
21912         ;
21913 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21914       foreach_pbb_vtr_op
21915 #undef _
21916         else if (unformat (i, "translate_pbb_stag"))
21917         {
21918           if (unformat (i, "%d", &tmp))
21919             {
21920               vtr_op = L2_VTR_TRANSLATE_2_1;
21921               outer_tag = tmp;
21922             }
21923           else
21924             {
21925               errmsg
21926                 ("translate_pbb_stag operation requires outer tag definition");
21927               return -99;
21928             }
21929         }
21930       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21931         dmac_set++;
21932       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21933         smac_set++;
21934       else if (unformat (i, "sid %d", &sid))
21935         ;
21936       else if (unformat (i, "vlanid %d", &tmp))
21937         vlanid = tmp;
21938       else
21939         {
21940           clib_warning ("parse error '%U'", format_unformat_error, i);
21941           return -99;
21942         }
21943     }
21944
21945   if ((sw_if_index == ~0) || (vtr_op == ~0))
21946     {
21947       errmsg ("missing sw_if_index or vtr operation");
21948       return -99;
21949     }
21950   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21951       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21952     {
21953       errmsg
21954         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21955       return -99;
21956     }
21957
21958   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21959   mp->sw_if_index = ntohl (sw_if_index);
21960   mp->vtr_op = ntohl (vtr_op);
21961   mp->outer_tag = ntohs (outer_tag);
21962   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21963   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21964   mp->b_vlanid = ntohs (vlanid);
21965   mp->i_sid = ntohl (sid);
21966
21967   S (mp);
21968   W (ret);
21969   return ret;
21970 }
21971
21972 static int
21973 api_flow_classify_set_interface (vat_main_t * vam)
21974 {
21975   unformat_input_t *i = vam->input;
21976   vl_api_flow_classify_set_interface_t *mp;
21977   u32 sw_if_index;
21978   int sw_if_index_set;
21979   u32 ip4_table_index = ~0;
21980   u32 ip6_table_index = ~0;
21981   u8 is_add = 1;
21982   int ret;
21983
21984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21985     {
21986       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21987         sw_if_index_set = 1;
21988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21989         sw_if_index_set = 1;
21990       else if (unformat (i, "del"))
21991         is_add = 0;
21992       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21993         ;
21994       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21995         ;
21996       else
21997         {
21998           clib_warning ("parse error '%U'", format_unformat_error, i);
21999           return -99;
22000         }
22001     }
22002
22003   if (sw_if_index_set == 0)
22004     {
22005       errmsg ("missing interface name or sw_if_index");
22006       return -99;
22007     }
22008
22009   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
22010
22011   mp->sw_if_index = ntohl (sw_if_index);
22012   mp->ip4_table_index = ntohl (ip4_table_index);
22013   mp->ip6_table_index = ntohl (ip6_table_index);
22014   mp->is_add = is_add;
22015
22016   S (mp);
22017   W (ret);
22018   return ret;
22019 }
22020
22021 static int
22022 api_flow_classify_dump (vat_main_t * vam)
22023 {
22024   unformat_input_t *i = vam->input;
22025   vl_api_flow_classify_dump_t *mp;
22026   vl_api_control_ping_t *mp_ping;
22027   u8 type = FLOW_CLASSIFY_N_TABLES;
22028   int ret;
22029
22030   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
22031     ;
22032   else
22033     {
22034       errmsg ("classify table type must be specified");
22035       return -99;
22036     }
22037
22038   if (!vam->json_output)
22039     {
22040       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
22041     }
22042
22043   M (FLOW_CLASSIFY_DUMP, mp);
22044   mp->type = type;
22045   /* send it... */
22046   S (mp);
22047
22048   /* Use a control ping for synchronization */
22049   MPING (CONTROL_PING, mp_ping);
22050   S (mp_ping);
22051
22052   /* Wait for a reply... */
22053   W (ret);
22054   return ret;
22055 }
22056
22057 static int
22058 api_feature_enable_disable (vat_main_t * vam)
22059 {
22060   unformat_input_t *i = vam->input;
22061   vl_api_feature_enable_disable_t *mp;
22062   u8 *arc_name = 0;
22063   u8 *feature_name = 0;
22064   u32 sw_if_index = ~0;
22065   u8 enable = 1;
22066   int ret;
22067
22068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22069     {
22070       if (unformat (i, "arc_name %s", &arc_name))
22071         ;
22072       else if (unformat (i, "feature_name %s", &feature_name))
22073         ;
22074       else
22075         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22076         ;
22077       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22078         ;
22079       else if (unformat (i, "disable"))
22080         enable = 0;
22081       else
22082         break;
22083     }
22084
22085   if (arc_name == 0)
22086     {
22087       errmsg ("missing arc name");
22088       return -99;
22089     }
22090   if (vec_len (arc_name) > 63)
22091     {
22092       errmsg ("arc name too long");
22093     }
22094
22095   if (feature_name == 0)
22096     {
22097       errmsg ("missing feature name");
22098       return -99;
22099     }
22100   if (vec_len (feature_name) > 63)
22101     {
22102       errmsg ("feature name too long");
22103     }
22104
22105   if (sw_if_index == ~0)
22106     {
22107       errmsg ("missing interface name or sw_if_index");
22108       return -99;
22109     }
22110
22111   /* Construct the API message */
22112   M (FEATURE_ENABLE_DISABLE, mp);
22113   mp->sw_if_index = ntohl (sw_if_index);
22114   mp->enable = enable;
22115   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22116   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22117   vec_free (arc_name);
22118   vec_free (feature_name);
22119
22120   S (mp);
22121   W (ret);
22122   return ret;
22123 }
22124
22125 static int
22126 api_sw_interface_tag_add_del (vat_main_t * vam)
22127 {
22128   unformat_input_t *i = vam->input;
22129   vl_api_sw_interface_tag_add_del_t *mp;
22130   u32 sw_if_index = ~0;
22131   u8 *tag = 0;
22132   u8 enable = 1;
22133   int ret;
22134
22135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22136     {
22137       if (unformat (i, "tag %s", &tag))
22138         ;
22139       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22140         ;
22141       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22142         ;
22143       else if (unformat (i, "del"))
22144         enable = 0;
22145       else
22146         break;
22147     }
22148
22149   if (sw_if_index == ~0)
22150     {
22151       errmsg ("missing interface name or sw_if_index");
22152       return -99;
22153     }
22154
22155   if (enable && (tag == 0))
22156     {
22157       errmsg ("no tag specified");
22158       return -99;
22159     }
22160
22161   /* Construct the API message */
22162   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22163   mp->sw_if_index = ntohl (sw_if_index);
22164   mp->is_add = enable;
22165   if (enable)
22166     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22167   vec_free (tag);
22168
22169   S (mp);
22170   W (ret);
22171   return ret;
22172 }
22173
22174 static void vl_api_l2_xconnect_details_t_handler
22175   (vl_api_l2_xconnect_details_t * mp)
22176 {
22177   vat_main_t *vam = &vat_main;
22178
22179   print (vam->ofp, "%15d%15d",
22180          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22181 }
22182
22183 static void vl_api_l2_xconnect_details_t_handler_json
22184   (vl_api_l2_xconnect_details_t * mp)
22185 {
22186   vat_main_t *vam = &vat_main;
22187   vat_json_node_t *node = NULL;
22188
22189   if (VAT_JSON_ARRAY != vam->json_tree.type)
22190     {
22191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22192       vat_json_init_array (&vam->json_tree);
22193     }
22194   node = vat_json_array_add (&vam->json_tree);
22195
22196   vat_json_init_object (node);
22197   vat_json_object_add_uint (node, "rx_sw_if_index",
22198                             ntohl (mp->rx_sw_if_index));
22199   vat_json_object_add_uint (node, "tx_sw_if_index",
22200                             ntohl (mp->tx_sw_if_index));
22201 }
22202
22203 static int
22204 api_l2_xconnect_dump (vat_main_t * vam)
22205 {
22206   vl_api_l2_xconnect_dump_t *mp;
22207   vl_api_control_ping_t *mp_ping;
22208   int ret;
22209
22210   if (!vam->json_output)
22211     {
22212       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22213     }
22214
22215   M (L2_XCONNECT_DUMP, mp);
22216
22217   S (mp);
22218
22219   /* Use a control ping for synchronization */
22220   MPING (CONTROL_PING, mp_ping);
22221   S (mp_ping);
22222
22223   W (ret);
22224   return ret;
22225 }
22226
22227 static int
22228 api_hw_interface_set_mtu (vat_main_t * vam)
22229 {
22230   unformat_input_t *i = vam->input;
22231   vl_api_hw_interface_set_mtu_t *mp;
22232   u32 sw_if_index = ~0;
22233   u32 mtu = 0;
22234   int ret;
22235
22236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22237     {
22238       if (unformat (i, "mtu %d", &mtu))
22239         ;
22240       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22241         ;
22242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22243         ;
22244       else
22245         break;
22246     }
22247
22248   if (sw_if_index == ~0)
22249     {
22250       errmsg ("missing interface name or sw_if_index");
22251       return -99;
22252     }
22253
22254   if (mtu == 0)
22255     {
22256       errmsg ("no mtu specified");
22257       return -99;
22258     }
22259
22260   /* Construct the API message */
22261   M (HW_INTERFACE_SET_MTU, mp);
22262   mp->sw_if_index = ntohl (sw_if_index);
22263   mp->mtu = ntohs ((u16) mtu);
22264
22265   S (mp);
22266   W (ret);
22267   return ret;
22268 }
22269
22270 static int
22271 api_p2p_ethernet_add (vat_main_t * vam)
22272 {
22273   unformat_input_t *i = vam->input;
22274   vl_api_p2p_ethernet_add_t *mp;
22275   u32 parent_if_index = ~0;
22276   u32 sub_id = ~0;
22277   u8 remote_mac[6];
22278   u8 mac_set = 0;
22279   int ret;
22280
22281   clib_memset (remote_mac, 0, sizeof (remote_mac));
22282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22283     {
22284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22285         ;
22286       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22287         ;
22288       else
22289         if (unformat
22290             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22291         mac_set++;
22292       else if (unformat (i, "sub_id %d", &sub_id))
22293         ;
22294       else
22295         {
22296           clib_warning ("parse error '%U'", format_unformat_error, i);
22297           return -99;
22298         }
22299     }
22300
22301   if (parent_if_index == ~0)
22302     {
22303       errmsg ("missing interface name or sw_if_index");
22304       return -99;
22305     }
22306   if (mac_set == 0)
22307     {
22308       errmsg ("missing remote mac address");
22309       return -99;
22310     }
22311   if (sub_id == ~0)
22312     {
22313       errmsg ("missing sub-interface id");
22314       return -99;
22315     }
22316
22317   M (P2P_ETHERNET_ADD, mp);
22318   mp->parent_if_index = ntohl (parent_if_index);
22319   mp->subif_id = ntohl (sub_id);
22320   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22321
22322   S (mp);
22323   W (ret);
22324   return ret;
22325 }
22326
22327 static int
22328 api_p2p_ethernet_del (vat_main_t * vam)
22329 {
22330   unformat_input_t *i = vam->input;
22331   vl_api_p2p_ethernet_del_t *mp;
22332   u32 parent_if_index = ~0;
22333   u8 remote_mac[6];
22334   u8 mac_set = 0;
22335   int ret;
22336
22337   clib_memset (remote_mac, 0, sizeof (remote_mac));
22338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22339     {
22340       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22341         ;
22342       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22343         ;
22344       else
22345         if (unformat
22346             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22347         mac_set++;
22348       else
22349         {
22350           clib_warning ("parse error '%U'", format_unformat_error, i);
22351           return -99;
22352         }
22353     }
22354
22355   if (parent_if_index == ~0)
22356     {
22357       errmsg ("missing interface name or sw_if_index");
22358       return -99;
22359     }
22360   if (mac_set == 0)
22361     {
22362       errmsg ("missing remote mac address");
22363       return -99;
22364     }
22365
22366   M (P2P_ETHERNET_DEL, mp);
22367   mp->parent_if_index = ntohl (parent_if_index);
22368   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22369
22370   S (mp);
22371   W (ret);
22372   return ret;
22373 }
22374
22375 static int
22376 api_lldp_config (vat_main_t * vam)
22377 {
22378   unformat_input_t *i = vam->input;
22379   vl_api_lldp_config_t *mp;
22380   int tx_hold = 0;
22381   int tx_interval = 0;
22382   u8 *sys_name = NULL;
22383   int ret;
22384
22385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22386     {
22387       if (unformat (i, "system-name %s", &sys_name))
22388         ;
22389       else if (unformat (i, "tx-hold %d", &tx_hold))
22390         ;
22391       else if (unformat (i, "tx-interval %d", &tx_interval))
22392         ;
22393       else
22394         {
22395           clib_warning ("parse error '%U'", format_unformat_error, i);
22396           return -99;
22397         }
22398     }
22399
22400   vec_add1 (sys_name, 0);
22401
22402   M (LLDP_CONFIG, mp);
22403   mp->tx_hold = htonl (tx_hold);
22404   mp->tx_interval = htonl (tx_interval);
22405   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22406   vec_free (sys_name);
22407
22408   S (mp);
22409   W (ret);
22410   return ret;
22411 }
22412
22413 static int
22414 api_sw_interface_set_lldp (vat_main_t * vam)
22415 {
22416   unformat_input_t *i = vam->input;
22417   vl_api_sw_interface_set_lldp_t *mp;
22418   u32 sw_if_index = ~0;
22419   u32 enable = 1;
22420   u8 *port_desc = NULL, *mgmt_oid = NULL;
22421   ip4_address_t ip4_addr;
22422   ip6_address_t ip6_addr;
22423   int ret;
22424
22425   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
22426   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
22427
22428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22429     {
22430       if (unformat (i, "disable"))
22431         enable = 0;
22432       else
22433         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22434         ;
22435       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22436         ;
22437       else if (unformat (i, "port-desc %s", &port_desc))
22438         ;
22439       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22440         ;
22441       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22442         ;
22443       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22444         ;
22445       else
22446         break;
22447     }
22448
22449   if (sw_if_index == ~0)
22450     {
22451       errmsg ("missing interface name or sw_if_index");
22452       return -99;
22453     }
22454
22455   /* Construct the API message */
22456   vec_add1 (port_desc, 0);
22457   vec_add1 (mgmt_oid, 0);
22458   M (SW_INTERFACE_SET_LLDP, mp);
22459   mp->sw_if_index = ntohl (sw_if_index);
22460   mp->enable = enable;
22461   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22462   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22463   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22464   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22465   vec_free (port_desc);
22466   vec_free (mgmt_oid);
22467
22468   S (mp);
22469   W (ret);
22470   return ret;
22471 }
22472
22473 static int
22474 api_tcp_configure_src_addresses (vat_main_t * vam)
22475 {
22476   vl_api_tcp_configure_src_addresses_t *mp;
22477   unformat_input_t *i = vam->input;
22478   ip4_address_t v4first, v4last;
22479   ip6_address_t v6first, v6last;
22480   u8 range_set = 0;
22481   u32 vrf_id = 0;
22482   int ret;
22483
22484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22485     {
22486       if (unformat (i, "%U - %U",
22487                     unformat_ip4_address, &v4first,
22488                     unformat_ip4_address, &v4last))
22489         {
22490           if (range_set)
22491             {
22492               errmsg ("one range per message (range already set)");
22493               return -99;
22494             }
22495           range_set = 1;
22496         }
22497       else if (unformat (i, "%U - %U",
22498                          unformat_ip6_address, &v6first,
22499                          unformat_ip6_address, &v6last))
22500         {
22501           if (range_set)
22502             {
22503               errmsg ("one range per message (range already set)");
22504               return -99;
22505             }
22506           range_set = 2;
22507         }
22508       else if (unformat (i, "vrf %d", &vrf_id))
22509         ;
22510       else
22511         break;
22512     }
22513
22514   if (range_set == 0)
22515     {
22516       errmsg ("address range not set");
22517       return -99;
22518     }
22519
22520   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22521   mp->vrf_id = ntohl (vrf_id);
22522   /* ipv6? */
22523   if (range_set == 2)
22524     {
22525       mp->is_ipv6 = 1;
22526       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22527       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22528     }
22529   else
22530     {
22531       mp->is_ipv6 = 0;
22532       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22533       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22534     }
22535   S (mp);
22536   W (ret);
22537   return ret;
22538 }
22539
22540 static void vl_api_app_namespace_add_del_reply_t_handler
22541   (vl_api_app_namespace_add_del_reply_t * mp)
22542 {
22543   vat_main_t *vam = &vat_main;
22544   i32 retval = ntohl (mp->retval);
22545   if (vam->async_mode)
22546     {
22547       vam->async_errors += (retval < 0);
22548     }
22549   else
22550     {
22551       vam->retval = retval;
22552       if (retval == 0)
22553         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22554       vam->result_ready = 1;
22555     }
22556 }
22557
22558 static void vl_api_app_namespace_add_del_reply_t_handler_json
22559   (vl_api_app_namespace_add_del_reply_t * mp)
22560 {
22561   vat_main_t *vam = &vat_main;
22562   vat_json_node_t node;
22563
22564   vat_json_init_object (&node);
22565   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22566   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22567
22568   vat_json_print (vam->ofp, &node);
22569   vat_json_free (&node);
22570
22571   vam->retval = ntohl (mp->retval);
22572   vam->result_ready = 1;
22573 }
22574
22575 static int
22576 api_app_namespace_add_del (vat_main_t * vam)
22577 {
22578   vl_api_app_namespace_add_del_t *mp;
22579   unformat_input_t *i = vam->input;
22580   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22581   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22582   u64 secret;
22583   int ret;
22584
22585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22586     {
22587       if (unformat (i, "id %_%v%_", &ns_id))
22588         ;
22589       else if (unformat (i, "secret %lu", &secret))
22590         secret_set = 1;
22591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22592         sw_if_index_set = 1;
22593       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22594         ;
22595       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22596         ;
22597       else
22598         break;
22599     }
22600   if (!ns_id || !secret_set || !sw_if_index_set)
22601     {
22602       errmsg ("namespace id, secret and sw_if_index must be set");
22603       return -99;
22604     }
22605   if (vec_len (ns_id) > 64)
22606     {
22607       errmsg ("namespace id too long");
22608       return -99;
22609     }
22610   M (APP_NAMESPACE_ADD_DEL, mp);
22611
22612   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22613   mp->namespace_id_len = vec_len (ns_id);
22614   mp->secret = clib_host_to_net_u64 (secret);
22615   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22616   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22617   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22618   vec_free (ns_id);
22619   S (mp);
22620   W (ret);
22621   return ret;
22622 }
22623
22624 static int
22625 api_sock_init_shm (vat_main_t * vam)
22626 {
22627 #if VPP_API_TEST_BUILTIN == 0
22628   unformat_input_t *i = vam->input;
22629   vl_api_shm_elem_config_t *config = 0;
22630   u64 size = 64 << 20;
22631   int rv;
22632
22633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22634     {
22635       if (unformat (i, "size %U", unformat_memory_size, &size))
22636         ;
22637       else
22638         break;
22639     }
22640
22641   /*
22642    * Canned custom ring allocator config.
22643    * Should probably parse all of this
22644    */
22645   vec_validate (config, 6);
22646   config[0].type = VL_API_VLIB_RING;
22647   config[0].size = 256;
22648   config[0].count = 32;
22649
22650   config[1].type = VL_API_VLIB_RING;
22651   config[1].size = 1024;
22652   config[1].count = 16;
22653
22654   config[2].type = VL_API_VLIB_RING;
22655   config[2].size = 4096;
22656   config[2].count = 2;
22657
22658   config[3].type = VL_API_CLIENT_RING;
22659   config[3].size = 256;
22660   config[3].count = 32;
22661
22662   config[4].type = VL_API_CLIENT_RING;
22663   config[4].size = 1024;
22664   config[4].count = 16;
22665
22666   config[5].type = VL_API_CLIENT_RING;
22667   config[5].size = 4096;
22668   config[5].count = 2;
22669
22670   config[6].type = VL_API_QUEUE;
22671   config[6].count = 128;
22672   config[6].size = sizeof (uword);
22673
22674   rv = vl_socket_client_init_shm (config);
22675   if (!rv)
22676     vam->client_index_invalid = 1;
22677   return rv;
22678 #else
22679   return -99;
22680 #endif
22681 }
22682
22683 static int
22684 api_dns_enable_disable (vat_main_t * vam)
22685 {
22686   unformat_input_t *line_input = vam->input;
22687   vl_api_dns_enable_disable_t *mp;
22688   u8 enable_disable = 1;
22689   int ret;
22690
22691   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22692     {
22693       if (unformat (line_input, "disable"))
22694         enable_disable = 0;
22695       if (unformat (line_input, "enable"))
22696         enable_disable = 1;
22697       else
22698         break;
22699     }
22700
22701   /* Construct the API message */
22702   M (DNS_ENABLE_DISABLE, mp);
22703   mp->enable = enable_disable;
22704
22705   /* send it... */
22706   S (mp);
22707   /* Wait for the reply */
22708   W (ret);
22709   return ret;
22710 }
22711
22712 static int
22713 api_dns_resolve_name (vat_main_t * vam)
22714 {
22715   unformat_input_t *line_input = vam->input;
22716   vl_api_dns_resolve_name_t *mp;
22717   u8 *name = 0;
22718   int ret;
22719
22720   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22721     {
22722       if (unformat (line_input, "%s", &name))
22723         ;
22724       else
22725         break;
22726     }
22727
22728   if (vec_len (name) > 127)
22729     {
22730       errmsg ("name too long");
22731       return -99;
22732     }
22733
22734   /* Construct the API message */
22735   M (DNS_RESOLVE_NAME, mp);
22736   memcpy (mp->name, name, vec_len (name));
22737   vec_free (name);
22738
22739   /* send it... */
22740   S (mp);
22741   /* Wait for the reply */
22742   W (ret);
22743   return ret;
22744 }
22745
22746 static int
22747 api_dns_resolve_ip (vat_main_t * vam)
22748 {
22749   unformat_input_t *line_input = vam->input;
22750   vl_api_dns_resolve_ip_t *mp;
22751   int is_ip6 = -1;
22752   ip4_address_t addr4;
22753   ip6_address_t addr6;
22754   int ret;
22755
22756   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22757     {
22758       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22759         is_ip6 = 1;
22760       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22761         is_ip6 = 0;
22762       else
22763         break;
22764     }
22765
22766   if (is_ip6 == -1)
22767     {
22768       errmsg ("missing address");
22769       return -99;
22770     }
22771
22772   /* Construct the API message */
22773   M (DNS_RESOLVE_IP, mp);
22774   mp->is_ip6 = is_ip6;
22775   if (is_ip6)
22776     memcpy (mp->address, &addr6, sizeof (addr6));
22777   else
22778     memcpy (mp->address, &addr4, sizeof (addr4));
22779
22780   /* send it... */
22781   S (mp);
22782   /* Wait for the reply */
22783   W (ret);
22784   return ret;
22785 }
22786
22787 static int
22788 api_dns_name_server_add_del (vat_main_t * vam)
22789 {
22790   unformat_input_t *i = vam->input;
22791   vl_api_dns_name_server_add_del_t *mp;
22792   u8 is_add = 1;
22793   ip6_address_t ip6_server;
22794   ip4_address_t ip4_server;
22795   int ip6_set = 0;
22796   int ip4_set = 0;
22797   int ret = 0;
22798
22799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22800     {
22801       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22802         ip6_set = 1;
22803       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22804         ip4_set = 1;
22805       else if (unformat (i, "del"))
22806         is_add = 0;
22807       else
22808         {
22809           clib_warning ("parse error '%U'", format_unformat_error, i);
22810           return -99;
22811         }
22812     }
22813
22814   if (ip4_set && ip6_set)
22815     {
22816       errmsg ("Only one server address allowed per message");
22817       return -99;
22818     }
22819   if ((ip4_set + ip6_set) == 0)
22820     {
22821       errmsg ("Server address required");
22822       return -99;
22823     }
22824
22825   /* Construct the API message */
22826   M (DNS_NAME_SERVER_ADD_DEL, mp);
22827
22828   if (ip6_set)
22829     {
22830       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22831       mp->is_ip6 = 1;
22832     }
22833   else
22834     {
22835       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22836       mp->is_ip6 = 0;
22837     }
22838
22839   mp->is_add = is_add;
22840
22841   /* send it... */
22842   S (mp);
22843
22844   /* Wait for a reply, return good/bad news  */
22845   W (ret);
22846   return ret;
22847 }
22848
22849 static void
22850 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22851 {
22852   vat_main_t *vam = &vat_main;
22853
22854   if (mp->is_ip4)
22855     {
22856       print (vam->ofp,
22857              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22858              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22859              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22860              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22861              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22862              clib_net_to_host_u32 (mp->action_index), mp->tag);
22863     }
22864   else
22865     {
22866       print (vam->ofp,
22867              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22868              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22869              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22870              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22871              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22872              clib_net_to_host_u32 (mp->action_index), mp->tag);
22873     }
22874 }
22875
22876 static void
22877 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22878                                              mp)
22879 {
22880   vat_main_t *vam = &vat_main;
22881   vat_json_node_t *node = NULL;
22882   struct in6_addr ip6;
22883   struct in_addr ip4;
22884
22885   if (VAT_JSON_ARRAY != vam->json_tree.type)
22886     {
22887       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22888       vat_json_init_array (&vam->json_tree);
22889     }
22890   node = vat_json_array_add (&vam->json_tree);
22891   vat_json_init_object (node);
22892
22893   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22894   vat_json_object_add_uint (node, "appns_index",
22895                             clib_net_to_host_u32 (mp->appns_index));
22896   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22897   vat_json_object_add_uint (node, "scope", mp->scope);
22898   vat_json_object_add_uint (node, "action_index",
22899                             clib_net_to_host_u32 (mp->action_index));
22900   vat_json_object_add_uint (node, "lcl_port",
22901                             clib_net_to_host_u16 (mp->lcl_port));
22902   vat_json_object_add_uint (node, "rmt_port",
22903                             clib_net_to_host_u16 (mp->rmt_port));
22904   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22905   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22906   vat_json_object_add_string_copy (node, "tag", mp->tag);
22907   if (mp->is_ip4)
22908     {
22909       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22910       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22911       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22912       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22913     }
22914   else
22915     {
22916       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22917       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22918       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22919       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22920     }
22921 }
22922
22923 static int
22924 api_session_rule_add_del (vat_main_t * vam)
22925 {
22926   vl_api_session_rule_add_del_t *mp;
22927   unformat_input_t *i = vam->input;
22928   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22929   u32 appns_index = 0, scope = 0;
22930   ip4_address_t lcl_ip4, rmt_ip4;
22931   ip6_address_t lcl_ip6, rmt_ip6;
22932   u8 is_ip4 = 1, conn_set = 0;
22933   u8 is_add = 1, *tag = 0;
22934   int ret;
22935
22936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22937     {
22938       if (unformat (i, "del"))
22939         is_add = 0;
22940       else if (unformat (i, "add"))
22941         ;
22942       else if (unformat (i, "proto tcp"))
22943         proto = 0;
22944       else if (unformat (i, "proto udp"))
22945         proto = 1;
22946       else if (unformat (i, "appns %d", &appns_index))
22947         ;
22948       else if (unformat (i, "scope %d", &scope))
22949         ;
22950       else if (unformat (i, "tag %_%v%_", &tag))
22951         ;
22952       else
22953         if (unformat
22954             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22955              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22956              &rmt_port))
22957         {
22958           is_ip4 = 1;
22959           conn_set = 1;
22960         }
22961       else
22962         if (unformat
22963             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22964              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22965              &rmt_port))
22966         {
22967           is_ip4 = 0;
22968           conn_set = 1;
22969         }
22970       else if (unformat (i, "action %d", &action))
22971         ;
22972       else
22973         break;
22974     }
22975   if (proto == ~0 || !conn_set || action == ~0)
22976     {
22977       errmsg ("transport proto, connection and action must be set");
22978       return -99;
22979     }
22980
22981   if (scope > 3)
22982     {
22983       errmsg ("scope should be 0-3");
22984       return -99;
22985     }
22986
22987   M (SESSION_RULE_ADD_DEL, mp);
22988
22989   mp->is_ip4 = is_ip4;
22990   mp->transport_proto = proto;
22991   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22992   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22993   mp->lcl_plen = lcl_plen;
22994   mp->rmt_plen = rmt_plen;
22995   mp->action_index = clib_host_to_net_u32 (action);
22996   mp->appns_index = clib_host_to_net_u32 (appns_index);
22997   mp->scope = scope;
22998   mp->is_add = is_add;
22999   if (is_ip4)
23000     {
23001       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
23002       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
23003     }
23004   else
23005     {
23006       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23007       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23008     }
23009   if (tag)
23010     {
23011       clib_memcpy (mp->tag, tag, vec_len (tag));
23012       vec_free (tag);
23013     }
23014
23015   S (mp);
23016   W (ret);
23017   return ret;
23018 }
23019
23020 static int
23021 api_session_rules_dump (vat_main_t * vam)
23022 {
23023   vl_api_session_rules_dump_t *mp;
23024   vl_api_control_ping_t *mp_ping;
23025   int ret;
23026
23027   if (!vam->json_output)
23028     {
23029       print (vam->ofp, "%=20s", "Session Rules");
23030     }
23031
23032   M (SESSION_RULES_DUMP, mp);
23033   /* send it... */
23034   S (mp);
23035
23036   /* Use a control ping for synchronization */
23037   MPING (CONTROL_PING, mp_ping);
23038   S (mp_ping);
23039
23040   /* Wait for a reply... */
23041   W (ret);
23042   return ret;
23043 }
23044
23045 static int
23046 api_ip_container_proxy_add_del (vat_main_t * vam)
23047 {
23048   vl_api_ip_container_proxy_add_del_t *mp;
23049   unformat_input_t *i = vam->input;
23050   u32 plen = ~0, sw_if_index = ~0;
23051   ip4_address_t ip4;
23052   ip6_address_t ip6;
23053   u8 is_ip4 = 1;
23054   u8 is_add = 1;
23055   int ret;
23056
23057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23058     {
23059       if (unformat (i, "del"))
23060         is_add = 0;
23061       else if (unformat (i, "add"))
23062         ;
23063       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23064         {
23065           is_ip4 = 1;
23066           plen = 32;
23067         }
23068       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23069         {
23070           is_ip4 = 0;
23071           plen = 128;
23072         }
23073       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23074         ;
23075       else
23076         break;
23077     }
23078   if (sw_if_index == ~0 || plen == ~0)
23079     {
23080       errmsg ("address and sw_if_index must be set");
23081       return -99;
23082     }
23083
23084   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23085
23086   mp->is_ip4 = is_ip4;
23087   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23088   mp->plen = plen;
23089   mp->is_add = is_add;
23090   if (is_ip4)
23091     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23092   else
23093     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23094
23095   S (mp);
23096   W (ret);
23097   return ret;
23098 }
23099
23100 static int
23101 api_qos_record_enable_disable (vat_main_t * vam)
23102 {
23103   unformat_input_t *i = vam->input;
23104   vl_api_qos_record_enable_disable_t *mp;
23105   u32 sw_if_index, qs = 0xff;
23106   u8 sw_if_index_set = 0;
23107   u8 enable = 1;
23108   int ret;
23109
23110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23111     {
23112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23113         sw_if_index_set = 1;
23114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23115         sw_if_index_set = 1;
23116       else if (unformat (i, "%U", unformat_qos_source, &qs))
23117         ;
23118       else if (unformat (i, "disable"))
23119         enable = 0;
23120       else
23121         {
23122           clib_warning ("parse error '%U'", format_unformat_error, i);
23123           return -99;
23124         }
23125     }
23126
23127   if (sw_if_index_set == 0)
23128     {
23129       errmsg ("missing interface name or sw_if_index");
23130       return -99;
23131     }
23132   if (qs == 0xff)
23133     {
23134       errmsg ("input location must be specified");
23135       return -99;
23136     }
23137
23138   M (QOS_RECORD_ENABLE_DISABLE, mp);
23139
23140   mp->sw_if_index = ntohl (sw_if_index);
23141   mp->input_source = qs;
23142   mp->enable = enable;
23143
23144   S (mp);
23145   W (ret);
23146   return ret;
23147 }
23148
23149
23150 static int
23151 q_or_quit (vat_main_t * vam)
23152 {
23153 #if VPP_API_TEST_BUILTIN == 0
23154   longjmp (vam->jump_buf, 1);
23155 #endif
23156   return 0;                     /* not so much */
23157 }
23158
23159 static int
23160 q (vat_main_t * vam)
23161 {
23162   return q_or_quit (vam);
23163 }
23164
23165 static int
23166 quit (vat_main_t * vam)
23167 {
23168   return q_or_quit (vam);
23169 }
23170
23171 static int
23172 comment (vat_main_t * vam)
23173 {
23174   return 0;
23175 }
23176
23177 static int
23178 statseg (vat_main_t * vam)
23179 {
23180   ssvm_private_t *ssvmp = &vam->stat_segment;
23181   ssvm_shared_header_t *shared_header = ssvmp->sh;
23182   vlib_counter_t **counters;
23183   u64 thread0_index1_packets;
23184   u64 thread0_index1_bytes;
23185   f64 vector_rate, input_rate;
23186   uword *p;
23187
23188   uword *counter_vector_by_name;
23189   if (vam->stat_segment_lockp == 0)
23190     {
23191       errmsg ("Stat segment not mapped...");
23192       return -99;
23193     }
23194
23195   /* look up "/if/rx for sw_if_index 1 as a test */
23196
23197   clib_spinlock_lock (vam->stat_segment_lockp);
23198
23199   counter_vector_by_name = (uword *) shared_header->opaque[1];
23200
23201   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23202   if (p == 0)
23203     {
23204       clib_spinlock_unlock (vam->stat_segment_lockp);
23205       errmsg ("/if/tx not found?");
23206       return -99;
23207     }
23208
23209   /* Fish per-thread vector of combined counters from shared memory */
23210   counters = (vlib_counter_t **) p[0];
23211
23212   if (vec_len (counters[0]) < 2)
23213     {
23214       clib_spinlock_unlock (vam->stat_segment_lockp);
23215       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23216       return -99;
23217     }
23218
23219   /* Read thread 0 sw_if_index 1 counter */
23220   thread0_index1_packets = counters[0][1].packets;
23221   thread0_index1_bytes = counters[0][1].bytes;
23222
23223   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23224   if (p == 0)
23225     {
23226       clib_spinlock_unlock (vam->stat_segment_lockp);
23227       errmsg ("vector_rate not found?");
23228       return -99;
23229     }
23230
23231   vector_rate = *(f64 *) (p[0]);
23232   p = hash_get_mem (counter_vector_by_name, "input_rate");
23233   if (p == 0)
23234     {
23235       clib_spinlock_unlock (vam->stat_segment_lockp);
23236       errmsg ("input_rate not found?");
23237       return -99;
23238     }
23239   input_rate = *(f64 *) (p[0]);
23240
23241   clib_spinlock_unlock (vam->stat_segment_lockp);
23242
23243   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23244          vector_rate, input_rate);
23245   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23246          thread0_index1_packets, thread0_index1_bytes);
23247
23248   return 0;
23249 }
23250
23251 static int
23252 cmd_cmp (void *a1, void *a2)
23253 {
23254   u8 **c1 = a1;
23255   u8 **c2 = a2;
23256
23257   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23258 }
23259
23260 static int
23261 help (vat_main_t * vam)
23262 {
23263   u8 **cmds = 0;
23264   u8 *name = 0;
23265   hash_pair_t *p;
23266   unformat_input_t *i = vam->input;
23267   int j;
23268
23269   if (unformat (i, "%s", &name))
23270     {
23271       uword *hs;
23272
23273       vec_add1 (name, 0);
23274
23275       hs = hash_get_mem (vam->help_by_name, name);
23276       if (hs)
23277         print (vam->ofp, "usage: %s %s", name, hs[0]);
23278       else
23279         print (vam->ofp, "No such msg / command '%s'", name);
23280       vec_free (name);
23281       return 0;
23282     }
23283
23284   print (vam->ofp, "Help is available for the following:");
23285
23286     /* *INDENT-OFF* */
23287     hash_foreach_pair (p, vam->function_by_name,
23288     ({
23289       vec_add1 (cmds, (u8 *)(p->key));
23290     }));
23291     /* *INDENT-ON* */
23292
23293   vec_sort_with_function (cmds, cmd_cmp);
23294
23295   for (j = 0; j < vec_len (cmds); j++)
23296     print (vam->ofp, "%s", cmds[j]);
23297
23298   vec_free (cmds);
23299   return 0;
23300 }
23301
23302 static int
23303 set (vat_main_t * vam)
23304 {
23305   u8 *name = 0, *value = 0;
23306   unformat_input_t *i = vam->input;
23307
23308   if (unformat (i, "%s", &name))
23309     {
23310       /* The input buffer is a vector, not a string. */
23311       value = vec_dup (i->buffer);
23312       vec_delete (value, i->index, 0);
23313       /* Almost certainly has a trailing newline */
23314       if (value[vec_len (value) - 1] == '\n')
23315         value[vec_len (value) - 1] = 0;
23316       /* Make sure it's a proper string, one way or the other */
23317       vec_add1 (value, 0);
23318       (void) clib_macro_set_value (&vam->macro_main,
23319                                    (char *) name, (char *) value);
23320     }
23321   else
23322     errmsg ("usage: set <name> <value>");
23323
23324   vec_free (name);
23325   vec_free (value);
23326   return 0;
23327 }
23328
23329 static int
23330 unset (vat_main_t * vam)
23331 {
23332   u8 *name = 0;
23333
23334   if (unformat (vam->input, "%s", &name))
23335     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23336       errmsg ("unset: %s wasn't set", name);
23337   vec_free (name);
23338   return 0;
23339 }
23340
23341 typedef struct
23342 {
23343   u8 *name;
23344   u8 *value;
23345 } macro_sort_t;
23346
23347
23348 static int
23349 macro_sort_cmp (void *a1, void *a2)
23350 {
23351   macro_sort_t *s1 = a1;
23352   macro_sort_t *s2 = a2;
23353
23354   return strcmp ((char *) (s1->name), (char *) (s2->name));
23355 }
23356
23357 static int
23358 dump_macro_table (vat_main_t * vam)
23359 {
23360   macro_sort_t *sort_me = 0, *sm;
23361   int i;
23362   hash_pair_t *p;
23363
23364     /* *INDENT-OFF* */
23365     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23366     ({
23367       vec_add2 (sort_me, sm, 1);
23368       sm->name = (u8 *)(p->key);
23369       sm->value = (u8 *) (p->value[0]);
23370     }));
23371     /* *INDENT-ON* */
23372
23373   vec_sort_with_function (sort_me, macro_sort_cmp);
23374
23375   if (vec_len (sort_me))
23376     print (vam->ofp, "%-15s%s", "Name", "Value");
23377   else
23378     print (vam->ofp, "The macro table is empty...");
23379
23380   for (i = 0; i < vec_len (sort_me); i++)
23381     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23382   return 0;
23383 }
23384
23385 static int
23386 dump_node_table (vat_main_t * vam)
23387 {
23388   int i, j;
23389   vlib_node_t *node, *next_node;
23390
23391   if (vec_len (vam->graph_nodes) == 0)
23392     {
23393       print (vam->ofp, "Node table empty, issue get_node_graph...");
23394       return 0;
23395     }
23396
23397   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23398     {
23399       node = vam->graph_nodes[0][i];
23400       print (vam->ofp, "[%d] %s", i, node->name);
23401       for (j = 0; j < vec_len (node->next_nodes); j++)
23402         {
23403           if (node->next_nodes[j] != ~0)
23404             {
23405               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23406               print (vam->ofp, "  [%d] %s", j, next_node->name);
23407             }
23408         }
23409     }
23410   return 0;
23411 }
23412
23413 static int
23414 value_sort_cmp (void *a1, void *a2)
23415 {
23416   name_sort_t *n1 = a1;
23417   name_sort_t *n2 = a2;
23418
23419   if (n1->value < n2->value)
23420     return -1;
23421   if (n1->value > n2->value)
23422     return 1;
23423   return 0;
23424 }
23425
23426
23427 static int
23428 dump_msg_api_table (vat_main_t * vam)
23429 {
23430   api_main_t *am = &api_main;
23431   name_sort_t *nses = 0, *ns;
23432   hash_pair_t *hp;
23433   int i;
23434
23435   /* *INDENT-OFF* */
23436   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23437   ({
23438     vec_add2 (nses, ns, 1);
23439     ns->name = (u8 *)(hp->key);
23440     ns->value = (u32) hp->value[0];
23441   }));
23442   /* *INDENT-ON* */
23443
23444   vec_sort_with_function (nses, value_sort_cmp);
23445
23446   for (i = 0; i < vec_len (nses); i++)
23447     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23448   vec_free (nses);
23449   return 0;
23450 }
23451
23452 static int
23453 get_msg_id (vat_main_t * vam)
23454 {
23455   u8 *name_and_crc;
23456   u32 message_index;
23457
23458   if (unformat (vam->input, "%s", &name_and_crc))
23459     {
23460       message_index = vl_msg_api_get_msg_index (name_and_crc);
23461       if (message_index == ~0)
23462         {
23463           print (vam->ofp, " '%s' not found", name_and_crc);
23464           return 0;
23465         }
23466       print (vam->ofp, " '%s' has message index %d",
23467              name_and_crc, message_index);
23468       return 0;
23469     }
23470   errmsg ("name_and_crc required...");
23471   return 0;
23472 }
23473
23474 static int
23475 search_node_table (vat_main_t * vam)
23476 {
23477   unformat_input_t *line_input = vam->input;
23478   u8 *node_to_find;
23479   int j;
23480   vlib_node_t *node, *next_node;
23481   uword *p;
23482
23483   if (vam->graph_node_index_by_name == 0)
23484     {
23485       print (vam->ofp, "Node table empty, issue get_node_graph...");
23486       return 0;
23487     }
23488
23489   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23490     {
23491       if (unformat (line_input, "%s", &node_to_find))
23492         {
23493           vec_add1 (node_to_find, 0);
23494           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23495           if (p == 0)
23496             {
23497               print (vam->ofp, "%s not found...", node_to_find);
23498               goto out;
23499             }
23500           node = vam->graph_nodes[0][p[0]];
23501           print (vam->ofp, "[%d] %s", p[0], node->name);
23502           for (j = 0; j < vec_len (node->next_nodes); j++)
23503             {
23504               if (node->next_nodes[j] != ~0)
23505                 {
23506                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23507                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23508                 }
23509             }
23510         }
23511
23512       else
23513         {
23514           clib_warning ("parse error '%U'", format_unformat_error,
23515                         line_input);
23516           return -99;
23517         }
23518
23519     out:
23520       vec_free (node_to_find);
23521
23522     }
23523
23524   return 0;
23525 }
23526
23527
23528 static int
23529 script (vat_main_t * vam)
23530 {
23531 #if (VPP_API_TEST_BUILTIN==0)
23532   u8 *s = 0;
23533   char *save_current_file;
23534   unformat_input_t save_input;
23535   jmp_buf save_jump_buf;
23536   u32 save_line_number;
23537
23538   FILE *new_fp, *save_ifp;
23539
23540   if (unformat (vam->input, "%s", &s))
23541     {
23542       new_fp = fopen ((char *) s, "r");
23543       if (new_fp == 0)
23544         {
23545           errmsg ("Couldn't open script file %s", s);
23546           vec_free (s);
23547           return -99;
23548         }
23549     }
23550   else
23551     {
23552       errmsg ("Missing script name");
23553       return -99;
23554     }
23555
23556   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23557   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23558   save_ifp = vam->ifp;
23559   save_line_number = vam->input_line_number;
23560   save_current_file = (char *) vam->current_file;
23561
23562   vam->input_line_number = 0;
23563   vam->ifp = new_fp;
23564   vam->current_file = s;
23565   do_one_file (vam);
23566
23567   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23568   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23569   vam->ifp = save_ifp;
23570   vam->input_line_number = save_line_number;
23571   vam->current_file = (u8 *) save_current_file;
23572   vec_free (s);
23573
23574   return 0;
23575 #else
23576   clib_warning ("use the exec command...");
23577   return -99;
23578 #endif
23579 }
23580
23581 static int
23582 echo (vat_main_t * vam)
23583 {
23584   print (vam->ofp, "%v", vam->input->buffer);
23585   return 0;
23586 }
23587
23588 /* List of API message constructors, CLI names map to api_xxx */
23589 #define foreach_vpe_api_msg                                             \
23590 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23591 _(sw_interface_dump,"")                                                 \
23592 _(sw_interface_set_flags,                                               \
23593   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23594 _(sw_interface_add_del_address,                                         \
23595   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23596 _(sw_interface_set_rx_mode,                                             \
23597   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23598 _(sw_interface_set_rx_placement,                                        \
23599   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23600 _(sw_interface_rx_placement_dump,                                       \
23601   "[<intfc> | sw_if_index <id>]")                                         \
23602 _(sw_interface_set_table,                                               \
23603   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23604 _(sw_interface_set_mpls_enable,                                         \
23605   "<intfc> | sw_if_index [disable | dis]")                              \
23606 _(sw_interface_set_vpath,                                               \
23607   "<intfc> | sw_if_index <id> enable | disable")                        \
23608 _(sw_interface_set_vxlan_bypass,                                        \
23609   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23610 _(sw_interface_set_geneve_bypass,                                       \
23611   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23612 _(sw_interface_set_l2_xconnect,                                         \
23613   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23614   "enable | disable")                                                   \
23615 _(sw_interface_set_l2_bridge,                                           \
23616   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23617   "[shg <split-horizon-group>] [bvi]\n"                                 \
23618   "enable | disable")                                                   \
23619 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23620 _(bridge_domain_add_del,                                                \
23621   "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") \
23622 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23623 _(l2fib_add_del,                                                        \
23624   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23625 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23626 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23627 _(l2_flags,                                                             \
23628   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23629 _(bridge_flags,                                                         \
23630   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23631 _(tap_connect,                                                          \
23632   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23633 _(tap_modify,                                                           \
23634   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23635 _(tap_delete,                                                           \
23636   "<vpp-if-name> | sw_if_index <id>")                                   \
23637 _(sw_interface_tap_dump, "")                                            \
23638 _(tap_create_v2,                                                        \
23639   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23640 _(tap_delete_v2,                                                        \
23641   "<vpp-if-name> | sw_if_index <id>")                                   \
23642 _(sw_interface_tap_v2_dump, "")                                         \
23643 _(bond_create,                                                          \
23644   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23645   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23646 _(bond_delete,                                                          \
23647   "<vpp-if-name> | sw_if_index <id>")                                   \
23648 _(bond_enslave,                                                         \
23649   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23650 _(bond_detach_slave,                                                    \
23651   "sw_if_index <n>")                                                    \
23652 _(sw_interface_bond_dump, "")                                           \
23653 _(sw_interface_slave_dump,                                              \
23654   "<vpp-if-name> | sw_if_index <id>")                                   \
23655 _(ip_table_add_del,                                                     \
23656   "table <n> [ipv6] [add | del]\n")                                     \
23657 _(ip_add_del_route,                                                     \
23658   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23659   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23660   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23661   "[multipath] [count <n>] [del]")                                      \
23662 _(ip_mroute_add_del,                                                    \
23663   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23664   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23665 _(mpls_table_add_del,                                                   \
23666   "table <n> [add | del]\n")                                            \
23667 _(mpls_route_add_del,                                                   \
23668   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23669   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23670   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23671   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23672   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23673   "[count <n>] [del]")                                                  \
23674 _(mpls_ip_bind_unbind,                                                  \
23675   "<label> <addr/len>")                                                 \
23676 _(mpls_tunnel_add_del,                                                  \
23677   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23678   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23679   "[l2-only]  [out-label <n>]")                                         \
23680 _(sr_mpls_policy_add,                                                   \
23681   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23682 _(sr_mpls_policy_del,                                                   \
23683   "bsid <id>")                                                          \
23684 _(bier_table_add_del,                                                   \
23685   "<label> <sub-domain> <set> <bsl> [del]")                             \
23686 _(bier_route_add_del,                                                   \
23687   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23688   "[<intfc> | sw_if_index <id>]"                                        \
23689   "[weight <n>] [del] [multipath]")                                     \
23690 _(proxy_arp_add_del,                                                    \
23691   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23692 _(proxy_arp_intfc_enable_disable,                                       \
23693   "<intfc> | sw_if_index <id> enable | disable")                        \
23694 _(sw_interface_set_unnumbered,                                          \
23695   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23696 _(ip_neighbor_add_del,                                                  \
23697   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23698   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23699 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23700 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23701   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23702   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23703   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23704 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23705 _(reset_fib, "vrf <n> [ipv6]")                                          \
23706 _(dhcp_proxy_config,                                                    \
23707   "svr <v46-address> src <v46-address>\n"                               \
23708    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23709 _(dhcp_proxy_set_vss,                                                   \
23710   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23711 _(dhcp_proxy_dump, "ip6")                                               \
23712 _(dhcp_client_config,                                                   \
23713   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23714 _(set_ip_flow_hash,                                                     \
23715   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23716 _(sw_interface_ip6_enable_disable,                                      \
23717   "<intfc> | sw_if_index <id> enable | disable")                        \
23718 _(ip6nd_proxy_add_del,                                                  \
23719   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23720 _(ip6nd_proxy_dump, "")                                                 \
23721 _(sw_interface_ip6nd_ra_prefix,                                         \
23722   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23723   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23724   "[nolink] [isno]")                                                    \
23725 _(sw_interface_ip6nd_ra_config,                                         \
23726   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23727   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23728   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23729 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23730 _(l2_patch_add_del,                                                     \
23731   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23732   "enable | disable")                                                   \
23733 _(sr_localsid_add_del,                                                  \
23734   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23735   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23736 _(classify_add_del_table,                                               \
23737   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23738   " [del] [del-chain] mask <mask-value>\n"                              \
23739   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23740   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23741 _(classify_add_del_session,                                             \
23742   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23743   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23744   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23745   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23746 _(classify_set_interface_ip_table,                                      \
23747   "<intfc> | sw_if_index <nn> table <nn>")                              \
23748 _(classify_set_interface_l2_tables,                                     \
23749   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23750   "  [other-table <nn>]")                                               \
23751 _(get_node_index, "node <node-name")                                    \
23752 _(add_node_next, "node <node-name> next <next-node-name>")              \
23753 _(l2tpv3_create_tunnel,                                                 \
23754   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23755   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23756   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23757 _(l2tpv3_set_tunnel_cookies,                                            \
23758   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23759   "[new_remote_cookie <nn>]\n")                                         \
23760 _(l2tpv3_interface_enable_disable,                                      \
23761   "<intfc> | sw_if_index <nn> enable | disable")                        \
23762 _(l2tpv3_set_lookup_key,                                                \
23763   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23764 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23765 _(vxlan_offload_rx,                                                     \
23766   "hw { <interface name> | hw_if_index <nn>} "                          \
23767   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23768 _(vxlan_add_del_tunnel,                                                 \
23769   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23770   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23771   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23772 _(geneve_add_del_tunnel,                                                \
23773   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23774   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23775   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23776 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23777 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23778 _(gre_add_del_tunnel,                                                   \
23779   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23780   "[teb | erspan <session-id>] [del]")                                  \
23781 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23782 _(l2_fib_clear_table, "")                                               \
23783 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23784 _(l2_interface_vlan_tag_rewrite,                                        \
23785   "<intfc> | sw_if_index <nn> \n"                                       \
23786   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23787   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23788 _(create_vhost_user_if,                                                 \
23789         "socket <filename> [server] [renumber <dev_instance>] "         \
23790         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23791         "[mac <mac_address>]")                                          \
23792 _(modify_vhost_user_if,                                                 \
23793         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23794         "[server] [renumber <dev_instance>]")                           \
23795 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23796 _(sw_interface_vhost_user_dump, "")                                     \
23797 _(show_version, "")                                                     \
23798 _(show_threads, "")                                                     \
23799 _(vxlan_gpe_add_del_tunnel,                                             \
23800   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23801   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23802   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23803   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23804 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23805 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23806 _(interface_name_renumber,                                              \
23807   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23808 _(input_acl_set_interface,                                              \
23809   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23810   "  [l2-table <nn>] [del]")                                            \
23811 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23812 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23813   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23814 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23815 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23816 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23817 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23818 _(ip_dump, "ipv4 | ipv6")                                               \
23819 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23820 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23821   "  spid_id <n> ")                                                     \
23822 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23823   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23824   "  integ_alg <alg> integ_key <hex>")                                  \
23825 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23826   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23827   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23828   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23829 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23830 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23831   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23832   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23833   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23834   "  [instance <n>]")     \
23835 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23836 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23837   "  <alg> <hex>\n")                                                    \
23838 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23839 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23840 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23841   "(auth_data 0x<data> | auth_data <data>)")                            \
23842 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23843   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23844 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23845   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23846   "(local|remote)")                                                     \
23847 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23848 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23849 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23850 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23851 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23852 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23853 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23854 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23855 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23856 _(delete_loopback,"sw_if_index <nn>")                                   \
23857 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23858 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23859 _(want_interface_events,  "enable|disable")                             \
23860 _(want_stats,"enable|disable")                                          \
23861 _(get_first_msg_id, "client <name>")                                    \
23862 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23863 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23864   "fib-id <nn> [ip4][ip6][default]")                                    \
23865 _(get_node_graph, " ")                                                  \
23866 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23867 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23868 _(ioam_disable, "")                                                     \
23869 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23870                             " sw_if_index <sw_if_index> p <priority> "  \
23871                             "w <weight>] [del]")                        \
23872 _(one_add_del_locator, "locator-set <locator_name> "                    \
23873                         "iface <intf> | sw_if_index <sw_if_index> "     \
23874                         "p <priority> w <weight> [del]")                \
23875 _(one_add_del_local_eid,"vni <vni> eid "                                \
23876                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23877                          "locator-set <locator_name> [del]"             \
23878                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23879 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23880 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23881 _(one_enable_disable, "enable|disable")                                 \
23882 _(one_map_register_enable_disable, "enable|disable")                    \
23883 _(one_map_register_fallback_threshold, "<value>")                       \
23884 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23885 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23886                                "[seid <seid>] "                         \
23887                                "rloc <locator> p <prio> "               \
23888                                "w <weight> [rloc <loc> ... ] "          \
23889                                "action <action> [del-all]")             \
23890 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23891                           "<local-eid>")                                \
23892 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23893 _(one_use_petr, "ip-address> | disable")                                \
23894 _(one_map_request_mode, "src-dst|dst-only")                             \
23895 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23896 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23897 _(one_locator_set_dump, "[local | remote]")                             \
23898 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23899 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23900                        "[local] | [remote]")                            \
23901 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23902 _(one_ndp_bd_get, "")                                                   \
23903 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23904 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23905 _(one_l2_arp_bd_get, "")                                                \
23906 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23907 _(one_stats_enable_disable, "enable|disable")                           \
23908 _(show_one_stats_enable_disable, "")                                    \
23909 _(one_eid_table_vni_dump, "")                                           \
23910 _(one_eid_table_map_dump, "l2|l3")                                      \
23911 _(one_map_resolver_dump, "")                                            \
23912 _(one_map_server_dump, "")                                              \
23913 _(one_adjacencies_get, "vni <vni>")                                     \
23914 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23915 _(show_one_rloc_probe_state, "")                                        \
23916 _(show_one_map_register_state, "")                                      \
23917 _(show_one_status, "")                                                  \
23918 _(one_stats_dump, "")                                                   \
23919 _(one_stats_flush, "")                                                  \
23920 _(one_get_map_request_itr_rlocs, "")                                    \
23921 _(one_map_register_set_ttl, "<ttl>")                                    \
23922 _(one_set_transport_protocol, "udp|api")                                \
23923 _(one_get_transport_protocol, "")                                       \
23924 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23925 _(one_show_xtr_mode, "")                                                \
23926 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23927 _(one_show_pitr_mode, "")                                               \
23928 _(one_enable_disable_petr_mode, "enable|disable")                       \
23929 _(one_show_petr_mode, "")                                               \
23930 _(show_one_nsh_mapping, "")                                             \
23931 _(show_one_pitr, "")                                                    \
23932 _(show_one_use_petr, "")                                                \
23933 _(show_one_map_request_mode, "")                                        \
23934 _(show_one_map_register_ttl, "")                                        \
23935 _(show_one_map_register_fallback_threshold, "")                         \
23936 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23937                             " sw_if_index <sw_if_index> p <priority> "  \
23938                             "w <weight>] [del]")                        \
23939 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23940                         "iface <intf> | sw_if_index <sw_if_index> "     \
23941                         "p <priority> w <weight> [del]")                \
23942 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23943                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23944                          "locator-set <locator_name> [del]"             \
23945                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23946 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23947 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23948 _(lisp_enable_disable, "enable|disable")                                \
23949 _(lisp_map_register_enable_disable, "enable|disable")                   \
23950 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23951 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23952                                "[seid <seid>] "                         \
23953                                "rloc <locator> p <prio> "               \
23954                                "w <weight> [rloc <loc> ... ] "          \
23955                                "action <action> [del-all]")             \
23956 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23957                           "<local-eid>")                                \
23958 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23959 _(lisp_use_petr, "<ip-address> | disable")                              \
23960 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23961 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23962 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23963 _(lisp_locator_set_dump, "[local | remote]")                            \
23964 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23965 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23966                        "[local] | [remote]")                            \
23967 _(lisp_eid_table_vni_dump, "")                                          \
23968 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23969 _(lisp_map_resolver_dump, "")                                           \
23970 _(lisp_map_server_dump, "")                                             \
23971 _(lisp_adjacencies_get, "vni <vni>")                                    \
23972 _(gpe_fwd_entry_vnis_get, "")                                           \
23973 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23974 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23975                                 "[table <table-id>]")                   \
23976 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23977 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23978 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23979 _(gpe_get_encap_mode, "")                                               \
23980 _(lisp_gpe_add_del_iface, "up|down")                                    \
23981 _(lisp_gpe_enable_disable, "enable|disable")                            \
23982 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23983   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23984 _(show_lisp_rloc_probe_state, "")                                       \
23985 _(show_lisp_map_register_state, "")                                     \
23986 _(show_lisp_status, "")                                                 \
23987 _(lisp_get_map_request_itr_rlocs, "")                                   \
23988 _(show_lisp_pitr, "")                                                   \
23989 _(show_lisp_use_petr, "")                                               \
23990 _(show_lisp_map_request_mode, "")                                       \
23991 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23992 _(af_packet_delete, "name <host interface name>")                       \
23993 _(af_packet_dump, "")                                                   \
23994 _(policer_add_del, "name <policer name> <params> [del]")                \
23995 _(policer_dump, "[name <policer name>]")                                \
23996 _(policer_classify_set_interface,                                       \
23997   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23998   "  [l2-table <nn>] [del]")                                            \
23999 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
24000 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
24001     "[master|slave]")                                                   \
24002 _(netmap_delete, "name <interface name>")                               \
24003 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
24004 _(mpls_fib_dump, "")                                                    \
24005 _(classify_table_ids, "")                                               \
24006 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24007 _(classify_table_info, "table_id <nn>")                                 \
24008 _(classify_session_dump, "table_id <nn>")                               \
24009 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24010     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24011     "[template_interval <nn>] [udp_checksum]")                          \
24012 _(ipfix_exporter_dump, "")                                              \
24013 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24014 _(ipfix_classify_stream_dump, "")                                       \
24015 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24016 _(ipfix_classify_table_dump, "")                                        \
24017 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24018 _(sw_interface_span_dump, "[l2]")                                           \
24019 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24020 _(pg_create_interface, "if_id <nn>")                                    \
24021 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24022 _(pg_enable_disable, "[stream <id>] disable")                           \
24023 _(ip_source_and_port_range_check_add_del,                               \
24024   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24025 _(ip_source_and_port_range_check_interface_add_del,                     \
24026   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24027   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24028 _(ipsec_gre_add_del_tunnel,                                             \
24029   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24030 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24031 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24032 _(l2_interface_pbb_tag_rewrite,                                         \
24033   "<intfc> | sw_if_index <nn> \n"                                       \
24034   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24035   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24036 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24037 _(flow_classify_set_interface,                                          \
24038   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24039 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24040 _(ip_fib_dump, "")                                                      \
24041 _(ip_mfib_dump, "")                                                     \
24042 _(ip6_fib_dump, "")                                                     \
24043 _(ip6_mfib_dump, "")                                                    \
24044 _(feature_enable_disable, "arc_name <arc_name> "                        \
24045   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24046 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24047 "[disable]")                                                            \
24048 _(l2_xconnect_dump, "")                                                 \
24049 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24050 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24051 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24052 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24053 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24054 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24055 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24056   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24057 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24058 _(sock_init_shm, "size <nnn>")                                          \
24059 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24060 _(dns_enable_disable, "[enable][disable]")                              \
24061 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24062 _(dns_resolve_name, "<hostname>")                                       \
24063 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24064 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24065 _(dns_resolve_name, "<hostname>")                                       \
24066 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24067   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24068 _(session_rules_dump, "")                                               \
24069 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24070 _(output_acl_set_interface,                                             \
24071   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24072   "  [l2-table <nn>] [del]")                                            \
24073 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24074
24075 /* List of command functions, CLI names map directly to functions */
24076 #define foreach_cli_function                                    \
24077 _(comment, "usage: comment <ignore-rest-of-line>")              \
24078 _(dump_interface_table, "usage: dump_interface_table")          \
24079 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24080 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24081 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24082 _(dump_stats_table, "usage: dump_stats_table")                  \
24083 _(dump_macro_table, "usage: dump_macro_table ")                 \
24084 _(dump_node_table, "usage: dump_node_table")                    \
24085 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24086 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24087 _(echo, "usage: echo <message>")                                \
24088 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24089 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24090 _(help, "usage: help")                                          \
24091 _(q, "usage: quit")                                             \
24092 _(quit, "usage: quit")                                          \
24093 _(search_node_table, "usage: search_node_table <name>...")      \
24094 _(set, "usage: set <variable-name> <value>")                    \
24095 _(script, "usage: script <file-name>")                          \
24096 _(statseg, "usage: statseg");                                   \
24097 _(unset, "usage: unset <variable-name>")
24098
24099 #define _(N,n)                                  \
24100     static void vl_api_##n##_t_handler_uni      \
24101     (vl_api_##n##_t * mp)                       \
24102     {                                           \
24103         vat_main_t * vam = &vat_main;           \
24104         if (vam->json_output) {                 \
24105             vl_api_##n##_t_handler_json(mp);    \
24106         } else {                                \
24107             vl_api_##n##_t_handler(mp);         \
24108         }                                       \
24109     }
24110 foreach_vpe_api_reply_msg;
24111 #if VPP_API_TEST_BUILTIN == 0
24112 foreach_standalone_reply_msg;
24113 #endif
24114 #undef _
24115
24116 void
24117 vat_api_hookup (vat_main_t * vam)
24118 {
24119 #define _(N,n)                                                  \
24120     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24121                            vl_api_##n##_t_handler_uni,          \
24122                            vl_noop_handler,                     \
24123                            vl_api_##n##_t_endian,               \
24124                            vl_api_##n##_t_print,                \
24125                            sizeof(vl_api_##n##_t), 1);
24126   foreach_vpe_api_reply_msg;
24127 #if VPP_API_TEST_BUILTIN == 0
24128   foreach_standalone_reply_msg;
24129 #endif
24130 #undef _
24131
24132 #if (VPP_API_TEST_BUILTIN==0)
24133   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24134
24135   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24136
24137   vam->function_by_name = hash_create_string (0, sizeof (uword));
24138
24139   vam->help_by_name = hash_create_string (0, sizeof (uword));
24140 #endif
24141
24142   /* API messages we can send */
24143 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24144   foreach_vpe_api_msg;
24145 #undef _
24146
24147   /* Help strings */
24148 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24149   foreach_vpe_api_msg;
24150 #undef _
24151
24152   /* CLI functions */
24153 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24154   foreach_cli_function;
24155 #undef _
24156
24157   /* Help strings */
24158 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24159   foreach_cli_function;
24160 #undef _
24161 }
24162
24163 #if VPP_API_TEST_BUILTIN
24164 static clib_error_t *
24165 vat_api_hookup_shim (vlib_main_t * vm)
24166 {
24167   vat_api_hookup (&vat_main);
24168   return 0;
24169 }
24170
24171 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24172 #endif
24173
24174 /*
24175  * fd.io coding-style-patch-verification: ON
24176  *
24177  * Local Variables:
24178  * eval: (c-set-style "gnu")
24179  * End:
24180  */